Thursday, November 25, 2010

Project Session 0

Date:
25/11 2010

Duration of activity:
3 hours

Group members participating:
Frederik, Christian & Lasse

Goals:
Discuss and describe possible end course projects and end up having one selected

Plan:
Make a description of three possible end course projects containing a description, overall architecture and point out some potential problems.

Results:
After a discussion we came up with the three following projects:

1. A convoy of Lego cars acting as a train with a leader car in front
This would require the robot wagons to keep a fixed distance to the wagon ahead but also to follow its direction. Ultrasonic sensors could be used both to measure the distance but also to ensure that the wagon ahead is between two ultrasonic sensors. Experiments with other sensors such as cameras and light sensors could also be done. The leader car could be driving randomly around or be controlled by a joystick or a Wii remote via a PC.

A sketch of a possible system setup is seen on figure 1 below:
Figure 1 - Possible architecture of the Lego convoy project


The main challenge would be to keep the direction with the wagon ahead, though it should be possible to accomplish a three-wagon convoy controlled with a Wii remote (via Bluetooth) that maintains a fixed distance between the wagons and lets the lead wagon control the direction.


2. Balancing robot experiments
We would take the issues identified in previous lab sessions with balancing robots as a starting point and experiment with diferent ways of keeping balance. How effective would it be to regulate using a balancing stick instead of the motors? The main problem with our previous work with the balancing robot was the inaccuracy of the light sensor as a means of regulating balance. The alternative methods for balancing a robot could maybe complement the existing sejway motor-approach in a 2-axis balancing robot.

Figure 2 - Different regulation methods for maintaining balance. a) Regulating the wheels by motors b) Using a slider to change the balance c) Make a stick swing to change the balance.

The addition of a second axis will be a challenge and will require a lot of experimenting with different sensors and regulation methods. Another goal for this project could be to introduce another or several other sensor(s) to measure the attitude thereby limiting the inaccuracy of our previous attempts. The main goal for this project will be to have a balancing robot working with diferent methods for balancing. Best case scenario is a 2-axis balancing robot that is able to correct for falls in 2 axis.

3. Gene inheritance among a flock of robots
The idea is to have some robot parents each with a set of genes that can be mixed when they have a baby. The parents should then mate several times and have children with different behaviours based on the genes of the parents.

The transferring of genes can be handled by a server PC which distributes the genes to the parents and the parents then combine their genes which is sent to a "baby robot". The challenge in this project is to handle the level of complexity because the definition and exchange of genes can easily get complex when new genes are introduced. A subsumption architecture can be used to define the priority of the different behaviours for each robot - an example is shown below:


Figure 3 - Example of a set of genes and the matching behaviours

A sketch of a possible system setup can be seen on figure 4 below:

Figure 4 - A proposal for a system with a flock of mating robots with inherited genes


Conclusion:
We ended up choosing the Balancing robot experiments because we were interested in improving the robot from the lab sessions, but also to investigate whether it is possible to add an axis and still make the robot balance satisfactory. In the lab sessions light sensors were used but we will also try to combine with other sensors such as a gyroscope. Alternatives to motor regulation for balancing will also be investigated as shown on Figure 2. The construction of the robot will also have a lot to say, which will lead to experiments with the construction of the robot. Because similar projects have been done in the previous years there should be plenty of inspiration.

Lab Exercise 10

Date:
18/11 2010

Duration of activity:
3 hours

Group members participating:
Frederik, Christian & Lasse

Goals:
To investigate the leJOS API "subsumption" architecture by using a BumperCar-example as a starting point. 

Plan:
1. Get the sample running and observe the behaviour
2. Do experiments with the BumperCar sample code
3. Implement a new behaviour called Exit, which shall exit the program


Results:

1. Running the sample
We reused the construction of the car from the last lab session equipped with two motors. Furthermore we needed to mount a bump sensor and an ultrasonic sensor on the car because they are used by the DetectWall behaviour in the BumperCar sample. We though chose to mount two bump sensors to achive a better detection of bumps in front of the car. An image of the car is seen below:



