... | ... | @@ -21,4 +21,64 @@ We are planning to conduct the different robot experiments under the same condit |
|
|
|
|
|
## Self-balancing robot with light sensor
|
|
|
![Robot one](http://gitlab.au.dk/uploads/u4099/legolabtimadala/99055ed2cc/Robot_one.png)
|
|
|
##### Picture 1: Robot setup and height from sensor to surface, inspired by Philippe Hurbain[1]. |
|
|
\ No newline at end of file |
|
|
##### Picture 1: Robot setup and height from sensor to surface, inspired by Philippe Hurbain[1].
|
|
|
|
|
|
### Results
|
|
|
Below is shown a video[5] of our end result when experimenting with the self-balancing robot that uses a light sensor.
|
|
|
|
|
|
[![image alt text](http://img.youtube.com/vi/UJJ_rJSJfTQ/0.jpg)](http://www.youtube.com/watch?v=UJJ_rJSJfTQ)
|
|
|
##### Video 1: Self-balancing robot with light sensor
|
|
|
|
|
|
It is seen in Video 1[5] that we were not able to make the robot balance completely by itself, but only for 1 or 2 seconds, and then it tends to lose balance and tip over. Before this video was recorded we observed a better result, but unfortunately we did not get it on tape. We tried many different setups and parameters and this constellation was the best one we obtained. Changing the wheels to see if that made the robot more steady was also done, however we did not see any difference in the balancing. Our parameter tuning, code optimisation together with the context for the robot will be presented and discussed in the latter.
|
|
|
|
|
|
**Implemented code:**
|
|
|
Our program is based on the code in sejway.java by Brian Bagnall [2]. It is extended so it can control the variable of the PID and offset on-the-fly. It can be found in reference [8,9]. We have further tweaked the original program, and changed some of the choices he made. This will be commented below.
|
|
|
|
|
|
```
|
|
|
// Adjust far and near light readings:
|
|
|
if (error < 0) error = (int)(error * 1.8F);
|
|
|
|
|
|
// Integral Error:
|
|
|
int_error = ((int_error + error) * 2)/3;
|
|
|
```
|
|
|
Code Snippet 1[2]
|
|
|
|
|
|
As it is seen in the above code snippet Bagnall tries to hinder that the integral increases out of proportions by multiplying it with ⅔. This has been removed and replaced with a method that checks if the error changes signum and by that it resets the integral (setting it to 0). It is further seen that he is trying to adjust the error, by multiplying it with 1.8, if it less than 0, as a means of adjusting the far and near light readings. We tried to remove this, because we were not quite sure why it should do that, and actually obtained a better results.
|
|
|
|
|
|
Bagnall further scales the entire calculated PID value, as seen in Code Snippet 2. It looks like he does this because of the usage of integers as data types for the parameters, meaning that he can not use decimals and tries to correct for this by using a scale variable.
|
|
|
|
|
|
```
|
|
|
int pid_val = (int)(KP * error + KI * int_error + KD * deriv_error) / SCALE;
|
|
|
```
|
|
|
Code Snippet 2[2]
|
|
|
|
|
|
At first, we changed the data types for the variables to use float instead of the type of an integer. Unfortunately we had to reverse it back again, because we ran into some troubles, when implementing the on-the-fly change of parameters. The GUI would not allow for digits, even though we told it read float, so we had to rely on integers and the scale variable. Of course this is not optimal as we could lose some decimals on the way, but it is a must, in our case, for the ability to change the parameters on-the-fly, and thereby achieving an easier and better way of tuning the robot.
|
|
|
|
|
|
In the next experiment (with the other type of self-balancing robots) we will be using the same program as a base layout, and as mentioned before it can be found in references [8,9]. Below is a snippet (Code Snippet 3) from the program that illustrates how we calculate the PID value and resets the integral.
|
|
|
|
|
|
```
|
|
|
// Proportional Error:
|
|
|
int error = normVal - offset;
|
|
|
// Reset integral:
|
|
|
if (error == 0 || !hasSameSignum(error, prev_error))
|
|
|
int_error = 0;
|
|
|
int_error = int_error + error;
|
|
|
|
|
|
// Integral Error:
|
|
|
int_error = (int_error + error);
|
|
|
|
|
|
// Derivative Error:
|
|
|
int deriv_error = error - prev_error;
|
|
|
prev_error = error;
|
|
|
|
|
|
int pid_val = (int)(kp * error + ki * int_error + kd * deriv_error) / scale;
|
|
|
```
|
|
|
Code Snippet 3[8,9]
|
|
|
|
|
|
**Parameters:**
|
|
|
We have found our PID values without complex math as mentioned in [4], meaning that we have used trial and error until we found the best value for the different parameters. We have further looked at the tuning of these in relation to Table 1[10], that states the effects of increasing parameters independently. The best values we found was Kp=400, Ki=0, Kd=600 (remember we scale the values by 100), these gave the best balance although only for a few seconds as seen in Video 1[5]. We found it difficult to tune the Ki parameter, and every time we increased this by more than 1 the robot acceleration became too big and it overshot and crashed. The best value for Ki we found was 0.01 (1), and an example of this can be seen in Video 2[6] where we used Kp=400, Ki=1, Kd=600 as parameters.
|
|
|
|
|
|
We further tried to scale all the values to Kp=800, Ki=200, Kd=1600, but this resulted in a even worse result as seen in Video 3[7]. Lastly, we tried even more tuning, but eventually stopped when realising that is was almost impossible for the robot to be self-balancing by the use of the light sensor only.
|
|
|
|
|
|
![Skærmbillede 2015-03-25 kl. 11.59.10](http://gitlab.au.dk/uploads/u4099/legolabtimadala/9cf9093fc2/Sk%C3%A6rmbillede_2015-03-25_kl._11.59.10.png)
|
|
|
##### Table 1: Effects of increasing a parameter independently (Wiki) [10] |