4. MPC理论基础:最优控制问题、滚动时域原理、预测模型与代价函数设计

各位同学,欢迎来到第四章。

前面我们聊了MPC在自动驾驶里到底能干啥。今天,咱们得把袖子撸起来,看看MPC的「内功心法」到底是什么。

说白了,MPC就是一个「走一步,看三步」的决策方法。它不像PID那样傻傻地只看当前误差,而是会预测未来一段时间的状态,然后选一个最优的动作序列。嗯,这里要注意,它只执行第一个动作,然后重新预测、重新规划。这就是它的精髓。

4.1 最优控制问题:MPC到底在解什么题?

先问大家一个问题:自动驾驶的决策,本质上是个什么问题?

我个人习惯把它理解成一个「带约束的优化问题」。你想想看,我们想让车沿着参考线走,这是目标;但车不能超速、不能压线、方向盘不能打太猛,这是约束。在满足这些约束的前提下,找一个最好的控制量——这就是最优控制问题。

核心公式(离散时间形式):

min J = Σ (x_k - x_ref)ᵀ Q (x_k - x_ref) + Σ u_kᵀ R u_k
s.t.  x_{k+1} = f(x_k, u_k)   // 车辆动力学
      x_min ≤ x_k ≤ x_max     // 状态约束
      u_min ≤ u_k ≤ u_max     // 控制量约束

这里J就是代价函数,x_k是状态(位置、速度、航向角),u_k是控制量(油门、刹车、方向盘转角)。

我在项目中遇到过一个问题:刚开始做MPC时,只关注了目标函数,忽略了约束的可行性。结果仿真跑得好好的,实车一跑,方向盘直接打到底——因为约束设得太紧了,求解器找不到解。嗯,这是个坑。

4.2 滚动时域原理:为什么MPC能实时运行?

滚动时域,英文叫Receding Horizon。这个名字起得挺形象——就像潮水一样,每次只往前看一段,然后退回来,再往前看一段。

具体流程是这样的:

  1. 预测:在当前时刻t,基于当前状态x_t,预测未来N步的状态。
  2. 优化:求解一个N步的最优控制问题,得到控制序列u_t, u_{t+1}, ..., u_{t+N-1}。
  3. 执行:只应用第一个控制量u_t。
  4. 滚动:时间步进到t+1,重复步骤1-3。

为什么会这样设计?你想想看,如果一次性规划出未来10秒的轨迹,那计算量得有多大?而且环境是变化的,预测越远越不准。滚动时域的好处就是:每次只算一小段,算得快,而且能及时修正误差

个人经验:预测时域N的选择很关键。N太小,MPC退化成PID,没有预见性;N太大,计算量爆炸,实时性跟不上。我一般从N=10开始调,根据CPU负载和车速动态调整。高速场景N可以小一点,低速泊车N可以大一点。

下面这张图,是我自己画的MPC滚动时域原理示意图,帮你直观理解这个过程:

MPC滚动时域原理示意图 t t+1 t+2 t+3 t+4 t+N 第一次预测(N步) 执行u_t 第二次预测(滚动后) 每次只执行第一个控制量,然后重新预测、重新优化

4.3 预测模型:MPC的「水晶球」

MPC之所以能预测未来,靠的就是预测模型。这个模型描述了车辆在给定控制输入下,状态会如何变化。

常用的预测模型有几种:

模型类型 精度 计算量 适用场景
运动学模型(自行车模型) 中等 低速泊车、城市道路
动力学模型(二自由度) 较高 中等 高速巡航、变道
非线性轮胎模型(Pacejka) 极限工况、漂移控制

我个人习惯在项目初期先用运动学模型。为什么?因为简单、快、容易调试。等基本功能跑通了,再换成动力学模型提升精度。我曾经在一个项目中,直接用运动学模型做高速MPC,结果在80km/h以上时预测误差越来越大——嗯,轮胎侧偏角不能忽略了,必须上动力学模型。

避坑指南:我曾经犯过一个错误——模型太复杂,导致求解器每次要算200ms,而控制周期只有50ms。结果就是:车都跑出去老远了,控制指令还没算出来。记住:实时性永远比精度重要。算不出来的最优解,等于没有解。

4.4 代价函数设计:如何让MPC「懂事」?

代价函数,就是告诉MPC「什么才是好的行为」。设计得好,MPC就像个老司机;设计得不好,它可能像个刚拿驾照的新手——要么太激进,要么太保守。

典型的代价函数包含三部分:

  1. 跟踪误差代价:偏离参考线越远,代价越大。用Q矩阵加权。
  2. 控制量代价:油门刹车打得太猛,代价大。用R矩阵加权。
  3. 控制量变化率代价:防止方向盘来回抖。用S矩阵加权。

完整的代价函数形式:

J = Σ (x_k - x_ref)ᵀ Q (x_k - x_ref)   // 跟踪误差
    + Σ u_kᵀ R u_k                       // 控制量
    + Σ (u_k - u_{k-1})ᵀ S (u_k - u_{k-1})  // 控制量变化率

这里Q、R、S都是权重矩阵。调参的时候,我一般遵循一个原则:先调Q,再调R,最后调S。Q决定了跟踪的紧度,R决定了控制的力度,S决定了平顺度。

举个例子:在高速公路上,我希望车稳稳地保持在车道中央,这时候Q可以设大一点;但在泊车场景,我更关心控制量的平顺性,R和S就要大一些。

一个小技巧:Q矩阵的对角线元素,我通常按物理单位归一化。比如位置误差的单位是米,速度误差的单位是米/秒,它们的数值量级可能差10倍。如果不归一化,MPC会「偏科」——只优化数值大的那个量。我习惯把每个状态量的权重除以它的典型误差范围,这样各个维度就公平了。

好了,这一章的内容就到这里。MPC的理论基础,说白了就是三件事:预测未来、滚动优化、代价引导。下一章我们会深入代码层面,看看这些理论怎么变成实实在在的C++代码。


公众号:蓝海资料掘金营,微信deep3321