最优控制理论

Linear Quadratic Regulator

LQR(线性二次调节器)是现代控制理论中最重要的最优控制方法之一,通过最小化二次型代价函数设计状态反馈控制律,在航天、机器人、自动驾驶等领域有广泛应用。

📖 1. 概述

LQR(Linear Quadratic Regulator,线性二次调节器)是一种经典的最优控制方法。其核心思想是在系统动态为线性、代价函数为二次型的假设下,求解使系统从初始状态回到平衡点且代价最小的控制问题。

📐

线性系统

系统动态由线性微分/差分方程描述

📊

二次代价

代价函数为状态和控制输入的二次型

🎯

状态反馈

控制律为状态的线性函数 \(u = -Kx\)

最优性

使代价函数最小化的控制律是唯一的

\(e(t)\)
LQR 控制器
\(u(t) = -Kx(t)\)
\(u(t)\)
被控对象
\(\dot{x}(t) = Ax(t) + Bu(t)\)
\(x(t)\)
输出
\(r(t)\)
\(J = \int (x^TQx + u^TRu) \, dt \to \min\)
💡
核心思想:通过调整权重矩阵 \(Q\) 和 \(R\) 的相对大小,权衡"跟踪性能"与"控制代价",得到唯一的最优状态反馈增益 \(K\)。

🔧 2. 问题建模

2.1 线性系统状态空间模型

连续时间

$$\dot{x}(t) = Ax(t) + Bu(t)$$

离散时间

$$x_{k+1} = Ax_k + Bu_k$$
符号维度含义
x\(n \times 1\)状态向量
u\(m \times 1\)控制输入
A\(n \times n\)系统矩阵(状态转移)
B\(n \times m\)输入矩阵(控制作用)

2.2 二次型代价函数

连续时间(有限时域)
$$J = x^T(T)Fx(T) + \int_0^T \left[ x^T(t)Qx(t) + u^T(t)Ru(t) \right] dt$$
离散时间(有限时域)
$$J = x_N^TFx_N + \sum_{k=0}^{N-1} \left[ x_k^TQx_k + u_k^TRu_k \right]$$
无限时域(稳态 LQR)
$$J = \int_0^{\infty} \left[ x^T(t)Qx(t) + u^T(t)Ru(t) \right] dt \quad \text{(连续)}$$
$$J = \sum_{k=0}^{\infty} \left[ x_k^TQx_k + u_k^TRu_k \right] \quad \text{(离散)}$$

权重矩阵的含义

矩阵条件作用
Q\(Q \succeq 0\)(半正定)惩罚状态偏离平衡点,希望状态尽快归零
R\(R \succ 0\)(正定)惩罚控制能量消耗,希望控制输入尽量小
F\(F \succeq 0\)(半正定)终端状态权重(有限时域)
Bryson 法则:设 \(x_{i,\max}\) 为状态 \(x_i\) 的最大允许偏差,\(u_{j,\max}\) 为控制输入 \(u_j\) 的最大允许值,则: \(Q_{ii} = \frac{1}{x_{i,\max}^2}, \quad R_{jj} = \frac{1}{u_{j,\max}^2}\)
大 Q 小 R 快速响应 控制能量大 响应快 超调大 Q R 平衡 适中响应 适中能量 响应适中 平滑 小 Q 大 R 响应慢 控制能量小 响应慢 节能

📝 3. 公式推导

3.1 连续时间无限时域 LQR

Step 1: 构造 HJB 方程

假设存在稳态代价函数 \(V(x) = x^TPx\),Hamilton-Jacobi-Bellman 方程为:

$$0 = \min_u \left[ x^TQx + u^TRu + \frac{\partial V}{\partial x}(Ax + Bu) \right]$$

Step 2: 求解最优控制

对 \(u\) 求导并令其为零:

$$2Ru + 2B^TPx = 0 \quad \Rightarrow \quad \boxed{u^* = -R^{-1}B^TPx}$$

Step 3: 推导 Riccati 方程

将最优控制律代入 HJB 方程,整理得连续代数 Riccati 方程 (CARE)

$$A^TP + PA - PBR^{-1}B^TP + Q = 0$$

Step 4: 闭环系统

最优控制律下的闭环系统动态:

$$\dot{x} = (A - BK)x = (A - BR^{-1}B^TP)x$$

3.2 离散时间无限时域 LQR

Step 1: 构造 Bellman 方程

