Date:
25/04/2012 & 01/05/2012
Duration:
3 hours & 2 hours
Attendants:
Stefan
Ravnholt, Thomas S. Sylvest & Jeppe Hansen
Goal:
Complete
exercises for this week’s lab session.
Plan:
Make BumperCar run on an NXT
This was archived first by constructing the following robot.
Then we
made sure that all sensors and actuators were connected to the same ports as
required by the program BumperCar.java. In the end we uploaded the
BumperCar.java program without any changes to the NXT and it ran successfully.
Press the touch sensor and keep it pressed.
What happens? Explain.
The robot
reverses and drives a bit against the clock. It is the same behavior that
happens when the sonic sensor detects something in the way.
Implement a third behavior, Exit. This behavior
should react to the ESCAPE button and call System.Exit(0) if ESCAPE is pressed.
Exit should be the highest priority behavior. Try to press ESCAPE both when
DriveForward is active and when DetectWall is active. Is the Exit behavior
activated immediately?
When
DriveForward is active and the ESCAPE button is pressed the robot exists pretty
much immediately, however when the DetectWall behavior is active, the robot did
ignore many of our button presses before finally exiting.
Both DriveForward and DetectWall have a method
takeControl that are called in the Arbitrator. Investigate the source code for
the Arbitrator and figure out if takeControl of DriveForward is called when the
triggering condition of DetectWall is true.
for (int i = maxPriority; i >= 0; i--)
{
if (_behavior[i].takeControl())
{
_highestPriority = i;
break;
}
}
for (int i = maxPriority; i >= 0; i--)
{
if (_behavior[i].takeControl())
{
_highestPriority = i;
break;
}
}
The code
above is taken from the private class Monitor that the Arbitrator class uses to
find out which is the behavior with the highest priority that also wants to
take control. As one can see the Monitor class calls the takeControl method one
by one from the highest priority to the lowest. When it finds a prority that
wants to take control the program breaks out of the loop. This means that
DriveForward’s takeControl method will not be called when DetectWall wants to
control the actuators.
Try to implement the behavior DetectWall so the actions taken also involve to move backwards for 1 sec before turning & t
The resulted behavior of the robot, after implementing a part of the takeControl method as a thread, was that the Exit function of the robot became much more responsive. We were now able to turn off the robot, at any given time, and not at specific intervals.
After expanding the code for DetectWall, so it now drives backwards for 1 second, when it detects an obstacle, the car now drives backwards for one second when we put something in front of the sensor.
We added a new class Action, which is a thread that can be interrupted when the taskeControl method is called and the criteria are met:
boolean a = touch.isPressed() || sony.getDistance() < 25;
if (a) {
action.interrupt();
action = new Action();
}
Now the robot continues to go backward as long as something is in front of it.
The takeControl method of DetectWall contains a
call to the ultrasonic sensor method getDistance that includes a delay. This
means that the call of takeControl for the other behaviors is delayed and the
reaction to an event is not immidiate. In [1] it is recommende that takeControl
"should return quickly, not perform a long calculation." To avoid the
pause in the takeControl method of DetectWall a local thread in DetectWall
could be implemented that sample the ultrasonic sensor e.g. every 20 msec and
stores the result in a variable distance accessible to takeControl. Try that.
We have
implemented the local thread that continuously samples the distance in the
following way:
class SonicDetect extends Thread{
private UltrasonicSensor sonar = new UltrasonicSensor(SensorPort.S3);
private UltrasonicSensor sonar = new UltrasonicSensor(SensorPort.S3);
private int distance;
public synchronized int getDistance(){
return distance;
}
public synchronized void setDistance(int newdist) {
this.distance = newdist;
}
}
public void run() {
while(true){
setDistance(sonar.getDistance());
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated
catch block
e.printStackTrace();
}
}
}
}
}
This way
the DetectWall object can get the sonic distance instantly.
Try to implement the behavior DetectWall so the actions taken also involve to move backwards for 1 sec before turning & t
ry to implement the behavior DetectWall so it can be interrupted and started again e.g. if the touch sensor is pressed again while turning.
The resulted behavior of the robot, after implementing a part of the takeControl method as a thread, was that the Exit function of the robot became much more responsive. We were now able to turn off the robot, at any given time, and not at specific intervals.
After expanding the code for DetectWall, so it now drives backwards for 1 second, when it detects an obstacle, the car now drives backwards for one second when we put something in front of the sensor.
We added a new class Action, which is a thread that can be interrupted when the taskeControl method is called and the criteria are met:
boolean a = touch.isPressed() || sony.getDistance() < 25;
if (a) {
action.interrupt();
action = new Action();
}
Now the robot continues to go backward as long as something is in front of it.
Implement motivation functions.
We have
studied and understood the given code in Behavior.java, Arbitrator.java and
BumperCar.java and have no suggested changes to the code.

.jpg)

