Recommended Posts

The lego Powered Up motors and functions have been used to create a 3 speed automatic gearbox. With the Powered Up functions you can accurately control motor speed and motor position, as well as being able to measure the angular position of a motor. These new possibilities have been used to create a three speed automatic gearbox. One motor is used to measure the torque at the output of the gearbox by detecting the rotation of an output differential; another motor is used to accurately set the position of an orange rotary catch controlling the switching between three forward gears, and finally one large powered up motor is used to drive the gearbox. The gearbox implements 3 forward speeds at gearing ratios of 1 to 1, 1 to 0.6 and 1 to 0.2 as well as one manual reverse gear. The Powered Up app has been used to program the gearbox controller on an iphone. Thanks to (racingbrick.com) for providing a great guide to all of the available programming blocks.

Hope you enjoy this video.

 

https://youtu.be/CRkvFffDef8

Edited by TechnicBrickPower
Add link

Share this post


Link to post
Share on other sites

Have you thought of using the diff between set speed and actual speed to detect when to switch gears? That way you don't loose force/torque at the physical torque detector and you only need two instead of three motors.

Here is a quick mock-up:

800x400.png

Blocks from left to right:

  • sets the value of with a the yellow slider widget 0
  • shows the set value of a on yellow display widget 1
  • show the actual speed of the motor connected to port A and green display widget 2
  • the diff between a and the actual speed of the motor is is stored in the var b
  • b is shown in the red display widget 3
  • the green round block reads the value from a and sets the motor speed accordingly.

The result looks like that, when the motors is stalled:

800x400.png

You could switch gears based on the diff you see in the red widget, couldn't you?

Edited by Andman

Share this post


Link to post
Share on other sites

One question. Why don't you just easily measure the current/speed of the drive motor insetad of measuring it with yet another, third motor?

Share this post


Link to post
Share on other sites
3 hours ago, Zerobricks said:

One question. Why don't you just easily measure the current/speed of the drive motor insetad of measuring it with yet another, third motor?

How would you measure the current?

Share this post


Link to post
Share on other sites
2 hours ago, Andman said:

How would you measure the current?

Pretty sure the lego PU hub can measure the current.

Share this post


Link to post
Share on other sites
20 minutes ago, Zerobricks said:

Pretty sure the lego PU hub can measure the current.

@Pybricks, can pybrick read the current on a given port?

 @Zerobricks, what do you think about my proposal? I haven't tried it out. I'm worried about the diff being too quickly changing. So it might happen that the gear is witch rapidly when the diff is close to the value where the gearbox has to switch to another gear.

A possible solution could be to get the average of, for example, the last 10 values of the diff (set motor speed - actual motor speed). But i haven't found a solution to calculate a running/moving average so far. @TechnicBrickPower, any idea regarding the running average?

Share this post


Link to post
Share on other sites
56 minutes ago, Andman said:

@Pybricks, can pybrick read the current on a given port?

 @Zerobricks, what do you think about my proposal? I haven't tried it out. I'm worried about the diff being too quickly changing. So it might happen that the gear is witch rapidly when the diff is close to the value where the gearbox has to switch to another gear.

A possible solution could be to get the average of, for example, the last 10 values of the diff (set motor speed - actual motor speed). But i haven't found a solution to calculate a running/moving average so far. @TechnicBrickPower, any idea regarding the running average?

Sound like you need hysterisis and a bit of a more intelligent shifting to avoid oscillations and such. 

Share this post


Link to post
Share on other sites
1 hour ago, Andman said:

@Pybricks, can Pybricks read the current on a given port?

While the hubs don't have hardware current sensors for each individual port, Pybricks lets you measure the estimated load torque. It works by keeping track of the extra torque applied by the feedback controllers to maintain your requested speed or position.

Depending on what you need, this can be pretty accurate. It can even detect a paper load :)

 

 

Share this post


Link to post
Share on other sites
26 minutes ago, Zerobricks said:

But the hubs have to measure current some way for center steering?

The lego PU hub can indeed measure the current, but not per port, only for the whole hub.

On the other hand, motors have a mode called Load in the Lego Wireless Protocol, maybe that can be used here? I guess that's not accessible from the app, only with custom code.. I hooked up some quick experimental code, and I was able to read the load out of the motor; when the motor starts, the load jumps up in the beginning, and then decreases back to zero as the motor is running free. If I hold the output axle back with my hand, the load readout goes up to positive values.

@TechnicBrickPower or @kbalage, have you seen something like that in the PU app?

Edited by gyenesvi

Share this post


Link to post
Share on other sites
1 hour ago, gyenesvi said:

The lego PU hub can indeed measure the current, but not per port, only for the whole hub.

On the other hand, motors have a mode called Load in the Lego Wireless Protocol, maybe that can be used here? I guess that's not accessible from the app, only with custom code.. I hooked up some quick experimental code, and I was able to read the load out of the motor; when the motor starts, the load jumps up in the beginning, and then decreases back to zero as the motor is running free. If I hold the output axle back with my hand, the load readout goes up to positive values.

@TechnicBrickPower or @kbalage, have you seen something like that in the PU app?

