woensdag 15 juni 2011

The Mars Mission


Today is the final day before the Mars Mission.
Although it is not smart to adjust the code the day before the actual mission, we tried to improve some minor things in the code.
Of course, the 'working' code from yesterday is kept, so we can also fall back on the working code.

For example, the Rover only used the left and right light sensor for edge detection.
If the Rover misses a lake (due to crappy video detection or due to driving over a lake that is already measured), the middle lights sensor is not used and thus the Rover could get stuck in a lake. (Although it can recover from driving inside a lake sometimes, this does not always work due to the extra weight of the batteries). This was still one of the problems that is not handled correctly by our program.
Now the code is adapted in such a way that the middle light sensor is also used for edge detection only IF the Rover is not close to a lake. Close to a lake, the middle light sensor is used for lake detection. This is also tested extensively on a 'table' with fake lakes.

Another bug that was still pending was that while measuring the lake, the edge detection is not 'stopped' correctly. If there was a sudden trigger in the left or right light sensor, the Rover just started driving backwards 'avoiding' the edge while the temperature sensor was still in the lake. This results in a broken Rover. Although we did not encounter this problem while testing, it is a risk. If for example somebody walks past the Rover and his shadow triggers a light sensor, the Mission is lost.
The code is also adapted such that this bug is removed. This modification is again tested extensively on a 'table' with fake lakes.

After the code seemed to work fine again, we asked if we could borrow the camera for 10 minutes to do some actual testing on Mars. Below a short movie is indicating that the Rover seems to work properly. However, there was not enough test time so we could not finish the Mission and do much more tests. Again the main problem was the detection of the lakes, which is really crappy.
The BEST Mission is still visible in the movie of yesterday, so please see that one also.
The adjustments to the code seemed to work properly, so we decided to use this last code for the final Mission tomorrow.



Now we will give the exact details and strategy of our code for the Mars Mission. The main idea is already discussed in the presentation.

The goal of the course is to find all the three the lake, measure the temperatures and send the temperatures to Earth. While doing so, the Rover should not fall off the Surface or falls into a lake.

First the hardware configuration setup for the different bricks:
RCX 1 : left + right light sensor , 1 encoder , motor left, motor right
RCX 2: middle light sensor, temperature sensor, motor temperature-crane. (second encoder is not used)

The different tasks on the different bricks (Note that the bold tasks are always active and running in parallel).

RCX 1:
- Read_from_ir (receive information from RCX 2)
- Received (store valid coordinates)
- Edge (edge detection and avoidance)
- Rand_drive (smart random driving)
- Drive2lake (drive to a lake via calculated path, receive/send lake information to/from RCX 2, avoid lake after measurement)

RCX 2:
- Read_from_ir (receive information from RCX 1)
- Send_to_ir (send temperature to Earth)
- Lake (detect a lake, or probably a cliff with the middle light sensor and send info to RCX 1)
- Measure (If no edge is found, this function is initiated and the temperature is measured. After this, the temperature is send to RCX 1 so the Rover knows it can start avoiding the lake and continue the mission)

Now our strategy:

The main thought is 'Safety First'. This means that the RCX 1 brick that is used for actuation of the motors is also used for edge detection. By doing this, the response time when an edge is found is minimized and the Rover can also stay safe if IR communication fails.
As an extra, the middle light sensor is also used for edge detection if the Rover is not close to a detected lake (detected by the camera).

Edge detection:
For edge detection, the left, right (and middle) light sensors are used. To read out the light values, we used the raw data (as we did with the line tracking contest). This means that the resolution of the light values is increased. For a standard light value, the brick gives values round 50, when the raw data is used this value is round the 700! The information for this raw data can be found in the 'C API'. The only thing that has to be used is the 'ds_scale()' function.
Edge detection itself uses the gradient of the light values. So if the difference between the current measured light value and the previous stored light value is deviating more than a certain value, an edge is detected. Then all the other tasks must stop and the edge avoiding algorithm is started. The Rover always drives backwards for a certain distance and then turns to the intended direction. If the left light sensor detects a cliff, the Rover turns to the right. If the right light sensor detects a cliff, the Rover turns to the left. I this way the Rover always continues in the direction it was driving. If however, both the left and the right light sensors, of also the middle light sensor detects a lake, the Rover is facing a cliff (almost) straight. We chose to drive the Mars landscape in a counter-clockwise direction as a 'standard' direction, so in the last case the Rover will always turn to the left.
If the Rover detects an edge during driving to a lake, we assume the lake was a 'fake' lake and the current stored coordinates are erased.

The middle sensor is only used for lake detection when valid coordinates 'close' to a lake are received. 'Close' to a lake means when the received 'i' coordinates are smaller than a certain value.
When these coordinates are received, first the Rover turns until it is facing the lake directly in the middle (according to the received coordinates). It then starts driving until the middle light sensor is triggered. When RCX 1 received this trigger, the Rover stops and looks with the other two light sensors if the Rover is still on the Mars Surface or if it is past an edge ( this can happen when false lakes are detected by the video processing in for example the DCT lab). If no edge is detected, the RCX 1 sends a message that the RCX 2 can start a measurement.

Asking coordinates from Earth and the sending temperature:
RCX 2 don't have many tasks while roaming over Mars (While RCX 1 has). This is the main reason why we chose to let RCX 2 continuously (every 300 ms) send the temperature of the last lake to Earth. If no lake is measured yet, the value 0 is send to the Earth station. By doing this, we smartly both send the temperature to Earth and ask for coordinates from the Earth computer continuously (every 300 ms).

