tirsdag den 9. november 2010

Lab session 8: Braintenberg Vehicles with Subsumption Architectures

Date: 4 - November - 2010
Duration: 3 hours
Participants: Kim Bjerge, María Soler, José Antonio Esparza

Goals of the lab session.

  • Improve the Braintenberg vehicles introduced in lab 7 by adding a subsumption architecture.
  • Learn how to implement autonomous agents by the use of different behavioural  threads and the subsumption architecture

Lego Car that exhibits several behaviors.

The SoundCar class is featuring three different behaviours, running concurrently on separated threads. As it can be seen in the main class structure, three different instances of the classes AvoidFront, PlaySounds and RandomDrive are started as separated threads. In the following code snippet, the instance corresponding to the RandomDrive action is shown.
      rd = new RandomDrive("Drive",1, null);
    ...
         rd.start();
         ...
The output from the three separated threads are reported in a while loop until the escape button is pressed part of the main program.
while (! Button.ESCAPE.isPressed())
{
rd.reportState();
      af.reportState();
      ps.reportState();
 }
The threads implements the Behavior class which is explained in the following section.

Behaviors as concurrent threads.

The Behavior class provides a concurrent base for the different concrete implementations of behaviors the robot. It contains the logic to coordinate robot reactions by the suppress and release methods.
A relationship with other behaviors is established by a self reference, which is pointing to the next Behaviour. It creates a linked list of behaviors, in which each node is an instance of the class.

  private Behavior subsumedBehavior;

Each behaviour can be suppressed or released. In case the Behavior receives the suppress signal, it will increment the supressCount and forward the suppress call to the rest of Behaviours contained in the list.
An analogous operation is carried out when the release method is executed. In this case the operation will be decreasing the value of the supressCount field.

In the case the behaviour is not suppressed, the supressCount should be equal to 0. A simple function to check that condition is implemented in the method isSuppressed().

In the case the behaviour is not suppressed, it is be able to command the motors through the methods forward, backward and stop.

This supressCount variable could be considered as a synchronisation, that provides safe access to the motors, which are the shared resources between the active behaviours running on the separated threads. It would not be possible to use a boolean type instead of a suppress counter. In the case of more behaviours in the list calling the same release (Button of list) would cause the lowest prioritized behaviour to start before expected.

By implementing the behaviors as separated threads independence and separation is gained in the implementation. The structure is the subsumption architecture which is more clear and logical. A different approach for implementing this behaviour coordination could be to use nested if conditions, as explained in [2]. This might be easier to implement but it may have lower performance and the structure is not so clearly defined. According to the signal pattern presented by Powel Douglas in [4], it is a good practice to associate one thread to process each incoming signal in the system. That is one additional reason to keep this threaded structure in the system.

The Fred Martin [5] algorithm is not object oriented, and is using a priority index to determine which action should be performed. The responsibility is hold by a central priority queue, which will be updated depending on the processing requests provided by the different running tasks. This solution is less flexible and could be more complex to expand. It is also computationally more expensive, since it is based on a search through an array.

The linked list threaded behaviour takes less time to be executed, since the control algorithm is going through the behaviours by following the references contained in the method declaration section. This is clearly more efficient since the whole operation is based on a structure composed by the actions increment/decrement integer and follow a pointer to the next element.

Class Behavior.

Add a behavior “Drive towards light”.


The new behaviour has been implemented as a class that extends Behaviour, like all the other ones in the project.

Light follower behaviour class:

public class LightFollower extends Behavior {..}

The robot is reused from the lab7, and therefore we used the same RCX light sensors again. After some empirical tests, it was decided that the threshold value for what should be considered light was 21. That’s the amount of light where the robot will start to move towards.

private RCXLightSensor leftLight;
private RCXLightSensor rightLight;
private int lightThreshold = 21;

The LightFollower class implements the run method of the Behaviour class. It checks constantly if the light value is over the threshold (this is displayed in the lcd), and in that case, it suppresses the rest of the behaviours and moves towards the light using the motors.

public void run() {
 while(true){
  while(leftLight.readValue() < lightThreshold
        && rightLight.readValue() < lightThreshold){
   String message = getStatusMessage();   
   drawString(message);
   
  }
  suppress();
  int leftPower = leftLight.readValue() + 50;
  int rightPower = rightLight.readValue() + 50;
  forward(leftPower, rightPower);
  String message = getStatusMessage();   
  drawString(message);
  delay(1500);
  stop();
  release();
 }

}

Main program that sets up the subsumtion layered architecture:

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

We have decided to let the AvoidFront to be the highest prioritized behaviour. That means when an object is detected by the ultrasound sensor all other behaviours will be suspended. The new light follower behavior is the second highest prioritized behaviour since we mean it is less important to follow the light than crashing into objects including the light source.

Link to video of Vehicle with four behaviours in the subsumtion architecture:




Link to JAVA code for vehicle in video: Source Code

References.

[1] The subsumption architecture. - Article on Wikipedia. http://en.wikipedia.org/wiki/Subsumption_architecture
[2] Scripting Subsumption Architecture. - The Game of Intelligent Design. http://gameofid.com/blog/scripting-subsumption-architecture
[3] Chain of responsibility Design Pattern - Article on Wikipedia.
http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern
[4] Douglass, Bruce Powel. Real-Time Design Patterns: Robust Scalable Architecture for Real-Time Systems, Addison Wesley 2002
[5] Fred Martin, Robotic Explorations: A Hands-on Introduction to Engineering,
Prentice Hall, 2001.

Ingen kommentarer:

Send en kommentar