Control Systems
How fast should a control loop run?
Run a control loop as fast as you practically can: a common rule is ten to twenty times faster than the quickest motion it has to control. A controller that runs only now and then holds its last output in between, and that hold acts as extra lag. If it must run slowly, its D term has to divide by the real time between runs, or every correction kicks too hard.
A slow loop is a lag
Suppose the drone's controller runs once every 20 steps of 10 ms, every 200 ms, and holds its thrust in between. The thrust becomes a staircase. Between decisions the drone keeps flying on a command up to 200 ms old, the same way it flies on a sensor reading that's 200 ms late. A slow loop and a slow sensor hurt in the same way, and they add.
The time step must match
The derivative is a change divided by the time it took. Run the controller every 5 steps and the error's change happened over 0.05 s, so divide by 0.05:
if (steps % EVERY == 0) { // EVERY = 5
float d = (error - prev) / 0.05; // the real time between runs
prev = error;
thrust = 9.8 + 2.0 * error + 2.0 * d;
}
Divide by 0.01 instead and the computed rate is five times too big: Kd 2 behaves like Kd 10, and the drone swings. Run every 20 steps with the same mistake and every kick is twenty times too strong. The integral needs the same care in reverse: it multiplies each error by the real Δt.
Live experiment
Run the controller less often
The lagging drone with Kp 2 and Kd 2, its controller running every 1, 5, 20 or 50 steps of 10 ms and holding its thrust in between. Divide the D term by 0.01 and the kicks grow with every slowdown; divide by the real step and 5 or 20 still settle in about 3.3 s, while 50, twice a second, swings.
“Fast enough” is lesson 6 of 6 in Lag Lagoon, Control Systems World 2. Free with an account. Lessons unlock in order, so you’ll do the 12 before it first.
How fast is fast enough?
This drone, behind a 200 ms sensor lag, swings with a period of about three seconds. Five decisions a second is still about fifteen per swing, and with the right divisor it settles in about 3.3 s, as fast as running every step. Two decisions a second, one every 500 ms, is too few: even the right divisor swings.
The sampling theorem says you need more than two samples per cycle just to see a wobble. Control needs far more, because each hold is a delay inside the loop. Hobby flight controllers run their loops a thousand times a second or faster; a room thermostat can get away with once a minute.
On a microcontroller
Never time a control loop with delay(): it stalls everything else and the interval drifts as the code grows. Check millis() or micros() each time round loop(), run the controller when its interval is up, and use the measured gap as Δt. That keeps the maths right even when a pass runs a little late.
Free lesson
Now build it yourself
Each lesson comes in three short parts: see the idea, try it on a live board, then build it yourself, with quick checks as you go.
“Fast enough” is lesson 6 of 6 in Lag Lagoon, Control Systems World 2. Free with an account. Lessons unlock in order, so you’ll do the 12 before it first.
Or start from the very first lesson, no account neededPractice questions
Three quick questions from the lessons. Pick an answer to check it.
Show the answer
Answer: Up to 200 ms of extra lag. Between decisions the thrust is stale. The drone keeps moving on a 200 ms-old command, the same way it moved on a 200 ms-old reading.
- Why not “A faster sensor”? Running less often makes the controller slower to react, the opposite of a faster sensor.
- Why not “Nothing”? Between runs the thrust is held for up to 200 ms, and that hold acts like extra delay.
- Why not “More gain”? The gains are unchanged. What changes is how stale each held command gets.
Show the answer
Answer: Five times too strong: the error changed over 0.05 s, not 0.01. A rate is a change over a time. The time between runs is 0.05 s. Divide by that.
- Why not “Five times too weak”? Dividing by a smaller time gives a bigger number, so the kick is too strong, not too weak.
- Why not “Zero”? The error still changes between runs, so d isn't zero. It's just scaled wrongly.
- Why not “Right”? The error changed over 0.05 s, so dividing by 0.01 makes the rate five times too big.
Show the answer
Answer: Where the drone was 200 ms ago. Twenty steps of lag: the reading the controller sees is twenty steps old, and the drone has moved since.
- Why not “Where it will be”? A plain feedback controller makes no prediction. It acts on the reading it gets, which is late.
- Why not “Where the drone is”? The reading is 200 ms old, so it shows the past, not the present.
- Why not “The target”? The target sets the goal, but the push comes from the error, which is worked out from the late reading.
“Fast enough” is lesson 6 of 6 in Lag Lagoon, Control Systems World 2. Free with an account. Lessons unlock in order, so you’ll do the 12 before it first.
Questions people ask
What sample rate does a PID loop need?
A common rule is ten to twenty times faster than the quickest motion the loop has to control, its natural frequency. Sampling theory says twice is the bare minimum just to see a wobble; control needs much more, because every hold between runs adds lag.
Do the PID terms depend on the sample time?
The D and I terms do. The derivative divides by the time between runs and the integral multiplies by it. Change the loop rate without changing those numbers and both terms come out wrong. The P term doesn't involve time.
How do I run a control loop at a fixed rate on an Arduino?
Check millis() or micros() each time round loop() and run the controller only when the interval has passed, instead of using delay(). Better still, measure the real time since the last run and use it as dt.
Related topics
- What is aliasing, and what is the Nyquist rate?Sample too slowly and a fast wheel seems to crawl backwards.
- PID control explainedWhat the P, I and D terms each do, shown on a drone climbing to 10 m.
- millis() vs delay() on ArduinoWhy delay() freezes your sketch, and how millis() runs several jobs at once.
- How a PD controller damps oscillationA push against how fast the error is changing: the shock absorber that lets a loop arrive fast and stop.