Week 6

In this lab session we will try to make a self-balancing LEGO robot inspired by Steve Hassenplug's original Legway controlled by the RCX [1].

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

Figure 1: The NXTWay self-balancing robot inspired by Steve Hassenplug's Legway

Goal

To complete the exercises for Lego Lab 5.

Plan

Since our goal is to complete the exercises for this weeks lab the plan will be to complete each exercise in sequence:

  1. Self-balancing robot with light sensor
    Constructing and experimenting with a self-balancing NXT robot using a light sensor
  2. Choice of parameters on-the-fly
    Expand the self-balancing robot with the ability to change parts of it's source code (constants) on-the-fly via Bluetooth.
  3. Self-balancing robot with color sensor
    Experiment with using the color sensor instead of the light sensor for the balancing robot.
  4. Alternative self-balancing robot - horizontal NXT unit
    Constructing and experimenting with an alternative self-balancing NXT robot using a light sensor. This robot will have the NXT laying down and an overall different construction.

1. Self-balancing robot with light sensor

We will construct the LEGO robot, NXTway, suggested by Phillippe Hurbain [2] and use the java program Sejway.java from Brian Bagnall [3] on this robot. Then we will experiment with it and try to find out under which conditions it works best.

1.1 Factors

Phillippe Hurbain [2] describes three factors that may influence the workings of the self-balancing robot:
  • Lighting conditions: the ambient light may influence the light readings from the sensor. If artificial lighting is used it's also possible that the type of light emitted has an effect. For example Phillippe mentions that fluorescent light is best because it emits very little infrared light that can influence the light sensor.
  • Surface: the surface on which the light reflects may affect the light sensor readings. According to Philippe a clear and non-uniform surface is best.
  • Equilibrium position: the robot needs to be calibrated to an offset/equilibrium that is perfectly balanced by manually placing it in the desired position. One should be careful when doing this.

1.2 Results

We have tried following Philippes advice and have observed that it was extremely difficult to make the robot balance even in a completely dark room or a room only with fluorescent light. We tried several surfaces: carpet, wooden table, whiteboard; on the carpet it turned out to be impossible to make it balance even for a second, due to the fact that the light readings from the carpet varied too little at different angles. On the whiteboard we were able to make the robot balance for a few seconds as can be seen in the video in figure 2. 
Figure 2: The constructed NXTway in action
As can be seen from the video the main problem with the balancing is that the robot isn't able to properly counteract the loss of balance; after loosing the balance it will keep driving in the direction of overbalance. This is generally the correct strategy but we believe the specific problem here was that the robot didn't generate enough acceleration to counteract the overbalancing. Since the robot was already providing max power to the motors the only way to increase acceleration that we could think of, was to use wheels of another size. Figure 3 shows the different types of wheels we tried. Of all these it turned out to be the largest wheels that were the best - this makes sense since larger wheels means the robot will move faster and thus also accelerate faster when provided with a quick burst of power. With the larger wheels we were able to make the robot balance a bit longer than before. Figure 4 shows this. The problem with larger wheels is that, due to the increase in acceleration, it will also oscillate more but we couldn't figure out a way to counteract this except adjusting the PID controller itself. We should add that we moved the sensor a bit downwards compared to the robot body to compensate for the increased distance with the larger wheels. This may be a factor affecting the experiment since the distance from the sensor to the ground isn't exactly the same with the large wheels as it is with the standard wheels - even with our height adjustment.

Figure 3: Wheel sizes used for the self-balancing robot
Figure 4: Our modified NXTway with larger wheels
To sum up: we tried following Phillippes advice but it was still extremely difficult to make the robot balance perfectly. It was impossible to make the robot balance on carpet but on a whiteboard or table it was much better. Using larger wheels improved the balancing time at the cost of more oscillations.

2. Choice of parameters on-the-fly

We have expanded the program for the self-balancing robot such that we can adjust the constants (P, I, D etc) on-the-fly from a PC instead of constantly downloading new programs to the NXT brick. This will make it more convenient to work with and debug in the future.