$$V(x_k) = \min_{u_k} \left[ x_k^TQx_k + u_k^TRu_k + V(x_{k+1}) \right]$$

Step 2: 求解最优控制

假设 \(V(x_k) = x_k^TPx_k\),对 \(u_k\) 求导令其为零:

$$\boxed{u_k^* = -(R + B^TPB)^{-1}B^TPAx_k}$$

Step 3: 推导 Riccati 方程

离散代数 Riccati 方程 (DARE)

$$P = A^TPA - A^TPB(R + B^TPB)^{-1}B^TPA + Q$$

⚖️ 4. 连续时间与离散时间对比

特性连续时间 LQR离散时间 LQR
系统模型\(\dot{x} = Ax + Bu\)\(x_{k+1} = Ax_k + Bu_k\)
代价函数\(\int_0^\infty (x^TQx + u^TRu)dt\)\(\sum_{k=0}^\infty (x_k^TQx_k + u_k^TRu_k)\)
Riccati\(A^TP + PA - PBR^{-1}B^TP + Q = 0\)\(P = A^TPA - A^TPB(R+B^TPB)^{-1}B^TPA + Q\)
最优增益\(K = R^{-1}B^TP\)\(K = (R+B^TPB)^{-1}B^TPA\)
求解方法Hamilton 矩阵特征值分解Schur 分解 / 迭代法
典型应用模拟控制器、理论分析数字控制器、嵌入式系统
💡
如何选择?
• 物理系统(模拟控制)→ 连续 LQR
• 数字控制器(采样控制)→ 离散 LQR
• 嵌入式系统 → 离散 LQR

5. 有限时域 LQR

连续时间

Riccati 微分方程(逆向求解):

$$-\dot{P}(t) = A^TP(t) + P(t)A - P(t)BR^{-1}B^TP(t) + Q$$

终端条件:\(P(T) = F\),最优控制律:\(u^*(t) = -R^{-1}B^TP(t)x(t)\)

离散时间

Riccati 差分方程

$$P_k = A^TP_{k+1}A - A^TP_{k+1}B(R + B^TP_{k+1}B)^{-1}B^TP_{k+1}A + Q$$

终端条件:\(P_N = F\),最优控制律:\(u_k^* = -(R + B^TP_{k+1}B)^{-1}B^TP_{k+1}Ax_k\)

有限 vs 无限时域

特性有限时域无限时域
\(P\) 是否时变否(常数)
终端条件\(P(T) = F\)
计算复杂度高(逆向积分)低(求解 ARE)
适用场景轨迹跟踪、终点控制稳定调节

⚙️ 6. 求解算法

LQR 设计流程

① 建立线性状态空间模型 ② 选择权重矩阵 Q, R ③ 求解 Riccati 方程 ④ 计算最优增益 K ⑤ 构建闭环系统 u = -Kx ⑥ 仿真验证 + 调参
\(A, B\) 矩阵
Bryson 法则
\(ARE / DARE\)
\(K = R^{-1}B^TP\)

6.1 连续时间 CARE 求解 — Hamilton 矩阵法

构造 Hamilton 矩阵:

$$\mathcal{H} = \begin{bmatrix} A & -BR^{-1}B^T \\ -Q & -A^T \end{bmatrix}$$

求解 \(\mathcal{H}\) 的特征值,取左半平面的特征向量构成 \(P\)。

Python 实现Python
import numpy as np
from scipy.linalg import solve_continuous_are, inv

def lqr_continuous(A, B, Q, R):
    """求解连续时间 LQR"""
    P = solve_continuous_are(A, B, Q, R)
    K = inv(R) @ B.T @ P
    return K, P

6.2 离散时间 DARE 求解 — Schur 分解法

构造 symplectic 矩阵,通过 Schur 分解求解。

Python 实现Python
import numpy as np
from scipy.linalg import solve_discrete_are

def lqr_discrete(A, B, Q, R):
    """求解离散时间 LQR"""
    P = solve_discrete_are(A, B, Q, R)
    K = np.linalg.inv(R + B.T @ P @ B) @ B.T @ P @ A
    return K, P

6.3 迭代法(适用于大规模系统)

