The feedback loop
Setpoint, error, controller, plant, measurement: the block diagram and the names.
Do this lesson in the simulatorEvery controller in this module is the same five boxes. Learning their names makes the literature readable, and most of the literature is worth reading.
setpoint --->(+/-)---> controller ---> actuator ---> plant ---> output
^ |
|------------------ sensor ----------------------|
| Name | On this robot |
|---|---|
| setpoint | the gap you want: 25 cm |
| measurement | distance(), filtered |
| error | setpoint minus measurement |
| controller | the arithmetic that turns error into a number |
| actuator | drive(), saturating at 100, dead below 15 |
| plant | the robot and the mat, with a time constant of about 0.25 s |
Open loop is setpoint to actuator with nothing coming back. It works when the plant is perfectly known and nothing disturbs it, which is never. Closed loop is the diagram above, and it is why a robot can drive to a point on a drive as ill behaved as this one.
The first loop
from bugbot import *
connect()
TARGET = 20.0
for tick in range(120):
error = distance() - TARGET
plot("error", error)
drive(max(-50, min(50, 2.0 * error)), 0, 0)
wait(0.1)
stop()
print("ended", round(distance(), 1), "cm from the wall")
The error starts large and positive, the command is large and forward, the robot approaches, the error shrinks, the command shrinks with it. Negative feedback.
The sign
error = measurement - setpoint or setpoint - measurement? Both conventions exist, and the difference is the sign of every gain in the controller.
Pick one, write it in a comment, and check it against the physical case: too far away should mean drive forwards. Here distance() - TARGET is positive when the robot is too far from the wall, and positive drive() means forwards. Consistent.
Get it backwards and the robot accelerates away from the target as fast as the gain allows, which is at least unmistakable.
What makes a good loop
Four questions, and every controller is judged by them:
- Stability. Does it settle, or does it oscillate for ever?
- Accuracy. Does it end up where it was asked, or near it?
- Speed. How long to get there?
- Effort. How hard is it working, and is it saturating?
Those four fight. More gain buys speed and accuracy and spends stability. Filtering buys smoothness and spends speed. There is no setting that wins all four, and a large part of control engineering is knowing which one you are allowed to give up.
Task: close the loop
Settle 20 cm from the wall, plotting the error as you go. The wall's face is 150 cm up the mat and the robot starts at 60.
from bugbot import *
connect()
TARGET = 20.0
Challenges
- Reverse the sign of the gain and describe what happens, in one sentence, before you run it.
- Start the robot closer than the target. Does the same loop push it back out?
- Put a filter on
distance()and see whether the loop is smoother, slower, or both.