4 Example robot control programs

In this notebook, we will see some more examples of using control flow operators to control the behaviour of a robot in various situations. You will have an opportunity to create a program of your own from scratch.

In the normal way, load in the simulator and then we can get started…

from nbev3devsim.load_nbev3devwidget import roboSim, eds

%load_ext nbev3devsim

4.1 Announcing bands as the robot encounters them

One of the ways we can use the say() function is to count out the bands as we come across them. To do this, we need to identify when we cross from the white background onto a band.

We can detect the edge of a band by noticing when the sensor value goes from white (a reading of 100) to a lower value. The following program will detect such a transition and say that it has crossed onto a band, also displaying a print message to announce the fact.

Reset the robot location in the simulator, run the following cell to download the program to the simulator, and then run it in the simulator. Does it behave as you expected?

You will need to stop the program manually to terminate its execution.

%%sim_magic_preloaded --background Grey_bands
# Onto a band...

# Drive the robot slowly
tank_drive.on(SpeedPercent(15), SpeedPercent(15))

previous_value = colorLeft.reflected_light_intensity_pc

while previous_value > 0:
    # Uncomment the following line if you want to see the trace of sensor values
    #print('Colour: ' + str(colorLeft.reflected_light_intensity_pc ))
    current_value = colorLeft.reflected_light_intensity_pc

    if previous_value==100 and current_value < 100:
        say("New band")

    # Set the current value from this iteration
    # as the previous value we'll refer to in the next
    previous_value = current_value

The program starts by turning the motors on to drive the robot forward (tank_drive.on(SpeedPercent(15), SpeedPercent(15))) and then taking a sample of the light sensor reading (previous_value = colorLeft.reflected_light_intensity_pc).

The while True: statement creates a loop that repeats until the program in the simulator is manually stopped. Inside the loop, a new sample is taken of the light sensor reading (current_value = colorLeft.reflected_light_intensity_pc).

If the robot was on the white background on the previous iteration (previous_value==100) and on a band in this iteration – that is, and (current_value < 100) – then the robot has moved onto a band; this is declared via the output display window (print('Onto a band...')) and audibly (say("New band")).

The previous_value variable is then updated to the current value (previous_value = current_value) and the program goes round the loop again.

You may notice that there may be a slight delay between the robot encountering a band and saying that it has done so. This is because it takes some time to create the audio object inside the browser. If we were to speed up the robot’s forward motion, it is quite possible that the robot might leave one band and encounter the next before it had finished saying it had entered the first band.

4.1.1 Activity – Announce when the robot has left a band

In the code cell below, the previous robot control program has been modified so that the robot says ‘on’ when it goes onto a band. Modify the program further so that it also says ‘off’ when it goes from a band back onto the white background.

Reset the robot location, download the program to the simulator and run it there. Does it behave as you expected?

%%sim_magic_preloaded --background Grey_bands
# On and off band...

# Drive the robot slowly
tank_drive.on(SpeedPercent(15), SpeedPercent(15))

previous_value = colorLeft.reflected_light_intensity_pc

while True:
    # Uncomment the following line if you want to see the trace of sensor values
    #print('Colour: ' + str(colorLeft.reflected_light_intensity_pc ))
    current_value = colorLeft.reflected_light_intensity_pc
    if previous_value==100 and current_value < 100:
        print('Onto a band...')
        say("On")
    
    # YOUR CODE HERE
    
    
    previous_value = current_value

Example solution

Click the arrow in the sidebar or run this cell to reveal an example solution.

To detect when the robot has left a band, we can check to see if it was on a band on the previous iteration of the while True: loop (previous_value < 100) and back on the white background on the current iteration (current_value == 100).

%%sim_magic_preloaded --background Grey_bands -R
# On and off band...

# Drive the robot slowly
tank_drive.on(SpeedPercent(15), SpeedPercent(15))

previous_value = colorLeft.reflected_light_intensity_pc

while True:
    # Uncomment the following line if you want to see the trace of sensor values
    #print('Colour: ' + str(colorLeft.reflected_light_intensity_pc ))
    current_value = colorLeft.reflected_light_intensity_pc
    if previous_value==100 and current_value < 100:
        print('Onto a band...')
        say("On")
    
    if previous_value < 100 and current_value == 100:
        print('Off a band...')
        say("Off")
    
    previous_value = current_value

4.1.2 Optional challenge

Using the magic switch to set the original y-coordinate of the simulated robot to a value of 850 (--ypos 850), see if you can program the robot to drive over all the bands and only stop when it sees the red circle.

4.2 Creating your own program

You have already seen several robot control programs in this notebook; you now have an opportunity to create your own from scratch.

The following activity includes the skeleton of a program based on descriptive, non-executed comments that describe what each line of the program should do.

Using comments in this way provides one way of helping you plan or design a new program.

As for the lines of code that you will need to write: you have seen examples of similar lines in the programs you have already encountered.

Reusing lines of code copied from programs that have used such lines successfully in previous programs is a completely valid way of writing your own programs.

4.2.1 Activity – Count the bands

Using the previous programs as inspiration, see if you can write a program that counts each new line as it encounters it, displaying the count to the output window and speaking the count number aloud.

Reset the location of the robot, download your program to the simulator and run it there. Does it work as you expected?

Hint: you may find it useful to create a counter, initially set to 0, that you increment whenever you enter a band, and then display it and speak it aloud.

How might you modify the program so that its execution stops once it has counted four lines?

%%sim_magic_preloaded --background Grey_bands
# Program to count the bands aloud

# Start the robot moving

# Initial count value

# Initial sensor reading

# Create a loop

    # Check current sensor reading
    
    # Test when the robot has entered a band

        # When on a new band:
        # - increase the count

        # - display the count in the output window
    
        # - say the count aloud

    # Update previous sensor reading
    

Example solution

Click the arrow in the sidebar or run this cell to reveal an example solution.

Using the comment skeleton as a plan for the program, we can reuse statements from the previous programs with just a few additions.

In the first case, we need to add a counter (count = 0). Inside the loop, when we detect we are on a new band, increase the counter (count = count + 1), display it (print(count)) and after casting the count to a string value, speak it aloud (say(count)).

Note that we could make our output display message a little bit more elaborate by constructing an output message string, such as print("Band count is" + str(count)). (Unfortunately, the simulator does not support the rather more elaborate Python ‘f-string’ formatting method that allows variable substitution within text strings.)

%%sim_magic_preloaded --background Grey_bands -R
# Program to count the bands aloud

# Start the robot moving
tank_drive.on(SpeedPercent(15), SpeedPercent(15))

# Initial count value
count = 0

# Initial sensor reading
previous_value = colorLeft.reflected_light_intensity_pc

# Create a loop
while True:

    # Check current sensor reading
    current_value = colorLeft.reflected_light_intensity_pc
    
    # Test when the robot has entered a band
    if previous_value==100 and current_value < 100:
        # When on a new band:
        # - increase the count
        count = count + 1
        # - display the count in the output window
        print(count)
        # - say the count aloud
        say(str(count))
        
    # Update previous sensor reading
    previous_value = current_value

To stop the program when the robot has counted four lines, we could define the loop as while count < 4:. This would keep looping until the count value reached four, at which point the while condition would fail and would no longer pass control into the body of the while loop: control would pass from the while loop to the end of the program.

4.3 Summary

In this notebook, you have seen further examples of simple robot control programs and had an opportunity to create your own from scratch.

In the next notebook, some challenges are defined that will exercise your newly learned programming skills a little bit more.