Project: the marker trail
Visit three tag cubes in order.
Do this lesson in the simulatorThree tags on cubes around the mat, numbered 1, 2 and 3. Visit them in order: find each one, drive up to it, move on. A treasure hunt for a robot, and the shape of every "go to A, then B, then C" job a real robot does.
Cubes, not cards
The tags in earlier lessons were printed on cards and could only be read from the front. These are on cubes, with a tag on every side, so they can be read from anywhere. Run this and turn slowly:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# camera: the tag detector
set_cv("apriltag")
# do this 8 times (step counts from 0)
for step in range(8):
print(round(heading()), "->", [t[0] for t in apriltags()])
# turn 45 degrees clockwise, then stop
turn_right(30, angle=45)
[t[0] for t in apriltags()] is just the ids: a list comprehension again.
The two functions
find and approach from lesson 4.5, unchanged:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
def bearing_of(cx):
return (cx - 160) * 120 / 320
def find(tag_id):
# again and again, for ever
while True:
tags = [t for t in apriltags() if t[0] == tag_id]
if tags:
# leave the loop
break
# spin clockwise on the spot at 40
turn_right(40)
# pause 0.1 s (the robot keeps doing what it was told)
wait(0.1)
# all motors off
stop()
# pause 0.3 s (the robot keeps doing what it was told)
wait(0.3)
def approach(tag_id, stop_at):
# again and again, for ever
while True:
tags = [t for t in apriltags() if t[0] == tag_id]
if not tags:
# spin clockwise on the spot at 30
turn_right(30)
# pause 0.1 s (the robot keeps doing what it was told)
wait(0.1)
# back to the top of the loop
continue
cx, dist = tags[0][1], tags[0][3]
if dist <= stop_at:
# leave the loop
break
speed = max(20, min(70, (dist - stop_at) * 3))
# forward, sideways, rotation: -100 to 100 each, until the next command
drive(speed, 0, bearing_of(cx) * 3)
# pause 0.1 s (the robot keeps doing what it was told)
wait(0.1)
# all motors off
stop()
# camera: the tag detector
set_cv("apriltag")
find(1)
approach(1, 10)
print("at marker 1:", position())
The trail is a loop
With the two functions written, the project is three lines:
for tag_id in [1, 2, 3]:
find(tag_id)
approach(tag_id, 10)
That is why functions matter. The hard part was written once and tested once; the plan on top of it is trivial to read and trivial to change.
Task: the marker trail
Visit markers 1, 2 and 3 in order, stopping close to each. Sixty seconds.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
def bearing_of(cx):
return (cx - 160) * 120 / 320
def find(tag_id):
# again and again, for ever
while True:
tags = [t for t in apriltags() if t[0] == tag_id]
if tags:
# leave the loop
break
# spin clockwise on the spot at 40
turn_right(40)
# pause 0.1 s (the robot keeps doing what it was told)
wait(0.1)
# all motors off
stop()
# pause 0.3 s (the robot keeps doing what it was told)
wait(0.3)
def approach(tag_id, stop_at):
# again and again, for ever
while True:
tags = [t for t in apriltags() if t[0] == tag_id]
if not tags:
# spin clockwise on the spot at 30
turn_right(30)
# pause 0.1 s (the robot keeps doing what it was told)
wait(0.1)
# back to the top of the loop
continue
cx, dist = tags[0][1], tags[0][3]
if dist <= stop_at:
# leave the loop
break
speed = max(20, min(70, (dist - stop_at) * 3))
# forward, sideways, rotation: -100 to 100 each, until the next command
drive(speed, 0, bearing_of(cx) * 3)
# pause 0.1 s (the robot keeps doing what it was told)
wait(0.1)
# all motors off
stop()
# camera: the tag detector
set_cv("apriltag")
find(1)
approach(1, 10)
Where next
In the Capture the marker competition, a tag keeps moving and four robots look for it. Module 5 is about behaviours: programs that decide what to do next, not just how to do it.
Challenges
- Visit them in the order 3, 1, 2. Which order is fastest?
- Print the time when you reach each marker, using a variable that counts your
waitcalls or thetfrom the telemetry. - Make
findremember which way it turned to find the last tag and search that way first.