Python 实现Python
def lqr_iterative(A, B, Q, R, max_iter=1000, tol=1e-10):
    """迭代求解离散 Riccati 方程"""
    P = Q.copy()
    for _ in range(max_iter):
        K_t = np.linalg.inv(R + B.T @ P @ B) @ B.T @ P @ A
        P_new = A.T @ (P - P @ B @ K_t) @ A + Q
        if np.linalg.norm(P_new - P) < tol:
            break
        P = P_new
    K = np.linalg.inv(R + B.T @ P @ B) @ B.T @ P @ A
    return K, P

算法选择指南

🔍

Hamilton 矩阵法

适合中小规模系统,理论清晰,scipy 内置

📉

Schur 分解法

数值稳定性好,适合大规模稀疏系统

🔄

迭代法

实现简单,可并行化,适合超大规模系统

🎯 7. 关键性质与定理

稳定性定理:若 \((A, B)\) 可控且 \((Q^{1/2}, A)\) 可观,则:
1. 连续时间 ARE 存在唯一正定解 \(P \succ 0\)
2. 闭环系统 \(\dot{x} = (A - BK)x\) 渐近稳定
3. 最优代价 \(J^* = x_0^TPx_0\)

LQR 系统架构

状态
\(x(t)\)
增益 K 权重 Q 权重 R
\(u = -Kx\)
控制输入 \(u\)
最小化 \(J = x^TQx + u^TRu\)
\(K\) 由 Riccati 方程的解 \(P\) 决定

鲁棒性(增益裕度与相位裕度)

增益裕度

[1/2, ∞)

LQR 可以承受 50%~∞ 的增益变化

相位裕度

≥ 60°

LQR 具有至少 60° 的相位裕度

最优性条件

🚀 8. 应用场景

🎡 倒立摆控制

状态:\([\theta, \dot{\theta}, x, \dot{x}]\)(角度、角速度、位移、速度)

Python 代码Python
# 倒立摆状态: [theta, theta_dot, x, x_dot]
g, l, m = 9.81, 1.0, 0.1

A = np.array([
    [0, 1, 0, 0],
    [g/l, 0, 0, 0],
    [0, 0, 0, 1],
    [0, 0, 0, 0]
])
B = np.array([[0], [-1/(m*l)], [0], [1]])
Q = np.diag([100, 10, 10, 1])  # 重点惩罚角度偏差
R = np.array([[0.1]])

K, P = lqr_continuous(A, B, Q, R)
🛰️ 卫星姿态控制

简化的三轴姿态控制模型

Python 代码Python
# 简化的三轴姿态控制
A = np.block([
    [np.zeros((3,3)), np.eye(3)],
    [np.zeros((3,3)), np.zeros((3,3))]
])
B = np.block([
    [np.zeros((3,3))],
    [np.eye(3)]
])
Q = np.diag([10, 10, 10, 1, 1, 1])  # 姿态误差 + 角速度
R = np.diag([0.01, 0.01, 0.01])     # 力矩代价
🚁 无人机高度控制

状态:\([z, \dot{z}]\)(高度、垂直速度)

Python 代码Python
m = 1.5  # 无人机质量
A = np.array([[0, 1], [0, 0]])
B = np.array([[0], [1/m]])
Q = np.diag([10, 1])   # 高度误差权重大
R = np.array([[0.1]])  # 推力代价
🚗 自动驾驶横向控制(自行车模型)

状态:\([e_y, \dot{e}_y, e_{\psi}, \dot{e}_{\psi}]\)

Python 代码Python
m, Iz = 1500, 2500
Cf, Cr = 80000, 80000
Lf, Lr = 1.2, 1.6
Vx = 20  # 车速

A = np.array([
    [0, 1, 0, 0],
    [0, -(Cf+Cr)/(m*Vx), (Cf+Cr)/m, (Lf*Cf-Lr*Cr)/(m*Vx)],
    [0, 0, 0, 1],
    [0, -(Lf*Cf-Lr*Cr)/(Iz*Vx), (Lf*Cf+Lr*Cr)/Iz,
     -(Lf**2*Cf+Lr**2*Cr)/(Iz*Vx)]
])
B = np.array([[0], [Cf/m], [0], [Lf*Cf/Iz]])
Q = np.diag([100, 1, 100, 1])  # 横向误差和航向误差最重要
R = np.array([[10]])            # 转向角代价
🏭 完整仿真示例(质量-弹簧-阻尼)
完整 Python 仿真Python
import numpy as np
import matplotlib.pyplot as plt
from scipy.linalg import solve_continuous_are

def lqr(A, B, Q, R):
    P = solve_continuous_are(A, B, Q, R)
    K = np.linalg.inv(R) @ B.T @ P
    return K, P

