Thursday, November 4, 2010

Lab session 8 : Concurrent Threads

Date: 4. November 2010
Duration of activity: 2,5 hours
Group members participating : Michal Owsinski, Michaël Ludmann, Guillaume Depoyant, Anders Dyhrberg

I. Objectives and summary

During this lab session, we managed to :

  • Try to understand how to have different behaviors implemented in the same robot
  • Understand the role of priority for tasks
  • See how the behavior suppression strategy works

II. Robot with different behaviors

II.1. LEGO car that exhibits several behaviors

For this first experiment, we merely tried to test the program and see what happened. Basically, the robot shows three different behaviors :

  1. It moves around randomly, driving forward by moving the wheels at different speeds in a random fashion, during some time (apparently random too). While moving forward, the LCD display shows the letter "f" on a line. Between two moves, the robot stops (letter "s" on the display).
  2. It reacts to the presence of an obstacle in front of its ultrasound sensor. If an object is too close, the robot moves backward and then turn right forward. The same letters appears on the screen, on top of a number displaying the distance seen by the ultrasound sensor (20 is the threshold)
  3. It plays some nice sounds every 10 seconds.
The LCD display shows in real time which behavior is currently followed by the robot. Whatever happens, the robot will always play its sound every ten seconds. It goes the same way for the US sensor : if there is an obstacle, the robot will stop its random driving task in order to avoid the obstacle. So task number 3 precedes task 2 which precedes task 1 : there are different priorities between them. 

The video below shows the general behavior of the robot while testing this program with those behaviors.

II.2. Behaviors as concurrent threads

III. Explaining the threading strategy

III.1. The purpose of making threads daemon threads
The purpose of making the thread a deamon thread, is to tell the the execution environment, in our case the VM. This thread can be terminated when the there is no more none-daemon threads, normally called User Threads.
The daemon thread is typically used for utility functionality that supports the core threads of the program.
One of the most regular known daemon thread is the Garbage Collector. This thread is daemon thread and support the functions of the main loop made by the user. But since the GC is a daemon thread, the VM will automatically end the GC thread when last user thread is ended, typical when the main loop expires.
This understanding is supported by the JaveSE doc[1] and Lejos doc[2]

III. 2. The behavior suppression strategy
The suppression system implemented in the Behavior class is a strategy know as the Subsumption Architechture[3]. It is basically a configuration of the threads where all threads can be parent to one another thread, hereby giving the thread priority. Parrent has higher priority than its child thread. When a parent wishes to execute it's implemented functionality, is suppress the functionality of its child (lower priority) thread. by incrementing the child threads suppression counter. Due to the nesting this will propagate to all the lower priority threads. All threads are continuously executing its functionality loop, also while being suppressed. Therefor is important that each thread check its suppression counter, before trying to actually start its action, by using the isSuppresed() function. The parrent is responsible for release this child again when it is done with its own actions. If it fails to do so, the lower priority thread will new perform any actions.
This strategy is similar to the Semaphore system.

III. 3. The arbiter strategy
The arbiter strategy from Fred Martins book,
... [Dyhrberg]

III. 4. Comparing the arbiter and behavior strategy

IV. Improvements

IV. 1. Adding a behavior : "drive towards light"

Basically, with the first version of the car, there were 3 different behaviors with a specific order on the priorities:

        rd = new RandomDrive("Drive",1, null);
        ps = new PlaySounds ("Play ",2,rd);
        af = new AvoidFront ("Avoid",3,ps);

Avoid Obstacles > Play Sounds > Random Drive

The next step was to try to add another function to the robot: following the light. To do this, we used the last prototype we crafted during the previous lab session. This way, the robot had two RCXLightSensor. The robot auto settled his own values of MIN_LIGHT and MAX_LIGHT and when the sensor sampled a value beyond 60% (or another value that can be settled) of the ratio (value_sampled - MIN_LIGHT)/(MAX_LIGHT - MIN_LIGHT), the "semaphore" process was engaged.

In order to give a reliable order of the behaviors, we initiate the process as follows:

        rd = new RandomDrive("Drive",1, null);
        fl = new FollowLight ("Light",4,rd);
        ps = new PlaySounds ("Play ",2,fl);
        af = new AvoidFront ("Avoid",3,ps);

This way, the robot would have such priorities

Avoid Obstacles > Play Sounds > Follow Light > Random Drive

IV. 2. Results

V. References

No comments:

Post a Comment