Skip to content
Menu

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.

PowerPoint handouts: Dark · Light

link to download code

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 np
import control.matlab as co
import json
m=1; M=5; L=2; g=-9.8; d=1
A = 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.

← All chapters