---
title: 进阶：最优控制与 MPC
url: https://doc.liz6.com/theory/02-control-theory/11-optimal-and-predictive-control
locale: zh
area: theory
tags:
- 控制理论
- 基础理论
date: 2026-09-10
modified: 2026-09-10
description: 极点配置告诉我们怎样得到指定动态，却没有直接回答“误差和动作各值多少代价”。最优控制把取舍写成目标函数；MPC进一步把有限未来和约束放进每轮决策。本篇需要状态反馈、数字控制与二次函数的基本概念。
---

# 进阶：最优控制与 MPC

极点配置告诉我们怎样得到指定动态，却没有直接回答“误差和动作各值多少代价”。最优控制把取舍写成目标函数；MPC进一步把有限未来和约束放进每轮决策。本篇需要[状态反馈](10-state-feedback-and-observers.md)、[数字控制](07-sampling-and-delay.md)与二次函数的基本概念。

## LQR：先明确优化的量

对连续线性系统 $\dot x=Ax+Bu$，考虑无限时域代价

$$J=\int_0^\infty(x^\mathsf TQx+u^\mathsf TRu)dt,\qquad Q\succeq0,\ R\succ0.$$

$Q$惩罚状态偏离，$R$惩罚动作。坐标和单位必须先约定：把米改成厘米却不调整权重，会改变实际偏好。允许误差和动作量可用来选择归一化尺度，权重仍表示设计取舍。

在 $(A,B)$可稳定、$(Q^{1/2},A)$可检测等标准条件下，稳定化Riccati解 $X$ 满足

$$A^\mathsf TX+XA-XBR^{-1}B^\mathsf TX+Q=0,$$

反馈为 $u=-Kx$、$K=R^{-1}B^\mathsf TX$。这里 $X$ 是代价矩阵，不是状态向量。约束不在这个基本LQR问题中；事后裁剪动作会改变原来的最优性与保证。

## 一个可以手算的最优反馈

对标量积分器 $\dot x=u$，权重 $Q=q>0,R=\rho>0$，Riccati方程变成 $-X^2/\rho+q=0$。取稳定化解 $X=\sqrt{q\rho}$，得到

$$u=-\sqrt{q/\rho}\,x.$$

$q=\rho=1$时，$x=e^{-t}x_0$；把动作代价增至 $\rho=4$，增益降为0.5，收敛变慢。对$x_0=2$，两种权重下各自最优值为 $J=Xx_0^2=4$ 与8；由于目标函数已经改变，不能用这两个数直接宣称某控制器更差。

## MPC：优化一段，只执行第一步

离散模型 $x_{k+1}=Ax_k+Bu_k$ 下，可在每个时刻求解

$$\min_{u_{0:N-1}}\sum_{i=0}^{N-1}(x_i^\mathsf TQx_i+u_i^\mathsf TRu_i)+V_f(x_N)$$

并满足 $x_0=\hat x_k$、模型递推、$x_i\in\mathcal X$、$u_i\in\mathcal U$，必要时再加终端约束。求出的动作是一整段，但当前只执行第一步。下个时刻重新测量/估计，再求解剩下的未来。

这样做可以修正模型预测与真实结果之间的偏差，也能利用已知的未来参考或扰动。预测值与已经发生的轨迹必须分别显示；未发生的最优预测不是事实。[do-mpc 原理说明](https://www.do-mpc.com/en/latest/theory_mpc.html)介绍了有限时域、状态估计与约束的组合。

## 用有限候选动作看清滚动优化

实验用无量纲标量模型 $x_{k+1}=x_k+u_k$，初始 $x_0=2.5$，目标0，动作集合 $\{-1,-0.5,0,0.5,1\}$。为了手算，代价专门定义为

$$J_N=\sum_{i=0}^{N-1}\left(x_{i+1}^2+\rho u_i^2\right),$$

无额外终端项。它与上一节使用 $x_i$ 的记法不同，明确惩罚每次动作后的状态。遍历全部 $5^N$ 条候选序列，得到这个有限集合内的全局最小值；它不是一般连续输入MPC的求解器。

**进阶：最优控制与 MPC · 实验**

x(k+1)=x(k)+u(k)，x0=2.5；动作候选0、±0.5、±1；代价Σ[x(i+1)²+ρu(i)²]。遍历全部5^N候选，执行第一步后重新优化。虚线是初次预测，外扰不提前告知控制器。


改变预测步数与动作权重，观察初次预测、实际滚动轨迹和逐步动作。可在第3步执行完动作后加入+1外扰；该扰动不在预测中，下一轮测量后重新优化。相同代价的方案优先选择当前动作绝对值较小者，再按枚举顺序决定。

对 $N=1,\rho=1,x=2.5$，$u=-1$ 的代价为 $1.5^2+1=3.25$；$u=-0.5$ 为 $2^2+0.25=4.25$，所以选择−1。如果输入连续且只有区间约束$[-1,1]$，先令导数为零得到 $u=-x/(1+\rho)$，再投影到区间；有限候选集合还需比较相邻候选。

## 可行不代表始终可行，有限最优不代表稳定

当前优化有解，不保证下一步在扰动后仍有解，这就是递归可行性问题。有限时域目标也不自动保证无限时间收敛。适当的终端代价、终端集合和局部控制律是建立保证的常见方法，具体条件随模型与约束而变。

增加预测步数通常能看见更远的影响，却会增加计算量；若计算超过采样预算，实际控制器就多出延迟。工程实现需要定义求解超时或不可行时的后备动作、约束优先级、状态估计误差以及模型更新策略。软化约束需要明确允许违背的量与代价，不能悄悄把硬边界当作可违反目标。

## 自检

LQR求出的动作超过执行器上限，直接截断后还能称为原问题的最优控制吗？

<details><summary>参考思路</summary>

不能。原问题没有这个约束，截断改变了闭环。可以把饱和纳入分析，或明确求解带约束问题，并重新核对稳定与可行性。

</details>

MPC为什么不一次算完全部动作后永久照着执行？

<details><summary>参考思路</summary>

实际状态可能因扰动、模型误差和估计修正而偏离预测。每轮只执行第一步并重新求解，才能利用新的信息；计算延迟也必须计入实现。

</details>

## 延伸与复现

[python-control `lqr`](https://python-control.readthedocs.io/en/stable/generated/control.lqr.html)返回反馈增益、Riccati解与闭环特征值。以下使用SciPy求解路径核对标量例子：

```python
import control as ct
K, X, poles = ct.lqr([[0.0]], [[1.0]], [[1.0]], [[4.0]], method="scipy")
print(K, X, poles)
# [[0.5]] [[2.0]] [-0.5]
```

完成本篇后，可以沿三条方向深入：以系统辨识改善模型，以非线性/鲁棒控制扩大保证范围，以随机估计处理噪声。返回[学习路线](index.md)，按实际问题选择后续入口。