When running the sample the overall behaviour was as expected; the car drives forward until an obstacle is detected by the ultra sonic sensor (within 25 cm) or the bump sensors, the car then backs of and rotates, and continues to drive forward. Before doing experiments with the sample code we decided to make it possible to exit the program when pressing the escape button - we just made as a thread listening for the button press, this was not the actual Exit behaviour implementation. This was done because the building structure of the car made it difficult the access the battery, which was necessary remove in order to exit the application (we later found out that a program can be terminated by pressing the enter and escape buttons simultaneously).

2. Experiments
When keeping the bump sensor pressed the DetectWall behaviour suppresses the DriveForward because the takeControl() method of DetectWall yields true when the bump sensor is pressed. When looking at the Arbitrator class it is seen that the list of behaviours is traversed and the highest index gets the highest priority and lower prioritized behaviours are supressed as seen below:




3. Exit behaviour
The escape code made in point 1 was removed to ensure that only the new Exit behaviour reacts to escape button presses. The exit behaviour was implemented with highest priority and when running the code we noticed that when the DetectWall behaviour has control the program is blocked i.e. it is not possible to poll the exit button until the rotation is finished. This is caused both by the Motor.A.rotate(-180, true); and Motor.C.rotate(-360); statements but the Sound.pause(20); statement also has a little influence. When increasing the Sound.pause parameter to 2000 ms a delay of 2 sec is added which causes the Arbitrator to block the takeControl() checks which is seen in the code example above.


The code for the exit behaviour is seen in the Exit class in the file BumperCar.java[1]


Because the DetectWall class is no longer the highest prioritized class we added some handling to its supress() method which stops the motors if they are running. We noticed that the action method of DetectWall had different behaviour for the two rotate-calls to the motors as seen below:
The true parameter is 'immediate return' which causes the method call to return right after it is called. This must not be done for the call to motor C because that would have caused that the action method returned right after it is called and thereby not getting enough time to back off.


To make the takeControl() in DetectWall more responsive we made a Thread which handles the reading of the sonar sensor and writes to a shared variable. This variable is then read by the takeControl() method and thereby avoiding the delay which previous was in the method, this is illustrated below:





To make sure that the routine stops if it is suppressed during the sleep period we made an action thread for DetectWall which performs the back off action; moves backwards for a second and then rotates. If the thread is interrupted during sleep (by a suppression) the thread returns and thereby ignores the rotation. This implementation sadly didn't work out because of some threading problems that we didn't manage to solve.

Conclusion:
We have seen that it is possible to improve the performance of a certain behaviour by moving the sampling of a particular sensor into a separate thread. This is because the sensor reading lasts a certain amount of time and thereby blocking the main program if the reading isn't performed in a separate thread. Generally a lot of tweaking can be done using the subsumption architecture by means of moving time consuming parts to threads and thereby making the program more responsive.


References:

Thursday, November 18, 2010

Lab Exercise 9

Date:
11/11 2010

Duration of activity:
3 hours

Group members participating:
Frederik, Christian & Lasse

Goals:
The main goal is to keep track of the position and direction (pose) of a Lego car by using the tacho counters. 

Plan:
1. Experiment with the SimpleNavigator class (instead of TachoNavigator which is deprecated)
2. Experiment with navigation while avoiding obstacles

Results:

1. Navigation

The first experiment was to make the car move to different positions and then return to the start position and thereby observe the accuracy. To get a better idea of the accuracy we mounted a whiteboard marker on the car and thereby made the car trace its own path on a whiteboard placed horizontally on the floor. The car with the marker mounted is seen below:



We made a route with 4 waypoints ending at the start point and saw an inaccuracy of approximately 10 cm as seen in the video below. As Brian Bagnall [1] also states the main source of error is the tacho rotation but wheel spin is also a source of error as we also experienced in the Lego race lab exercise. 




To avoid the wheel spin we experimented with a paper surface instead of the whiteboard. The idea behind using paper as surface was that we assumed 1) that the tyres would have better traction than on a slippery whiteboard, and 2) that the paper would easier slip on the surface of the whiteboard than under the tyres of the vehicle. We actually didn't notice a huge difference but when we tried to use the Reverse property in the TachoPillot constructor we got an even worse behaviour. We also noticed that the starting angle of the rear wheel has an impact of the result. So we concluded that performances on the two different surfaces were roughly the same.