We have implemented the expansion by using the PCarController.java and BTControlledCar.java java classes. These classes use Bluetooth to communicate between a PC and a NXT. We modified the PC program (PCarController.java) such that we can control the following four values on our NXT: the offset (light value of balance point), kP, kI and kD where the k-values are the constants in our PID controller. The PC GUI is shown on figure 5. Figure 6 shows a video of the robot being controlled from the PC.
Since our source code is almost identical to PCarController.java and BTControlledCar.java except the addition of a few extra controllable variables and running a new Thread on the NXT, we won't show it here.
Figure 5: The PC GUI for controlling the robots constants
Figure 6: The robot being controlled from the PC (figure 5). Legend: O - offset, P,I,D -  PID constants

3. Self-balancing robot with color-sensor

We exchanged the light sensor on our NXTway with a color sensor from the NXT 2.0 set to see if it made the robot balance better.

3.1 Results

The ColorSensor
class in leJOS has different properties that affects the operation of the color sensor. One of these properties is the mode of the sensor that determines what colors it will use as flood light and also how the final light value is calculated from these colors. For our tests we tried these different modes:

  • Colorfull mode: The sensor outputs all supported colors (like a rainbow) and uses these to calculate a final light value by taking an average of the color response
  • Red mode: The sensor outputs a red light and reads the returned value as is
  • Blue mode: The sensor outputs a blue light and reads the returned value as is
  • Green mode: The sensor outputs a green light and reads the returned value as is
In colorfull mode it was impossible to make the robot balance since the light readings would only vary very little with large changes in the angle of the robot. In green and blue mode the change in light vales was much wider when varying the angle of the robot but still not as good as the variation from the standard light sensor. The mode that turned out to work the best was the red mode. This is the same mode the standard light sensor uses, and not surprisingly the results with the color sensor in this mode were the exact same as with the standard light sensor; the robot was just as good (or bad) at balancing with the color sensor as with the light sensor.

4. Alternative self-balancing robot - horizontal NXT unit

We will here test an alternative NXT segway kind of robot. We will construct the NXT Rider [4] and see how well it can be controlled with the program of Philippe Hurbain.

Results

Constructing the NXT Rider was much easier then constructing the LegWay, since the building instructions were very superior. We locked the rider in place, as suggested by the buildings instructions. The program of Phillippe Hurbain would not be able to control the third motor which moved the rider.

Our initial test run showed that the robot were able to stay upright for longer times. We began to experiment with the PID controller constants, using Bluetooth to send over new values to the NXT.

We ended up with a configuration with P = 50, I = 50 and D = 33. We could then observe that if the robot had it's balance, it would keep upright and never fall down. However, if we were to push it too much, it would not be able to accelerate fast enough, and thus have the same problem as the LegWay. A test run can be seen in Figure 7.
Figure 7: Test run of our final LegWay robot
We think that we might have been able to make the NXT Rider handle harder pushes if we could use larger wheels. We did not test this though.

References

  • [1] Steve Hassenplug, LegWay
  • [2] Philippe Hurbain, NXTway
  • [3] Brian Bagnall, Maximum Lego NXT - Building Robots with Java Brains, Chapter 11, 243 - 284
  • [4] nxtprograms.com, NXT Segway with Rider
Posted on 11:19 AM | Categories:

Week 5


We experiment with the light sensor and complete the exercises for Lego Lab 4.

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

Goal

To complete the exercises for Lego Lab 4.

We will experiment with the light sensor and in the process create several variations of a line follower robot.

Plan

Since our goal is to complete the exercises for this weeks lab the plan will be to complete each exercise in sequence:
  1. Black & White detection and LineFollower:
    Experiment with the BlackWhiteSensor class. Investigate ability to differentiate between black and white. 
  2. Color sensor:
    Creating a class capable of detecting black, white and green based on the BlackWhiteSensor class.
  3. LineFollower with Goal zone:
    We will try to enhance the LineFollowerCal to use our BlackWhiteGreenSensor and stop in a green goal zone.
  4. PID controlled LineFollower:
    Here we will try to enhance the LineFollower so that it can use PID control on the raw sensor values from a LightSensor.
  5. LineFollower using ColorSensor:
    Here we will experiment with the NXT ColorSensor and see if we are able to create a LineFollower using it.

Black & White detection and LineFollower

In this exercise we will test if the BlackWhiteSensor class can reliably differentiates between black and white after a calibration run. We will then try the LineFollowerCal application and see how it behaves.

