This is an old revision of the document!
Table of Contents
Lab report 10
Date: November 21st 2008
Duration of activity: 8-12
Participants: Kasper, Bent and Johnny
Project Goal
In this lab session we will investigate how a behaviour-based architecture1), has been implemented in the subsumption API of leJOS NXJ. We will investigate the interface lejos.subsumption.Behavior and the class lejos.subsumption.Arbitrator and try to make an alternative implementation of the Arbitrator.
Plan
The plan for today is devided into two parts. First we will investigate and evaluate the behaviour of BumperCar2). And second we will change the behaviour of Arbitrator for BumberCar3)
Part One
This will include the following:
Part Two
Implementation of an alternative Arbitrator that will make sure that takeControl of all behaviours are called each time through the loop. When the Arbitrator is working we will compare it to the lejos Arbitrator.
Execution
The program bumberCar.java is run in the NXT and we observe what happens when the touch sensor is kept pressed constantly. We expect the hitWall behaviour to be active making Marvin go backwards and turn over and over. This is not what happens though and the reason for this is found by inspection of the arbitrator within the Lejos system. The source code for the arbitrator is shown below.
The lejOS Arbitrator
public class Arbitrator { . . . public void start() { int totalBehaviors = behavior.length - 1; while(true) { // Check through all behavior.takeControl() starting at highest level behavior for(int i = totalBehaviors;i>=0;--i) { if(behavior[i].takeControl()) { // As soon as takeControl() is true, execute the currentBehavior.suppress() //if(behavior[i] != currentBehavior) { if(i != currentBehavior) { // Prevents program from running same action over and over again if (currentBehavior != NONE) { if(currentBehavior >= i) // If higher level thread, wait to complete.. while(!actionThread.done) {Thread.yield();} behavior[currentBehavior].suppress(); } // Make currentBehavior this one currentBehavior = i; // Run the currentBehavior.behaviorAction() actionThread.execute(i); Thread.yield(); } break; // Breaks out of for() loop } } } } . . . private class BehaviorAction extends Thread { public boolean done = true; int current = NONE; public void run() { while(true) { synchronized(this) { if(current != NONE) { done = false; behavior[current].action(); current = NONE; done = true; } } Thread.yield(); } } public synchronized void execute(int index) { current = index; } } }
Observe the test if(i != currentBehavior). This condition ensures that the same behaviour is not detected over and over, which is in fact the reason why HitWall() is not run continuously when the touch sensor is held pressed. Both DriveForward and HitWall contains the method takeControl and again by inspection of the arbitrator we observe that takeControl of DriveForward is called when HitWall is active, but because HitWall has a higher priority, the arbitrator waits until HitWall is done. In order to further investigate the arbitrator we now implement a new behaviour called Exit, which calls System.exit(0) when the button escape is pressed.
Motivation Functions
The “normal” case is that when hitWall is active, Marvin will back out, turn a little bit an step out of that rutine. But what if the hitWall rutine is activated repeatly. What happes then? In the group, we talked about the case where Marvin would hit a bouncing wall, e.g. a wall with a spring attached to tha back of it, so that it would move towards Marvin when pushed once. In this case Marvin would react the normal way, that is, back out and turn, but the wall will then hit him again, and this will repeat itself. In this case, it would be convient to implement some sort of mechanism that would help Marvin to get out of that situation. Lets could it a motivation to do something. Thiemo Krink6) has some proposals on this topic. Marvin could have some sort of motivation factor to get away from the wall on change direction. As is seen in the picture below we have drawn a simpel graph to illustrate how we think Marvin should behave in the case where he hits the wall several times. XXXX INDSÆT BILLEDE DER ER TAGET AF GRAFEN DER BLEVET TEGNET PÅ TAVLEN!!! XXXX
The first time Marvin hits the wall his motivation to backout and turn should be major. If takeControl takes over to reactivate the rutine the motivation should thereafter me minor because of e.g. the spring wall mentioned earlier. There after the motivation should again rise over some time (the time period is case not important as we only talk principles, but is ofcourse important in the implementation) to improve the motivation to get away from the wall. It should be noted that the first time Marvin hits the wall, it would be the normal case and after some time the motivation should be greater than normal state. This may not be that well illustrated on the graph.
The implementation of this could be e.g. 10-20 seconds time interval from first hit to full motivation and could be an integer or percentage (floating point number) that will increase the speed Marvin backs up with and second the degree of turn that he makes.