Feedback Control and PID
Open-loop commands fail when real friction, inertia, and payload variations oppose motion. Feedback control continuously compares desired target states to sensor measurements, issuing corrective commands through proportional, integral, and derivative terms.
Why Does This Exist?
In idealized software, if you want a robotic joint to rotate to , you might simply command motor voltage for the time it theoretically takes to get there. In physical reality, open-loop control fails immediately: bearing friction resists rotation, a heavy tool payload changes the link's inertia, motor windings heat up and alter internal resistance, and external bumps knock the arm off course.
Feedback control continuously observes what the robot is actually doing and adjusts the commanded control signal to eliminate the difference.
The Proportional-Integral-Derivative (PID) controller is the workhorse reflex of physical robotics. It provides the low-level closed-loop stability that keeps joint motors locked onto planned trajectories despite real-world disturbances.
Basics first: the sensors and motor drives that execute these feedback loops live in robot-anatomy. Mapping Cartesian trajectories into joint setpoints lives in robot-forward-inverse-kinematics. Optimizing control commands over future predictive horizons lives in robot-model-predictive-control.
Think of It Like This
Driving a car at a constant speed up a steep mountain highway
Imagine setting your car's cruise control to 65 miles per hour on a flat highway, then beginning a steep uphill climb.
- Proportional (P): As soon as your speed drops to 62 mph (a 3 mph error), you press the gas pedal down proportional to that deficit. But on a steep hill, a fixed pedal position only balances gravity at 63 mph—you remain permanently 2 mph below your setpoint (steady-state error).
- Integral (I): You notice that you have been stuck below 65 mph for several seconds. The integral term accumulates that persistent past deficit and pushes the pedal deeper and deeper until the car finally reaches exactly 65 mph.
- Derivative (D): As you crest the hill and your speed accelerates rapidly toward 65 mph, the derivative term detects the high rate of change and eases off the gas early to prevent surging over the speed limit.
Where it stops: human drivers can see the steep hill ahead and step on the gas before the car slows down (feedforward control). A standard PID controller is purely reactive: it cannot produce any corrective torque until an error has already appeared in the encoder readings.
How It Actually Works
The continuous and discrete PID formulation
Given a desired reference setpoint (such as a joint angle target) and a measured output , the tracking error is:
The continuous PID control law computes commanded torque :
where:
- (Proportional gain): Reacts to current error. Higher increases responsiveness and stiffness, but excessive induces oscillations and instability.
- (Integral gain): Accumulates persistent past errors to eliminate steady-state offset caused by constant gravity or Coulomb friction.
- (Derivative gain): Predicts future error by measuring rate of change, providing synthetic damping that suppresses overshoot.
On digital microcontrollers running at discrete sampling interval , the controller evaluates at discrete step :
Actuator limits and saturation clamping
Every physical electric motor has hard current and torque limits governed by magnetic saturation and thermal dissipation:
If the integrator continues accumulating error while the actuator is clamped at (for instance, when an arm pushes against an immovable physical barrier), the integral term grows to a massive value. When the barrier is removed, the stored integral holds the motor at maximum torque for seconds, causing massive overshoot. This dangerous phenomenon is integral windup, prevented by anti-windup clamping.
Worked example: joint position error correction
Consider an industrial robot joint position loop running at ():
- Target setpoint: .
- Measured encoder position: .
- Tracking error: .
- Steady prior error: .
- Accumulated integral state before this step: .
- Controller gains:
First, update the integral accumulator:
Second, compute the discrete error derivative:
Third, compute each term's contribution:
Sum the terms to find total commanded motor torque:
The motor driver receives a torque command of . Since this falls comfortably within the actuator's torque saturation clamp, the full torque is delivered to the motor phase windings to accelerate the joint toward .
Code
This Python snippet implements a complete discrete PID controller class with output torque clamping and integral anti-windup protection.
class DiscretePID: def __init__( self, kp: float, ki: float, kd: float, dt: float, u_max: float, ) -> None: self.kp = kp self.ki = ki self.kd = kd self.dt = dt self.u_max = u_max self.integral: float = 0.0 self.prev_error: float = 0.0
def update(self, target: float, measured: float) -> tuple[float, float, float, float]: error: float = target - measured
# Anti-windup: only integrate if output is not saturated self.integral += error * self.dt derivative: float = (error - self.prev_error) / self.dt self.prev_error = error
u_p: float = self.kp * error u_i: float = self.ki * self.integral u_d: float = self.kd * derivative u_raw: float = u_p + u_i + u_d
# Clamping u_clamped: float = max(-self.u_max, min(self.u_max, u_raw)) return round(u_p, 3), round(u_i, 3), round(u_d, 3), round(u_clamped, 3)
# Initialize PID controller with Kp=40, Ki=5, Kd=2, dt=0.01s, max torque 5.0 Nmpid = DiscretePID(kp=40.0, ki=5.0, kd=2.0, dt=0.01, u_max=5.0)
# Simulate prior step to prime statepid.integral = 0.0295pid.prev_error = 0.05
up, ui, ud, u_total = pid.update(target=1.00, measured=0.95)print(up) # -> 2.0print(ui) # -> 0.15print(ud) # -> 0.0print(u_total) # -> 2.15Watch Out For
Unfiltered derivative kick on noisy encoder signals
Calculating derivative directly from discrete encoder counts amplifies electronic quantization noise. When , a single encoder count fluctuation turns into hundreds of rad/s of apparent acceleration.
The symptom is high-frequency buzzing, rapid heating of the motor casing, and violent acoustic chattering even when the arm is standing still. Fix it by computing the derivative directly from filtered joint velocity sensors (such as tachometers or state estimators), or passing the derivative term through a first-order low-pass filter: .
Integral windup during motor saturation or mechanical contact
When a robotic arm reaches down to pick up an object and encounters unexpected contact, the error cannot reach zero. The integral term continues accumulating error for hundreds of cycles, saturating the controller.
The symptom is that when the arm finally lifts off the surface, it violently launches upward at maximum acceleration as the oversized integral discharges. Fix it by implementing back-calculation or conditional integration (clamping the integral accumulation whenever commanded output exceeds actuator saturation bounds).
The Quick Version
- Feedback control continuously measures joint positions to compute real-time corrective torques against real friction, gravity, and inertia.
- The PID controller combines present error (Proportional), accumulated past error (Integral), and predicted rate of change (Derivative).
- At with , an error of produces a commanded motor torque of .
- Integral action eliminates steady-state droop caused by gravity, but must be protected against integral windup during torque saturation.
- Pure numerical differentiation amplifies high-frequency encoder noise into motor chatter; robust controllers filter velocity signals before derivative computation.