Receive coordinates from Earth:
It is always possible for RCX 1 to receive valid coordinates. If for a longer time (officially it is a number of counts with invalid coordinates) no valid coordinates are received, the
'Random Drive' sequence is started. This 'Random Drive' sequence is directly stopped if a valid coordinate is received. If a valid coordinate is received, this coordinate is stored and the 'Drive2lake' sequence is started. While the 'Drive2lake' sequence is busy with turning and driving, no new coordinate information is used.
Only the coordinates of the first lake are used. Due to the 'crappy' lake detection (probably due to the combination of light intensity, camera and video processing algorithm) a real second lake is never detected simultaneously. This is also the reason that we don't use the information of other detected lakes further away.

Driving to and Measuring a lake:
The 'Drive2lake' sequence first converts the camera coordinates into world coordinates using a polar coordinate system. From the 'j'th coordinate, the number of encoder counts the Rover should turn to position the Rover straight to the lake is computed. Then this calculated turn is made.
From the 'i'th coordinate, the distance to the lake is calculated. If the rover is 'far' way, the rover first drives closer to the lake for such a distance that the camera can still detect the lake and asks new coordinates for repositioning. When it has received new coordinates, it can adjust its turn angle once more and then drives directly to the lake until it receives the trigger from the middle light sensor on RCX 2 (RCX 2 sends this trigger 2 times, so if the first transmission is missed, there are no problems) and then the Rover stops and sends a trigger to RCX 2 (also this trigger is send 2 times in order to prevent deadlock) if it is safe to start a measurement.
RCX 2 then performs a measurement by lowering the temperature sensor and waits for 5 seconds before the temperature is measured. The temperature is measured in degrees Celsius and is specially calibrated. When the sensor is moved back up to a safe position, RCX 2 sends the temperature to RCX 1 (again the temperature is send 2 times). When RCX 1 receives the temperature, it knows that the measurement was a success and it is going to avoid a lake by driving backwards for a certain distance and then turn to the left. Knowing the Mars Surface, a turn to the left with counter-clockwise driving was the best option. Smarter lake avoiding is not implemented due to a lack of time. Of course, the RCX 2 continues to send the temperature to Earth.

Searching a lake smartly:
The 'Random Drive' sequence starts if no coordinates are received for a while. We programmed this program smartly by letting the Rover turn every now and then to see if a lake is nearby. This turn angle is optimized such that over the complete turn the total field of view of the camera is approximately 180 degrees. At every turning endpoint, the Rover stops for a while so the camera processing and IR communication has its time to send detect a lake and send coordinates to the Rover. Then the Rover turns back to the direction it was heading previously and drives forward for a certain distance. Now the procedure is started over again.
When an edge or a lake is found, this task is stopped and edge avoidance / drive2lake is started.
After the edge avoidance / lake measurement, the 'Random Drive' sequence is started again if no new lake coordinates are received again.

Stopping when 3 lakes are found:
Every time a lake is measured and a temperature is send to RCX 1 (and Earth), a lake is counted. We programmed that the Rover BEEPS and displays 'END' on the LCD-screen when 3 lakes are measured and then all the tasks are killed.

Shortly, the Rover thus does the following:
When the Rover is initiated, It first looks for valid incoming coordinates. When coordinates are received it drives to a lake, measures it and resumes the Mars Mission until 3 lakes are found. If in the meanwhile no coordinates are received, the smart random drive sequence is used to detect lakes efficiently. If an edge is detected during the mission, safety goes first! All the other tasks are stopped and first the edge is avoided.


Now there are still some things to mention that we encountered during the coding of the program.
  • To use our CPU resources efficiently, we first thought of also killing the communication threads during the measurement of a lake and during edge avoidance (then no coordinates are needed). However, when re-initiating these communication threads, the brick crashes every time.
    The solutions was to never kill the communication threads
  • Although we did not kill and reinitialize communication threads, other threads where killed and re-initialized in for example the edge detect and avoidance thread. However, the brick crashed sometimes for a vague reason and sometimes not at the same point. We thought that maybe the memory is not cleaned entirely when a thread is killed and thus eventually the brick has not enough resources to start the thread again.
    We solved this by using main files on both bricks without killing and reinitializing at all. However, now we had some problems with correct starting and ending of different threads wanting to simultaneously use the motors. But this is solved now.
  • The use of different priorities for different threads did not work, because it constantly tries to start the tread with the highest priority and don't bothers about the other threads.
  • With this 4 wheel design with 'slipping' wheels on the back while turning, the Rover can get stuck if a rough surface on Mars is encountered during turning. We programmed this turning on a number of counts, so if it is stuck, the Rover is lost.
    We solved this by inserting a counter/time. If the turning takes too much time, the turn is ended and the program/Rover continues.
  • THIS IS OUR BIGGEST PROBLEM: The detection of a lake!
    We only use the camera to detect lakes (as was intended). If no lake is found with the camera, always an edge is assumed for safety precautions.
    Probably the combination of the camera, the light intensity, the water in the lakes and the video processing algorithm (or only one of them) gives the problem that almost no lake is detected and thus sent to the Rover.
    We already encountered that at a high light intensity of the lamps above the surface, it is harder for the camera to detect lakes.
    The lakes are also better detectable when there is no water in the lakes (disturbing the blue color).
    Furthermore, the camera and/or video processing could use an update, because even close (and directly facing) to the lake, most of the time no lakes are detected.
    We can't do anything about this, but this will be probably the deciding factor for a successful Mars Mission tomorrow.


We did some extra checks like checking (and replacing) the batteries, erase all bricks, put the firmware on it again and only put the final code on the bricks.

We hope we will perform well again tomorrow. As said before, the deciding factor for a successful mission will be the lake detection by the camera!

Geen opmerkingen:

Een reactie posten