What do you mean by experimental code? What would be the advantage over the possible solution I posted above?

Share this post


Link to post
Share on other sites
2 minutes ago, Andman said:

What do you mean by experimental code

Sorry for not being clear, I don't mean code in the PU app, but I mean a custom app running on my laptop, communicating with the hub through BT. I have done that before, just needed to play with the readouts a bit.

4 minutes ago, Andman said:

What would be the advantage over the possible solution I posted above?

I am not sure what would be the best way to tackle this problem, first I thought about the same solution as you mentioned. However, I remembered that I saw this load readout mode previously, and didn't know what it could be used for, and now figured it out. It could be a more direct way of achieving what you calculate with the speed differences, and therefore it may be a more robust way to do it. For example, I noticed that with new batteries there is no noticeable speed difference between the set speed and what you can read out of the motor when it's running free, but when the batteries are depleted the actual speed only reaches like 90% of what you set. At the same time, I'd expect the load would still be zero (for a free running motor), though I haven't tested. Such factors may impact the gear changing decision, though not sure what would be better in this case; maybe with depleted batteries it is better to switch to lower gear earlier.. Just thinking out loud.

Share this post


Link to post
Share on other sites
18 minutes ago, gyenesvi said:

For example, I noticed that with new batteries there is no noticeable speed difference between the set speed and what you can read out of the motor when it's running free, but when the batteries are depleted the actual speed only reaches like 90% of what you set.

I didn't think about that problem. Good catch!

19 minutes ago, gyenesvi said:

maybe with depleted batteries it is better to switch to lower gear earlier.. Just thinking out loud.

Agreed, since in that case the motor wouldn't be able to deliver enough torque. But measuring the load would be better. What bothers me more is, how can i calculate a running average of a given number of value of a certain interval in Powered Up to prevent to frequently oscillating gear switches. I'll probably create a thread in the Mindstorms forum tomorrow to ask for help.

Share this post


Link to post
Share on other sites

I'm glad to see some more effort being put into PU automatic gearboxes. I've played around with the concept before, with the shift point being determined by the difference between the motor's actual measured speed and the theoretical speed dictated by the remote's position, but this looks quite a bit more sophisticated.

Good job!

Share this post


Link to post
Share on other sites

@gyenesvi afaik there's no code block to access the current level in the PU app.

Regarding the automatic gearbox concept, I created some experimental code last year for the 42114 set that used the motor power vs motor speed difference to detect high/low load on the motor and shift accordingly:

It was before the custom controller interface and the simplified steering/throttle blocks were introduced so I'm sure it can be done in a much simpler way today. Recreating and fine tuning the code is in the pipeline, unfortunately among a lot of other things :)   

Share this post


Link to post
Share on other sites

I finally had an idea how to flatten the diff between the set and the actual speed. The goal with that code is to replace the physical torque detector. Here is my approach:

speed_diff_code_4.png

800x400.png

Declaration of variables/widgets/ports

a to j - stores the actual speed of the motor at a given time

v - speed set by slider widget 3

t - sets the interval at which the actual speed is read

y - sum of a to j divided by the number of data points (10 in my case)

z - difference between the measured average speed of the last 10*t seconds (1,5s in my case)

Port A - driving motor

Widget 0 - shows set speed

Widget 1 - shows actual motor speed

Widget 2 - shows the average diff between set and actual speed

Detailed walk-through

It's actually quite simple. Every 0,15s the actual motor speed an port A is measured and assigned to one of the 10 variables. Every time a value is stored the average of all ten variables is calculated. That makes the diff between set and actual speed less "jumpy".

I haven't really thought through how to deal with acceleration and deceleration done by the slider 3.

 

What do you guys think?

 

 

 

Edited by Andman
typo

Share this post


Link to post
Share on other sites

Nice @Andman. Since you tagged Pybricks earlier, I'll post a code example as well:

from pybricks.pupdevices import Motor
from pybricks.parameters import Port
from pybricks.tools import wait

# Run the motor at 500 deg/s
motor = Motor(Port.A)
motor.run(500)

# Print the load in mNm
while True:
    print(motor.control.load())
    
    # Wait to so we can read the value
    wait(100)

The load already varies smoothly so no averaging is needed.

This is used in the video above as well.

Share this post


Link to post
Share on other sites

Thanks @Pybricks! I thought a little bit about shifting gears and ac-/deceleration and have to think out loud.

So... when do we want to shift up?

  • When set speed is max (100) AND actual speed is 100 (or close to 100)

When do we not want to shift up?

  • When highest gear is already active
  • When driving backwards (depending on the model and the preferences)

When do we want to shift down again?

  • When set speed is max (100) AND actual speed is not 100 (or close to 100)
  • When set speed is 0 (shifts down to lowest gear)

When do we not want to shift down?

  • When lowest gear is already active

Did i miss anything?

I also noticed different behavior of the motor depending on which block you use to control it.

When i use the motor power 035.png , the motor is running at 112 when i set the slider position to 100. I assume that the hub is then providing the max current allowed and provided by the batteries. When the motor is stalled, it returns to the original speed before it was stalled.

