In my previous post, I introduced how to use stalling detection method to avoid motor stalling or identifying the existence of obstacles. That model is programmed with LEGO programming blocks. In this post, I will introduce how to use LEGO Micro Python 2.0 to do stalling detection and what are some issues in implementing this.
I will use the same vehicle model as that in the previous post. It has a front attachment driven by a medium motor. The attachment could rotate upward or downward. There are two big motors driving the wheels. Let’s start our coding of Micro Python 2.0 now.
This is the default head of main.py, and I just use it directly.
Method 1: Use touch sensor and time estimation
Like LEGO programming blocks, you could use touch sensor and time estimation to detect stalling in Micro Python 2.0. Please note that the units of some input parameters in Micro Python 2.0 are different from that in LEGO programming blocks.
For example, “motor.run (speed)” method. The input parameter “speed” specifies the rotation speed of motor as degree/second. While in LEGO programming blocks, both Medium Motor block and Big Motor blocks use power level to control the speed of the motor.
According to the information provided at the website ev3devpython, “The rated maximum speed of the Lego EV3 large motor is 1050 degrees per second. The rated maximum speed of the Lego EV3 medium motor is 1560 degrees per second.” Based on this information, we could convert proportionally between rotation speed and power level.
As in the below sample, when the medium motor’s speed is -300, its power level is approximately 300/1560 = 20%.
Another point needing attention is time unit. In Micro Python 2.0, all the time unit is milliseconds. Therefore, when we use “wait (2000)”, it means to wait 2 seconds, not 2000 seconds.
Method 2: Use “motor.run_until_stalled” function
In the previous LEGO programming block example, I use motor rotation data to check if stalling occurs. If the motor rotation degree does not change, it means that stalling happens. Good news is that stalling detection function has been defined in Micro Python 2.0, so you just need to use it directly.
In the above sample code, the medium motor at Port B calls “run_until_stalled” function twice. The first time, it calls this function to turn the front attachment upward till reaching the highest point. After waiting 2 seconds, the program calls this function again to turn the attachment downward to the lowest position.
Explanation of “run_until_stalled” function
The following is the specification of this method in LEGO Micro Python 2.0 Documentation.
Please note the first and third parameters in this function. The first parameter is speed, as I mentioned in the above section. It refers to the rotation degree per second of the selected motor. While the third parameter refers to the duty limit, which is corresponding to the power level used in LEGO programming blocks. If the duty limit is set to 60, the motor could not spin, then stalling happens. If the duty limit is set to 100 or None, the power level could increase to 100% before checking if stalling occurs.
In the above section, I have mentioned the proportional conversion relationship between rotation speed and duty_limit. If the first parameter “rotation speed” is bigger than what “duty_limit” could drive, the motor will run at the speed at which the duty limit could drive. If the rotation speed is smaller than the latter, the motor will run at the specified rotation speed.
For this method to run properly, you need to set a duty_limit a bit bigger than the expected speed. When a motor encounters the external resistance, it will maintain its speed but increase the duty level. When the duty level exceeds duty_limit, this method detects stalling.
Use this method to control big motors
In the above section, we use “run_until_stalled” to check stalling status of medium motor. How about using it to check big motors? Is it possible to detect stalling for big motors? The following is one code example.
In the above example, the program calls twice of “run_until_stalled” to check stalling for both left and right motors. However, “run_until_stalled” could not run simultaneously with the following code. Therefore, the code surrounded by red circle could not be executed to detect stalling of right motor. A workaround is to check one motor only. The updated code is shown below.
Motor Control Difference in Micro Python 2.0
In LEGO programming block, those motor related blocks, such as Big Motor, Medium Motor, Move Tank and Move Steering blocks, could not control speed directly, but use power level as input to control the speed. When the motor encounters obstacles, its power level is reduced due to the increased load. The rotation speed is reduced, too.
While in Micro Python 2.0, things are different. According to the information from website ev3devpython, “EV3 Python usually uses a feature called ‘speed regulation’ when using motors. When speed regulation is on, the motor controller will vary the power supplied to the motor to try to maintain the requested speed.” LEGO Micro Python 2.0 is based on EV3 Python, so it has the same feature.
Due to this logic, in Micro Python 2.0, when motor encounters resistance, it will try to maintain speed by increasing its duty level. When the external load is not big enough to reach duty_limit, the rotation speed could keep unchanged. Only when the motor’s duty level has exceeded the amount defined by “duty_limit”, “run_until_stalled” could detect stalling.
That explained why the function might fail when used to detect stalling of big motors running at a higher speed. As shown in the below video, the vehicle has reached the wall. When the motor is running at the speed of 500, the employed duty could not exceed the duty_limit even though duty_limit has been set a bit more than what could drive the vehicle at the specified speed. The big motor could still keep its speed without triggering stalling.
In summary, It has no problem to detect stalling of medium motors by using method “run_until_stalled”. Since the torque range of medium motor is small, an increase of load could easily make duty level exceed the threshold duty_limit, triggering stalling status.
However, it is not easy to use this method to detect if the vehicle touches the wall. It could work when big motor runs at low speed like lower than 250 degrees/second. When big motor runs at a speed higher than that, the existence of wall would make the wheels skid on the ground, but big motors still spin at the same speed. If your robot really needs to detect the wall, using touch sensor or ultrasonic sensor could be better choices.
Of course, LEGO Micro Python 2.0 is just a second version for LEGO to support Python. Let’s wait to see it improve in future. Anyway, enjoy the coding and have fun!
Note: All the analysis articles are copyright products of http://www.thecodingfun.com. Anyone re-posting them should credit author and original source. Anyone using them for commercial purposes or translating them into other languages should notify TheCodingFun and get confirmation first. All Rights Reserved.