Project: hold the gap

Sit 25 cm from a wall, steadily, on a depth sensor that is 3 cm noisy.

U4.7Noise and filteringUniversity40 min

Do this lesson in the simulator

Sit 25 cm from the wall and stay there, on a sensor with 3 cm of noise on it.

It sounds trivial, and it is the first problem in this course where every piece of the module has to be right at once. Without a filter, the noise goes straight into the motors and the robot buzzes back and forth. With too much filter, the robot reacts late, overshoots, and hunts.

What the program has to do

  1. Read the depth sensor.
  2. Filter it, with an alpha you chose for a reason.
  3. Work out the error: filtered gap minus 25.
  4. Drive in proportion to the error, forwards if too far, backwards if too close.
  5. Stop when the error is small, so the robot sits still rather than trembling.
  6. Plot the gap, so you can see what happened rather than guess.

Step 5 is a dead band, and it is how a real machine stops fidgeting. Inside a centimetre, do nothing. On its own, the cost is that the robot settles to somewhere within a centimetre of the target rather than exactly on it, which for a robot with 3 cm of sensor noise is not a cost at all.

from bugbot import *
connect()

TARGET = 25.0
ALPHA = 0.3
gap = distance()
for tick in range(200):
    gap = ALPHA * distance() + (1 - ALPHA) * gap
    plot("gap", gap)
    error = gap - TARGET
    if abs(error) < 1.0:
        stop()
    else:
        drive(max(-45, min(45, 2.2 * error)), 0, 0)
    wait(0.1)
stop()
print("settled at", round(gap, 1))

Run this in the simulator

It prints settled at 27.8: not within a centimetre of 25, but 2.8 cm out. There is a second dead band underneath the one in the code, the drive's own from U1.2. Once the error is under about 7 cm, 2.2 times the error asks for less than 15 percent, and the robot stops moving before the code tells it to. For a sensor with 3 cm of noise that is close, and it is exactly the third shape in the list below.

The drive command the controller asks for at each error, with the code's dead band and the drive's own-20-1001020-45-1501545error = gap - 25, cmdrive command, %settled at 27.8:asks for 6%robot does not move(error under 6.8 cm)drive's dead band, 15%capped at 45%2.2 x error
The lesson's controller: 2.2 times the error, capped at 45%, and nothing inside the code's own dead band of 1 cm (the small step at the middle). The wide shaded band is the drive's: any command under 15% does not move the robot, which is every error under 6.8 cm. The run stopped at 27.8 cm, where the code asks for 6%.

Reading your own chart

  • A noisy band around 25. Good, if the band is smaller than the sensor's own noise. The filter is doing its job.
  • A slow sine wave. Too much gain, or too much filter delay. Turn one down.
  • Settles at 27 and stays. A steady state error, from the dead band or from the drive's dead band. U5.4 is the proper fix.
  • Looks right, but the robot is too close. The chart plots the estimate and the controller holds the estimate, so a biased one never shows: an estimate that reads 5 cm long draws the same chart while the robot sits 5 cm nearer the wall. Measure the real gap once, with a ruler.
Sketches of four shapes the gap chart can take: a noisy band at 25, a slow sine wave, settling at 27, and one that looks right while the robot's real gap, which the chart does not show, is smallera noisy band around 25good, if the band is small25timea slow sine wavetoo much gain or filter delay25timesettles at 27 and staysa steady state error25timelooks right, robot too closea biased estimate25solid: the gap on the chartdashed red: the real gaptime
Sketches, not runs: the gap the chart plots against time for the four items in the list, with 25 cm dashed. Only the first is a controller doing its job. The last looks just as good, because the controller holds the estimate at 25; the robot, 5 cm nearer (dashed red), never shows on the chart. Each of the others points at a different cause, so name the shape before you change anything.

Task: hold the gap

Settle 25 cm from the wall and stay there. The checker watches the last part of the run as well as the end, so hunting fails even if the final position is right.

from bugbot import *
connect()

TARGET = 25.0

Challenges

  1. Remove the filter and run it again. Plot both and put the charts side by side.
  2. Set alpha to 0.03 and find the gain at which it oscillates. Compare that with the gain at alpha 0.3.
  3. Hold the gap while the wall is approached from the other side, starting too close. Does the same controller work in both directions?

What comes next

U5 takes the controller seriously. This one is proportional only, with a dead band papering over the steady state error. The next module is what the other two terms are for, how to tune all three, and how to tell which one you need from the shape of the chart.