donderdag 16 juni 2011

#1 !! And the real winners are...

Today, on June the 16th, we have managed to ALSO win the Mars Mission!
Although this was certainly not one of our best runs; As we never experienced before while testing, the Rover didn't move anymore halfway the mission and seemed to be in some kind of deadlock. But after a quick restart, the rover could continue and measure the lake again (although it was the same lake).
Another thing that went wrong was that the first lake measurement was not actually in the lake. The temperature sensor missed the lake a bit and hit the ground.

But we could give a short representation of our code and convince the jury. The Rover managed to receive coordinates from Earth multiple times, drive to it and measure a lake 2 times (although it was the same lake). Both lake-temperatures were sent succesfully to Earth. Furthermore, we could give a nice impression of our smart lake finding stategy (the 'random drive' mode) and showed that we had a robust edge detection by not falling of an edge.

As said before, our Mission today was not a very good mission, but we still outperformed the other groups.
The best mission of our Rover is visualized in the movie on June the 14th, where all the lakes where found and 2 of them where measured correctly.

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!

dinsdag 14 juni 2011

Real time testing of the (semi-) final code

Today we had our last 2 official test hours before the actual Mars Mission. We made some minor adjustmunts to the code.
For example, we first had some problems with the Rover getting stuck while turning in the random drive mode due to the rough surface. Because the encoder then does not count anything in that case, the motor kept running for eternity, because the Rover is not moving. Now the 'random drive' will stop if after a while the counts are not met, so the Rover can continue. We also tried an extra burst to let the Rover come loose again, but this can be too dangerous near an edge.
Another bug was that sometimes the Rover wanted to measure the lake twice before proceeding, this bug is also fixed now.

We tried several test runs today and made some adjustments while testing. The resulting best Mars Mission is depicted in the video below:
In this Mission all the 3 lakes are found, but only 2 are measured and transmitted to Earth correctly.
The Rover starts and directly finds the first lake. It then turns towards it and drives closer. When it is closer, it again recheives coordinates and adjusts the turn-angle once more before it drives to the first lake. The Rover stops in time and measures a temperature of 22 degrees Celcius. After the temperature measurement, the Rover advoids the lake and goes into 'random drive' mode. It then turns left and right is such a way that a field on vision of 180 degrees is obtained. Note that the Rover stops at the maximum turn-angles and does regular stops, so the video processing has enough time to detect lakes.
When the Rover has found the second lake, it first drives closer to the lake. When it is close, the Rover turns and starts driving towards the lake untill the middle lightsensor detects the lake. However, the middle lightsensor already triggers a too big change and thinks the lake is there already (before the actual lake is reached). This results in a fake second measurement.
But the Rover again 'avoids' the 'lake' and starts to drive 'randomly' as we programmed. In the meanwhile, the Rover detects an edge and adjusts for it as we designed (drive a little bit backwards and then turn to the right direction, which is in this case turning right).
Then it again starts the random drive sequence (because still no coordinates are received) untill it finds the last lake. This lake is again measured perfectly, resulting in a temperature of 21 degrees Celsius.
The Rover now thinks it has measured 3 lakes, so it BEEPS and 'END' is displayed on the lcd screen of RCX 1. The mission was a (partial) succes!


Our Rover still does not perform perfectly and still some small bugs are in the program. However, (testing) time is limited, there are a lot of groups and the deadline is tight. We will possibly try to adjust some minor things tomorrow (the day before the real mission) and off course we will test this. (If we can borrow some time from other groups).
However, we assume that we now have our (semi-) final code, because more testing and debugging is almost impossible.

Hopefully we will perform well in the actual mission, as we did at the linetracking contest!

vrijdag 10 juni 2011

And the winner is...

Today, on June the 10th, we have managed to win the Chess Line Tracking Competetion!
Beforehand we were quite confident of ending in the top 3 of best line trackers. The last couple weeks our line tracker performed well with all sorts of tape and surfaces; it could measure the line with 1 mm accuracy every time. However, today before the competition, somehow we could only measure the line with 4 mm accuracy. We could not find an explanation for it, but we have listened to the advice of Marcel Verhoef: do not change your code just before the competition. With fingers crossed we saw our line tracker ending up first with an error of 4 mm (as we already expected), because the only group that outperformed us did not code beeps at start and end. We have measured 735 mm, while the true length was 739 mm.

So the first prize, one crate of beer, was ours to keep. Cheers!

This is a good start towards the Mars mission next week, let's hope we can perform like true winners...

P.S. the presentation can be found here: http://www.student.tue.nl/V/a.bos/EMCfajl.ppt

donderdag 9 juni 2011

Chess Line-Tracking Competition

Because tomorrow the final Chess Line-tracking competition will start, it is time for us to reveal our strategy for the line-tracking.
We have held the exact details of our code and strategy secret to make sure other teams do not copy our ideas. We do the same with our Mars Mission. Tomorrow in the presentation most of our ideas will be showed, but also just before the Final Mars Mission we will update our blog with our strategy and code for the Mission.

The first idea for the line tracking is to keep things as simple and effective as possible. This is the reason that we chose for one RCX brick. On this brick we use the following things:
RCX 1:   Light sensor 1      Determine the start and the end of the line and reject cracks on the way.
              Light sensor 2      Track the edge of the line with a PD controller
              Encoder 1            To measure the distance of the tape
              Motor 1               Drive the left front wheel
              Motor 2               Drive the right front wheel

