[From Bruce Abbott (2018.02.20.1935 EST)]
The Lego Mindstorms EV3 kit comes with an electronic gyro sensor and plans to build a two-wheeled robot that can balance itself on its two wheels using the gyro sensor to determine the angle and rate of tilt. The robot acts as an inverted pendulum. To balance, it must keep its sensed angle close to vertical by constantly adjusting speed and direction of its wheel rotations as needed to compensate for disturbances.
Although the robot’s plans include a block-based program that allows the robot to balance and to move around under the control of an infrared transmitter, I decided to write my own program using a hierarchical control system similar to that developed by Bill Powers for the inverted pendulum demo that is included with LCS III. I couldn’t get it to work. In an attempt to identify the problem, I took a look at the signal coming from the gyro sensor, and found it to be rather noisy. It appears that my program was attempting to compensate for these random signal variations, thereby producing disturbances to angle that the program then attempted to compensate for, destabilizing the robot.
At this point I decided to try the program supplied for the robot and found it to work well. So how does it succeed where mine failed? Investigating the code, I discovered that the program actually reads the gyro signal five times in a row and then averages the readings, thus acting as a filter to reduce the sensor noise.
There are second-party vendors that supply their own EV3-compatible gyro sensors, including HyTechnic (the same company that produced my angle sensor). At the point in the program where the gyro readings are taken there is a SWITCH block that runs different code depending on whether the gyro in use is the one supplied by Lego or the HyTechnic one. The Lego version implements the filter. In contrast, the HyTechnic version simply reads the raw sensor value and multiplies it by -4. Apparently the HyTechnic version is a lot less noisy, eliminating the need to filter its output.
The balancing code supplied with the EV3 is quite complex and therefore difficult to follow. The block programming environment allows the user to create “MyBlocks” that are built up from the standard blocks and connections among them. For example, the gyro filter is implemented in a MyBlock called “ReadGyro.” The purpose of MyBlocks is to make the final program take up less real estate on the screen. If the MyBlocks are given descriptive names, they can also make the program steps easier to understand., e.g., ReadGyro returns the (filtered) gyro sensor readings.
By clicking on a MyBlock in the program, you can bring up the actual subprogram hidden in the block. Figuring out how the balancing program works requires understanding what each MyBlock accomplishes in addition to understanding how their functions contribute to the overall program. I’ve been working toward gaining a thorough understanding of how this program does what it does, after which I plan to try to create my own balancing program once again, using hierarchical control with appropriate filtering of the gyro signal.
It would be easier to program the EV3 (and understand how the program works) in a text-based language such as JAVA and I’ll probably be moving to that relatively soon. However, I’ve been curious to see what can be done with the supplied software. For simple programs it is child’s play to connect a few blocks and wire them up to do something useful (literally: I’ve had my 5 year old grandson make a couple). However, some steps that are rather simple in a text-based programming language become more involved when programming with blocks. For example, let’s say that you want to increment a number by 1. A textual statement that does this might look like this:
X = X + 1
Using blocks, you have to wire a Variable Block (holding the value of X) to a Math Block in which 1 is added to the input from the Variable Block, then connect the output of the Math Block to the same Variable Block in order to store the result in the same variable. That’s three blocks that have to be dragged onto the programming area and wired appropriately. In addition the Math Block has to be set to addition (+) and the unused input set to 1 (the number to be added to X). The first Variable Block has to be set to Read and the second instance to Write. All in all, it’s a more involved set of operations than simply typing X = X + 1. Creating and debugging a program as complex as the balancing program provided by Lego becomes a lengthy and involved process.
Bruce