The worksheetDownload the PDF
Answers

4.2 Where is it?

Vision · Robot club · about 15 min

BugBotLab

What this lesson is about

Pixels to degrees, and a controller that turns to face a tag.

Questions 6 marks in all

  1. [1 mark]Using bearing = (cx - 160) * 120 / 320, what is the bearing in degrees of a tag at cx = 240?

    Answer: 30 (accept within 0.5). 240 minus 160 is 80 pixels, and the formula shares 120 degrees evenly over 320 pixels, 0.375 each, so 30 degrees to the right. The true bearing is nearer 41: the even share reads low away from the centre, which a controller does not mind.
  2. [1 mark]Using bearing = (cx - 160) * 120 / 320, where is a tag at cx = 100?

    1. ATo the left, about 22 degrees
    2. BTo the right, about 22 degrees
    3. CStraight ahead
    4. DTo the left, about 100 degrees
    Answer: A. Under 160 is left. (100 - 160) * 0.375 is -22.5, and negative bearings are to the left.
  3. [1 mark]What does this program print?

    def bearing_of(cx):
        return (cx - 160) * 120 / 320
    
    for cx in [0, 160, 320]:
        print(bearing_of(cx))
    Answer:
    -60.0
    0.0
    60.0

    The edges of the picture are 60 degrees either side of straight ahead, because the camera sees 120 degrees in total.

  4. [1 mark]The loop runs drive(0, 0, bearing_of(cx) * 3) and the tag is at cx = 220. What does the robot do?

    1. ATurns clockwise, towards the tag
    2. BTurns anticlockwise, away from the tag
    3. CDrives forward
    4. DSlides right without turning
    Answer: A. The bearing is positive, so the rotation is positive, which is clockwise. The tag slides towards the middle of the picture.
  5. [1 mark]A student writes error = (160 - cx) * 120 / 320 and uses drive(0, 0, error * 3). What happens?

    1. AThe robot turns away from the tag until it loses it
    2. BThe robot faces the tag, just more slowly
    3. CNothing different, because the sign does not matter
    4. DThe robot drives towards the tag
    Answer: A. Reading cx the wrong way round flips the sign, so the controller pushes the tag further off-centre instead of pulling it in.
  6. [1 mark]Once the error is under 1.5 degrees, the program stops, waits 0.3 s and checks again. Why check again?

    1. AThe robot coasts after stopping, so the tag may have slid off centre
    2. BThe camera needs 0.3 s to switch on
    3. CThe tag might have changed its id
    4. DTo let the battery recover
    Answer: A. Stopping is not instant. Settle, then check that you really are still centred before you finish.

The task: face the marker

Turn until marker 3 is in the middle of the picture, then print centred. Do not drive.

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

# camera: the tag detector
set_cv("apriltag")
print(apriltags())

The hint students can ask for: Marker 3 is off to the right of the picture. Turn until it sits in the middle (cx near 160), then print centred. Do not drive.

A solution

from bugbot import *
connect()
def bearing_of(cx):
    return (cx - 160) * 120 / 320      # pixels to degrees, 120 degree view across 320 pixels
set_cv('apriltag')
while True:
    tags = apriltags()
    if not tags:
        turn_right(30)
        wait(0.1)
        continue
    error = bearing_of(tags[0][1])
    if abs(error) < 1.5:
        stop()
        wait(0.3)                  # settle, then look again
        if abs(bearing_of(apriltags()[0][1])) < 1.5:
            break
        continue
    drive(0, 0, max(-30, min(30, error * 3)))
    wait(0.05)
stop()
print('centred')

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