Robotics, 2nd Semester (Jan-May) 2012
Nii Adjetey Sowah
-Build a two-wheeled robot using the Lego Mindstorm kit
-Properly equip the robot with a gyro sensor
-Programme the robot to achieve self-balancing using RobotC
– * Implement basic movement routines while auto-balancing
The main objective of this project is to achieve dynamic balancing with a two-wheeled LEGO robot. The model for this robot originated from the Segway. Figure 1 shows a commercially available self-balancing transportation device called a Segway .
The Segway type of balancing is a classic engineering problem known as the inverted pendulum problem. The inverted pendulum is a pendulum that has its mass suspended directly over its freely moving base. It is also a problem that can be found in Dynamics and Control theory . Figure 2 shows a picture of an inverted pendulum on a cart.
Robot design and other decisions:
Linear-quadratic regulator, lead-lag, state-feedback, pole placement, fuzzy controller, and proportional-integral-derivative controller, are all controllers that have been successfully used to control such an inherently unstable system like this Segway-type robot . For this project, the PID (proportional-integral-derivative) controller was chosen because of my familiarity with it. Fortunately, I found a sample program in the RobotC IDE directories (i.e. C:\Program Files (x86)\Robomatter Inc\ROBOTC Development Environment\Sample Programs\NXT\Miscellaneous) which implemented a PID controller on a two-wheeled robot. I used this sample program as the basis for my implementation.
The only sensor used in this project was an NXT gyro sensor from HiTechnic . The gyroscope (i.e. gyro sensor) provides a way to measure the rate of rotation, also known as angular rate. This gyroscope only returns readings on a single axis, and according to the manufacturer measures up to +/- 360 degrees per second of rotation.
For the most effective readings, the gyroscope needed to the placed at the correct and most sensitive part of the robot. After experimenting with many different placements, I finally found the most effective position for the robot. Figure 4 gives details of the fore-mentioned placement.
Implementation in RobotC programming language:
Before using the gyroscope from HiTechnic, I tested it with a few mini programmes that I wrote. The programmes were designed to only print out readings from the gyroscope. This was done to find out the bias of the sensor, since different gyro sensors have different biases. Instead of using the drivers from the manufacturer which will help me print out values ranging from +360 to -360, I printed raw values ranging from 0 to 1024 because I read that, using raw values makes the readings more accurate. After running my mini programme several times, I identified the bias of my gyro sensor. The gyro bias was 600. This value would be used as my equilibrium value in the main programme.
Figure 5 shows a general overview of the main programme. When the programme starts, it calculates the tilt of the robot using the gyro sensor readings. Since the gyroscope is unstable, to get a trust worthy tilt calculation, the gyro readings are sampled many times in a second and integrated to get the absolute position. These values are then averaged to get a more stable desired angle/tilt measure. Keep in mind that, every time a gyro sensor reading is made, the bias is accounted for, by the function defined as follows: (#define getGyroValue()(((SensorValue(GyroSensor)*-1)-GyroBias)/GyroScale)). After this stage, the programme also records the position of the wheels by reading the internal wheel encoders of the NXT Mindstorm robot. Using all these pieces of information, it then calculates the power required to drive the motors in order to catch the robot if it is falling. The PID controller is part of this section of the programme; it keeps track of the errors of previous calculations and adjusts to correct itself over time. Before the resulting power is supplied to the wheels, a function named driveadjustments() is called. Its job is to adjust the otherwise even power that will be sent to the two wheels. driveadjustments() connects via Bluetooth to a control-pad (another NXT brick), listening to whether or not a command to turn has been sent. After this stage, the power ranging from 0 to 100 is sent to the robot wheels.
In supplying the power level for the motors, the robot sometimes over-shoots. This occurrence causes the robot to fall after balancing for about 25 seconds. I tried to control this over-shooting behaviour by forcing the programme to assign the maximum power of +/- 100 when the controller gives a number beyond any of these two values. This did not work as it fell in even shorter periods. After doing some research, I found that some other programmers solved this problem by employing two PID controllers; one PID controller was used for the angle/tilt calculations and the other PID controller was used to control the behaviour of the wheels. However, I discovered this approach too late in my project, hence, I could not implement it. If I had implemented it, my research revealed that, the robot would even be able to maintain balance when it is hit by an outside/foreign force; it would balance in the midst of external disturbance like a push.
The code base I used was designed for a two-wheeled robot that had its gyro sensor on the opposite to the position I placed it on mine. Because of this, the robot initially could not balance at all. After I identified the issue, I multiplied all gyro readings by (-1). This solved the problem.
Picture of the robot for this project:
 Segway Inc. (2012). “Segway For Individuals: x2 Adventure” [Online]. Available: http://www.segway.com/individual/models/x2-adventure.php
 Wikipedia. (2012, April 26). “Inverted pendulum” [Online]. Available: http://en.wikipedia.org/wiki/Inverted_pendulum
 P. Miller. “Building a Two Wheeled Balancing Robot”. BEng. thesis, Univ. of South Queensland, Australia, 2008.
 Hitechnic. (2012). “HiTechnic NXT Gyro Sensor for LEGO Mindstorms NXT” [Online]. Available: http://www.hitechnic.com/cgi-bin/commerce.cgi?preadd=action&key=NGY1044