Week 3

We experiment with the ultrasonic sensor and complete the exercises for Lego Lab 2.

Duration of activity: 10 hours
Group members participating: Ole Rasmussen, Kasper Sørensen

Computer Environment

We are running leJOS on Windows 7 and 8 both 64 bit using IntelliJ (NOT eclipse =)).

Goal

To complete the exercises for Lego Lab 2.

We will experiment with the ultrasonic sensor and in the process construct a line-follower robot (the 9797 robot with the sensor mounted).

Plan

Since our goal is to complete the exercises for this weeks lab the plan will be to complete each exercise in sequence:
  1. Exercise 1: Ultrasonic sensor experiments with different objects
  2. Exercise 2: Experimenting with the sample interval in leJOS of the ultrasonic sensor
  3. Exercise 3: Sensor distance and time limit measurements
  4. Exercise 4: Tracker robot and experiments with its constants
  5. Exercise 5: Tracker robot oscillation and PID
  6. Exercise 6: Wall follower

Exercise 1

In this exercise we will experiment with the ultrasonic sensors by placing it in front of different objects and comparing its readings to the real distance.

Factors

  • Object size: how small (and large) objects can the ultrasonic sensor detect and how does object size affect the sensor accuracy? What is the optimal size?
  • Object material: which types of material can the ultrasonic sensor detect? Are there any materials it cannot detect at all? How does the material affect the sensor accuracy? What is the optimal material?
  • Object shape: what effect does the object shape have on the sensor accuracy? Are there any shapes the sensor cannot detect? What is the optimal shape?
  • Distance to object: does distance affect the sensor accuracy? What is the optimal distance or distance range?

Setup

We have used a whiteboard on which we have a diagonal line. On this line we have marked the distance between the two corners in 10cm increments - since the whiteboard was only 190cm diagonally (and we needed around 250cm) we have extended it with two papers. We will place the LEGO 9797 car with the ultrasonic sensor in one corner such that the ultrasonic sensor is exactly above the corner and we will then place the different objects on the line at different distances. See Figure 1.
Figure 1 - Setup

Results

Figure 2 - Red paper case
We used four different objects:
  • Red paper case: See Figure 2. 
  • Sweatshirt: See Figure 3.
  • Hood with wool-like texture: See Figure 4.
  • Small transformer: See Figure 5.
Figure 2 shows the results for the red paper case. The transformer was undetectable when the distance was above 40cm's, but below it was comparable with the red paper case. The sensor had a difficult time detecting the sweatshirt or the hood. If detected in one echo, it could easily disappear in the next.
Figure 3 - Sweatshirt being tested
Figure 4 - Hood being tested
Figure 5 - Transformer being tested

Analysis

Object size
As can be seen from the tables large objects (the red paper case) can be detected from all distances within the limits (6-254). At larger distances, it was increasingly hard to get the NXJ to detect it. We had to make sure it was not slightly tilted to either side. With small objects it is very hard for the sensor to see when they aren't close. For example we experienced that the sensor had a hard time seeing the transformer at a distance of more than 40cm. Our conclusion is that the larger the objects the easier they are to detect and the further away they can be detected.

