title: "PID Controller" description: "Closed-loop control for drones, robotics, and industrial automation." order: 4
PID Controller
Vibe Prompt
"Simulate PID temperature control. Target 100C. Tune Kp, Ki, Kd."
import numpy as np
class PID:
def __init__(self, Kp, Ki, Kd, setpoint):
self.Kp, self.Ki, self.Kd = Kp, Ki, Kd
self.setpoint = setpoint
self.prev_error = 0
self.integral = 0
def update(self, measurement, dt):
error = self.setpoint - measurement
self.integral += error * dt
derivative = (error - self.prev_error) / dt
self.prev_error = error
return self.Kp*error + self.Ki*self.integral + self.Kd*derivative
pid = PID(Kp=2.0, Ki=0.5, Kd=1.0, setpoint=100)
temp = 25.0
dt = 0.01
for _ in range(1000):
output = pid.update(temp, dt)
temp += output * dt * 10
temp -= (temp - 25) * 0.01 * dt
print(f"Final temperature: {temp:.1f}C")
PID Control Principles
Three terms:
$$u(t) = K_p \cdot e(t) + K_i \cdot \int_0^t e(\tau) d\tau + K_d \cdot \frac{de(t)}{dt}$$
| Term | Name | Intuition | Effect | |:----:|:----:|-----------|--------| | P | Proportional | "How far?" | Speeds response, may overshoot | | I | Integral | "Accumulated?" | Eliminates steady-state error | | D | Derivative | "Future trend?" | Reduces overshoot, improves stability |
Parameter Impact
| Effect | Kp Up | Ki Up | Kd Up | |:------:|:----:|:----:|:----:| | Rise time | Shorter | Minor | Minor change | | Overshoot | Increases | Increases | Decreases | | Settling time | Minor | Increases | Decreases | | Steady error | Decreases | Eliminates | No effect | | Stability | Degrades | Degrades | Improves |
Ziegler-Nichols Tuning
- Set Ki=0, Kd=0
- Increase Kp until stable oscillation (record Ku)
- Measure oscillation period Pu
- Use table:
| Controller | Kp | Ki | Kd | |:----------:|:--:|:--:|:--:| | P only | 0.5 x Ku | - | - | | PI | 0.45 x Ku | 0.54 x Ku/Pu | - | | PID | 0.60 x Ku | 1.20 x Ku/Pu | 0.075 x Ku x Pu |
Applications
| Domain | Application | |:------:|-------------| | Drones | Flight stabilization, hover, waypoint tracking | | Robotics | Motor position/speed, arm precision | | Industry | Temperature/pressure/flow control | | Automotive | Cruise control, stability program | | Appliances | AC temperature, oven thermostat |
Advanced Variants
| Variant | Description | Use Case | |:-------:|-------------|----------| | PI | No derivative term | Noisy systems | | PD | No integral term | No steady-error needed | | Cascade | Two PID nested | Drone flight control | | Fuzzy PID | Dynamic parameter adjustment | Non-linear systems | | Adaptive PID | Auto-tune parameters | Time-varying systems |
Key Takeaways
- P: correction based on current error
- I: eliminates accumulated steady-state error
- D: predicts error trend, reduces overshoot
- Ziegler-Nichols: classic tuning method
- Real implementations need anti-windup and filtering
- PID requires no system model - works for most control scenarios
What Is PID Control?
PID (Proportional-Integral-Derivative) control is a feedback mechanism that continuously calculates an error value and applies corrections.
The Three Components
| Component | Effect | Formula | |-----------|--------|---------| | Proportional (P) | Reacts to current error | $K_p e(t)$ | | Integral (I) | Corrects accumulated past error | $K_i \int e(t) dt$ | | Derivative (D) | Predicts future error trend | $K_d \frac{de(t)}{dt}$ |
$$u(t) = K_p e(t) + K_i \int_0^t e(\tau) d\tau + K_d \frac{de(t)}{dt}$$
How Each Component Affects Response
| Component | Rise Time | Overshoot | Settling Time | Steady-State Error | |-----------|-----------|-----------|---------------|-------------------| | P | Decreases | Increases | Small change | Decreases | | I | Decreases | Increases | Increases | Eliminates | | D | Minor change | Decreases | Decreases | Minor change |
PID Tuning Methods
Manual Tuning
def tune_pid(Kp_start=1.0, Ki_start=0.0, Kd_start=0.0):
"""Manual PID tuning procedure."""
print("Step 1: Set Ki=0, Kd=0. Increase Kp until oscillation.")
print("Step 2: Reduce Kp by half (stable Kp).")
print("Step 3: Increase Ki to eliminate steady-state error.")
print("Step 4: Increase Kd to reduce overshoot.")
print("Step 5: Fine-tune all three together.")
return {
"Kp": Kp_start * 0.5, # Half of ultimate gain
"Ki": Ki_start + 0.1, # Slowly increase
"Kd": Kd_start + 0.05 # Slowly increase
}
Ziegler-Nichols Method
| Control Type | $K_p$ | $T_i$ | $T_d$ | |-------------|-------|-------|-------| | P | $0.5 K_u$ | — | — | | PI | $0.45 K_u$ | $0.83 T_u$ | — | | PID | $0.6 K_u$ | $0.50 T_u$ | $0.125 T_u$ |
Where:
- $K_u$ = ultimate gain (when system oscillates steadily)
- $T_u$ = oscillation period at ultimate gain
Python PID Implementation
class PID:
def __init__(self, Kp, Ki, Kd, setpoint=0):
self.Kp = Kp
self.Ki = Ki
self.Kd = Kd
self.setpoint = setpoint
self.last_error = 0
self.integral = 0
self.last_time = None
def update(self, measurement, current_time=None):
if current_time is None:
current_time = time.time()
# Calculate error
error = self.setpoint - measurement
# Delta time
if self.last_time is None:
dt = 0.01
else:
dt = current_time - self.last_time
# Proportional
P = self.Kp * error
# Integral (with anti-windup)
self.integral += error * dt
self.integral = max(-10, min(10, self.integral)) # Clamp
I = self.Ki * self.integral
# Derivative
derivative = (error - self.last_error) / dt if dt > 0 else 0
D = self.Kd * derivative
# Save state
self.last_error = error
self.last_time = current_time
return P + I + D
# Temperature control example
pid = PID(Kp=2.0, Ki=0.1, Kd=0.5, setpoint=37.0) # Target: 37°C
temperature = 25.0 # Starting temp
for minute in range(20):
output = pid.update(temperature)
# Heater power = output (clamped to 0-100%)
heater_power = max(0, min(100, output))
# Simulate heating
temperature += heater_power * 0.1 - 0.2 # Heat + cooling loss
print(f"Minute {minute}: Temp={temperature:.1f}°C, Heater={heater_power:.0f}%")
Summary
PID control combines proportional (current error), integral (past error), and derivative (future trend) terms. It's the most widely used control algorithm in industry.
Key takeaways: | P: reacts to current error — reduces rise time but causes overshoot | | I: eliminates steady-state error — accumulates past errors | | D: predicts future error — dampens overshoot and oscillation | | Anti-windup: clamp integral term to prevent excessive buildup | | Ziegler-Nichols: systematic tuning from ultimate gain and period | | PID requires no system model — works for most real-world control | | Applications: temperature, speed, position, pressure, flow |
Next Chapter: Kalman Filter
The next chapter covers Kalman filters for state estimation from noisy measurements.