With regards to differentiating between black and white the BlackWhiteSensor does a great job. Our test program can be seen in Figure 1. On paper (See Figure 2), the robot is able to detect without error what color is under the sensor.
Figure 1 - Our test program.
Figure 2 - Robot on paper. Detects black and white correctly.
Out of interest we tried lifting the robot to see how far from the paper it could differentiate between black and white. It turned out not to be very capable at a distance of around 5cm or more (see Figure 3) which was expected due to the line not being very thick.
Figure 3 - Robot lifted from the surface. Unable to detect correctly.
We also tried testing the robot above one of our computers where each surface (white, black) was much larger than on the paper (see Figure 4). It turned out that the robot had a much easier time distinguishing black from white even when lifted above 5cm
Figure 4 - Lifted above computer, still detects correctly.

Results

Based on the above observations we believe the robot will be able to follow a black line. It turned out we were right (see Figure 5).
Figure 5 - Primitive line follower

Color sensor

Having tested the BlackWhiteSensor class we will now try to enhance it so that it is able to detect one more color, namely green. We will call this class BlackWhiteGreenSensor.

First we checked what light values we would get from the sensor above surfaces of Black, White and Green.
The results can be seen on Figure 6 (the three arrows above the bar).

Figure 6 - Sensor values and interpretation of color for a given value.
We observed that the green color is situated between the readings of black and white colors. On the basis of this, we defined the BlackGreen and GreenWhite threshold and used these to determine what color is currently below the sensor. See Figure 6 for our implementation of this. One note: we changed the design of our class (compared to BlackWhiteSensor) such that instead of having three different methods isGreen(), isBlack() and isWhite() we simply return the current color under the sensor readColor() - we feel like this is a better design and allows for less clutter in the client code as can be seen on figure 6.
Figure 7 - Implementation of BlackWhiteGreenSensor
To test our new BlackWhiteGreenSensor we write a test program (See Figure 7). This program will display the color returned from the sensor on the LCD display. We observed that it correctly detects the colors if placed directly above them. However, if we placed the robot just at the edge of a black line, the robot would believe it detects a green color, since the light value returned is in this region (average between black and white).

Figure 8 - Test program for BlackWhiteGreenSensor

LineFollower with Goal zone

In this exercise we will use our newly implemented BlackWhiteGreenSensor to follow a line and stop in a green goal zone.

First we simply used the code from LineFollowerCal.java with the only modification that it will stop the robot when reading a single green value from the BlackWhiteGreenSensor. The result can be seen in figure 9. As expected, it will sometimes stop on the edge of a line, since it believes it is inside the goal zone. This is due to the fact that the sensor will read the color as green when its placed directly above the intersection between black and white.
Figure 9 - First attempt at following line with our BlackWhiteGreenSensor
In our second attempt we modified the program to only stop the robot if it reads several consecutive green values in a predefined period of time (like 500ms). The result of this modification can be seen in figure 10.
The reason that this works is that it will discard spontaneous green readings occurring when the sensor is directly above the edge of the line.
Figure 10 - Second and final attempt at following line with our BlackWhiteGreenSensor
The implementation of this line follower can be seen in Figure 11.

Figure 11 - Final code for our line follower using BlackWhiteGreenSensor

PID controlled LineFollower

We have constructed a PID line follower as can be seen in figure 12. The video of this robot can be seen in figure 13.
Figure 12 - Source code for PID line follower
Figure 13 - Final code for our line follower using BlackWhiteGreenSensor

By comparing the PID line follower (figure 13) to the bang-bang line follower (figure 10) we can clearly see that the PID follower is faster and smoother. It still oscillates a bit but we couldn't get it perfect.

LineFollower using ColorSensor

We didn't have time to do this exercise.

Conclusion

We have made all parts for this week unless the last exercise so next week we'll start on the week 6 exercises.
Posted on 12:36 PM | Categories:

Week 4

We experiment with the sound sensor and complete the exercises for Lego Lab 3.
Duration of activity: 8 hours
Group members participating: Ole Rasmussen, Kasper Sørensen

Goal

To complete the exercises for Lego Lab 3.

We will experiment with the sound sensor and in the process construct several robots that are variations of the 9797.

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 & 2: Experiment with the sound sensors ability to measure sound: distance, frequencies and object types
  2. Exercise 3: Sound controlled car
  3. Exercise 4: ButtonListener implementation
  4. Exercise 5: Clap controlled car
  5. Exercise 6: Party finder that drives towards loud sounds

