Lesson 6 · Two-Sensor Line Following
Lesson 6 · Two-Sensor Line Following
Teacher mode is on. Toggle it off (bottom-right) to preview the student view.
Last lesson the robot followed one edge with a single sensor. Now you'll use both sensors together — and the code actually gets simpler. The robot straddles the line and follows its center, giving smoother, more reliable tracking.
Learning Objectives
By the end of this lesson you will be able to:
- Explain why two sensors track better than one
- Compute error with two sensors:
error = left − right - Predict the sign of the error from the robot's position
- Build a two-sensor proportional control loop
- Explain the negative sign in
arcade(base_effort, -correction)
The difference is the error
With two sensors straddling the line, you don't need a setpoint anymore. Just subtract one reading from the other:
error = left − right
When both sensors read the same, the difference is zero and the robot drives straight. When one drifts onto the line, the difference tells you exactly how much and which way:
| Position | left | right | error = L − R | Meaning |
|---|---|---|---|---|
| Centered | 0.5 | 0.5 | 0.0 | drive straight |
| Drifted left | 0.8 | 0.2 | +0.6 | steer left to correct |
| Drifted right | 0.2 | 0.8 | −0.6 | steer right to correct |
| Both on white | 0.1 | 0.1 | 0.0 | straight (lost line) |
| Both on black | 0.9 | 0.9 | 0.0 | straight (an intersection!) |
The left sensor reads 0.8 and the right reads 0.2. What is the error, and which way has the robot drifted?
The control loop (and that negative sign)
The loop is the same rhythm as Lesson 5 — read, compute, steer — just with the new error and a negated correction:
from XRPLib.differential_drive import DifferentialDrive
from XRPLib.reflectance import Reflectance
from XRPLib.board import Board
import time
drivetrain = DifferentialDrive.get_default_differential_drive()
reflectance = Reflectance.get_default_reflectance()
board = Board.get_default_board()
Kp = 0.5 # tune this
base_effort = 0.3
board.wait_for_button()
while True:
left_sensor = reflectance.get_left()
right_sensor = reflectance.get_right()
error = left_sensor - right_sensor
correction = error * Kp
drivetrain.arcade(base_effort, -correction) # note the minus sign
time.sleep(0.01)
Why the minus? A positive error means the robot drifted left, so it must
steer left — and in arcade() a negative turn steers left. Negating the
correction lines the math up with reality.
Why is the correction negated in arcade(base_effort, -correction) here, when Lesson 5 didn't negate it?
Activity · Follow the circle, then compare
- Run the two-sensor follower with the line running between the sensors, and watch it track the circle.
- Run your Lesson 5 (one-sensor) version right after. Which is smoother? Which handles the curves and higher speeds better?
- Challenge: turn
base_effortup to 0.4–0.5 on both and watch what happens to each. Which one degrades first, and what does that tell you about how much information one sensor gives the robot?
Both sensors suddenly read high (0.9 and 0.9), so error ≈ 0 and the robot drives straight. What has it most likely reached?
Real-world connections
Comparing two sensors to find a position is a workhorse technique:
Stereo & hearing
You locate a sound from the tiny difference between your two ears — same differential idea.
Differential GPS
Comparing two receivers cancels error and pins a position down to centimeters.
Sensor arrays
Advanced line followers use 5–8 sensors, but the principle is the one you just learned.
Wrap-up
- What's the two-sensor error formula, and why no setpoint? (
left − right; equal readings already mean zero.) - Positive error means the robot drifted which way? (Left.)
- Why the negative sign on the correction? (A positive error needs a left steer, which is a negative turn in
arcade().)