When i use the tacho motor speed block 041.png the motor runs at more or less exactly at the set speed regardless, if your batteries could deliver more power. Another thing i noticed is that the motor "overshoots" for a short amount of time after it was stalled and released again. Means it will run for a short time at 112 in my case and the returns to the set speed 100

Not sure what to do with these findings yet.

Share this post


Link to post
Share on other sites
18 hours ago, Andman said:

how can i calculate a running average of a given number of value of a certain interval in Powered Up

You can try the following formula:

o = o * (1 - a) + i * a

where `i` is the input, `o` is the output, and `a` is a scaling factor between 0 and 1. A higher `a` is more sensitive to input changes.

Of course strictly this is not a running average - instead if `a` is 1/3, then the most recent input counts as 1/3, the second most recent is 2/9, the third 4/27, etc.

Edited by pleegwat

Share this post


Link to post
Share on other sites
14 hours ago, kbalage said:

afaik there's no code block to access the current level in the PU app

I guessed that, my question was more about accessing the load on a motor, but I suspect the answer is the same..

14 hours ago, kbalage said:

I created some experimental code last year for the 42114 set

Thanks for that video, I haven't seen that, great start with that concept!

@Andman Your method seems okay on paper, along with the cases for up/down shifting, but I have the feeling that if you tried to implement it you could run into some unexpected corner cases :) For example when the moving average hasn't yet caught up with a sudden change, it might trigger some false gear switches. These things just need to be tested in reality..

4 hours ago, pleegwat said:

o = o * (1 - a) + i * a

And yes, this exponential averaging could be an easier way to implement a moving average.

Share this post


Link to post
Share on other sites
11 minutes ago, gyenesvi said:

Your method seems okay on paper, along with the cases for up/down shifting, but I have the feeling that if you tried to implement it you could run into some unexpected corner cases :) For example when the moving average hasn't yet caught up with a sudden change, it might trigger some false gear switches. These things just need to be tested in reality.

Absolutely right. Testing a lot IRL is absolutely mandatory. But to use something like that IRL was the purpose from the beginning on! :-) A pity that I dissembled my 42114 for another MOC. I don't have any C+ motors left to assemble it again.

As for the extrem cases, a sudden stop could be handled by a conditional statement, which monitors the actual motor speed, for the gear shifting logic, which i haven't build yet, to immediately stop the motor(s) or shift to lower/neutral gear.

5 hours ago, pleegwat said:

o = o * (1 - a) + i * a

Will try to replicate that in Powered UP. Thanks!

Edited by Andman

Share this post


Link to post
Share on other sites
On 6/21/2021 at 11:04 PM, Zerobricks said:

One question. Why don't you just easily measure the current/speed of the drive motor insetad of measuring it with yet another, third motor?

Hi Zerobricks. Thanks mate that is a great suggestion - I had tunnel vision with my solution - I think that will work very well and will solve a few issues that I had tuning the torque measurement system. Look forward to trying that idea.

Cheers!

Share this post


Link to post
Share on other sites
On 6/21/2021 at 10:16 PM, Andman said:

Have you thought of using the diff between set speed and actual speed to detect when to switch gears? That way you don't loose force/torque at the physical torque detector and you only need two instead of three motors.

Here is a quick mock-up:

800x400.png

Blocks from left to right:

  • sets the value of with a the yellow slider widget 0
  • shows the set value of a on yellow display widget 1
  • show the actual speed of the motor connected to port A and green display widget 2
  • the diff between a and the actual speed of the motor is is stored in the var b
  • b is shown in the red display widget 3
  • the green round block reads the value from a and sets the motor speed accordingly.

The result looks like that, when the motors is stalled:

800x400.png

You could switch gears based on the diff you see in the red widget, couldn't you?

Hi Andman, Thanks for your great suggestion and code blocks - it's something I totally didn't think about or realize was a possibility - I have come to Powered Up from a Power Functions upbringing! LOL

Share this post


Link to post
Share on other sites
On 6/22/2021 at 6:03 PM, pleegwat said:

You can try the following formula:

o = o * (1 - a) + i * a

While both, your formula and my approach, have the same responsiveness and serve their purpose, especially at lower values for a, i much prefer your solution. It is less code to "write"! So thanks again for sharing!

I made a mistake. Have to rebuild the code.

Edited by Andman

Share this post


Link to post
Share on other sites

Hi, 

gonna dig up this topic. I’m trying to recreate 42114 control+ scheme using powered up custom controls. Right now I’m kinda stuck at automatic gearbox blocks. I managed to make it work, I’ve found a way to stop the drive motor (without releasing throttle button) for the moment when gears are changing like in original control+. What I came up with is to store variable at the start of changing procedure, and if throttle loop detects it then it lowers the power to 0, and after changing gear variable is changed and full power restored. Works ok, but not that smooth like in original app, so I’m wondering if there’s better way to stop motor before changing gear. Any help will be highly appreciated.

https://drive.google.com/file/d/1SprVPSXxYK0udDemFoueVW0UvmC1nnmQ

https://drive.google.com/file/d/1_GLE8aNM3280yCVEBHmoMUkkGp6X_N29/view?usp=drivesdk

Edited by bsodziak

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.