Exercise 1 & 2

In this exercise we will experiment with the sound sensors capabilities by measuring different sounds coming from different objects at different distances.

Factors

  • Environment: the physical environment in which the experiment takes place may interfere with the measurements of the sound level. The shape and texture of the of the room may for example absorb or allow sound to pass around it more or less thus allowing or disallowing more or less sound to reach the robot. Background noise is also something that should be taken into account
  • Human error: If we for example want to measure sounds from a clap, the human producing the clap will not be able to generate the exact same clap each time
  • Sound frequency: High frequency sounds tends to loose momentum faster than lower frequency sounds. This would mean that the sensor might have a hard time registering high frequency sounds emitted far away as they don't travel as far as easily as low frequency sounds

Setup

We have placed the robot with the sensor in an area where we believe the environment has the least impact on the measurements: on one of the large tables in Lego Lab (see figure 1). The placement of the robot is ca. center in the room and thus allows for the minimal disturbance from close objects. The elevation means the sound won't easily be disturbed by table legs etc.
With regards to background noise we did this experiment at a time where only we were in the room. The sound sensor would read a background-noise value of 3-4 which we consider as close to complete silence as we could possibly get.
Figure 1 - Setup: 10cm, 1m, 3m, 5m and 10m

The sounds we have chosen to measure are picked based on their charasteristics. We believe that some are low frequency while some are high frequency. We will be making the following measurements:

  • Sound sources: clapping, whistle (high frequency), and hitting a cardboard box with a stick (low frequency)
  • Distances: 10cm, 1m, 3m, 5m, 10m

Results

Figure 2 - Clapping measured with sound sensor
Figure 3 - Whistling measured with sound sensor
Figure 4 - Cardboard box hit with a stick measured with sound sensor

Analysis

Starting with the clapping we can see on the graph (figure 2) that it is easily detectable at 10cm from the robot. At 1m the sound readings decrease dramatically from peaking at around 90 to peaking at around 55 but it's still easily detectable. Even at 10m the sound sensor registers well above 30 for a clap. An interesting observation is that the 5m measurement seems to be louder than the 3m one. We believe this to be caused by the human factor we described above - we simply clapped a bit louder than we should have.

The whistling (figure 3) is very interesting because it's clearly detectable at 10cm but moving further away dramatically decreases the detectability to almost zero already at a distance of 3m. At 3m it would be difficult to distinguish between whistling and background noise assuming the robot isn't be in a completely silent environment. At 10m it's almost impossible to detect the whistling.

Compared to the whistling the cardboard box measurement is completely opposite, and this supports our initial theory about it emitting the lowest frequency sounds among the three. It is easily detectable at all measured distances. An interesting trend on all graphs except 10m is that the sound reading seems to be capped at around 93 or so. This is most pronounced on the graph for 10cm; the sound reading rises quickly and then when reaching around 93 it keeps outputting that reading for a while. In reality the cardboard box sound looks nothing like this so we conclude it's a restriction in the NXT sound sensor that a max of 93 can be output.

Exercise 3

In this exercise we are to install SoundCtrCar.java and observe and describe how it behaves.

Results

We installed the program and held the robot in our hands. We saw on the display, that it reacted to loud sounds, and that it had four different states {stop, forward, right, left} that it changed between.
We placed it on the ground, and quickly found that we needed to make pretty loud noises for it to change to the next state. After a short testing session, we were able to guide it towards a preset point and stop it there.

Analysis

We looked inside the SoundCtrCar.java program and quickly found what we expected. It listened for loud sounds and changed between states if such a sound was heard.

Exercise 4

The SoundCtrCar.java program from Exercise 3 had the problem that it would only exit if you held the ESCAPE button down at the exact moment when changing state from stop to forward. Since this is rare, we are asked to implement a ButtonListener that reacts when the button is pressed.

Results

Figure 5 shows the original program to the left and our modified program to the right.
Figure 5- Original SoundCtrCar (left) and  our modified version using ButtonListener (right)

As can be seen we have added a listener (green color) to exit the system when ESCAPE is pressed. It does not matter in what states the SoundCtrCar is in or if it is waiting for a loud sound to be heard, the system will end if ESCAPE is pressed.
We have also modified the condition (gray color), since we do not need to check the ESCAPE button here anymore.
Last, we deleted the statements (red color) after the while loop, since we would never reach this point in the program anymore. We did not add this to the listener, since the listener runs in a different thread. One could run the main program in a thread that the listener could stop, and then execute the deleted statements.

