Feedback control · University · about 30 min
Damping the overshoot, and why D on a noisy signal needs a filter or it is useless.
[1 mark]The distance sensor in the lesson wobbles by about 1 cm, so two readings 0.1 s apart can differ by 4 cm with the robot all but still. What approach speed, in cm/s, does a differenced derivative report?
[1 mark]One tick of the PD controller from the lesson. What does it print?
KP, KD, DT = 3.0, 1.2, 0.1 last, error = 20.0, 14.0 d = (error - last) / DT cmd = max(-70, min(70, KP * error + KD * d)) print(round(d, 1), round(cmd, 1))
-60.0 -30.0
The error fell by 6 cm in 0.1 s, so d = -60 cm/s. The command is 3 x 14 + 1.2 x (-60) = 42 - 72 = -30: the controller is already braking before it arrives.
[1 mark]The robot is approaching the target quickly, so the error is shrinking fast. What does the D term do?
[1 mark]The setpoint jumps from 30 to 40 cm and the command spikes hugely for one tick. What is the standard fix?
[1 mark]Which is the best treatment for derivative noise on this robot, according to the lesson?
[1 mark]On the quarter turn, Kp = 4 alone overshoots by about 20 degrees. With a D term added, the response has no overshoot, a slower approach, and stops about 1.4 degrees short. What does that say about Kd?
This robot is carrying a load, so it takes about three times as long to speed up and to slow down. That extra lag is exactly the job the D term is for. Turn to face 90 degrees and be within 3 degrees of it from three seconds onwards. Plot error and d term.
On this robot P alone cannot do it, whatever the gain and however fast the loop runs: a gain low enough not to swing past arrives too late, and a gain high enough to arrive in time swings past and is still swinging at three seconds. Start from KP = 4 and find a KD that brakes it in time.
from bugbot import * connect() KP, KD = 4.0, 0.0 DT = 0.25 last = 90.0 # the error at the start
The hint students can ask for: This robot is carrying a load, so it takes about three times as long to speed up and slow down. With P alone it either creeps in too slowly or swings past, whatever the gain. Add a term that pushes against how fast the error is shrinking, so the robot starts braking before it arrives.
from bugbot import *
connect()
KP, KD = 4.0, 1.6
DT = 0.25
last = 90.0 # the error at the start
for tick in range(40):
error = (90 - heading() + 180) % 360 - 180
d = (error - last) / DT
last = error
plot("error", error)
plot("d term", KD * d)
drive(0, 0, KP * error + KD * d)
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.