Object material
The material of four objects was: rugged plastic (red paper case), smooth plastic (transformer) and wool-like fabric (hood and sweatshirt). Our experiment showed (can't be seen in the tables) that the sensor easily detected the plastic objects but had a harder time detecting the wool-like fabric of the hood. This was expected as the material of the sweatshirt and hood has a very uneven and soft surface thus absorbing more sound than the others. Our conclusion is that materials that absorb a lot of sound are harder to detect.

Object shape
We haven't directly tested the shape of the objects. However, we have seen that if we tilt the red paper case slightly, the sensor is unable to detect it. We therefore believe that the shape has a very high impact on the readings. Optimal shapes are those that are perpendicular on the sensor and thus reflect a maximum amount of sound back in the direction of the sensor.

Distance to object
The measurements seems to be fine in the range from [7, 250] where we had very precise readings. However, as already mentioned, it is increasingly difficult to detect the target at larger distances. At the range [0,6] the device always registers a distance of 6cm but smaller objects are easier to detect at smaller distances.

Exercise 2

In this exercise we will experiment with different values of sample intervals (delays) when reading from the sensor.

Figure 6 - The sleep interval in old leJOS must be at least 300ms

In old versions of leJOS it was necessary to wait minimum 300ms between the ultrasonic sensor readings (see Figure 6) due to a bug. This should no longer be the case and we want to verify that.

Results

We tried changing the sleep interval to 150ms, 100ms, 50ms and finally 1ms in the program seen in Figure 6. As far as we could see all intervals worked perfectly fine so we completely removed the sleep from the loop. This also worked out fine.

Analysis

Figure 7 - UltrasonicSensor.getDistance method source code
We were curious as to why the program functioned normally without sleeping at all so we took at look into the source code of UltrasonicSensor (Figure 7). It turns out that the getDistance method has an internal sleep instruction that waits until the sensor is ready before reading its value and returning. When the sensor is in "normal" mode the wait time is DELAY_DATA_OTHER which is defined as 30ms. From this we can conclude that the time it takes to read two consecutive sensor values is minimum 30 milliseconds. In practice it is probably a bit higher (more around 35) due to the overhead in processing the data inside the ultrasonic sensor as well as communicating it over I2C.

We can conclude that it is no longer necessary to wait manually between ultrasonic sensor readings as leJOS does that by itself internally.

Exercise 3

We are asked to answer if it is possible to detect objects at a distance of 254 centimeters using the ultrasonic sensor and at what circumstances if possible. We are also asked if there are any time limits and if that might limit the sensor usage.

Results

We have already tested if the sensor was able to find objects at a distance of 254cm, which it was (See Exercise 1). We used the red paper case, and it was very hard to get it position so that the sensor could pick it up. We can therefore conclude, that we cannot rely on the sensor to pick up objects at such a distance.

In the worst case, the sensor has to wait for a response from an object 254 cm's away, meaning that the sound would need to travel 254*2 = 508cm. The time it takes for sound to travel such a distance is ~14.93ms, meaning that we cannot make (different) measurements unless we wait this long.
One could argue that if you detect an object at a closer range, you can immediately issue a scanning, decreasing the wait time if a close object is detected. However, if such a strategy is used, it might be possible that when sending a new ultrasonic pulse, a prior echo may return, making the sensor think that an object is really close. Therefore to conclude, one has to wait at least 14.93ms, and possibly more. A safe 30ms is used in leJos to safeguard against this (See Exercise 2).

The delay time practically does not limit the sensor capabilities. However, there are circumstances where it is not usable. For example, the sensor could have a hard time detecting small objects flying by at high speeds, for example a pendulum.

Exercise 4

In this exercise we will experiment with the Tracker Beam robot provided by the following code: Tracker.java, Car.java.

Observed robot behavior

We have observed the behavior of the robot. The robot will try to keep a constant distance to an object in front of it. If it is too close to the object it will back off and if it is too far away it will approach. The speed at which is backs off or approaches depends on the distance to the object. When the robot gets within the desired distance it will start oscillating back and forth and never settle on a single position.

Without having seen the source code we believe this to be a P-controller (without integral and derivative terms). The proportional term is used to drive the robot towards its goal. The derivative term is used to stop/dampen oscillations which this robot clearly have so we don't believe there is a D term in the code.

Changing the constants

The gain constant has a default value of 0.5. We tried changing it to 0.1 which resulted in the robot driving slower overall. Changing it to 0.9 had the opposite effect and made the robot drive faster overall. This was expected as the gain controls how much influence the error has on the power to the motors. With a small gain a given error value won't influence the motor power as much as with a large gain.

We tried changing another constant, minPower, to 20 and the result was that the robot would halt well before reaching its designated distance. This was expected as we know from prior experience that the Lego motors need a certain amount of power to move; even though it's programatically possibly to send i.e. 10 power to a motor that does not mean that the motor will move. Our experience tells us that we need at least 55 power to move a motor with a Lego 9797 robot body attached.

Exercise 5

In this exercise we are asked to change the constants so that the Tracker will oscillate around the goal value. We are also asked to use a derivative term in the power calculation to remove these oscillations.

Early observations

Figure 8 - The Tracker.java program
Before doing the actual exercise we examined the source code in Tracker.java.

We noted there was an if-statement surrounding the P-control loop ([1] on figure 8). It ensures that the motor power is set to 100 (full power) when the distance reading from the sensor is 255 (no objects in sight). This seemed strange to us: is that a real P-controller? In practice what's happening is that we override whatever value is calculated for the controlled variable when the sensor doesn't detect any objects. We can see the point; the sensor has a limit of 255 cm and therefore we assume that we need to set the power to 100 for any objects farther away, but what if we wanted the car to approach the object really slowly from 500cm away? We would do this by setting a low pGain (lets say 0.3) but with the if-statement overriding it wouldn't work. We want the car to drive with a power of pGain*(distance-desiredDistance) = 0.3*(255-35) = 66 but it would drive with 100 for anything farther away than 255 due to the if-statement. We believe this to be an artificial restriction with no use in our experiment so we removed the if-statement to make the code clearer.

As mentioned earlier a Lego motor requires a certain amount of power to begin rotating. Typically this is somewhere between 40 and 60 depending on the load on the motor. For a PD controller to work the Lego car needs to stand still when the calculated power is 0. For the Tracker.java program this will only be the case if the car stands still at a power of minPower due to the way the control loop works (marked by [2] in figure 8). The question is does our lego car stand still at the default minPower value of 60? Who says this value applies to our specific robot and environment? For example different floors have different resistance and the robot may have a harder time moving on eg. carpet than hardwood floors. For the experiment to work we of course need to calibrate the minPower constant such that the Lego car will be on the verge of moving when provided with the power value in minPower. We experimented and concluded that the default constant of 60 would move our car on the hardwood floor easily so we adjusted it to 55 where it was just below the limit of movement.

Changing the constants

We couldn't get the car to oscillate around 35cm. What we did manage, however, was to make it overshoot the target by a few cm when setting the pGain value to 4. This is the phenomenon we seek to minimize with the derivative term introduced next.

Introducing the D term

Our first shot was calculating the derivative term by calculating the difference in distances for each measurement. We found out that this didn't work because the difference in distances measured were too small to have any impact in the PD equation. In other words, the resolution of the ultrasonic sensor was too low. We needed another value with a higher resolution and that is why we turned to the tacometer in the Lego motors.

We implemented the new derivative term by the difference between the taco counts of the left motor at each sample (could have been the right as well, they are given equal power always so it doesn't really matter). We experimented with different dGain values and eventually settled at 0.6 as that seemed to eliminate the overshoot.

Results

Figure 9 - Comparison of  the robot approach a wall with and without the derivative term
Figure 9 shows two graphs with the power, error and velocity values logged in the Lego robot when approaching a wall from approximately 80cm. We can see that the the initial run is basically identical but when the car gets close to the wall the behaviors are very different. Figure 10 shows the last part of the run in detail.
Figure 10 - Last part of the run (figure 9) in detail
From figure 10 we can see that the overshoot is minimized like we aimed for. It is however not a perfect PD control. Optimally we would like the PD controller to smoothly stop the Lego car and in our case it does that, almost. The car oscillates a bit before settling as can be seen on the power curve. We couldn't fix this so the graph shows the best result we could achieve within limited time. The comparison between the P and PD controller boils down to this: either the car overshoots a bit but doesn't oscillate (dgain 0) or the car doesn't overshoot but oscillates a bit. 

Conclusion

We had time to do all exercises except from exercise 6. We have looked at it but haven't built the robot. Perhaps we will do it next time.