Where will it be

Two sightings give a velocity: give way to a robot crossing your path.

6.7Seeing moreRobot club20 min

Do this lesson in the simulator

Seeing 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)

Run this in the simulator

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")

Run this in the simulator

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")

Run this in the simulator

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

  1. Print coming or leaving each time you see the robot.
  2. Instead of stopping, slow down to 20 when the robot is coming across, and see whether it still passes safely.
  3. 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.