The modified program terminates immediately when the ESCAPE button is pressed, just as expected.

Exercise 5

The SoundCtrCar reacts to all kinds of sounds because it uses a very primitive way of deciding which sound to reach to:if the sound level passes the magic threshold of 90 it will react. In this exercise we are asked to implement a small algorithm to detect only claps. A clap starts at a low sound level, increases quickly to a high sound level and then decreases to a low sound level again. The following pattern is suggested:

A clap is a pattern that starts with a low-amplitude sample (say below 50),
followed by a very-high amplitude sample (say above 85) within 25 milliseconds,
and then returns back to low (below 50) within another 250 milliseconds.

Implementation

We have developed the program which can be seen in figure 6.
Figure 6 - Program for detecting claps
Our algorithm works by detecting the states defined in the clap pattern. We have defined three ClapStates = {Attack, Peak, Decay} each defined by a ClapState enum. We start with a ClapState of Attack. We then move from one ClapState to another when specific sound levels are reached. These levels are defined by the ClapState enum. A maximum allowed time for detecting a matching sound value is also recorded in the enum. If a sound level is not reached in the allowed time, we reset the algorithm by setting our state to Attack.  
The highlighted parts describe the following for our ClapState enum:
  • Red part
    This is a boolean flag, describing if we need to detect something below or above a given threshold.
  • Brown part
    This is the threshold value we need to detect to move to the next state in the detection algorithm.
  • Blue part
    This is the time in milliseconds that we have to detect the threshold. If not detected within this time, we start over by moving back to ClapState Attack.
Given the implementation of the ClapState enum, it is easy to implement the algorithm, which can be seen in the detectClap() method. Here we simply move to the next state if the current ClapState is satisfied. If we satisfy the last ClapState (Decay) we have detected a clap. If we cannot move to the next ClapState in the allowed time, we reset to Attack.

Results

With the initial values for thresholds (brown in figure 6) set to 50, 85 and 50, it was very hard to detect a clap. We looked at our graphs from the first exercise to derive some useful constants. We tried with 50, 70, 50 and it was much better at detecting claps than for the default ones.We also had problems with the motors generating a lot of noise, and at times the sound level would never decrease to below 50, making it impossible for our algorithm to move from the Attack state to the Peak state.
When we made constant high noises, it would not react, as the Decay state would never be satisfied. This means that we could evade some noises which have longer Decay times then the allowed 250ms.

Exercise 6

In this exercise we construct a "party finder" robot with 2 sound sensors that can move towards a loud sound.

Results

The constructed robot can be seen in figure 7. The program for the robot can be seen in figure 8. Figure 9 shows a video of the robot following a computer playing music.
Figure 7 - Our partyfinder robot
Figure 8 - Partyfinder source
Figure 9 - Partyfinder robot demonstration

Analysis

Our first try at the partyfinder had the sound sensors mounted just above the wheels. This turned out to not work at all since the sensors would pick up noise from the wheels when moving. In the second try we mounted the sensors much higher as can be seen on figure 7.

The partyfinder works OK for sound sources close to the car (as can be seen in figure 9) but anything further away than 1 or 2 meters won't make the car turn. We are not completely sure as to why this is but we believe it to be either due to reflections in the room or interference between the sound sensors. An idea might be to mount a piece of paper between the sensors so e.g. sound coming from the left won't pass on to the right sensor and vice versa.

Conclusion

We have made all exercises for this week so next week we'll start on the week 5 exercises.
Posted on 12:45 PM | Categories:

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.
Posted on 1:48 PM | Categories:

Week 2

We experiment with the NXT light sensor and complete the exercises for Lego Lab 1.

Goal

To complete the exercises for Lego Lab 1.

We are given a LineFollower program to experiment with. The LineFollower is an NXJ robot that follows black lines by using a light sensor to measure the amount of reflected light. Black reflects less light than white and this is exploited in the program by turning the robot right on white sensor values and left on black sensor values. This results is the robot following a line along its left edge.

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: Light sensor measurements with flood light on
  2. Exercise 2: Light sensor measurements with flood light off
  3. Exercise 3: Experiment with delays between light sensor readings in LineFollower program
  4. Exercise 4: DataLogger: Experiment with sample rate in LineFollower program
  5. Exercise 5: Experiment with LCD.drawString() and memory usage

