Legolab 10 - behavior
Date: 26-04-12
Duration: 3 hours
Group members attending: Tore, Troels & Kristian
Goal
Complete today’s exercises, that is experiment with behavior program given.
Plan
1. Mount pressure and ultra sonic sensors.
2. Get the program running and do tests:
3. Press the touch sensor and keep it pressed. What happens?
4. Implement a third behavior, Exit.
5. Investigate the source code for the Arbitrator.
6. Implement a local thread in DetectWall.
7. Implement the behavior DetectWall so the actions taken also involve to move backwards for 1 sec before turning.
8.
Implement the behavior DetectWall so it can be interrupted and started
again e.g. if the touch sensor is pressed again while turning.
Execution
1. We mounted the sensors on our usual robot, to make it look like the one shown in the lecture:
3.
When the touch sensor is touched, the robot stops, backs away and turns
a bit. When the sensor is pressed and held, the before mentioned
behavior just loops.
4.
The escape mechanism was implemented as a behaviour equal to the
others. When DriveForward is active there is no behaviour blocking it.
If there is no behaviour blocking the exit mechanism will be invoked
immediately. If DetectWall is being invoked, the behaviour of the robot
is already blocked rendering the escape mechanism useless for the time.
5.
The arbitrator iterates through all the behaviours from the highest to
the lowest. This automatically creates hierarchy amongst the the
behaviours. First the highest gets the opportunity to takeControl over
the robot and so forth.
6.
We implemented the ultrasonic sensor in a separate thread. We could,
however, not get it to work as intended. The thread was not called
correctly, and we could not figure out why.
7. The rest will have to be done some other time.
Status
We
went through most of the tests and some of the implementations, and now
have a better understanding of how the behavior system works. We would
have liked to get more of the threads to work correctly.
Legolab 9
Date: 19-04-12
Duration: 3 hours
Group members attending: Tore, Troels & Kristian
Goal
Complete today’s exercises, that is experiment with navigation.
Plan
1. Implement and test the given test-program from the exercises (*1).
2. Implement a program that has the robot follow a route while avoiding obstacles.
Execution
1.
We used the same car, we have used for weeks now, but detached the sensors:
The wheel diameter is 5.6 cm and the distance between the wheels is 17.1 cm.
We detached a whiteboard and put it on the floor, so we can draw where the car starts and ends.
Then
it turns out that the class TachoNavigator is deprecated and we cannot
use it. The package does not exist. We instead use the class
DifferentialPilot. This however does not use a coordinate system.
We wrote a program, example seen below, to test the robot, The robot drives in a square with side length of 50 cm.
DifferentialPilot dp = new DifferentialPilot(5.6, 17.1, Motor.C, Motor.B);
public void driveInSquare(){
dp.travel(50.0);
dp.rotate(90.0);
dp.travel(50.0);
dp.rotate(90.0);
dp.travel(50.0);
dp.rotate(90.0);
dp.travel(50.0);
dp.rotate(90.0);
}
The following video shows the square driven. One can see, the it is about a centimeter off.
(video on the way)
Next step, we attached a marker as suggested:
We had the robot drive the square 5 times. The result is seen in the picture below.
The result is fairly good, off only by ½-1 cm.
We
then found the class Navigator, which used a coordinate system. This
class however did not work correctly. The method rotateTo() worked, but
goTo() did not and when we tried to use it, the robot just reset. We
googled solutions and the best suggestion was to use NavPathFinder
instead of Navigator. We were, however, not able to import this class,
it was not in our lejOS package. We finally found out that in lejOS
version 0.9.1 the Navigator class does not work properly, so we skipped
the coordinate system, went back to using DifferentialPilot and found
out we could get the robot position/direction from the
OdometryPoseProvider.
2.
The
plan is to make a program that uses the travel() and rotate() methods
from the DifferentialPilot and has the robot follow some pre-defined
path. The robot should be able to avoid obstacles on the path. The first
idea is to mount a bumper to the robot using the pressure-sensors. We
would then have some hardcoded avoid function and use the
OdometryPoseProvider to get the position and direction, when the robot
gets back on track, to re-calculate the path from the current position.
This however will be a project for another time.
Status
We
did not get far in the exercises. This is because some of the classes
we thought, we could use, was outdated, which we only found out after
googling it a lot and reading through the different navigation classes
as well as their documentation. So we did not get work done, but we
still feel that we learned a lot about navigation and how to implement
it.
References
(*1) http://legolab.cs.au.dk/DigitalControl.dir/NXT/Lesson9.dir/Lesson.html
Legolab 8Date: 12-04-12 and 17-04-12Duration: 9 hoursGroup members attending: Tore, Troels & KristianGoalMake a robot to complete the Alishan Train Track challenge.Plan1. Mount sensors on the car.2. Come up with an idea and implement it.Execution1.
We started with a single light sensor, hoping it was enough to follow
the line. We later added a second light sensor, seen here:
2.
The first idea was to use our PIDcar and a sound sensor. The plan is
now to use two threads, one to drive straight and follow the line, and
one to do the turns. The second thread would be activated by a clap. We
took the code from last lab session and modified it to contain only two
layers with the above mentioned properties. This however did not work
that well, and we figured it would be cheating, so we scrapped the idea.Next
step, we have mounted two light sensors. The basic idea was to have the
left sensor make the car follow the line and the right sensor detect
when the 90 degree turn is reached and hardcode the turns. But
hardcoding is hard, when the battery level of the NXT dictates how fast
the wheels turn, and thus the time a turns takes varies. And even though
the power level to both motors are the same, their speed is different.StatusWe
went through a lot of ideas and constantly changed our minds. At one
time we also used the ultrasonic sensor to detect when the plateau was
reached and do a turn. And we had different ideas as to how the light
sensors should be used.We
got the car to complete the first turn and almost the second turn once.
But then something went wrong and our robot would get stuck in the top
layer thread of the program, and just spin around from the beginning. We
tried deleting everything on the NXT and upload the program again, it
worked once and then the same error occured. We could not find any
changes in the code that should cause this.We have no more time and must accept that we can not complete the goal.
Legolab 7
Date: 29-03-12
Duration: 3 hours
Group members attending: Tore, Troels & Kristian
Goal
Complete todays exercises concerning threading.
Plan
1. Mount the ultrasonic sensor on our car.
2. Try out the program SoundCar (*1), observe behavior, analyse the program.
3. Add behavior to the robot.
Execution
1. This was easily done, as shown below:
2.
We transfered the SoundCar program to the robot. It appears the program
runs 3 threads, one to drive, one to avoid obstacles and one to play a
sound. The LCD displays an overview of the threads, whenever a thread
has control, a “1” is displayed next to the thread of the level below.
The RandomDrive is level 0, the AvoidFront is level 1 and the PlaySounds is level 2.
Every
tenth second the sound is played. The avoid-thread is triggered, when
the distance measured is below 20, thus making the car drive backwards
for a little while and then turn. The drive-thread has the control the
rest of the time.
The RandomDrive is level 0, the AvoidFront is level 1 and the PlaySounds is level 2.
The
purpose of making the daemon threads is to make sure that the whole
program exits when we close the main program. The daemon threads works
as supporting threads to the main program. When the main program exits
there is no need for daemon threads and the interpreter will exit.
The
suppressCount is used to check, whether a thread can take control or
not. If e.g. the PlaySounds thread is in control, it uses the suppress()
method to suppress AvoidFront and RandomDrive, making these threads
unable to control the car. When the PlaySounds is done it releases
control again with the realease() method. If a thread calls suppress(),
it recursively suppresses all the levels below.
We could not find the article of Fred Martin mentioned in the exercises.
3.
We modified todays testprogram with an extra thread level between the
RandomDrive and the AvoidFront, to make the car drive towards the light.
It was mostly copy-paste from last labsession and editing the
suppress-mechanism. The light-sensors was mounted on the car like we did
last time.
Condition
lightThreshold = 800;
while (light1 < lightThreshold &&
light2 < lightThreshold) {
light1 = ls1.getNormalizedLightValue();
light2 = ls2.getNormalizedLightValue();
drawInt(ls1.getNormalizedLightValue());
}
Subsumption
rd = new RandomDrive("Drive",1, null);
tl = new TowardsLight("Light",2,rd);
af = new AvoidFront ("Avoid",3,tl);
ps = new PlaySounds ("Play ",4,af);
Status
The
exercises today taught us the basics of multi-threading and how to
manage thread control. We were impressed with how simple yet powerful
the structure of the layers were. It’s very easy to add new layers and
the structure will adapt automatically. This could be very useful later
on.
references
(*1) http://legolab.cs.au.dk/DigitalControl.dir/NXT/Lesson7.dir/SoundCar.java