mandag den 7. april 2014

Week 8 - Lesson 7

Date:
3/4-2014(round 1), 7/4-2014(round 2)
Duration of activity:
10:00 - 15:00(round 1), 11:00 - 14:00(round 2)
Group members participating:
Levi, Christina, Benjamin

Goal:
We will use the behaviour control paradigm to implement several observable behaviours on a single NXT that controls a LEGO vehicle with an ultrasonic sensor, a light sensor and two touch sensors.

LEGO vehicle that exhibits a single behaviour

Behaviour of car:

The car drives forward if no obstacles are met. If an obstacle is met, the car stops, and then turns approximately 45 degrees to the right. Immediately after, it drives backwards to original position, and then turns approximately 45 degrees to the left. Looking at the code, we can see that it stores the distance when having turned left and right respectively. If it measures that the right distance is further than the left, it drives backwards again to original position, turns approximately 45 degrees to the right again, and then drives forward. 

Change the program:

Despite the uncertainty of what a "tree" distance is, here is our take.

First of all we need to make sure that if all the three distances measured (frontDistance, leftDistance and rightDistance) are less than the value of stopThreshold, the car sets itself back to the original position after having completed the measurements, as this is not directly in the code provided. When it has done this the car should back up a little and following this, it should spin around on the spot 180 degrees.
The altered code for this behaviour of the car can be found at [1].

A video showing the new behaviour of the car is shown here:

Behaviours as concurrent threads

Describe how the car behaves:

We tried two different environments when testing the car. The first was our TA room where the light is somewhat dim. Afterwards we moved to the entrance area of the TA room where there are windows and thus more sunlight. We did not reset the program between the two settings, so the car did not get new thresholds in the new setting, and thus would act like it was in the first setting.

We tested the triggers by doing different things: when we held a hand close in front of the sonar the LCD displayed ‘Winner 1’ (and executed the ‘avoid’ action) and when nothing was in front of the sonar (at least not in the distance corresponding to the value of 30 - which we found was about a distance of about 30-35 cm) it displayed ‘Winner 2’ if the car was oriented in way that it measured light with a value higher than the value from when the program was started (which is the action ‘follow’).
If the car was oriented in a way that it measured light with a value lower than the value it measured when the program was started and if nothing was in front of the sonar for at least 30-35 cm, the program executed ‘cruise’ and displayed ‘Winner 3’.

The conditions that trigger ‘cruise’ is when there isn’t anything to avoid and when there isn’t any light to follow. When there is light to follow it will follow it (until and unless there is something to avoid) and it won’t start cruising until there isn’t any light to follow anymore.

Triggering conditions:

Avoid: The avoid class acts exactly like the programme ‘AvoidFigure9_3.java’ in the first task
Follow: Here the car drives left and right respectively and measures the light intensity. Then it calculates the delta value, subtracts it from the left motor power, and adds it to the right motor power. This way it will turn towards the brighter side.
Cruise: This class make the car cruise like a gangsta with style!

Add an Escape behaviour

The implementation of the escape behaviour from page 305 of [2] is to check if the two touch sensors bump into anything. If both sensors register that they have touched something it means that the car is being bumped from the front, and the program therefore makes the car drive backwards.
If only the left sensor is bumped, the implementation believes that the car has run into something on the left side of the car, and henceforth turns the car to the right (for a while, the comments for the code says).
Vice versa; if the touch sensor on the right touches something, the car is set to turn to the left.
In this way the robot is able to escape from collisions with obstacles.

First of all we put two touch sensors on the car and attached the two to each other via a ‘bumper’. A picture that shows this is here:


In our implementation of making the car escape from a front bump we start with experimenting with making the car drive backwards for large amount of time in order to get the car to get entirely clear of the wall so that it will not hit it with the bumper when turning to the side to measure the leftDistance and rightDistance.

The code for the programme can be found here [3].

The behaviour can be seen in the video here:

Add a third motor to turn the light sensor

We followed instructions to mount a horizontal motor on the vehicle, and mounted the light sensor on the motor:


In order to reimplement the follow behaviour with the new motor, we utilised LeJOS' NXTRegulatedMotor. This allowed us to turn the motor to specific angles, and thus switch between 45 degrees and -45 degrees from start point.
Here is a video of our implementation in practice:
The altered code can be seen at [4].

The classes SharedCar and Arbiter

In [3] multiple outputs are directed to the same input (that is the function arbitrate()) and the outputs occurring latest in the ordered list of statements have superiority of the earlier ones in the list.
The function arbitrate() is shown below.


As described, the latest output subsume the earlier ones. In the function above, this means that the process for ‘escaping’ overwrites the process for ‘avoiding’ which overwrites the process for ‘following’ that in turn overwrites the process for ‘cruising’. This behaviour makes sure the robot isn’t going to start following light if it has to avoid an object in front of it or if it has hit something.

In the class Arbiter the hierarchy of actions to be performed is implemented. The priority of actions is from the list of car’s in the SharedCar list. The list is run through from the 0th car to the x’th car in the list. In our case this is from the 1st car to the 3rd car.

The code for the Arbiter class is seen below.


If a carCommand from the first car from the list that is checked is different from null, the action of this car is performed. If the carCommand is null, then the carCommand from the next car in the list is checked, and if this is null, the last car’s carCommand from the list is checked. Whenever a car in the list has a carCommand that isn’t null, the for loop that checks all the list’s car’s carCommand’s is broken out of. This means that if the first car in the list has a carCommand different from null, then the other cars carCommand isn’t checked. In this way, the action of the first car in the sharedCar list has priority over the cars further into the list of cars in the sharedCar list.
Establishing the order of prioritisation is done by adding cars to the sharedCar list in the order of decreasing importance, as shown below. 


This order means that the action of an ‘avoiding’ car has superiority over a ‘following’ car which again has superiority over a ‘cruising’ car. In this example the action of an ‘escaping’ car isn’t implemented, but it is prepared to be added to the sharedCar list of cars as the first element (0-indexed), because it has to be prioritised over the action of ‘escaping’.



In [5] there is no need to put the actions in a list in a prioritised order. This implementation is slightly different and makes use of assigned numbers to each action, where a higher number equals higher priority. In his implementation the entire list of enabled processes is searched, and the enabled process with the highest number gets to run.

Conclusion:

Everything went better than expected.

References:

[1] AvoidFigure9_3.java
[2] Jones, Flynn and Seiger
[3] RobotFigure9_9.java
[4] Follow.java
[5] Fred Martin p. 214-218

Ingen kommentarer:

Send en kommentar