This idea is also visualized in the figure below. The tape detection light sensor is placed a little bit up front to the PD line following light sensor in order to find upcoming disturbances, cracks and of course the beginning and the end of the tape.


First the rover is placed at the beginning of the tape and started. It then calibrates the light values of the tape for both the sensors (because the sensors are not the same). It then drives backwards and calibrates the light values of the surface for both sensors. Note that we read out the raw data of the light sensors, so we have a better resolution which will give us an advantage in tracking the line and to be more robust. After this, the Rover drives towards the tape and stops when the beginning of the line is detected. It then BEEPS and starts the tracking.
The first light sensor tracks the line and when a crack with a too high variation from the original tape light value (this can be both a lighter or a darker disturbance on the tape) or the end of the tape is detected, the PD controller will be shut down for a certain time and the Rover drives straight until again the tape is found. If it takes too long before a tape is found, the Rover assumes it was the end of the tape, stops driving, BEEPS again and displays the length of the tape in [mm] on the screen.
The second light sensor tracks the EDGE of the tape (and thus the transition between the tape and the surface) with a PD controller. In this way the line can be tracked very smooth and precise. The P action makes sure it tracks the edge of the line by letting the Rover make small corrections on the speed of the motors. The D action is used to correct errors that ‘haven’t even occurred yet’ and thus to let the Rover drive smoother. In our first implementation we also used an I action (PID controller) to let the error go to zero. But we know we only have to drive a ‘straight’ line and because the distance measurement is very important, we preferred the smoother PD controller.
Another very nice thing about this PD controller is that we scaled the error such that the PD controller is tuned the same for every possible tape and surface.
To have an accurate measurement of the length of the tape in [mm], it was demanded to have at least a resolution of 1 [mm/ encoder increment]. We made a special gearbox with a different transmission ratio form the motor to the wheels to acquire a certain amount of torque and speed and a ‘different’ transmission ratio from the wheels to the encoder. A transmission ratio of 0.948413 [mm/encoder increment] is achieved with this method, giving very accurate measurements of the line.

Even better would be to also use the second encoder, so we can average the length of both encoders in case there is a lot of curvature in the line. To implement this, a second RCX brick is needed together with communication. Because of the tight schedule for the Mars Mission and a Line-tracking design that is already satisfying our requirements, we decided to put our (limited) time and energy into more important things.

A last movie of the line tracking is depicted below. We have a lot of confidence that our Line-tracking Rover will perform well and hopefully finish in the top 3 at least.


woensdag 8 juni 2011

Putting it all together, part 2

Today we started where we left off yesterday: Trying to let all the functions work together. After a lot of attempts and some strange problems with IR communcation between bricks with codes that where just working fine yesterday (a simple firmware update solved the problem eventually), we thought of a way of changing the starting and killing of threads. The code now seems to works without crashing and most of the problems are solved, but now it seems that at the point of switching between two different threads the motors sometimes behave a little bit strange. We need to figure this out in the next days.

After a while we had the opportunity to use the camera for a moment and try to test our code on the real Mars Surface. The first thing that attracted our attention was that the right 'building-lamp' above the Surface was shining much brighter than yesterday and the days before. We think that the bulb is changed.
The problem now is that the camera (together with the software) almost can't detect lakes anymore. While yesterday 2 lakes could be detected easily and 1 was hard to detect, today only 1 lake was detectable, and it was much harder than the other days. I also heard the group before us complain about the same thing: For some reason also they had trouble detecting lakes today.
I hope this will be changed, otherwise I think the real Mars Mission next week will be a disaster for most of the groups, due to the crappy lake detection by the 'blazing' light.
We also found out that the gradient values we use for the lake detection on the middle lightsensor now must be adapted. Due to the new lamp also this value has changed.

The only testrun we had is displayed below: We made a test on the lake that was just detectable. First it does not see the lake and starts the 'random drive' mode. After a while it recheives coordinates and start to turn and drive to the lake. As I said before, the gradient of the lake detection has changed, so now it thinks there is a lake just in front of the true lake. Probably due to the combination of the shadow of the rover and the new shining lamp. We had no chance to correct it today, but that will be done later.
After the lake is measured, the rover avoids the lake and the cliff and drives further away up to the possible next lake (which can not be found)

dinsdag 7 juni 2011

Putting it all together, part 1

Today the starting of the random drive is modified al little bit. Now it does not starts after a certain time, but after a certain amount of receiving non-valid coordinates.
Furthermore, most of the implementation problems are gone now. Random drive starts and drives smoothly together with edge avoidance. Also, when a lake is found, it drives towards the lake and measures it.
The lake avoidance is new: after RCX 1 receives the temperature from RCX 2, it starts to drive back and turn and remebers that it already measured one lake. Then the random drive or cliff detection can take over again. The problem we have now, is that after measuring a lake, when the robot is in random drive mode and tries to avoid an edge, the program crashes and the whole RCX block must be updated again.
This is probably due to using to much resources of the bricks memory/cpu, because the problem does not occur before a lake is measured.
It is very hard to find the problem and make sure that it will not happen again, but when this problem is finished, the core program with the core elements is finished and the improvement of minor things, the testing and debugging can start.