2. Navigation with obstacle avoidance
We mounted the ultrasonic sensor on the Lego car to be able to detect obstacles in front of the car. The SimpleNavigator was investigated by means of its behaviour when a goTo()-action is aborted, because this will be the case when avoiding obstacles. We wanted to make the car continue when aborted in a goTo() action. We did this by creating a Thread to simulate the avoidance behaviour and thereby blocking the navigation thread. The navigator thread uses a flag to determine if the goTo()-action was finished or aborted, if aborted the command should be repeated. This principle was used for a set of positions where an obstacle was placed in the way of the path - this scenario can been on the video below:



The code is found in the class BlighbotExtended [2] and the avoidance is done in the method avoider():



The handling of the positions is done in the main thread where the flag as mentioned before is used to check for interruption: 





Conclusion:
When using the tacho counter we observed and measured that the distance travelled by using tacho count was very accurate but the rotation was not. To improve the rotation accuracy additional control of the motors is needed because the inaccuracy occurs because the motors "may not stop smoothly at the target angle if called when the motor is already moving" [3]. The implementation should be less fluent like our implementation for the Lego race[4] where the car stopped before each rotation.

As seen on the second video the vehicle is able to avoid an obstacle dynamically appearing in front of it. The chosen method for this avoidance is to let the vehicle stray a given distance to one side, when an obstacle is detected, and when finished this avoidance, recalculate the direction needed to obtain the original goal. This simple method has a problem if the next goal is too close the obstacle, because the obstacle could be in the path needed to reach the goal. A solution to this could be to Add More Sensors. Alternatively a more complex algorithm for letting the vehicle work itself around the obstacle could be used, but this method might also require More Sensors.

