Where will it be
Two sightings give a velocity: give way to a robot crossing your path.
Do this lesson in the simulatorSeeing a robot tells you where it is. Seeing it twice tells you where it is going. A robot that avoids where another one is will still be hit by where it is about to be. This lesson is about looking at the next second, not this one.
A robot that crosses your path
Robot 102 shuttles left and right across the mat between you and the goal. Watch its bearing change:
# 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
# camera: the tag detector
set_cv("apriltag")
# do this 12 times (i counts from 0)
for i in range(12):
tags = [t for t in apriltags() if t[0] == 102]
if tags:
print(f"{i}: {tags[0][3]} cm, bearing {round(bearing_of(tags[0][1]), 1)}")
else:
print(f"{i}: out of view")
# pause 0.5 s (the robot keeps doing what it was told)
wait(0.5)
The bearing sweeps from left to right as it crosses, then it leaves the view, then it comes back the other way. The distance barely changes. That pattern, bearing moving and distance steady, is a robot crossing in front of you.
Give way
The simplest safe rule: if another robot is close and in front, stop and let it pass.
# 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
# camera: the tag detector
set_cv("apriltag")
waited = 0
# do this 390 times (tick counts from 0)
for tick in range(390):
# where am I? (cm from where I started)
x, y = position()
if y > 80:
# leave the loop
break
tags = [t for t in apriltags() if t[0] == 102]
in_the_way = tags and tags[0][3] < 30 and abs(bearing_of(tags[0][1])) < 35
if in_the_way:
# all motors off
stop()
waited += 1
else:
# drive forward at 50 (keeps going until the next command)
forward(50)
# pause 0.1 s (the robot keeps doing what it was told)
wait(0.1)
# all motors off
stop()
print("arrived after waiting", waited / 10, "seconds")
It works, and it is cautious: the robot stops for a robot that is already moving away from its path as readily as for one coming across it.
Predicting
Two sightings give a velocity. Remember the last bearing and compare:
# 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
# camera: the tag detector
set_cv("apriltag")
last = None
waited = 0
# do this 390 times (tick counts from 0)
for tick in range(390):
# where am I? (cm from where I started)
x, y = position()
if y > 80:
# leave the loop
break
tags = [t for t in apriltags() if t[0] == 102]
danger = False
if tags:
cx, dist = tags[0][1], tags[0][3]
bearing = bearing_of(cx)
if last is not None:
# its bearing is shrinking: heading for my path
coming_across = abs(bearing) < abs(last)
if dist < 40 and coming_across:
danger = True
last = bearing
else:
last = None
if danger:
# all motors off
stop()
waited += 1
else:
# drive forward at 50 (keeps going until the next command)
forward(50)
# pause 0.1 s (the robot keeps doing what it was told)
wait(0.1)
# all motors off
stop()
print("arrived after waiting", waited / 10, "seconds")
A robot whose bearing is growing is leaving; only one whose bearing is shrinking is a problem. Less waiting, same safety. The general version of this keeps the last few positions, works out a velocity, and checks whether the two paths cross in the next second or two. Cars, drones and ships all do exactly that.
Task: give way
Reach the green zone without touching robot 102.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# drive forward at 50 for 80 cm, then stop
forward(50, distance=80)
Challenges
- Print
comingorleavingeach time you see the robot. - Instead of stopping, slow down to 20 when the robot is coming across, and see whether it still passes safely.
- Work out the robot's position on the mat from your position and its bearing and distance, keep the last two, and print its speed in cm per second.