# 质量-弹簧-阻尼系统
m, b, k = 1.0, 0.1, 1.0
A = np.array([[0, 1], [-k/m, -b/m]])
B = np.array([[0], [1/m]])
Q = np.diag([10, 1])
R = np.array([[0.1]])

K, P = lqr(A, B, Q, R)
print(f"K = {K}")

# 仿真
dt, T = 0.01, 10
t = np.arange(0, T, dt)
x = np.zeros((2, len(t)))
x[:, 0] = [1, 0]  # 初始位移=1

for i in range(1, len(t)):
    u = -K @ x[:, i-1]
    x[:, i] = x[:, i-1] + dt * (A @ x[:, i-1] + B.flatten() * u)

fig, axes = plt.subplots(1, 3, figsize=(14, 4))
axes[0].plot(t, x[0]); axes[0].set_title('Position'); axes[0].grid(True)
axes[1].plot(t, x[1]); axes[1].set_title('Velocity'); axes[1].grid(True)
axes[2].plot(t, -K @ x); axes[2].set_title('Control Input'); axes[2].grid(True)
plt.tight_layout()
plt.savefig('lqr_response.png', dpi=150)
plt.show()

🔥 9. 扩展与变体

9.1 LQG (Linear Quadratic Gaussian)

当系统存在过程噪声和量测噪声时:

$$\dot{x} = Ax + Bu + w, \quad w \sim \mathcal{N}(0, W)$$
$$y = Cx + v, \quad v \sim \mathcal{N}(0, V)$$
💡
分离原理
1. 设计 Kalman 滤波器估计状态 \(\hat{x}\)
2. 基于估计状态设计 LQR 控制器:\(u = -K\hat{x}\)

9.2 约束 LQR / MPC

当存在输入/状态约束时,转化为二次规划 (QP) 问题:

$$\min_{u_0,...,u_{N-1}} \sum_{k=0}^{N-1} (x_k^TQx_k + u_k^TRu_k) + x_N^TFx_N$$

约束条件:

$$x_{k+1} = Ax_k + Bu_k, \quad u_{\min} \leq u_k \leq u_{\max}, \quad x_{\min} \leq x_k \leq x_{\max}$$

9.3 加权 LQR (Weighted LQR)

跟踪期望轨迹/输入:

$$J = \sum_{k=0}^{\infty} \left[ (x_k - x_d)^TQ(x_k - x_d) + (u_k - u_d)^TR(u_k - u_d) \right]$$

9.4 iLQR (迭代 LQR)

适用于非线性系统,通过在工作点线性化后迭代求解 LQR:

  1. 给定初始控制序列 \(\bar{u}\)
  2. 沿 \(\bar{u}\) 正向传播状态,得到 \(\bar{x}\)
  3. 在 \((\bar{x}, \bar{u})\) 处线性化系统
  4. 求解 LQR 得到改进的控制律
  5. 重复直到收敛

9.5 离散 vs 连续选择

场景选择
物理系统(模拟控制)连续 LQR
数字控制器(采样控制)离散 LQR
嵌入式系统离散 LQR

📊 10. 与其他控制方法对比

方法优点缺点适用场景
LQR最优性、鲁棒性好需要精确模型、线性假设线性系统、标称工况
PID简单、不需模型非最优、调参困难简单系统、工程应用
MPC处理约束、非线性计算量大多约束、非线性系统
H∞鲁棒性强保守、计算复杂不确定性大的系统
滑模控制对不确定性强抖振强鲁棒性要求

决策流程图

选型指南:

✅ 系统线性 + 无约束 + 需要最优 → LQR
✅ 系统线性 + 有噪声 + 需要估计 → LQG(LQR + Kalman)
✅ 非线性 + 有约束 + 计算资源充足 → MPC
✅ 简单系统 + 快速部署 → PID
✅ 非线性 + 需要在线优化 → iLQR / DDPA

🏗️ 11. 调参指南

11.1 如何选择 Q 和 R?

目标调整策略
快速响应增大 \(Q\) 中对应状态的权重
减少控制能量增大 \(R\)
平衡响应与能量使用 Bryson 法则:\(Q_{ii} = 1/x_{i,\max}^2\), \(R_{jj} = 1/u_{j,\max}^2\)
过冲大增大 \(Q\),减小 \(R\)
振荡增大 \(R\),适当减小 \(Q\)

