Drift and correction
Why the robot wanders, and the first closed loop.
Do this lesson in the simulatorYou have seen it in every lesson: ask for straight and get a slight curve; ask for 20 and get 20.2. This lesson is about why, and about the idea that fixes it, which is the most important idea in all of robotics.
The robot in this lesson is a bad one on purpose: it leaks sideways much more than the one you have driven so far. Every BugBot does this a little. This one does it a lot, so you can see it.
Watch the drift
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# drive forward at 70 (keeps going until the next command)
forward(70)
# do this 6 times (i counts from 0)
for i in range(6):
# pause 0.5 s (the robot keeps doing what it was told)
wait(0.5)
# where am I? (cm from where I started)
x, y = position()
print(f"{i}: x={x} y={y} heading={round(heading())}")
# all motors off
stop()
x should stay 0. It does not: the robot slides sideways as it goes, and the further it drives the further off the line it gets. The four feet do not push exactly equally, the mat is not perfectly even, and tiny errors add up over a long drive.
Open loop and closed loop
A program that says "forward for 3 seconds" and never looks is open loop: it acts and hopes. A program that looks at the sensors while it acts and adjusts is closed loop: what the sensors say feeds back into what the motors do. Every accurate robot is closed loop.
The simplest correction
Drive in short legs. After each leg, look at x and strafe back to the line:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# do this 6 times (step counts from 0)
for step in range(6):
# drive forward at 70 for 10 cm, then stop
forward(70, distance=10)
# where am I? (cm from where I started)
x, y = position()
if x > 1:
left(40, distance=x)
elif x < -1:
right(40, distance=-x)
print("end:", position(), "facing", round(heading()))
Compare the final x with the open-loop drive above. Same robot, same leak; the difference is that this program looks.
Correcting the heading too
Sideways is only half of it: the heading wanders as well, and a wrong heading turns into a sideways error on the next leg. Check it and turn back:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# do this 6 times (step counts from 0)
for step in range(6):
# drive forward at 70 for 10 cm, then stop
forward(70, distance=10)
# which way I face: degrees clockwise from 0
error = heading()
if error > 180:
# 355 means -5, not 355
error = error - 360
if abs(error) > 2:
# turn back by the amount we drifted
turn_left(30, angle=error)
# where am I? (cm from where I started)
x, y = position()
if abs(x) > 1:
right(40, distance=-x) if x < 0 else left(40, distance=x)
print("end:", position(), "facing", round(heading()))
Steering while moving
Stopping to correct is slow. drive can steer a little while driving. The amount of steering depends on the error: small error, small correction. This is a proportional controller, and Module 3 is all about it.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# do this 40 times (tick counts from 0)
for tick in range(40):
# where am I? (cm from where I started)
x, y = position()
# forward, and sideways against the error
drive(70, -x * 15, 0)
# pause 0.1 s (the robot keeps doing what it was told)
wait(0.1)
# all motors off
stop()
print("end:", position())
Try -x * 5 and -x * 40. Too little and it drifts; too much and it wobbles.
Task: straight and true
Drive about 64 cm and finish inside the small square, still facing 0 within 6 degrees. Correct as you go.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# drive forward at 70 for 64 cm, then stop
forward(70, distance=64)
Challenges
- Make the straight-line task pass at speed 100.
- Combine heading correction and sideways correction in one loop and time it against the two-step version.
- Print the largest
xerror you saw during the drive.