Week 12 – Oliver – 2019

Today our task was to navigate around the watertower. We had to find our way without touching the watertower, and efficiently and reliably. We had to write pseudocode for the task, turn it into code and comment it.

This was my first pseudocode attempt:

Original pseudocode:

if watertower within 15cm:
    turn right
    go forward 1 wheel rotation
    turn left
    go forward 1 wheel rotation
    turn left
    go forward 1 wheel rotation
    turn right
else:
    keep following line

When converted to code, however, the problem was that the robot never turns exactly 90° when it turns left or right. This meant that when the robot turned right at the end and rejoined the line, it rarely lined itself up right and ended up continuing through the white.

The other problem with this code was that the robot tried to detect the watertower too soon. This meant that it found it too far back, and crashed into it when it tried to rejoin the line. I changed this to 7cm instead of 15, which let the robot get close but not close enough to knock it. I also tweaked the amount the robot moved forward to go around the can, from 1 full wheel rotation (360°) to 420° and 710°.

The biggest change I made was adding the last line: go forward until right sensor is on black, then turn right. This fixed the first problem of the robot not lining up with the line correctly when it finished, by only turning when the right sensor was on black.

I wrote this pseudocode, then converted it into code again:

Revised pseudocode:

if watertower within 7cm:
    turn right
    go forward 420
    turn left
    go forward 710 wheel degrees
    turn left
    go forward right sensor is on black
    turn right 
else:
    keep following line

There was one problem with this new code, as Richard noticed: the robot did a little wiggle as it found the line again. When I looked closer, I noticed that while the robot stopped when the right colour sensor was on black, when it turned back onto the line, the left sensor was on black. This caused it to turn left again. To fix this, I replaced the last line, turn right, with the following lines

turn right until left sensor is on black

This meant that the robot did not have to do a wiggle to orient itself on the line. This is what the pseudocode looked like converted into code:

1. The first part of the code sets the variables:

WATERTOWER_TURNSPEED, which controls how fast the turns are made

WATERTOWER_SPEED, which controls how fast the robot moves.

I decided to only make use of 1 variable, because I used the same turnspeed as in my main line-follower program.

2. The switch block determines if the watertower is within 7 cm of the Ultrasonic sensor. If it is, then it replies true and goes through the watertower code, otherwise it repeats back to the main line-follower.

3. If the switch block replies true, then a sound is played. I used ‘Fantastic.’ The program then fetches the WATERTOWER_SPEED variable and feeds it into all of the move blocks to set their speed. Then the robot goes in a square around the watertower using move blocks.

4. The robot sets both motors to move forward at the speed determined by the variable. The wait block prevents the robot from stopping until it finds the right sensor on black.

5. The robot then uses another wait block to turn until it finds the left sensor on black, then returns to the normal loop.

This is the code we have made so far for the Robocup:

I am now using the same code as Sara, if it looks familiar.

As in the watertower code, I am setting the vairables at the start. One of the variables, watertower found, is set to true. I will explain this later. The code then enters an infinite loop, than checks through the watertower code. If no watertower is detected, then the robot checks the reflected light intensity of sensor 3 (the right sensor), if it is higher than 40, the robot assumes that sensor is on white and takes the top path, otherwise it takes the bottom.

If the robot takes the top path then the same question is asked again, but this time for the sensor 1 (the left sensor). If the answer is yes again, both sensors are on white and that means that the robot doesn’t need to turn and can go forward.

If the answer for the second question is no, then the right sensor is on white and the left sensor is on black. This means the robot must turn left to get both sensors on white and the robot on the line.

However, if the answer to the first question is no, then the second question is asked again. If the answer to the second question is yes, then the right sensor must be on a colour that reflects less than 40% of the light shone at it, and the other sensor is on a colour that reflects more. This means that the right sensor is on black and the left sensor is on white, which means that the robot has to turn right to get back on track.

But what if the answer to both questions is ‘no?’ This means that both sensors are on a surface that reflects less that 40% of the light shone at it. This is where the fourth branch of code comes in. There are 2 reasons why less than 40% of the light shone is received – a hint, or silver.

By using an algorithm that subtracts the sensor values from each other then uses the absolute value (removes the negative sign if there is one and turns a negative number into a positive number), the robot is able to decide whether it is on a hint or on silver.

Silver/hint detector

Imagine the left sensor has a reflected light value of 56 and the right sensor’s value is 70. The program would find the answer by finding the reflected light from the sensors, in our case 56 and 70, and puts their results into the red block (a math block). The math block then subtracts the first sensor from the second (56-70) and finds the answer (-14). That answer is then put into the next red block, which finds the absolute value. (absolute value ignores the – sign. So negative numbers become positive numbers and positive numbers stay positive numbers.) In our case the absolute value would be 14. The next math block checks whether the absolute value is less than or equal to 2. Then, the yellow blocks check whether the sensors values are less than 20.

If both answers are yes, and the numbers are within 2 of each other and less than 20, than the robot has found silver and goes onto the can finder. Otherwise, it has found a hint. In our case, with the ABS at 14, the robot has found a hint.

For the hints, the robot finds the last action using a variable we set at the start, last action. Last action finds the last turn the robot did, left or right. It then splits the code into 2 parts yet again: right hint and left hint. Basically, all either hint does is turn a minute amount (0.025 rotations) left or right. It then sets the motors to forward and runs through again.

At the beginning of the code the watertower found variable was set to true. The watertower found variable is a flag variable, which checks if that part of the code has been run through before. The variable checks for a grey dot, like the one at the chemical spill at the end, where the water tower is placed upon. If the competition managers decide not to include a water tower, they could include a grey dot in place of the watertower.

If both conditions are true and the top path is chosen, then the robot will stop for 2 seconds and start the can finding code.

Our can-finding code needs improvement, and that is what we will work on next week. For now, this is what we’ve got…

Can-finding code. The blue blocks are comments. Click to enlarge.

When the can-finding code is activated, the robot turns in place until it finds the can. If the robot can see the can already, it turns until it can’t see it and starts again. When the robot can see the can within 50cm from the ultrasonic sensor, it brakes. It then slowly turns 5 degrees at a time until it can’t see the can, while counting how many times the loop has gone around. When it cant see the can, it takes the number of times the loop has gone around, multiplies it by 5 then divides it by 2. It then takes that result and turns the opposite way that many times. This results in it finding the middle of the can. The robot then charges at the can using a move forward block for 75cm.

That was my explanation of how our code works. This is how it all came together in this video: try to see if you can see the different parts of the code in action!

Useless fact of the day: People say “bless you” when you sneeze because your heart stops for a millisecond. Achoo!!!