11.2 权重敏感性分析

Python 代码Python
import numpy as np
import matplotlib.pyplot as plt
from scipy.linalg import solve_continuous_are

def lqr(A, B, Q, R):
    P = solve_continuous_are(A, B, Q, R)
    return np.linalg.inv(R) @ B.T @ P

# 系统
A = np.array([[0, 1], [-1, -0.1]])
B = np.array([[0], [1]])

fig, axes = plt.subplots(2, 2, figsize=(10, 8))
r_vals = [0.01, 0.1, 1.0, 10.0]

for ax, r in zip(axes.flat, r_vals):
    Q = np.diag([10, 1])
    K = lqr(A, B, Q, np.array([[r]]))
    dt, T = 0.01, 15
    t = np.arange(0, T, dt)
    x = np.zeros((2, len(t))); x[:, 0] = [1, 0]
    for i in range(1, len(t)):
        u = -K @ x[:, i-1]
        x[:, i] = x[:, i-1] + dt * (A @ x[:, i-1] + B.flatten() * u)
    ax.plot(t, x[0], label='Position')
    ax.plot(t, -K @ x, label='Control', alpha=0.7)
    ax.set_title(f'R = {r}, K = [{K[0,0]:.2f}, {K[0,1]:.2f}]')
    ax.legend(); ax.grid(True)
plt.tight_layout()
plt.savefig('lqr_tuning.png', dpi=150)
plt.show()

11.3 常见调参经验

💡

位置控制

\(Q = \text{diag}(q_1, 0)\),\(R = \text{small}\),位置权重最大

💡

速度控制

\(Q = \text{diag}(0, q_2)\),\(R = \text{medium}\),速度权重最大

💡

能量最优

\(Q = \text{small}\),\(R = \text{large}\),优先减小控制量

💡

快速收敛

\(Q = \text{large}\),\(R = \text{small}\),牺牲控制能量换速度

12. 常见问题

12.1 LQR 无法求解?

⚠️
常见原因:
1. \((A, B)\) 不可控 → 检查可控性矩阵 \(\text{rank}[B, AB, ..., A^{n-1}B] = n\)
2. \((Q^{1/2}, A)\) 不可观 → 检查可观性矩阵
3. \(R\) 不正定 → 确保 \(R\) 正定
4. \(Q\) 负定 → \(Q\) 应半正定

12.2 可控性与可观性检查

Python 代码Python
def check_controllability(A, B):
    n = A.shape[0]
    ctrb = np.hstack([A**i @ B for i in range(n)])
    rank = np.linalg.matrix_rank(ctrb)
    return rank == n, rank

def check_observability(A, C):
    n = A.shape[0]
    obsv = np.vstack([C @ A**i for i in range(n)])
    rank = np.linalg.matrix_rank(obsv)
    return rank == n, rank

# 示例
A = np.array([[0, 1], [-1, -0.1]])
B = np.array([[0], [1]])
C = np.array([[1, 0]])

ctrl_ok, r1 = check_controllability(A, B)
obs_ok, r2 = check_observability(A, C)
print(f"可控: {ctrl_ok} (rank={r1}), 可观: {obs_ok} (rank={r2})")

12.3 LQR 与 PID 的关系

对于一阶系统 \(\dot{x} = -ax + bu\),LQR 的增益 \(K = R^{-1}B^TP\) 中,当 \(Q = q, R = r\) 时,\(K = \sqrt{q/r}\),这类似于 PID 中比例增益的效果。

12.4 最优代价的含义

$$J^* = x_0^TPx_0$$

表示从初始状态 \(x_0\) 出发,采用最优控制律所能达到的最小代价。可用于:
• 比较不同初始状态的控制难度
• 设计观测器时评估估计误差的影响
• 作为控制性能的量化指标

📚 13. 参考文献

  1. Anderson, B. D. O., & Moore, J. B. (2007). Optimal Control: Linear Quadratic Methods. Dover Publications.
  2. Lewis, F. L., Vrabie, D., & Syrmos, V. L. (2012). Optimal Control (3rd ed.). Wiley.
  3. Astrom, K. J., & Murray, R. M. (2008). Feedback Systems. Princeton University Press.
  4. Bertsekas, D. P. (2005). Dynamic Programming and Optimal Control (Vol. 1). Athena Scientific.

← 返回首页 | Last updated: 2026-06-25 | Made with love for optimal control