Sharing what you see
Telling a robot without a camera where the ball is.
Do this lesson in the simulatorThe Fetcher on this mat has no camera. You have one. Somewhere in front of you is a red ball that the Fetcher would like to collect, and the only way it will find it is if you tell it where.
Where is the ball?
Lesson 7.7 worked a ball's position out from the camera: the bearing from cx, the distance from how wide the ball looks (a 4 cm ball, 92 pixels of focal length), and a little trigonometry from where you are and which way you face.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# maths: atan2, hypot, sin, cos, radians
import math
def bearing_of(cx):
return (cx - 160) * 120 / 320
# camera: look for red blobs
set_cv("blob", "red")
# until a blob of that colour is in view
while not blobs():
# 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)
b = blobs()[0]
width = b[5] - b[3]
dist = 4 * 92 / max(width, 1)
h = math.radians(heading() + bearing_of(b[0]))
# where am I? (cm from where I started)
x, y = position()
bx, by = x + math.sin(h) * dist, y + math.cos(h) * dist
print(f"ball: {width} px wide, {dist:.0f} cm away, at ({bx:.0f}, {by:.0f})")
Say what, not what you see
Send the ball's position, not your camera reading. red blob at cx 210, 40 px wide means nothing to a robot standing somewhere else; ball at 20,30 means the same to everyone. Translate into the shared map before you send.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# radio this to every other robot
send("ball at 20,30")
# do this 50 times (tick counts from 0)
for tick in range(50):
for sender, text in messages():
print(f"{clock():.1f} s: {sender} says {text}")
# pause 0.1 s (the robot keeps doing what it was told)
wait(0.1)
The Fetcher set off the moment it heard the position, and reported back when it got there. Two robots, one camera, one ball.
Task: share what you see
Find the red ball with the camera, work out where it is, and send ball at <x>,<y> within 10 cm of the truth. The Fetcher does the rest.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# camera: look for red blobs
set_cv('blob', 'red')
# until a blob of that colour is in view
while not blobs():
# 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()
print(blobs())
Challenges
- Send the distance from the Fetcher to the ball as well (the Fetcher starts 38 cm to your right and 8 cm behind you).
- Add a second ball of another colour in free play and report both.
- Keep watching: if the ball is pushed, send the new position.