Exercise 1 and 2

We wanted to test if it was possible to use the LightSensor to detect different colors.

Factors

We thought about what kind of factors might influence our experiment:
  • Ambient Light: The amount of light in the surroundings. This could interfere with the light readings of the light sensor.
  • Material surface: Flat surface vs rugged surface.
  • Distance from sensor: Different distances will yield different results.

Experimentation

Before making our final setup, we tried experimenting with material surface.
Figure 1: Rugged lego bricks
We tried two kinds of materials, one with flat Lego bricks having studs as our rugged surface (See Figure 1) and then some Lego bricks with a flat surface (See Figure 2).

We found that the light values read from the sensor when using the rugged Lego bricks varied a lot depending on the material position under the sensor. The flat surface did not have such a problem.
Figure 2: Flat pieces

We also found that ambient light, while testing without the sensor floodlight had a tremendous influence. For example, it made a big difference if we were leaning over the robot and therefore shadowing for the ambient light or not. We therefore must make sure to not influence our readings in our experiment.

Setup

Figure 3: Test setup
As can be seen on Figure 3, we have used the standard NXT Lego robot. We have raised it a bit with some flat Lego bricks (marked in red circles) under the NXT's wheels to allow our test material to enter under the sensor.

Results

Here are the raw light results:
                Floodlight
Corlor
ON OFF
Black
31
26
Yellow
61
40
Red
58
38
White
62
41
Blue
36
32

Conclusions

If we were to read the value 60 while having the floodlight turned on, it would be impossible to tell what color was under the sensor, since the light values are so close to eachother. It could be red, yellow or white. The same holds for when the having the floodlight turned off.

All in all, we do not believe it is possible to use the LightSensor to detect colors. It can detect what it was designed for - the amount of light returned. This can of course be used to detect lighter colors from darker ones.

Exercise 3

In this exercise we will experiment with the delay in the control-loop (see figure 4) and see what happens when increasing it from the default 10ms to 100ms, 500ms and 1000ms.

Figure 4: Control-loop delay in LineFollower

Hypothesis

Increasing the delay means that the robot will have a harder time following the line.

Results

100ms
The robot follows the line for 1 or 2 seconds whereafter it starts turning right. When turning right it will sometimes start following the line again for 1-2 seconds until the process repeats.

500ms/1000ms
With 500 or 1000ms delay the robot is completely unable to follow a line. 

Analysis

With a polling rate of 100ms the robot is able to follow the line for a few seconds but eventually looses sight of it. This was expected as the line isn't very thick and it is therefore likely that the robot doesn't poll the sensor quickly enough to see it before passing over it. Recall that the robot works by turning right on white and left on black thus if it doesn't see black at all it thinks it still needs to turn right to get onto the line. The result is that it will skip the line and keep turning right until hitting the line again (if ever) at which point the process repeats.

A polling rate of 500/1000ms rendered the robot completely unable to follow lines with the same argumentation as for the 100ms case.

Exercise 4

In this exercise we will use the supplied DataLogger to log the light sensor values in the LineFollower program and use these to experiment with different sample rates to see their effects on the oscillations of the  robot. We use the provided SLineFollower program updated with data logging.

Hypothesis

Increasing the sample rate will increase the frequency of the robots oscillations. 

Results

Exercise 5

We are asked what happens with memory usage if a String is created for each LCD.drawString(...) call in the LineFollower program.

Hypothesis

Figure 5: Memory test programs
We believe that the amount of memory free will be decreased for each iteration of the while loop.

Results

Instead of modifying the code for the LineFollower program, we made two simple test programs, seen in Figure 5.

The first program, called test1, creates a local String object for each iteration of the while loop, and then writes to the LCD the amount of available memory left. Looking at the display, we could see that the amount of available memory decreases from ~58.000 bytes down to ~42.000 bytes. At this point garbage collection kicks in and we now have our ~58.000 bytes available again.

Our second, program called test2, does not create a local String object to throw away. Instead it uses one local variable on the stack and uses drawInt(...) to write the amount of available memory left to the screen. This program has fixed amount of memory used, which resulted in a steady 58.984 bytes being free memory.
Posted on 2:40 PM | Categories: