The worksheetDownload the PDF
Answers

9.6 Sharing what you see

Talking to each other · Robot club · about 20 min

BugBotLab

What this lesson is about

Telling a robot without a camera where the ball is.

Questions 6 marks in all

  1. [1 mark]Which message is useful to the Fetcher, which is standing somewhere else?

    1. Aball at 20,30
    2. Bred blob at cx 210, 40 px wide
    3. Cball in my camera
    4. Dturn right 15
    Answer: A. Camera readings only make sense from where you stand. A position on the shared map means the same to everyone.
  2. [1 mark]What does this program print?

    import math
    
    def bearing_of(cx):
        return (cx - 160) * 120 / 320
    
    x, y, heading = 10, 0, 0
    cx, width = 160, 23
    dist = 4 * 92 / max(width, 1)
    h = math.radians(heading + bearing_of(cx))
    bx, by = x + math.sin(h) * dist, y + math.cos(h) * dist
    print(f"ball at {bx:.0f},{by:.0f}")
    Answer:
    ball at 10,16

    The ball is centred, so straight ahead, and 16 cm away. Facing up the mat from (10, 0), that is (10, 16).

  3. [1 mark]The blob's cx is 200. Using bearing_of(cx) = (cx - 160) * 120 / 320, what is its bearing in degrees?

    Answer: 15. (200 - 160) x 120 / 320 = 40 x 0.375 = 15 degrees to the right.
  4. [1 mark]Why is the direction to the ball heading() + bearing_of(cx)?

    1. AThe bearing is measured from where the camera points, so adding the heading turns it into a direction on the mat
    2. BTo make the number positive
    3. CBecause the camera is on the back of the robot
    4. DThe heading is always zero
    Answer: A. Heading says which way the robot faces on the mat; bearing says how far off that the ball is.
  5. [1 mark]Why does the code use max(width, 1) when working out the distance?

    1. ASo it never divides by zero
    2. BSo the ball is never closer than 1 cm
    3. CTo round the width to a whole number
    4. DBecause the width is measured in metres
    Answer: A. A width of 0 would crash the division. Using at least 1 keeps the program running.
  6. [1 mark]The robot faces up the mat and the red ball is right of centre in the picture. Roughly where is the ball?

    1. AUp the mat and to the right, at larger x
    2. BUp the mat and to the left, at smaller x
    3. CBehind the robot
    4. DExactly straight ahead
    Answer: A. A positive bearing is clockwise, which is to the right when facing up the mat.

The 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())

The hint students can ask for: Find the red ball with the camera, work out where it is from its bearing and its width, and send ball at <x>,<y> (from your start). The Fetcher cannot see it, but it can hear you.

A solution

from bugbot import *
connect()
import math

def bearing_of(cx):
    return (cx - 160) * 120 / 320

set_cv("blob", "red")
while not blobs():
    turn_right(40)
    wait(0.1)
stop()
wait(0.3)
b = blobs()[0]
width = b[5] - b[3]
dist = 4 * 92 / max(width, 1)                    # a 4 cm ball, 92 px focal length
h = math.radians(heading() + bearing_of(b[0]))
px, py = position()
bx, by = px + math.sin(h) * dist, py + math.cos(h) * dist
send(f"ball at {bx:.0f},{by:.0f}")
print(f"ball at {bx:.0f},{by:.0f}")
wait(5)
print(messages())

Any program that meets the task's checks is marked correct in the simulator; this is one way, not the only way.