References:
[1Brian Bagnall, Maximum Lego NXTBuilding Robots with Java Brains, Chapter 12, Localization, p.297 - p.298.

Thursday, November 11, 2010

Lab Exercise 8

Date:
4/11 2010

Duration of activity:
3 hours

Group members participating:
Frederik, Christian & Lasse

Goals:
The overall goal for this lab exercise is to analyse and experiment with a provided subsumption architecture

Plan:
1. Observe behaviour with only RandomDrive active.
2. Observe behaviour with RandomDrive and AvoidFront active
3. Observe behaviour with all 3 classes active.
4. Integrate "Drive towards light" behaviour (from ex. 7).

Results:


Figure 1 - Car with ultra sonic sensor mounted

1.
The vehicle had only one behaviour; driving randomly around, not caring if there were any obstacles. The display shows the characters 'f' and 's' when driving forwards and stopped respectively.


2.
Behaviour:
The vehicle now shows an extra external behaviour; avoiding obstacles in front. Inspection of the code behind shows that the threshold for deciding when to begin avoidance is 20 cm.
Besides this the vehicle still drives randomly around.

Display:
General:
Display shows a '1' when it is being suppressed, and 'b', 'f', and 's' when vehicle is driving backwards, forwards or is stopped respectively.

AvoidFront:
Shows distance to obstacle - value of 255 is max/none obstacles detected.

3.
Besides the behavoiur from pt. 2 the vehicle now displays the additional behaviour of emitting a mating* sound every 10 sec. This is the highest prioritized behaviour in the vehicle, and it will suppress the other behaviours when active.

The display shows '1' next to each component when this is suppressed; AvoidFront and RandomDrive show '1' when PlaySound is active, and RandomDrive shows '1' when AvoidFront is active.

The hierarchy for the three components are shown below.

Figure 2 - The three original behaviours shown as a subsumption architecture

*The reasoning for assuming this is a mating sound is that this behaviour has the highest priority in the hierarchy, and thereby suppresses any other behaviour.

4.
The vehicle was retrofitted with RCX lightsensors as seen on Figure 3, and the "Drive towards light" behaviour was attempted to be integrated into the vehicle.

Figure 3 - Car with two RCX light sensors and an ultrasonic sensor

A modified version of the class used for this behaviour was recycled from exercise 7. Unfortunately it was not a perfect modification, as the overall behaviour of the robot degraded as seen in the video below.



It was, however, still possible to observe the suppress mechanism, when the PlaySounds-component was prioritized over TowardsLight[1]; when PlaySounds was active, the TowardsLight was suppressed. An illustration of the hierarchy is shown on Figure 4 below

Figure 4 - The updated architedture with the TowardsLight behaviour as second priority

Conclusion:

The Thread.setDaemon(true) allows us to treat the thread as a daemon ie. no need to manually handle thread termination since daemon threads automatically will shut down whn other threads are terminated.

The suppressCount integer used for suppresion in the Behavior class is used like a semaphore - incrementing on suppress() and decrementing on released(). This is useful when multiple behaviors are active and uses supress() to supress lower prioritized behaviors. In this case the lowest prioritized behaviors supressCount will be incremented to the amount of higher prioritized behavior that has supressed it. Therefor the lowest prioritized behavior will be suppressed until all higher prioritized behaviors has released the suppression.

The problems with integrating the TowardsLight behavior was caused by the fact that the original design of that class was not made with subsumption architecture in mind. Hence the degraded overall functionality of the behavior. To fix this we would probably need to implement the behavior from scratch.

Overall a good exercise in how to implement several prioritized behaviors in an architectural easy and manageable way.

References:

Thursday, November 4, 2010

Lab Exercise 7

Date:
28/10 2010

Duration of activity:
3½ hours

Group members participating:
Frederik, Lasse & Christian

Goals:
The overall goal for this lab session is construct and program three different Braitenberg vehicles and thereby do experiments with different sensor setups.

Plan:
The plan for the lab session is to construct the three Braitenberg vehicles shown on figure 1 by means of using different sensors as input.
We will use a sound sensor for vehicle 1 because it it easy to create distinguishable inputs. For vehicle 2a and 2b  we will use light sensors because it is fairly easy to change the light conditions for a single sensor by for example covering one of the sensors. This would be more difficult if sound sensors were used, but ultrasonic sensors could also be a solution.


Figure 1

Results:
This section describes the implementation of the three mentioned vehicles supported with photos and videos.

Vehicle 1
According to figure 1 vehicle 1shall move closer to the source which in our case is move faster the louder the sound.
The car was built with one sound sensor mounted. The car structure was reused from the previous lab session.
We made a thread for the control program to encapsulate the functionality/behaviour and make it easier to terminate the program and re-use some of the program stucture for the multi-threaded solutions for vehicle 2a and 2b. The code for the class in found in Vehichle1[2].

We had no major difficulties in getting the right behaviour. A video of the program in action is seen below:



Vehicle 2a
According to figure 1 vehicle 2a shall move away from the source which in our case is move away from the bright source.
The car was built with two RCX light sensors mounted. The car structure was reused from the Alishan-lab exercise as seen on figure 2.


Figure 2

Our first attempt was a direct mapping from the light values to the motor power. With this implementation it was hard to notice the difference so improvements had to be done to make a better distinguishing of the colours.
The second attempt made use of normalization because the sensor measurements didn't cover the whole spectrum of possible values.
A video of the program in action is seen below (one sensor thread):



The code for the class in found in Vehichle2a[3].

Vehicle 2b
According to figure 1 vehicle 2b shall move closer to the source which in our case is move towards the bright source.
The car was (as the previous car) built with two RCX light sensors mounted. 


The program from the car was based on the code from vehicle 2a including normalization. We extended the code for the normalization regulation so it was able to dynamically adapt to the surrounding environment be setting the min and max values as seen below.



We later on created a thread for each sensor to see if the difference was noticeable. By observing the car we noticed a more smooth performance. Afterwards we refactored the code so we ended up having the following threads:
  • One thread per connection which is two (connecting the sensors with the motor)
  • Control thread (closed loop controller regulating according to the environment)
  • Info thread (displaying information on the LCD)
  • Main thread (Initiating the program by performing bootstrapping)
A video of the program in action is seen below :


The final code the class in found in Vehichle2b[4].


Conclusion:
From what we found it is important to make sure that the range output from the sensor readings is proper utilized by normalization. If this is not done, the impact on behaviour is not great enough. Furthermore it was important to dynamically adapt to the environment, as the light conditions more or less constantly changed.
When the program was made more multithreaded, the vehicle seemed to behave more smooth, and it also behaved more reactive.
The main focus during this exercise was to experiment with the "original" design of the vehicle. Because of this we did not use ressources on expanding the vehicle with e.g. the bump-sensors.

References: