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

A robot with a red dome 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

# do this 20 times (i counts from 0)
for i in range(20):
    seen = [r for r in robots() if r[0] == "red"]
    if seen:
        print(f"{i}: {seen[0][3]} cm, bearing {round(bearing_of(seen[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, from -36.4 to 32.6 degrees, then it turns and comes back the other way. The distance changes much less: from 58 cm down to 40 cm as it passes straight ahead, and back out to 55 cm. That pattern, the bearing sweeping through zero while the distance stays about the same, is a robot crossing in front of you. A robot coming straight at you does the opposite: its bearing stays put while its distance shrinks.

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

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
    seen = [r for r in robots() if r[0] == "red"]
    in_the_way = seen and seen[0][3] < 30 and abs(bearing_of(seen[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: it waits 4.0 seconds in all, because 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

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
    seen = [r for r in robots() if r[0] == "red"]
    danger = False
    if seen:
        cx, dist = seen[0][1], seen[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, 2.8 seconds instead of 4.0, and still no touch. 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 the red robot.

# 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.