Driving by distance
Tell the robot how far, not how long. Where it thinks it is.
Do this lesson in the simulatorPrint it: worksheet (PDF) · answers (PDF) · as a web page
"Go for two seconds and hope" is no way to drive a robot. In this lesson you tell the robot how far to go, and it measures its own movement to get there.
distance=
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# drive 20 cm, then stop
forward(60, distance=20)
print("I am at", position())
Give forward a distance in centimetres and two things change. The robot stops itself when it has gone that far, and your program waits until it has. It prints (-0.2, 20.0): 20 cm forward to the millimetre, even though the drive itself is never quite straight.
How it knows
Underneath the robot is an optical-flow sensor, the same kind of chip as in a computer mouse, pointed at the mat. It watches the mat slide past and counts how far, in each direction, which is how the robot knows when it has gone 20 cm. position() tells you where it has got to since the program started: (x, y) in centimetres, x to the right, y forward. In the simulator position() is exact, as if a camera above the mat were watching; the robot's own count from the flow sensor is close, but it drifts.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
print("start:", position())
# drive forward at 50 for 15 cm, then stop
forward(50, distance=15)
print("after 15:", position())
# drive forward at 50 for 15 cm, then stop
forward(50, distance=15)
print("after 30:", position())
# drive backward at 50 for 10 cm, then stop
backward(50, distance=10)
print("after coming back 10:", position())
The robot coasts
Look at the numbers again: within a millimetre or so of what you asked for, but not always exact (30.1 instead of 30). The robot cannot stop dead; at 50 it slides about 2 cm after the motors switch off. It allows for that by switching off early, but not perfectly. When you plan a route, leave a margin.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# drive forward at 100 for 20 cm, then stop
forward(100, distance=20)
print("fast:", position())
# drive backward at 100 for 20 cm, then stop
backward(100, distance=20)
# drive forward at 30 for 20 cm, then stop
forward(30, distance=20)
print("slow:", position())
The fast drive ends at 20.2, the slow one (after coming back) at 20.1. Faster means more coasting: at 100 the robot slides nearly 4 cm after the motors stop, twice as far as at 50, so the early switch-off has more to guess. Lesson 1.5 is about that trade.
Distance and time together
distance= is a blocking call: nothing after it runs until the move is done. Compare the order of the printed lines:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
print("starting")
# drive forward at 60 for 25 cm, then stop
forward(60, distance=25)
print("arrived")
# drive forward at 60 (keeps going until the next command)
forward(60)
print("driving on, not waiting")
# pause 1 s (the robot keeps doing what it was told)
wait(1)
# all motors off
stop()
print("stopped at", position())
Task: twenty, then forty
Drive 20 cm, print after 20: followed by position(), then drive 40 cm more and stop inside the green band 60 cm from the start.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# drive forward at 60 for 20 cm, then stop
forward(60, distance=20)
print("after 20:", position())
Challenges
- Drive 10 cm five times with a loop, printing
position()each time. How much does the error grow? - Drive out 30 cm and back 30 cm. How far from (0, 0) do you end up?
- Find the speed at which
forward(speed, distance=20)lands closest to 20.