13. Linear Quadratic Optimal Control
The book’s first real optimal control method, LQ draws together state-space modeling, stability, positive-definiteness, controllability, and observability into a single framework built around the Riccati equation.
Lecture videos
Section titled “Lecture videos”Slides
Section titled “Slides”PowerPoint handouts: Dark · Light
Interactive example
Section titled “Interactive example”Cart-pendulum LQR
Section titled “Cart-pendulum LQR”The example linearizes an inverted pendulum on a cart around its upright equilibrium, giving a 4-state model (cart position, cart velocity, pendulum angle, angular velocity) in the (A, B) matrices. The weighting matrix Q penalizes the angle and angular-velocity states most heavily (weights 10 and 100) since keeping the pendulum upright is the real objective, while R penalizes control effort.
co.lqr(A, B, Q, R) solves the continuous-time algebraic Riccati equation for the optimal state-feedback gain K and returns the closed-loop eigenvalues E. The slider controls R: increasing it makes control more expensive, so LQR backs off and produces a gentler (but slower) response; decreasing it lets the controller push harder, moving the closed-loop poles further left (faster response) at the cost of larger control signals.
import numpy as npimport control.matlab as coimport json
m=1; M=5; L=2; g=-9.8; d=1A = np.array([[0, 1, 0, 0], [0, -d/M, -m*g/M, 0], [0, 0, 0, 1], [0, -d/(M+L), -(m+M)*g/(M+L), 0]])B = np.array([[0], [1/M], [0], [1/(M*L)]])Q = np.block([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 10, 0], [0, 0, 0, 100]])R = float(param_value)[K, S, E] = co.lqr(A, B, Q, R)json.dumps({"K": K.tolist()[0], "closed_loop_eig_real_parts": [float(np.real(e)) for e in E]})Cart-pendulum LQR (mcimp/codes/lq/pendulum_lq.py)
Click "Run" to execute.
Beyond this chapter
Section titled “Beyond this chapter”- Dynamic programming graduate / optional
- Discrete-time LQ optimal control graduate / optional
- Frequency-shaped LQ graduate / optional