D.HOSKIA
Module 1·55 min

PID Fundamentals

PID Control

PID controllers are used in the vast majority of real-world control systems, including joint controllers on robot arms and legs. Understanding them deeply — not just the formula — separates good engineers from cargo-cult tuners.

The Control Problem

You have a system with an output (position, velocity, temperature). You want to drive it to a setpoint (desired value). The error is the difference:

e(t) = r(t) - y(t)

Where r(t) is the setpoint and y(t) is the measured output.

PID Law

u(t) = Kp·e(t) + Ki·∫e(t)dt + Kd·(de/dt)

Each term has a distinct role:

TermWhat it doesAnalogy
Kp × ePushes toward setpoint proportionally to errorSprings — stiffer with higher Kp
Ki × ∫eEliminates steady-state errorMemory — accumulates past mistakes
Kd × ėDamps oscillationDamper — resists fast changes

Discrete Implementation

Controllers run on digital hardware at a fixed loop rate. The discrete form:

class PIDController:
    def __init__(self, kp: float, ki: float, kd: float, dt: float):
        self.kp = kp
        self.ki = ki
        self.kd = kd
        self.dt = dt
        self._integral = 0.0
        self._prev_error = 0.0

    def update(self, setpoint: float, measurement: float) -> float:
        error = setpoint - measurement
        
        # Proportional
        p = self.kp * error
        
        # Integral (with anti-windup clamp)
        self._integral += error * self.dt
        self._integral = max(-50.0, min(50.0, self._integral))
        i = self.ki * self._integral
        
        # Derivative (on measurement, not error — avoids derivative kick)
        d = self.kd * (measurement - self._prev_error) / self.dt
        self._prev_error = measurement
        
        return p + i - d  # Note: -d because we differentiate measurement

# Usage at 1 kHz loop rate
controller = PIDController(kp=10.0, ki=0.1, kd=0.05, dt=0.001)
command = controller.update(setpoint=1.0, measurement=current_pos)

Tuning Heuristic (Ziegler-Nichols Simplified)

  1. Set Ki = Kd = 0
  2. Increase Kp until the system oscillates at the stability limit
  3. Record this critical gain Ku and oscillation period Tu
  4. Set: Kp = 0.6·Ku, Ki = 2·Kp/Tu, Kd = Kp·Tu/8

This is a starting point — most real systems need empirical refinement from here.