Where am I?
position(), heading(), velocity(), and resetting them.
Do this lesson in the simulatorPrint it: worksheet (PDF) · answers (PDF) · as a web page
Guide: How do robot vacuums know where to go?
A robot that does not know where it is cannot go anywhere on purpose. This module is about the robot's senses. It starts with the ones that answer "where am I and which way am I facing".
position()
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
print("start:", position())
# drive forward at 60 for 20 cm, then stop
forward(60, distance=20)
# slide right at 60 for 15 cm, then stop
right(60, distance=15)
print("now:", position())
(x, y) in centimetres from where the program started, measured along the mat: x across it to the right, y up it. The robot here starts facing up the mat, so that is x to the right and y forward. In the simulator position() is exact, as if a camera over the mat were watching. The real robot works it out with the optical-flow sensor underneath, which watches the mat go by.
heading()
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
print("start:", round(heading()))
# turn 45 degrees clockwise, then stop
turn_right(30, angle=45)
print("after 45:", round(heading()))
# turn 135 degrees anticlockwise, then stop
turn_left(30, angle=135)
print("after -135:", round(heading()))
Degrees clockwise from facing straight up the mat, which is how the robot starts here, 0 up to 360. -90 shows as 270. The compass inside is a 9-axis inertial sensor: gyroscope, accelerometer and magnetometer together.
velocity()
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# drive forward at 80 (keeps going until the next command)
forward(80)
# pause 0.5 s (the robot keeps doing what it was told)
wait(0.5)
print("moving at", velocity(), "cm/s")
# pause 0.5 s (the robot keeps doing what it was told)
wait(0.5)
# all motors off
stop()
# pause 0.5 s (the robot keeps doing what it was told)
wait(0.5)
print("stopped:", velocity())
(vx, vy): sideways and forward speed right now, in centimetres per second. Half a second after stop() this one still says (0.0, 1.8): the robot is coasting, as in lesson 1.5. That is what velocity() is useful for, knowing whether the robot has actually stopped.
Resetting
Sometimes "here" should be zero:
# 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)
# turn 90 degrees clockwise, then stop
turn_right(30, angle=90)
print("before reset:", position(), round(heading()))
# count from here as (0, 0)
reset_position()
# this way is now heading 0
reset_heading()
print("after reset:", position(), round(heading()))
# drive forward at 60 for 10 cm, then stop
forward(60, distance=10)
print("10 cm from the new zero:", position())
reset_heading() makes the current facing 0. reset_position() makes the current spot (0, 0). Do this at the start of a task so the numbers mean what you think.
Look at the last line, though: (10.1, -0.0). The robot drove 10 cm "forward", and it shows up in x. Resetting the heading changes what heading() calls 0, but position() still measures along the mat, and after the right turn forward is across the mat.
Estimates, not truth
Every move the robot makes is a little off, and on the real robot every reading of where it is is a little off too: an estimate, not the truth. Errors add up:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# do this 4 times (i counts from 0)
for i in range(4):
# drive forward at 60 for 30 cm, then stop
forward(60, distance=30)
# turn 90 degrees clockwise, then stop
turn_right(30, angle=90)
print("should be home:", position(), "facing", round(heading()))
A perfect robot would say (0, 0) facing 0. This one says (0.4, -0.7) facing 356: under a centimetre out, but 4 degrees, and a heading error grows into a position error on every drive after it. Real robots look at landmarks to correct that; the camera does it in Module 4.
Task: report from the corner
Get to the point 30 cm right and 30 cm forward of where you start, and print a line in the shape at (30.1, 29.8) facing 1.2 from position() and heading().
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# drive forward at 60 for 30 cm, then stop
forward(60, distance=30)
Challenges
- Print
position()andvelocity()every 0.5 s while driving. - Drive a triangle and print how far from home you end up:
x*x + y*yunder a square root. - Reset the heading after each turn of a square. Does the final error change?