Control Loop Tuning Problems
Diagnose and fix the classic closed-loop failures: integral windup, voltage sag, actuator saturation, and missing feedforward.
Sign in to track progress, earn XP, and save lessons.
A mechanism that overshoots, oscillates, or never quite reaches its setpoint is almost always a tuning problem with a known cause. WPILib documents the recurring ones.
Integral windup
If kI is too large, the integral term accumulates error during a big setpoint change until it exceeds the maximum control effort -- the mechanism blows past the target and takes a long time to settle. Fixes, in order of preference (these methods live on WPILib's PIDController):
- Reduce kI, often to zero -- most FRC mechanisms need no integral term at all. Tune the feedforward model instead.
- Reset the integrator outside a tolerance band with
setIZone()-- when the position error exceeds IZone, the accumulated error resets to zero, disabling integral until you are close again. - Cap the integrator with
setIntegratorRange().
controller.setIZone(5.0); // only integrate within 5 units of target
controller.setIntegratorRange(-2, 2); // clamp accumulated effort
Voltage sag
Drawing current drops bus voltage, so a controller tuned at 13V behaves differently at 11V -- the mechanism slows as the battery droops. Fix it by commanding voltage rather than duty-cycle percent so output is consistent regardless of bus voltage:
motor.setVoltage(feedforward.calculate(setpointVelocity));
Using setVoltage() (or the controller's voltage-compensation feature) makes your gains battery-independent.
Actuator saturation
If gains are so aggressive that the mechanism demands more torque or acceleration than the motor can deliver, it saturates at maximum output and can become unstable -- you can't tune your way past physics. The fix is mechanical: change the gearing or move to a higher-power motor (e.g. NEO -> NEO Vortex, Falcon 500 -> Kraken X60) to gain control authority.
Missing or wrong feedforward
The single most common 'bad PID' is actually missing feedforward. A flywheel or drivetrain is feedforward-dominated; an arm needs kG that varies with the cosine of its angle; an elevator needs a constant kG. If you try to do the whole job with kP, you get sluggish tracking and steady-state error. Get kS/kV/kA from a SysId characterization run, add kG for gravity-loaded mechanisms, and let P handle only the residual.
A disciplined process
Start from zero gains. Add feedforward until the mechanism roughly follows commands open-loop. Then raise kP until tracking is crisp; add a little kD only if it overshoots; reach for kI last and rarely. Throughout, watch the measured-vs-setpoint plot in AdvantageScope -- oscillation means too much kP or noisy kD; lag means too little kP or missing FF; steady offset means missing kG or FF. Change one gain at a time and re-plot.
Key takeaways
- Integral windup comes from too-large kI; prefer kI=0 with good feedforward, or bound it with setIZone()/setIntegratorRange() on WPILib's PIDController.
- Command voltage with setVoltage() so gains stay consistent as battery voltage sags.
- Actuator saturation is a physics limit -- fix it with gearing or a higher-power motor, not more gain.
- Most 'bad PID' is missing feedforward; get kS/kV/kA from SysId, add kG for gravity, and diagnose with the AdvantageScope setpoint-vs-measured plot.
Go deeper
Lesson quiz
RequiredAnswer all 3 questions correctly to complete this lesson.
1.If a mechanism using only proportional (P) control settles close to but never exactly reaches its setpoint, which gain is typically added to eliminate that steady-state error?
2.What is integral windup in a PID controller?
3.A robot's PID loop is oscillating rapidly and the output looks jumpy with a noisy sensor; which symptom points to the derivative (kD) term?
Answer every question to submit.