Week 10

In this lab session we will experiment with navigating a differential-driven Express Bot like car while using the tacho counters to keep track of its position and direction.

Duration of activity: 10 hours
Group members participating: Ole Rasmussen, Kasper Føns

Goal

To complete the exercises for Lego Lab 9.

Plan

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

  1. Blightbot
    Investigate the accuracy of a Lego car inspired by Brian Bagnall's Blightbot [1] navigating in a Cartesian coordinate system.
  2. Avoiding objects while navigating
    Experiment with navigating the Lego car with the leJOS classes while avoiding obstacles.
  3. Improved navigation
    Experiment with different navigation methods.

1. Blightbot

In this section we will measure how accurately our Lego car drives with the navigator class in leJOS. We will be performing two experiments: accuracy of general navigation and comparing accuracy of driving straight and rotating.

1.1 Setup

The setup for both experiments consists of the following parts: the Lego car, a whiteboard and a whiteboard marker. The car will be driving on the whiteboard with the whiteboard marker.

The car we have used for the experiment is a slightly modified version of the Express Bot (the modifications are just a result of it's usage for the Sumo competition and thus of no relevance to this experiment).

To measure the accuracy of the cars navigation we have attached a marker to the back of the car by using an elastic cord (figure 1 & 2). The car will be performing several navigational runs on a whiteboard.
Figure 1: The marker is attached to the back and is used as the "back-wheel" for the car. This way the car will partly be resting on the marker, pressing it downwards towards the whiteboard (see figure 2).
Figure 2: The marker touching the whiteboard.
The source code for the program used to generally navigate the car can be seen in figure 3.

Figure 3: Source code for a test program using the Navigator and DifferentialPilot classes.
Notice that we have shortened the path by a factor of 2 to stay within the bounds of the whiteboard.
Original code was borrowed from here.

1.2 Influencing factors

We believe the following to be factors that could influence the experiment:
  • Initial placement of the car
    For subsequent runs the car must be placed on the exact same position facing the exact same direction.
  • Position of whiteboard marker
    The position of the whiteboard marker may influence where on the whiteboard is drawn compared to the base of the car. It may also influence the thickness of the drawings. 

1.3 Experiment 1: comparing accuracy of several navigation runs

Figure 4 and 5 shows the Lego car performing two navigational runs.

Figure 4 - First run with our code from Figure 3.
Figure 5 - Second run with our code from Figure 3.

Figure 6 shows the result of the two runs.
Figure 6: Two subsequent runs of the Lego car with the same navigation program. The green dot marks the starting point while the two red dots mark the ending points. The blue circle is a circle with radius 4.5cm interpolated from the starting point as center and ending points a points on the circumfence.
As can bee seen on figure 6 the two runs aren't exactly matching but what's interesting is that they seem to be displacements of each other. It is important to mention that it was relatively easy to place the car on the same starting point each run but it was much harder to ensure the initial directions were the same as well. This was not unexpected though, as we mentioned it to be an influencing factor in section 1.2. From the figure it looks like the displacement could very well be due to initial differences in direction, as the runs differ already from the start on the first straight line. Had we placed the facing the exact same directions we may have had two almost exact matching runs apart from the ending point.

The ending points are interesting because they both seem to be offset from the starting position by a certain amount. The evidence for this is that the ending point closest to the starting point is the ending point for the run that goes a bit more upwards in the beginning; thus turning the direction upwards (or left depending on how you view it) displaces the ending point upwards (and out) as well. In other words it seems like the initial direction of the car determines an ending point on a circle that's surrounding the starting point. We have measured the radius of this circle to be 4.5cm based on the distance to either of the ending points for the two runs. Basically this means that had the initial directions of the car been the exact same the two ending points may have been also the exact same (almost). We are not sure what causes this offsetting anomaly but in the next experiment we will investigate Brian Bagnall observations that rotating (not driving straight) is the hard part that may be the most likely cause.

1.4 Experiment 2: Accuracy of driving straight. vs rotating

Here we will test both straight line and rotation accuracy.

1.4.1 Straight line accuracy

First we will test if we can drive straight and check that the distance driven matches the real world. The setup is a whiteboard with two parallel lines 120cm apart. We want to test if the robot can drive the 120 centimeters to hit the other line. Figure 7 shows the setup. Figure 8 shows the source code. 


Figure 7 - Test setup. Two lines parallel lines 120cm apart.
We will test if the robot will travel from one side to the other.

Figure 8 - Forward test source code. Same wheel diamater and trackWidth as in Figure 4.
The navigator is told to move 120cm forward.

We then placed the robot on the left side and started it. We did this multiple times. Figure 9 shows the overall result while Figure 10 shows the stopping positions in closeup. 

Figure 9 - The robot started from the left and moved towards the right side.
It was told to travel 120cm, but as can be seen, it did not go that far and stopped a bit short of the goal.
Figure 10 - Even though the runs don't actually hit the 120cm line, they are very consistent.
This means that the robot will travel the same distance, even though it might be a bit too short compared to the real world.

We can see that the robot does not travel the full 120cm, but it is very close (1,5 - 2,0cm off). The runs are very consistent, all traveling the approximately the same distance. We believe the distances are precisely the same, but because of small errors in the start direction and start position they end up with different distances to the black finish line.

From this we can conclude that straight-line moving is not what makes our test run in Figure 6 end up in the wrong position. We suspect the rotation accuracy might be the problem and will test this now.

1.4.2 Rotational test

We will test the rotation by telling the navigator to go forward 120cm, and then go back to the starting point. This will then be done 10 times to see if it is precise enough for that.
The source code for the rotating accuracy test can be seen in Figure 11.

Figure 11 - Test code for performing 10 runs going forward and back to start.

The actual test run can be seen in Figure 12.
Figure 12 - Test run with program from Figure 11.
It can be seen that the rotation performed is not precise.
From this we can conclude that the rotation is not precise. We are unsure of why this happens. We suspect that it might be when making fast rotation moves, that the robot does not have enough traction with the surface. We will test this in the next section.

1.4.3 Decreasing acceleration

We modified the program from Figure 11 slightly. We simply called pilot.setAcceleration(1) before giving it to the navigator. The result can be seen in Figure 12.

Figure 12 - Test run with acceleration set to 1. It took forever to complete, but is much more precise.

It can be seen that it runs better, staying closer to the start position, but it is still not perfect. This time we will test if going forward or backwards is the problem, and not the rotation.

1.4.4 Straight line again

In this test we will only go forward for 100cm, then reverse for 100cm. This is done 10 times. The code can be seen in Figure 13, the result can be seen in Figure 14.

Figure 13 - Test code for driving forward and backward. Notice that no navigator is used.

Figure 14 - Result from driving 100cm forward and backward 10 times.
Still not precise.

1.4.5 Accuracy conclusion

As can be seen from all our experiments, it seems that it is not possible to get a very precise run with the robot. Even straight line forward and reverse is not precise. It should therefore be noted, that if one is the build a map, drifiting of coordinates will occour over time.

2. Avoiding objects while navigating

The simplest way to avoid objects is to attach some ultrasonic sensors on top of the robot, and when an object is closer then some threshold, the navigator should be stopped and an avoid behavior should take command. The avoid behavior could use three ultrasonic sensors to make decisions about what way to turn, just like Maja J Mataric [2]. When the avoid behavior does not detect any more objects, the navigator is restarted. We even made a robot design (Figure 15), but then found that we were not to implement a program, just discuss how to avoid objects.

3. Improved navigation

In Enabling Your Robot to Keep Track of its Position [3] it is assumed that all moves are divided into small moves all assumed to be in straight lines. In Foreward Kinematics for the Khepera Robot [4] it is not assumed to move in straight lines. Here we can calculate more precisely where we are if we are moving in an arc.

The question is then if it is possible to upgrade Lejos navigation system to use the more precise mechanisme in [4] to get better locations. After examining Lejos code, it seems they are already using that mechanism. The DifferentialPilot fires move events and these move events describes if the move happened in an arc or in a straight line. An OdemeterPoseProvider is used to update locations and it uses the math described in [4] if an arc move happened and uses the simple math in [3] if the move was a straight move.

Therefore the optimizations of [4]is already implemented in lejos.

References

  • [1] Brian Bagnall, Maximum Lego NXT - Building Robots with Java Brains, Chapter 12, Localization, p.297 - p.298.
  • [2] Maja J Mataric, Integration of Representation Into Goal-Driven Behavior-Based Robots.
  • [3] Java Robotics Tutorials, Enabling Your Robot to Keep Track of its Position.
  • [4] Thomas Hellstrom, Foreward Kinematics for the Khepera Robot
Posted on 2:13 PM | Categories:

Week 9 - Sumo



In this lab session we will make a Sumo Wrestler.

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

Figure 1 - Sump Wrestler Baby.
Lets see if we can take him out....

Goal

To build a Sumo Wrestling robot and win the competition. Also, learning some behavior driven robot programming.

Plan

We will execute the following in sequence:
  1. Create the base sumo wrestling robot from building instructions
  2. Compile, test and observe default behavior driving wrestling controller program
  3. Examine the source code to determine how it works
  4. Explain questions about the source code
  5. Add OverturnOpponent behavior

1. Create base Sumo Wrestling robot

In this step we will construct the base sumo wrestling robot. We will build it from the instructions given here. There were no problems constructing the robot. The base robot as constructed can be seen in Figure 2.

Figure 2 - The constructed base sumo wrestling robot.
There is not much more to say to this section. Lets move on and add some behavior to the robot.

2. Sumo Wrestling controller program

In this section we will install a pre-programmed controller program onto the robot. Dependencies for the program is given here. Having installed the robot we took a test run at the wrestling area. We observed that the robot only drove forward for very little time and then stopped to change direction. We adjusted the threshold value inside the AvoidEdge behavior from 45 to 50.

Testing the robot again, we observe that the robot manages to stay inside the wrestling ring, stopping when approaching the edge. If not at the edge, the robot randomly drives forward and turns. Our robot was able to push another standard robot out of the arena - Hurrah!

3. Examine source code

Here we will examine which behaviors exists on how they work.
Examining the source code shows three different behaviors. They each have the ability to disable the behavior listed before it. They are listed below.
  1. Drive behavior
  2. Turn behavior
  3. AvoidEdge behavior
Lets see how they are each triggered:

3.1 Drive behavior

The drive behavior is not triggered by anything, it simply drives forward, and then yields, letting other Threads be scheduled.

3.2 Turn behavior

The turn behavior is triggered every five seconds. It then stops the car, waits for it to stop, and turns it for some milliseconds in the interval [500, 1500].

3.2 AvoidEdge behavior

The AvoidEgde behavior is highest priority behavior. It has the ability to supersede all the other behaviors. It is triggered by a the LightSensor registering a light value above a given threshold.
The behavior is then to drive backwards for one second, turning left for 800msec and then stopping and staying there for 500msec.

3.3 Sum up

The given behaviors will make the robot drive around randomly, but avoiding the edge. The code is nicely structured and it should be easy to extend with new behaviors.

4. Explain questions about the source code

In the lab lesson, three questions are asked. We will try to answer them here.

4.1 Why are threads running in Daemon mode?

The behavior class extends from the Thread class. The constructor inside the Behavior class sets the thread to run in Daemon mode. The question is here, why?
The JDK Javadoc has a good explanation of what a Daemon thread is:
"Marks this thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads. 
This method must be invoked before the thread is started."
So if only Damon threads exists in a given Java Runtime, the Runtime will exit. This is used in the SumoBot class, so that when pressing the Exit button, the Main method will return and thereby the only thread running in non-daemon mode has halted, making the program exit.
Had the Behavior threads not been marked as Daemon threads, the program would continue to execute.

4.2 How is the SuppressNode used to suppress access to the motors in the Behavior class?

The suppression mechanism used is a hierarchy where a behavior on level is able to suppress any behavior on levels below it. This hierarchy can be seen in Figure 3.
All behaviors have access to the sensors, but only one behavior have access to the actuators at a given time. Level 1 is able to suppress Level 0, and so on up the levels.

Figure 3 - Layered behaviors
When constructing a behavior using the Behavior class, one can supply a behavior which it is able to suppress. This can be used to create a hierarchy as just described. When a behavior at level N calls the suppress method on the Behavior object, the SupressNode's suppress method is called. This method will increment a counter for the Behavior at level N-1 and call the supress method on that SuppressNode which, in turn, will increment a counter at level N-2 and so on until the bottom is reached. This will make sure that a behavior at Level [0, N-1] have a SuppressNode with a counter value larger than 0.
When a behavior wants to control the actuators, the behavior will first check if the SuppressNode given for it has a counter value at zero, if not, nothing happens.

4.3 Compare the suppression mechanism with Fred Martins' Arbiter

Fred Martins' Arbiter is a central component which registers which behaviors wants to have access to an actuator. The behaviors have a priority, and the behavior with the highest priority will have sole access to the actuator. This acomplishes the exact same thing.

5. Add OverturnOpponent behavior

This section is about adding a behavior to flip over our opponent. We did not believe in the construction of the forlift arm in the hinted building instructions. Lifting heavy robots is not an easy thing.

We wanted to build our own system. Figure 4 shows our construction with our forklift system.
Figure 4 - Custom built forklift system
We added an behavior to supersede all behaviors except the AvoidEdge behavior.
The behavior triggers every four seconds, lifting the forklift, waiting a bit, then taking it down again. See below for a run against another robot in the arena:



Posted on 4:12 PM | Categories:

Week 8


In this lab session we will try to make a robot racer that races to the top of a mountain as defined in Lesson7 - Also called the Alishan Train Track.

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

Figure 1: The Alishan Train Track

Goal

To build the fastest robot to complete the Alishan Train Track.

Plan

We will execute the following in sequence:

  1. Create a super fast robot using gearing
    Constructing and experimenting with a self-built NXT robot which maximizes speed.
  2. Make a control program for the robot
    Here we will create the control program for the robot created in the previous step.

1. Create a super fast robot using gearing

In this step we will construct a fast robot. In a later step, we will make this robot complete the Alishan Train Track.

We decided to develop two distinct robots in paralleled.
  1. One which uses two motors and gearing on these to achieve speed. Lets call it Speedy.
  2. A second robot, which uses three motors for each wheel with gearing for maximum speed. Lets call it The Rock.

1.1 Speedy

Our speedy robot can be seen on Figure 2. It has a large gearing but only two motors, one for each wheel.
It can drive at very high speeds. The gearing can be seen in Figure 3. Our idea is to make this robot "fly" up the Alishan Train Track and win the competition. As you will see, we did not manage this.
Figure 2 - The Speedy Robot. It would drive in the opposite direction.
Figure 3 - The Speedy gearing




1.2 The Rock

The Rock robot is an experiment where we wanted to use three motors to drive one wheel, which should be massively geared for an even higher speed. It can be seen on Figure 4.

Figure 4 - The Rock. As can be seen, it is massive and consists of two NXT's.
The gearing can be seen in the lower left corner.
 We did not manage to actually make The Rock drive, thereby the name. The power from the motors were too much for the gearing, which always gave in and needed to be repaired. Also, at one point, we erroneously uploaded a program for the Speedy robot to The Rock, which made a pair of the motors turn opposite of each other  This skewed both of the "sticks" which were inserted in the motors. See Figure 5.
Figure 5 - Skewed "stick" - destroyed by the force of The Rock.

2. Make a control program for the robot

Since we only made Speedy actually move, this is the only robot we have tried to implement a controller program.
Our idea was to create a sequential program which did not have any sensors. We only had to get to the top and back once, and have that on video, if we tried this enough times, one of the times should be good enough. This was at least the intuition behind our program.

We measured the distance from the bottom of the track up to the first corner, in the number of tacho counts needed. Our program would then move forward for that amount of tacho counts, make a turn, and then forward for the same amount of tacho counts.

We inserted sleeps between each action (forward, turn, ...) to see how it behaved. This is one of the test runs:

As can be seen, we did not do very well. This is not the best run we have had. We had a run which got to the second turn and fell off the track when going to the top. However, we did not get that taped.

Our robot is very susceptible to changes of the track, the battery level, inconsistencies of motor power and both wheels must drive straight.
We were not able to get it to the top. If we had more time, our next attempt would be to add a light sensor in the front to detect on which side of the line we were, and correct a little bit to stay on track.

Posted on 11:55 AM | Categories:

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: