Feedback control · University · about 25 min
What a controller should do when the actuator has nothing left to give.
[1 mark]A PI controller with conditional integration, run on four errors. What does it print?
KP, KI, DT = 1.5, 0.7, 0.1
integral = 0.0
for error in (30, 40, 30, 10):
want = KP * error + KI * integral
cmd = max(-55, min(55, want))
if abs(want - cmd) < 0.01:
integral += error * DT
print(round(cmd, 2), round(integral, 2))45.0 3.0 55 3.0 47.1 6.0 19.2 7.0
Tick 1 wants 45, not saturated, so the integral becomes 3. Tick 2 wants 62.1, clipped to 55, so the integral is frozen at 3. Ticks 3 and 4 are unsaturated and resume integrating to 6 and 7.
[1 mark]drive() is asked for 250 and then for 6. What does the robot get each time?
[1 mark]What is the name of the anti-windup method that stops accumulating the integral while the actuator is saturated?
[1 mark]With back-calculation, integral -= (want - cmd) / Kt. If want = 62.1, cmd = 55 and Kt = 2, by how much is the integral reduced? Give two decimal places.
[1 mark]A robot switches from manual driving to a PI controller and jumps. What is the fix?
[1 mark]A diagonal drive command saturates the lateral axis but not the forward one. What happens?
The same blocker, the same 12 cm. Run a PI controller with anti-windup, keep KI at 0.7, plot error and i term, and be settled 12 cm from the blocker, within 3 cm, from 21 seconds onwards. Without protection the integral winds up on the way in and the robot is not settled until about 25 seconds; with it, about 15.
from bugbot import * connect() KP, KI = 1.5, 0.7 TARGET = 12.0 DT = 0.1 integral = 0.0
The hint students can ask for: The command is pinned at its limit for most of the way in, and an unprotected integral keeps growing the whole time, so the robot arrives with far more push than it needs and drives into the blocker. Stop adding to the integral while the command is saturated, and it has much less to unwind.
from bugbot import *
connect()
KP, KI = 1.5, 0.7
TARGET = 12.0 # closer to the blocker than the robot can get
DT = 0.1
integral = 0.0
for tick in range(500):
error = distance() - TARGET
want = KP * error + KI * integral
cmd = max(-55.0, min(55.0, want))
# only add to the integral while the actuator still has something to give
if abs(want - cmd) < 0.01:
integral += error * DT
plot("error", error)
plot("i term", KI * integral)
drive(cmd, 0, 0)
wait(DT)
stop()
Any program that meets the task's checks is marked correct in the simulator; this is one way, not the only way.