Thursday, 26 April 2012

Legolab 10 - Behavioer

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 - Navigation

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

Tuesday, 17 April 2012

Legolab - Alishan train track

Legolab 8
Date: 12-04-12 and 17-04-12
Duration: 9 hours
Group members attending: Tore, Troels & Kristian

Goal
Make a robot to complete the Alishan Train Track challenge.

Plan
1. Mount sensors on the car.
2. Come up with an idea and implement it.

Execution
1. 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.


Status
We 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.

Monday, 9 April 2012

Legolab 7

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