Computing Library › Worked Examples
Worked Examples

PID vs LQR on a Mass-Spring

Control a damped mass-spring to a setpoint with a tuned PID loop and with an optimal LQR gain, and compare the closed-loop behavior.

Problem

A mass-spring-damper is the canonical second-order plant. We regulate its position to a target using two controllers: a hand-tuned PID and a linear-quadratic regulator (LQR) that minimizes a weighted sum of state error and control effort. Comparing them shows the difference between heuristic and optimal design.

Plant and LQR gain

State is position and velocity. The LQR solves the algebraic Riccati equation to find the gain K that minimizes integral of x'Qx + u'Ru. PID instead sums proportional, integral, and derivative terms of the error with gains chosen by tuning rules.

python

import numpy as np
from scipy.linalg import solve_continuous_are
m,k,c=1.0,1.0,0.4
A=np.array([[0,1],[-k/m,-c/m]]); B=np.array([[0],[1/m]])
Q=np.diag([10,1]); R=np.array([[1.0]])
P=solve_continuous_are(A,B,Q,R)
Klqr=np.linalg.inv(R)@B.T@P
print('LQR gain',np.round(Klqr,3))
eig=np.linalg.eigvals(A-B@Klqr)
print('closed-loop poles',np.round(eig,3))  # damped, stable

Comparison

The LQR gain places the closed-loop poles for a fast, well-damped response and guarantees stability given a controllable plant. A PID can match the settling time but requires manual balancing of overshoot against integral windup, and it has no built-in optimality. LQR extends to many coupled states where PID tuning becomes intractable.