Lines

The line detector: cx and angle, and the empty list.

6.1Seeing moreRobot club15 min

Do this lesson in the simulator

A dark line taped to the mat is the oldest guide a robot has. Factories still use them. The camera looks down at the mat just in front of the robot, and the line detector on the vision processor tells you where the line crosses the picture. This module starts there and ends with the robot reading tags on other robots and staying out of their way.

The line detector

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

# camera: the line detector
set_cv("line")
print(line())

Run this in the simulator

Two numbers: [cx, angle]. set_cv("line") picks the detector, the same way set_cv("apriltag") picked tags in Module 4.

  • cx is where the line crosses a scan row about 10 cm ahead of the robot, in pixels across the 320 wide picture. 160 is dead ahead. The line here is 4 cm to the right, so cx is 197.
  • angle is which way the line is heading relative to you, in degrees, positive to the right. A line running straight ahead gives 0.

Move and look again

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

# camera: the line detector
set_cv("line")
print("start:", line())
# slide right at 50 for 4 cm, then stop
right(50, distance=4)
print("over the line:", line())
# turn 20 degrees clockwise, then stop
turn_right(30, angle=20)
print("turned right 20:", line())

Run this in the simulator

Sliding right by the 4 cm puts the line under the nose: cx is 160. Turning right makes the line appear to swing left, to cx 127 with an angle of -18.1: it is you that turned.

Three views from above, robot facing up: the line 4 cm to the right, under the nose, and after turning right 20 degreesstart0160320cx 197angle 0slid right 4 cm0160320cx 160angle 0.1turned right 200160320cx 127angle -18.1
The camera's scan row, 10 cm ahead, runs from 0 on the left of the picture to 320 on the right, with 160 dead ahead. The green dot is where the line crosses it: cx. Turn right and the line seems to swing left, so cx falls and the angle goes minus.

When there is no line

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

# camera: the line detector
set_cv("line")
# turn 90 degrees clockwise, then stop
turn_right(30, angle=90)
print("looking away:", line())

Run this in the simulator

An empty list, like an empty tag list. The camera is wide, 120 degrees from edge to edge, so the strip 10 cm ahead is about 35 cm across: a line more than about 17 cm off to either side is out of view. Here the line is not off to the side: turned 90 degrees, it runs across your path only 4 cm in front, nearer than the scan row, so the detector misses it. Every line program has to cope with [].

From above, robot facing up after turning 90 degrees: the line runs across 4 cm in front, nearer than the scan row 10 cm ahead0160320scan row, 10 cm ahead, 35 cm acrossthe line, 4 cm aheadedge of the matline() gives []
Turned 90 degrees, the line crosses the robot's path only 4 cm in front. The detector reads the row 10 cm ahead, and nothing crosses it there, so it reports no line.

Where the numbers come from

The detector looks for a dark band on the light mat along a row of the image and reports its centre. On the real robot that is a contour detector on the lower part of the frame; in the simulator it is the same geometry. Either way, what reaches your program is the two numbers, not the picture, so the code you write here runs unchanged on a BugBot.

Task: see the line

Print line at cx <cx>, angle <angle> from the detector. Do not drive.

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

print(line())

Challenges

  1. Print cx as a distance in centimetres. Ten centimetres ahead, one pixel is about 0.108 cm.
  2. Turn left in steps of 5 degrees and print the angle each time. When does the line leave the view?
  3. Drive forward 30 cm and print the line reading every 5 cm.