|
|
# Group 8
|
|
|
|
|
|
## Lab Notebook 3
|
|
|
|
|
|
**Date:** 2/3 - 2015
|
|
|
|
|
|
**Duration:** 6-8 hours
|
|
|
|
|
|
**Participants:**
|
|
|
|
|
|
- Frederik Jerløv
|
|
|
- Casper Christensen
|
|
|
- Mark Sejr Gottenborg
|
|
|
- Peder Detlefsen
|
|
|
|
|
|
## Goal
|
|
|
The goal is to equip our NXT Robot with a light sensor and execute the exercises.[1]
|
|
|
|
|
|
## Plan
|
|
|
Our plan is to follow the exercises exactly as described.
|
|
|
|
|
|
## Results
|
|
|
|
|
|
### Exercise 1
|
|
|
During this exercise we mounted a light sensor on our robot, much like we did in the first week of the course, which were documented in Lab Report Notebook 1. The goal was to test the class `BlackWhiteSensor.java` by exposing it to different colors. We first calibrated the sensor using the method made available to us in the class. This was done by placing the robot on a black surface followed by a white one to let the robot know which light reading corresponds to black and white. After the initial calibration we did some experiments with different shades of black and white.
|
|
|
|
|
|
The first thing we noticed was that the sensor was very good at distinguishing clear black and white since the readings for black were around 33-35 compared to 56-59 for white. We also discovered that the sensor readings were basically the same in a pitch black room as in a well light one.
|
|
|
One problem we found was that some yellow and red colors had the same readings as white and some blue colors, such as the floor in Zuse, had almost the same values as black.
|
|
|
Another thing was that sensor doesn’t read the light value of a single point but rather a small circle. This means that if you measure the value right where white changes to black you will get a value of e.g. 45 and not 34 or 57.
|
|
|
|
|
|
### Exercise 2
|
|
|
Following the black line did not show any problems at first hand, but on closer inspection hard turns could give some problems, as the robot did not always read these correctly, which left it spinning around itself. We experienced this very same problem back in Lab report 1, and know that the problem was the sensor not being able to read the black line fast enough for it to correct its course, the solution were to lower the speed of the robot giving it more time to correct for changes in the sensors read values.
|
|
|
|
|
|
### Exercise 3
|
|
|
We wrote the program `ThreeColorSensor.java`[3] based on the `BlackWhiteSensor.java`[4] which includes a third color (Green). This makes it possible to detect a third light value, and have two different light thresholds to work with instead of just one. That extra threshold made it possible for us to set new behavior for the robot. Below is shown a snippet for the code
|
|
|
|
|
|
```Java
|
|
|
public void calibrate()
|
|
|
{
|
|
|
blackLightValue = read("black");
|
|
|
whiteLightValue = read("white");
|
|
|
greenLightValue = read("green");
|
|
|
|
|
|
// The threshold is calculated as the median between
|
|
|
// the two readings over the two types of surfaces
|
|
|
blackGreenThreshold = (blackLightValue+greenLightValue)/2;
|
|
|
greenWhiteThreshold = (greenLightValue+whiteLightValue)/2;
|
|
|
}
|
|
|
|
|
|
public boolean green() {
|
|
|
int light = ls.readValue();
|
|
|
return (blackGreenThreshold < light && light < greenWhiteThreshold);
|
|
|
}
|
|
|
```
|
|
|
To the ```calibrate```method we added a calibration of the third sensor for green. Then we made two thresholds ```blackGreen```and ```greenWhite``` in order to distinct the 3 colors. We did some testing by measuring the three different colors by having the robot standing still on top of the colors using the program ```ThreeSensorTest```[5]. Here the robot distincted the three colors correctly. Then when we started trying running the line follower from ```exercise 1``` again. Here we ran into trouble because when shifting between white and black we enter the state green, because the green threshold was in between white and black. So in order to make the line follower stop at a green zone we should be sure that we are in the green zone and not just switching between black and white. This can be achieved by checking that the last ```n``` readings was green. This trick we will use in the next exercise.
|
|
|
|
|
|
### Exercise 4
|
|
|
The goal of this exercise was to make a line follower using the ```ThreeColorSensor```we made in the previous exercise. As we saw in the previouse exercise, when changing from white to black the sensor would read the value as green, making it stop. In order to fix this problem we check made sure that we have seen 50 green readings before we chose to stop.
|
|
|
Below is a code snippet of the used program ```LineFollower.java```[6]
|
|
|
|
|
|
```Java
|
|
|
while (! Button.ESCAPE.isDown())
|
|
|
{
|
|
|
LCD.drawInt(sensor.light(),4,10,2);
|
|
|
LCD.refresh();
|
|
|
|
|
|
if ( sensor.black() ) {
|
|
|
Car.forward(power, 50);
|
|
|
greenCounter = 0;
|
|
|
} else if ( sensor.white() ) {
|
|
|
Car.forward(50, power);
|
|
|
greenCounter = 0;
|
|
|
} else if ( sensor.green() ) {
|
|
|
Car.forward(power, power);
|
|
|
greenCounter++;
|
|
|
}
|
|
|
|
|
|
if (greenCounter >= 50) {
|
|
|
Car.stop();
|
|
|
}
|
|
|
|
|
|
if (Button.ENTER.isDown()) {
|
|
|
greenCounter = 0;
|
|
|
}
|
|
|
|
|
|
Thread.sleep(10);
|
|
|
}
|
|
|
```
|
|
|
|
|
|
As we can see from the code each time we see green, we count ```greenCounter``` one up. Then we check if we have seen green for the last 50 times. If so we would stop cause then we were in the green zone.
|
|
|
|
|
|
Below is a video to the Line Follower as described above running on a big square track.
|
|
|
[LineFollower on the big square track](http://1drv.ms/1GeWo0m)
|
|
|
|
|
|
Below is a video of the Line Follower as described above trying to make a 90 degree turn and failing.
|
|
|
[LineFollower at a 90 degree turn](http://1drv.ms/1GeWAg1)
|
|
|
|
|
|
Below is a video of the Line Follower as described above stopping when it reaches a green zone on the track.
|
|
|
[LineFollower stopping in the green zone](http://youtu.be/JGIgmwjfyAA)
|
|
|
|
|
|
### Exercise 5
|
|
|
|
|
|
For this exercise the goal was to make a PID Line Follower that should be able to follow the line more smoothly and also driver faster. To get us started we implemented the pseudocode for a PID controller [2] but had difficulties figuring out proper values for the constants `Kp`, `Ki` and `Kd`. This meant that our first few guesses resulted in a robot that would immediately move away from the line and start spinning in circles. Then later we realised that there was a section about how to calibrate the constants so we used it to calculate proper values. Here’s our control loop that we implemented in ```PIDLineFollower.java```[7] based on the pseudocode:
|
|
|
|
|
|
```Java
|
|
|
while (! Button.ESCAPE.isDown())
|
|
|
{
|
|
|
int lightValue = sensor.light();
|
|
|
int error = lightValue - offset;
|
|
|
integral += error;
|
|
|
derivative = error - lastError;
|
|
|
|
|
|
double turn = Kp * error + Ki * integral + Kd * derivative;
|
|
|
turn /= 100;
|
|
|
int powerLeft = Tp - (int)turn;
|
|
|
int powerRight = Tp + (int)turn;
|
|
|
|
|
|
Car.forward(powerLeft, powerRight);
|
|
|
|
|
|
lastError = error;
|
|
|
Thread.sleep(10);
|
|
|
}
|
|
|
```
|
|
|
|
|
|
The first constant to define was `Kc` which would later be used to calculate `Kp`. This one was found by only using the `Kp` value to calculate the `turn` variable in our program. The LEGO robot should oscillate within 0.5 seconds and 2 seconds and still stay on the line and we found that it did so with a `Kp` of around 150 so this became our `Kc`. We kept power at 65 since setting the power to 75 was too much and the oscillation resulted in the robot going over the line in correction. Now we just needed to determine the time per loop (`dT`) and oscillations per second (`Pc`). We didn’t measure `dT` but set it to 0.015 seconds as this was suggested in the article. Finally we set `Pc` to 1 as an initial value but this was later adjusted a bit to fine tune the robot. When we had all the variables we used the Ziegler-Nichols method to calculate our `Kp`, `Ki` and `Kd`.
|
|
|
|
|
|
To do the actual fine tuning we modified `Kc`, `dT` and `Pc` one at a time to see what gave the best result. After that we started incrementing the power with steps of 5 and ended up with a successful run at power of 100. Here’s a [video of the run on the oval track](https://www.youtube.com/watch?v=LRy1er3wP_c). We managed to run with power 75 on the small round track and [here’s the video](https://www.youtube.com/watch?v=P9joxvXGXPo). Furthermore, the robot could also run with power 75 on large square track which we also made a [video of](http://1drv.ms/1DYjWnO). However, we could only run 65 on the small square track which can be seen in this [video](http://1drv.ms/1DYk2M0). This was most likely because we didn’t modify the PID algorithm at all.
|
|
|
|
|
|
## Exercise 6
|
|
|
We were not able to attend the lecture and did not get to request a color sensor, we were therefore not able to do this exercise.
|
|
|
|
|
|
## Conclusion
|
|
|
We used the light sensor in order to make a NXT robot follow a black and then stop when it reached the end, indicated by a green zone. We made 2 kind of robots a simple one which just zigzag through black and white then stop when it sees green. The other we used PID to control the robot and then stop in the green zone.
|
|
|
|
|
|
## References
|
|
|
[1], [Exercise material](http://legolab.cs.au.dk/DigitalControl.dir/NXT/Lesson4.dir/Lesson.html)
|
|
|
|
|
|
[2], [PID Controller For Lego Mindstorms Robots](http://www.inpharmix.com/jps/PID_Controller_For_Lego_Mindstorms_Robots.html)
|
|
|
|
|
|
[3], [ThreeColorSensor code](https://gitlab.au.dk/lego-group-8/lego/blob/master/lesson4/ThreeColorSensor.java)
|
|
|
|
|
|
[4], [BlackWhiteSensor](http://legolab.cs.au.dk/DigitalControl.dir/NXT/Lesson4.dir/Lesson4programs/BlackWhiteSensor.java)
|
|
|
|
|
|
[5], [ThreeSensorTest code](https://gitlab.au.dk/lego-group-8/lego/blob/master/lesson4/ThreeSensorTest.java)
|
|
|
|
|
|
[6], [LineFollower code](https://gitlab.au.dk/lego-group-8/lego/blob/master/lesson4/LineFollower.java)
|
|
|
|
|
|
[7], [PIDLineFollower code](https://gitlab.au.dk/lego-group-8/lego/blob/master/lesson4/PIDLineFollower.java)
|
|
|
|