跳转至

第 9 章 MPPI vs 梯度式 MPC——何时选谁

前八章我们把采样式 MPC 的内核(第 2–3 章)、家族变体(第 4–6 章)、最难的腿足战场(第 7 章)和最广的导航/自驾/无人机落地(第 8 章)走了一遍。一路上有一个对手反复出现,却始终没被正面端上桌——梯度式 MPC(iLQR、DDP、SQP 那一类)。第 7 章说"接触不可微让采样法成为腿足主场",第 8 章说"代价不可微让采样法成为导航主场",这些论断的另一半,是"那么在动力学和代价都光滑可微的地方,梯度式 MPC 反而是更好的选择"。本章把这两家放在一起,做一场认真的对比:给定一个控制问题,我到底该用采样式还是梯度式?什么时候该把两者混在一起用?

这一章的气质和前八章都不同。前面是"建设性"的——一章章把采样 MPC 的能力垒起来;本章是"判断性"的——不教你新算法,而是教你**选择**:在采样式与梯度式之间、在纯方法与混合架构之间,依据问题的特征做出工程上正确的决策。读完前八章,你已经是个会用采样 MPC 的人;读完本章,你要成为一个**知道什么时候不该用采样 MPC、该用什么、怎么把它和别的方法拼起来**的人——这是从"会用一把锤子"到"会挑工具、会组合工具"的跃迁。

为了做这场对比,本章会先补上一块前面刻意略过的拼图——梯度式 MPC 到底怎么工作(§9.2 讲 iLQR/DDP/SQP 的机制),不然"对比"就成了对一个黑箱的空谈。然后从**梯度需求、代价函数、动力学、计算平台**等维度系统对比两家(§9.3、§9.4),讲清各自的杀手场景与失效模式;再讲四种把两家拼起来的**混合架构**(§9.5);最后给一套**决策方法论**(§9.6 的案例剖析与决策树)和一个把采样式、梯度式放在同一个任务上跑的**横向基准**(§9.7)。本章是采样 MPC 方向的"对比与定位"章——它让你跳出"采样 MPC 视角",站在更高处看清它在整个最优控制版图里的位置。


📋 前置自测

开始前,先用这几道题检验你是否具备读本章的基础(答案在本章各节展开,读前先想一想):

  1. 第 2–3 章的 MPPI 更新公式里,有没有任何一步用到了**代价函数对控制的梯度**或**动力学的雅可比**?如果没有,这意味着 MPPI 对代价和动力学有什么"不要求"?
  2. 一个函数"能算出值"和"能算出梯度"是两回事。请举一个"能轻松算值、但算不出(或算不好)梯度"的例子(提示:第 8 章的代价地图)。
  3. 牛顿法为什么比梯度下降收敛快?它多用了什么信息(一阶还是二阶)?这个差别和"iLQR 为什么比一阶方法收敛快"是同一个道理吗?
  4. "全局最优"和"局部最优"的区别是什么?一个从随机初值出发、只会往代价下降方向走的方法,能保证找到全局最优吗?
  5. 如果一个控制问题有**硬约束**(如"推力绝对不能超过上限""绝对不能撞到障碍"),你觉得"把约束变成代价里的一个高惩罚项"和"把约束作为优化问题的硬性约束",这两种处理方式哪种能给出更强的保证?

如果第 1、2 题答不上来,建议先回顾第 2–3 章 MPPI 的更新公式和第 8 章 §8.1;第 3–5 题是本章要展开的核心,带着疑问读即可。


本章目标

读完本章,你应该能够:

  1. 讲清梯度式 MPC(iLQR/DDP/SQP)的工作机制:理解它们如何利用动力学雅可比和代价的一阶/二阶导数,通过"线性化-二次化-Riccati 反向递推-前向 rollout"迭代求解,以及它们为什么在光滑问题上收敛快、精度高。
  2. 从多个维度系统对比采样式与梯度式 MPC:梯度需求、代价/动力学的可微性要求、GPU 利用、收敛性质(全局概率 vs 局部二次)、硬约束处理、计算平台、适用维度——并能解释每个维度差异背后的原因。
  3. 判断各自的杀手场景与失效模式:知道采样式在"不可微代价 + 黑箱动力学"上不可替代、梯度式在"光滑约束优化 + CPU 平台"上占优,以及各自在对方主场会怎样失效。
  4. 理解并设计混合架构:MPPI 初始化 + iLQR 精炼、MPPI + CBF 安全滤波(Shield-MPPI)、RL 策略偏置采样(Biased-MPPI)、MPPI 高层 + WBC/PD 底层分层——知道每种混合"取了两家的什么长"。
  5. 掌握一套求解器选型的决策方法论:给定问题特征(动力学可微?代价光滑?有 GPU?约束重要?),用一棵决策树选出合适的求解器;并能剖析真实工业系统(Nav2/AutoRally/acados/OCS2/DIAL-MPC)的选型理由。

本章知识导航

本章是"对比与综合"型,建议这样使用:

  • 顺序精读(推荐):§9.1 建立"求值 vs 求导"的根本分野 → §9.2 补上梯度式 MPC 的机制(对比的前提)→ §9.3/§9.4 系统对比与失效模式 → §9.5 混合架构 → §9.6 决策方法论 → §9.7 横向基准与累积项目收尾。这条线让你从"理解两家"到"会选、会混、会评测"。
  • 带着问题查:手头有个具体控制问题、纠结用采样还是梯度 → 直接看 §9.6 决策树,再回 §9.3/§9.4 看维度对比;想把两个方法拼起来 → 看 §9.5。
  • 动手验证:§9.2–§9.7 每节都有能跑的对照 demo(iLQR 摆起、光滑问题上两家对比、非光滑代价上梯度式失效、双势阱上混合架构、三方横向基准),建议边读边跑,亲手看到两家的差异。

前置知识桥接

本章是前八章的综合对比,依赖广。开始前确认这些前置(不熟的回对应章节):

前置知识 来自 本章如何用到
MPPI 更新公式(采样-rollout-加权) 第 2–3 章 对比的一方;理解它"不求导"是全章起点
信息论推导(指数加权的由来) 第 2 章 §2.1 解释采样法的全局/概率收敛性质
CEM 家族(精英重拟合) 第 4 章 §9.7 横向基准里的 iCEM/CEM
退火、warm-start 第 5、7 章 解释采样法如何缓解非凸/维度灾难
学习模型、价值函数 第 6 章 混合架构里的 RL 先验、终端价值
代价来自感知、不可微 第 8 章 §8.1 采样法杀手场景的核心论据
规划-执行分层(MPPI + PD/WBC) 第 7 章 §7.5、第 8 章 §8.5 §9.5 分层混合架构
控制屏障函数(CBF)的概念 后续方向预告 §9.5 的 MPPI + CBF 安全滤波

特别地,本章会**首次正面讲梯度式 MPC**(iLQR/DDP/SQP)。如果你完全没接触过最优控制里的这类方法,§9.2 会从零讲起,但若你学过 LQR(线性二次调节器)或牛顿法,理解会更顺。


如果跳过本章会怎样

如果你学完前八章就停在"会用采样 MPC",跳过这场对比,会留下三个隐患。

其一,你会过度使用采样 MPC。手里有锤子,看什么都像钉子——遇到一个动力学光滑、代价是漂亮二次型、还要在 CPU 上跑的问题(比如四旋翼的轨迹跟踪),你可能仍然上 MPPI,却不知道梯度式 MPC(如 acados)在这种问题上收敛更快、精度更高、还能给硬约束保证。用错工具,事倍功半。

其二,你不会"混"。真实的高性能系统极少是纯采样或纯梯度,而是两者的混合——MPPI 找全局、iLQR 精炼局部;MPPI 出性能、CBF 保安全;RL 给先验、MPPI 在线微调。不懂混合架构,你就只能在"纯采样"和"纯梯度"之间二选一,错过了"取两家之长"的整片设计空间。

其三,你说不清"为什么"。面试官或合作者问你"这个任务你为什么用 MPPI 而不用 iLQR",如果你只会说"MPPI 比较通用",那是没真正理解。本章给你的是一套**可论证的选型依据**——从可微性、收敛性、约束、平台几个维度讲清楚"为什么"。能讲清为什么,才说明你真正掌握了这些工具,而非只会调包。

一句话:跳过本章,你会是一个"只会用采样 MPC 的人";读完本章,你会是一个"懂得在采样式、梯度式及其混合之间做出正确选择的人"。后者才是这套课程想培养的工程判断力。


科研发展脉络

本章无独立的论文线——它是对前八章的综合对比,串联的是采样式与梯度式两大家族的代表性工作。把它们放在一条时间/谱系线上:

梯度式 MPC 这一支(更古老、更主流):DDP(微分动态规划)可追溯到 1960 年代(Mayne、Jacobson & Mayne),是二阶的轨迹优化方法;iLQR(迭代线性二次调节器,Li & Todorov 2004)是 DDP 的高斯-牛顿简化,去掉了动力学二阶项,更轻更稳,成为机器人轨迹优化的主力;SQP(序列二次规划)是处理**带约束**非线性优化的经典框架,配上实时迭代(RTI)和高效 QP 求解器(如 HPIPM),催生了 acados 这类嵌入式实时 NMPC 工具;腿足领域的 OCS2(Farshidian 等)用 SLQ(DDP 的连续时间变体)做开关系统的实时 MPC。

采样式 MPC 这一支(更年轻、随 GPU 和学习兴起):从 Williams 等 2016 年的 MPPI(第 2–3 章、第 8 章)起,到 CEM 家族(第 4 章)、扩散启发采样(第 5 章)、学习世界模型 + 采样(第 6 章 TD-MPC)、腿足全身 MPPI(第 7 章 MJPC/DIAL-MPC)、导航/无人机采样 MPC(第 8 章 Nav2/AutoRally/STORM)。

两家交汇处(本章的真正主角):混合架构正是这条脉络近年最活跃的方向——Shield-MPPI(Yin 等 2023)把控制屏障函数嵌进 MPPI 保安全、Biased-MPPI(Trevisan & Alonso-Mora 2024)用辅助控制器偏置采样分布、各类"MPPI 初始化 + 梯度精炼"的两阶段方法。这些工作的共同信念是:采样式与梯度式不是非此即彼的竞争者,而是可以互补的搭档——这正是本章想传达的核心立场。

本章会按需引用这些工作,但重点不是逐篇精读(那是前几章和论文解读类文档的任务),而是**用它们作为"对比"和"混合"的论据与样本**,帮你建立选型与组合的判断力。


§9.1 为什么要做这场对比——采样式与梯度式的根本分野 ⭐⭐

动机

前八章你一直在采样 MPC 的世界里,可能已经默认"采样 MPC 就是做 MPC 的方式"。但这是个幸存者偏差——你只看了采样这一支。事实上,在你接触 MPPI 之前,最优控制和 MPC 领域的主流一直是梯度式方法(iLQR/DDP/SQP),它们更古老、理论更成熟、在工业界(尤其汽车、航空航天、过程控制)部署得更广。采样 MPC 是近十年随 GPU 和机器学习才崛起的"新贵"。要在这两家之间做出正确选择,你得先理解一个最根本的问题:它们的本质差别到底在哪? 这一节回答这个问题——答案出奇地简单,却能解释后面所有的维度差异:梯度式要对问题"求导",采样式只对问题"求值"。

如果不这样做会怎样:把"求值"和"求导"混为一谈

设想你不区分"求值"和"求导",笼统地认为"两家都是在优化一个代价函数,应该差不多"。你会做出一系列错误判断。比如:你有一个代价来自神经网络的问题,你以为"反正都能优化",随手选了梯度式 MPC——结果发现要让整个网络可微、还要导出成优化器能用的格式,工程上极其麻烦(第 8 章 §8.6 讲过)。又比如:你有一个动力学光滑、代价是二次型的问题,你习惯性地上了 MPPI,撒了几千个样本还只得到一个"差不多"的解,却不知道 iLQR 几次迭代就能收敛到高精度的最优解。这些错误的根源,都是**没有抓住"求值 vs 求导"这条根本分野**。一旦抓住它,你看任何控制问题,第一反应就该是问:"这个问题的代价和动力学,是只能求值、还是也能求导?"——这一问,往往就决定了该用哪家。

历史:两家为什么会分道扬镳

两家的分野有其历史必然。梯度式方法诞生于"算力昂贵、问题规模小、模型解析可写"的年代——1960 年代的 DDP、2000 年代的 iLQR,都假设你有一个**解析的、可微的**动力学模型和一个**光滑的**代价函数,于是可以用微积分的全部威力(梯度、Hessian、牛顿法那套)来高效求解。在那个算力稀缺的年代,"用导数信息指引搜索"是必须的——你撒不起几千个样本,只能靠梯度精准地走每一步。

采样式方法则诞生于"GPU 让大规模并行变廉价、机器学习让黑箱模型(神经网络、仿真器)无处不在"的年代。当动力学是一个不可微的物理仿真器(MuJoCo 接触)、代价是一张感知生成的地图或一个 CNN 时,"求导"这条路要么走不通、要么代价高昂——但"求值"永远可行(给定输入,仿真器/网络总能算出输出)。GPU 又让"同时求几千个值"变得廉价。于是采样式方法应运而生:放弃求导,改用大规模并行的求值 + 加权来近似最优控制

所以两家不是谁取代谁,而是**为不同的时代、不同的问题特征而生**。理解这个历史背景,你就不会简单地认为"采样式更先进所以更好"——它只是更适合某一类问题(不可微、黑箱、有 GPU),而梯度式在它的主场(光滑、解析、要精度和约束)至今无可替代。

理论:一张图看清两家的工作方式

把两家的工作方式并排画出来,分野一目了然。两家要解的是同一个最优控制问题:找一段控制序列 \(U = (u_0, \dots, u_{H-1})\),最小化代价 \(J(U) = \sum_t \ell(x_t, u_t) + \ell_f(x_H)\),其中 \(x_{t+1} = f(x_t, u_t)\)。区别全在"怎么找":

梯度式 MPC (iLQR/DDP/SQP):
  当前 U → 沿轨迹线性化动力学(求 ∂f/∂x, ∂f/∂u)
         → 二次化代价(求 ∇ℓ, ∇²ℓ)
         → 解一个局部的 LQR/QP 子问题 → 得到下降方向
         → 沿方向更新 U(带线搜索) → 重复至收敛
  本质: 用「导数信息」精准地走每一步, 二阶收敛, 但要求处处可微

采样式 MPC (MPPI/CEM):
  当前 U → 在 U 周围撒 K 个扰动样本(纯随机, 不看导数)
         → 每个样本 rollout 求代价(只求值, 把 f 和 ℓ 当黑箱)
         → 按代价指数加权/取精英 → 加权平均得到新 U → 重复
  本质: 用「大规模求值 + 加权」近似最优, 全局/概率收敛, 只要求能求值

看这张图,核心差别就是那两个词:梯度式在每一步都**求导**(线性化动力学、二次化代价),用导数信息精准地确定"往哪走、走多远";采样式从不求导,只**求值**(rollout 算代价),用"撒一片、看哪好、往哪靠"的随机搜索逼近最优。这一个差别,像一颗种子,长出了后面所有的维度差异——它决定了对模型可微性的要求(§9.3)、收敛的性质(局部二次 vs 全局概率)、对 GPU 的利用、能否处理硬约束、适合多大维度。记住这颗种子,后面的一切都是它的推论。

深一层:为什么"求导"能让你走得又准又快,但有前提

梯度式之所以在光滑问题上高效,是因为**导数是"局部的精确向导"**。代价函数在当前点的梯度,精确地告诉你"哪个方向下降最快";二阶导(Hessian)进一步告诉你"代价的局部曲率长什么样",让你能像牛顿法一样一步跳到局部最优附近(二阶收敛)。这是采样式比不了的——采样式只能靠"撒样本看哪个低"来猜方向,没有导数那样的精确指引,所以在光滑问题上它"绕远路"(需要很多样本和迭代才能达到梯度式几步就能达到的精度,§9.3 的 demo 会让你亲眼看到)。

但"求导"有个铁打的前提:导数必须存在且有意义。如果代价是一个不连续的 indicator(第 8 章 §8.1 的代价地图、本章 §9.4 的障碍),它的梯度处处为零(平的地方)或在跳变处无定义——求出来的"导数"要么是零(没有任何指引)、要么是错的。如果动力学是一个黑箱仿真器(MuJoCo 接触),你根本求不出 \(\partial f/\partial x\)(接触的不连续让雅可比要么不存在、要么数值上爆炸)。这时候,梯度式那套"用导数精准走每一步"的威力,就**完全失效**了——它的快和准,是建立在"处处可微"这个前提上的,前提一塌,优势归零。

本质洞察:采样式与梯度式的根本分野,是**"只需要求值" vs "需要求导"——而这背后是一个更深的权衡:**梯度式用"对问题更强的假设(处处可微)"换来"在满足假设时的高效率(二阶收敛、高精度)";采样式用"对问题更弱的假设(只需可求值)"换来"普适性(黑箱、不可微都能用),代价是效率较低(要大规模求值)"。 这是工程和科学里反复出现的权衡模式——更强的假设换更高的效率,更弱的假设换更广的适用。没有免费的午餐:你想要梯度式的高效,就得交出"可微"这个前提;你想要采样式的普适,就得接受"撒一片样本"的算力开销。理解这个权衡,你选工具时就有了一把根本的尺子:先看你的问题能满足多强的假设(可微到什么程度),再据此选能利用这些假设的方法——问题越"干净"(光滑、解析、有约束需求),越该用能榨取这些结构的梯度式;问题越"脏"(黑箱、不可微、感知驱动),越该用不挑结构的采样式。这把尺子贯穿全章。

深一层:采样是"零阶"优化、梯度式是"一阶/二阶"——统一在"用几阶导数信息"的谱上

"求值 vs 求导"还能再升一层,得到一个把两家统一起来的优雅视角——它们其实是同一条"优化方法谱"上、用了不同阶导数信息的点

优化方法按"用到代价的几阶导数"分:零阶方法**只用函数值 \(f(x)\)(不用任何导数);**一阶方法**用一阶导(梯度 \(\nabla f\));**二阶方法**用到二阶导(Hessian \(\nabla^2 f\))。对号入座:采样式(MPPI/CEM)是**零阶**方法——它只 rollout 求值、从不碰导数;iLQR 是**一阶/二阶混合(用动力学一阶雅可比 + 代价二阶 Hessian 的高斯-牛顿近似);DDP 是更彻底的**二阶**(连动力学的二阶导都用);SQP 也是一阶/二阶。所以"采样 vs 梯度"的本质,是**"用零阶信息" vs "用一阶/二阶信息"**——用的导数阶数越高,每一步的信息越丰富、收敛越快(二阶的牛顿法比一阶的梯度下降快,§9.2),但对函数光滑性的要求也越高(要算二阶导,函数得二阶可微)。

更妙的是,采样式甚至可以看成在**用零阶信息"估计"梯度**——MPPI 的指数加权平均 \(\sum_k w_k \epsilon_k\),在数学上近似于代价对控制的(带温度的)梯度的一个**零阶估计**(用一堆函数值的加权差分来逼近梯度方向,而不直接求导)。这就是为什么采样式"没有梯度也能往好的方向走"——它在用函数值偷偷地、近似地估计那个方向。

本质洞察:采样式与梯度式不是两个孤立的阵营,而是**"优化方法按使用导数阶数排成的谱"上的不同点**——零阶(采样,只用值)、一阶(梯度下降)、一阶/二阶(iLQR/SQP)、二阶(DDP/牛顿)。沿这条谱,用的导数阶数越高,单步信息越丰富、收敛越快,但对光滑性的要求也越苛刻。这个统一视角的威力在于:它把"采样 vs 梯度"从"两种对立的东西"还原成"一个连续权衡(用多少阶信息)的两端",让你看清它们的亲缘——采样式那个"看似不求导却能找方向"的魔法,本质是"用一堆函数值零阶地估计梯度"。掌握这个谱,你再看任何优化方法(贝叶斯优化、进化策略、拟牛顿法……)都能立刻定位它"用了几阶信息、因此快在哪、挑剔在哪"。这比把方法死记成孤立的名字深刻得多——理解一个领域,往往就是找到那条把所有方法串起来的谱

多视角:两家像"登山"的两种策略

给这条分野配个直觉。把"最小化代价"想象成在一片山地里**找最低点**(谷底)。

梯度式像一个蒙着眼、但能感知脚下坡度的登山者:他看不到全局,但能精确感知"脚下哪个方向最陡峭地向下"(梯度),还能感知"坡度变化的快慢"(曲率/Hessian),于是他每一步都朝最陡下降方向走、且能根据曲率调整步长,下山又快又稳——只要这片山地是**光滑**的(处处有明确的坡度)。但如果地面是"阶梯状"的(不连续代价),他脚下是平的(梯度为零),就不知道往哪走了;如果地面有很多小坑(局部最优),他会掉进离他最近的那个坑出不来(局部收敛)。

采样式像一群从直升机上空降下来、散布在山地各处的探子:他们不感知坡度,只各自报告"我这儿的海拔是多少"(求值),然后队伍朝"海拔低的探子聚集的方向"整体移动(加权平均)。因为探子撒得广,他们不容易被单个小坑困住(全局/概率收敛),而且不管地面是光滑还是阶梯状,"报海拔"这件事总能做(不挑可微性)。代价是:要派很多探子(大规模求值),而且就算到了谷底附近,因为没有精确的坡度指引,他们也只能大致聚到最低点附近、很难精确踩到那个点(精度不如梯度式)。

像的地方:两种策略都在找谷底,准确反映了两家求解同一个优化问题。不像的地方(边界):真实登山者/探子是在二维地面上,而控制问题的"山地"是高维的(\(U\)\(H \times m\) 维),高维下"撒探子"的覆盖会变稀疏(维度灾难,第 7 章讲过),这正是采样式在高维控制上吃力、而梯度式(不靠覆盖、靠导数)反而能上百维的原因(§9.3)。别把这个二维直觉无限套用到高维——它帮你理解"坡度指引 vs 海拔采样"的本质差别,但维度一高,故事会有新的转折。

深一层:为什么"会选"比"会用"更难、也更值钱

本章不教新算法,只教"选择"——这值得正名:"会选工具"是比"会用工具"更高阶、更难、也更值钱的能力,理解这点能让你正确看待本章在整套课程里的分量。

  • "会用"是可教、可练的;"会选"需要判断力:学会用 MPPI(调参、跑通)有明确的步骤,练几次就会。但"面对一个新问题,判断该用 MPPI 还是 iLQR 还是混合"没有机械步骤——它要求你**理解每个工具的适用边界、并把它和问题特性匹配**,这是判断力,不是操作技能。判断力更难获得(要理解"为什么",不只是"怎么做")。
  • "会用"的人多,"会选"的人少:能调通一个算法的人很多(网上有教程、有现成库);能在多个方案间做出有依据的、正确选择的人少。这正是"会选"更值钱的原因——它是稀缺的、难以速成的、体现真正理解的能力。
  • "会选"错了,"会用"白搭:你把 MPPI 用得再溜,若在一个该用梯度式的光滑问题上选了它(§9.3),结果还是事倍功半——选错工具,再精的使用也救不回来。选择在使用之前,且决定使用的上限。
  • "会选"是可迁移的,"会用"是局部的:具体怎么用 MPPI 只在 MPPI 这个工具上有用;而"按问题特性选方法"的判断力(§9.6 方法论、§9.1 那把尺子)能迁移到任何工具选择、任何领域(§可迁移判断力)。可迁移的能力,价值远高于局部的技能。

本质洞察:一套技术教育的最高目标,不是教会学生"使用"尽可能多的工具,而是培养"在工具间做出明智选择"的判断力——"会用"是术,"会选"是道;术可教可练、局部且易得,道需理解需判断、可迁移且稀缺。本章在整套采样 MPC 课程里的特殊地位正在于此:前八章教你"会用"采样 MPC(术),本章教你"会选"(道)——知道它何时该用、何时该让位、何时该混合。这也是为什么本章"不教新算法"却至关重要:它完成了从"工具使用者"到"工具选择者"的关键跃迁。推广到你的整个学习:每学会一个工具,都该追问"它的适用边界在哪、什么时候不该用它、有没有更合适的替代"——把'会用'升级为'会选'。这个追问的习惯,会让你从"会很多工具的人"成长为"知道何时用何工具的人",后者才是真正的专家。专家与新手的差别,往往不在"会用多少工具",而在"选工具的判断力"。

易错点:别把"采样式更通用"误读成"采样式更好"

学到这里有个极常见的认知偏差:因为采样式"假设更弱、更通用"(黑箱、不可微都能用),就觉得它"更先进、更好、应该优先用"。这是错的,而且是本章要反复纠正的核心误区。"更通用"恰恰意味着"更不挑结构",也就意味着"无法利用问题的结构来加速"——当问题确实有好结构(光滑、可微、二次型代价)时,采样式因为不利用这些结构,反而比能利用它们的梯度式慢得多、精度低得多(§9.3 demo:光滑摆起 iLQR 代价 2.22,MPPI 撒 1000 样本还停在 7.11)。这就像"瑞士军刀 vs 专用螺丝刀"——瑞士军刀更通用,但拧一颗特定的螺丝,专用螺丝刀又快又好。通用性是有代价的,代价就是在专门场景下的效率。正确的心态不是"采样式更好",而是"采样式更通用、梯度式在其适用场景下更高效,按问题选"。

⚠️ 常见陷阱

陷阱 1:用有限差分给黑箱模型"造"梯度,然后硬上梯度式方法 ⚠️ 编程陷阱 - 错误做法:手头是个不可微的黑箱动力学(如接触仿真),但你想用 iLQR,于是用有限差分(数值微分)去近似 \(\partial f/\partial x\),强行喂给梯度式方法。 - 现象/后果:在接触/不连续处,有限差分算出的"雅可比"要么巨大(跨越了一个不连续跳变)、要么为零(落在平段里),数值极不稳定;iLQR 据此算出的下降方向是错的,迭代发散或在接触附近剧烈震荡,根本不收敛。 - 根本原因:有限差分只是在"假装"函数可微——它在一个小邻域里算割线斜率。但对真正不连续/不可微的函数,这个邻域里的割线斜率没有意义(不连续处割线斜率随步长趋于无穷或剧烈跳变)。给本质不可微的问题"造"梯度,造出来的是垃圾。 - 正确做法:如果动力学/代价本质不可微(接触、indicator、黑箱),就**用采样式方法**(它本就不需要梯度),而非给梯度式"造"假梯度。判断标准:你的 \(f\)\(\ell\) 是否有不连续/不可微点(接触切换、indicator 跳变)?有就别用梯度式。自检:如果你的有限差分雅可比随步长 \(\epsilon\) 剧烈变化(缩小 \(\epsilon\) 结果大变),说明函数在该点不可微,梯度式不适用。

陷阱 2:以为"采样式不求导"等于"采样式不需要任何问题结构" ⚠️ 概念误区 - 错误想法:"采样式只求值、不挑可微性,那它对问题就毫无要求,什么问题都能很好地解。" - 现象/后果:你把采样式用在一个高维(如 200 维控制)或代价地形极其崎岖的问题上,撒了海量样本还是解不好,困惑"不是说采样式万能吗"。 - 根本原因:采样式确实不要求可微,但它隐含地要求**"在当前解附近撒样本能撒到更好的解"**——这在低维、代价地形不太崎岖时成立,但在高维(样本覆盖指数级稀疏,维度灾难)或代价地形极崎岖(好解藏在采样几乎触不到的窄缝里)时就不成立。采样式不挑可微性,但挑"维度"和"代价地形的可采样性"。 - 正确做法:理解采样式的真实适用边界——它擅长"中低维(个位数到二十维左右)+ 不可微/黑箱",在高维上要靠降维、好的采样分布、warm-start 等技巧(第 5、7 章)才勉强可用,且仍不如梯度式(梯度式靠导数不靠覆盖,能上百维)。自检:你的控制维度(\(H \times m\))有多大?几十维以内采样式还行,上百维就要重新考虑梯度式或重度降维。

陷阱 3:把"两家之争"看成"谁淘汰谁",而非"各有主场" ⚠️ 思维陷阱 - 错误想法:"采样式是新方法、随 GPU 和深度学习兴起,肯定会逐渐淘汰老旧的梯度式 MPC,以后大家都用采样式。" - 现象/后果:你忽视梯度式的学习(觉得"过时了"),结果遇到光滑约束优化问题(四旋翼、机械臂轨迹、过程控制)时没有合适的工具,或者硬用采样式做这些问题、效果远不如同行用的 acados/OCS2。 - 根本原因:把方法的"新旧"等同于"优劣"。但方法的价值由它**适合的问题**决定,不由它的年龄决定。梯度式 MPC 在光滑、可微、要精度和硬约束的问题上至今是最优选择,且这类问题(汽车、航空、机械臂、腿足)大量存在、不会消失。采样式的兴起扩展了 MPC 能处理的问题范围(黑箱、不可微),但没有、也不会淘汰梯度式在其主场的地位。 - 正确做法:把两家看成**互补的、各有主场的工具**,而非竞争淘汰的关系——这正是本章的核心立场,也是 §9.5 混合架构的前提(既然互补,就能组合)。自检:当你想说"X 方法过时了/被淘汰了"时,停一下问"它原来擅长的那类问题消失了吗?"——没消失,它就没被淘汰,只是有了新的搭档。

陷阱 4:在采样式的主循环里"顺手"加梯度信息,破坏了它"不挑可微"的根本优势 ⚠️ 编程陷阱 - 错误做法:你在实现 MPPI 时,看到代价局部可微,"顺手"在更新里加了一项梯度下降("反正有梯度,加上更快"),把采样和梯度耦合进同一个循环、且没做开关。 - 现象/后果:① 这个"采样 + 梯度"的实现一旦遇到不可微的代价(换个任务用了 indicator / 接触),梯度项就崩了(NaN / 发散),而你的代码已假定梯度存在、无法优雅退回纯采样;② 你失去了"纯采样"这个最稳健的退路,调试时也分不清问题来自采样还是梯度项。 - 根本原因:采样式最宝贵的特性就是"只需求值、不挑可微"(§9.1 核心)。在主循环里硬塞梯度、且不留"关掉梯度"的开关,等于**亲手放弃了这个特性**——把一个普适的采样器降级成了"要求可微"的耦合体(这也是 §9.5 第五种隐式混合"该做成可配置选项"的原因)。 - 正确做法:若要融入梯度(如 §9.5 第五种隐式混合),把它做成**可开关的选项**(use_gradient=False 时退回纯采样),并明确它的前提是可微——保住"纯采样"这条普适退路。自检:你的采样实现里如果掺了梯度,关掉它能不能干净地退回纯采样?不能的话,你已经把采样式的普适性弄丢了。

练习

  1. (概念·辨析求值与求导,⭐⭐) 对下面四个"代价函数",分别判断它"能不能求值""能不能求(有意义的)梯度",并据此说它更适合采样式还是梯度式:(a) \(\ell(x) = x^\top Q x\)(二次型);(b) $\ell(x) = $ 一个训练好的 CNN 对图像 \(x\) 的打分;(c) \(\ell(x) = \mathbb{1}[x \in \text{障碍}]\)(indicator);(d) \(\ell(x) = \|x - x_\text{goal}\|^2 + \mathbb{1}[\text{碰撞}]\)(光滑项 + indicator)。最后一个最有意思——它部分可微、部分不可微,你觉得该用哪家?
  2. (思考·假设与效率的权衡,⭐⭐⭐) 本节本质洞察说"更强的假设换更高的效率"。请再举两个本质洞察之外的、机器人或计算机领域里"更强假设换更高效率"的例子(提示:排序算法对数据分布的假设、SLAM 对环境静态性的假设、某些数据结构对数据有序性的假设),说明它们各自"假设了什么、换来了什么效率、假设不成立时怎样"。
  3. (思考·维度的转折,⭐⭐⭐) "登山"多视角里提到,二维直觉在高维会有转折。请论证:(a) 为什么"撒探子"(采样)的策略在高维下覆盖会变稀疏(提示:高维球的体积集中在表面、单位立方体的角落数指数增长);(b) 为什么"感知坡度"(梯度)的策略不受维度灾难影响(梯度是 \(H \times m\) 维向量,算一次就有全部方向信息);(c) 由此解释为什么 §9.3 会说"采样式适合 4–20 维、梯度式能上百维"。
  4. (开放·定位采样 MPC,⭐⭐⭐) 跳出前八章的"采样 MPC 视角",用本节的"求值 vs 求导"分野,画一张"最优控制方法版图":横轴是"问题可微性(从黑箱不可微到光滑解析)",纵轴是"问题维度(从低维到高维)",把 MPPI、CEM、iLQR、DDP、SQP/acados 各放到合适的区域,并说明你这样放的理由。这道题帮你建立对整个版图的结构化认知。

§9.2 梯度式 MPC 速览:iLQR / DDP / SQP 是怎么工作的 ⭐⭐⭐

动机

§9.1 说梯度式 MPC"求导、用导数精准走每一步",但具体怎么个走法?前八章一直没正面讲。要做一场公平的对比,你必须先打开梯度式这个"对手"的盒子——否则"对比"就是拿采样式跟一个黑箱比,空对空。这一节用最少的篇幅讲清三个最常见的梯度式 MPC 方法的工作机制:iLQR(迭代线性二次调节器,机器人轨迹优化的主力)、DDP(微分动态规划,iLQR 的二阶版本)、SQP(序列二次规划,处理硬约束的框架)。讲清它们怎么工作,你才能在 §9.3 之后真正理解"为什么它们在光滑问题上快、为什么它们能处理硬约束、为什么它们要求可微"。

如果不这样做会怎样:对着黑箱谈对比

设想跳过这一节,直接进 §9.3 的维度对比表。你会看到"梯度式收敛性=确定/局部二次""梯度式硬约束=强(QP/NLP)"这些结论,但**不知道它们从何而来**——"局部二次收敛"是因为什么?"用 QP 处理约束"是怎么处理的?没有机制的理解,这些结论就是一堆需要死记的标签,你既记不牢、也不会用。更糟的是,你无法判断一个具体问题"梯度式能不能用、好不好用"——因为你不知道它内部需要什么(雅可比?Hessian?约束怎么进 QP?)。所以这一节是必要的地基:理解了机制,对比表里的每一条结论你都能自己推出来,选型时也能对症下药。

历史:从 DDP 到 iLQR 到 SQP

梯度式轨迹优化有半个多世纪的历史。DDP(Differential Dynamic Programming)**由 Mayne 在 1966 年提出、Jacobson & Mayne 在 1970 年系统化,是一个基于贝尔曼原理的二阶轨迹优化方法——它沿当前轨迹做二阶展开,反向递推求出局部最优的控制修正。DDP 收敛快(二阶),但要算动力学的**二阶导(一个三维张量),又重又容易数值不稳定。

2004 年,Li & Todorov 提出 iLQR(iterative LQR)——把 DDP 里那个又重又烦的动力学二阶项**扔掉**,只保留一阶(这相当于高斯-牛顿近似)。这一扔,让每次迭代只需要动力学的**一阶雅可比** + 代价的二阶导,又轻又稳,且在大多数机器人问题上收敛速度几乎不输 DDP。iLQR 因此成为机器人轨迹优化的事实主力(你在腿足、机械臂、四旋翼的文献里到处能见到它)。

但 iLQR/DDP 有个软肋:它们原生是**无约束**的(或只能处理简单的控制边界)。真实工程里大量问题有**硬约束**——推力上限、关节限位、避障、摩擦锥。处理硬约束的经典框架是 SQP(Sequential Quadratic Programming,序列二次规划):把非线性约束优化问题,在当前点线性化约束、二次化目标,变成一个**带约束的二次规划(QP)子问题**,解这个 QP 得到下降方向,迭代逼近。配上"实时迭代(RTI)"(每个控制周期只解一次 QP)和高效 QP 求解器(如 HPIPM),SQP 催生了 acados 这类嵌入式实时 NMPC 工具,广泛用于汽车、航空、四旋翼(§9.6 案例)。腿足领域的 OCS2(Farshidian 等)则用 SLQ(DDP 的连续时间变体)做实时 MPC。

一句话谱系:DDP(二阶、无约束)→ iLQR(一阶简化、更稳、无约束);SQP(带约束、QP 子问题)→ acados/OCS2(实时化、工程化)

把这三个梯度式方法并排成一张表,它们的分工和取舍就清楚了——注意它们共享"求导"的根基(都要可微),区别在"用几阶导数"和"能否处理硬约束":

方法 用到的导数 硬约束 收敛 代价 / 软肋 代表实现 / 场景
DDP 动力学一阶 + 二阶;代价二阶 原生不支持 二阶(最快) 动力学二阶导(三维张量)重、易数值不稳 经典轨迹优化、研究
iLQR 动力学一阶;代价二阶(高斯-牛顿) 原生不支持(仅简单控制边界) 近二阶(够快) 扔掉二阶项,偶尔比 DDP 多几次迭代 机器人轨迹优化主力(腿足 / 机械臂 / 四旋翼)
SQP 一阶 + 二阶(或拟牛顿近似) 原生支持(QP 子问题里直接加约束) 超线性 / 二阶 每步解一个带约束 QP,比 iLQR 重 acados(四旋翼 / openpilot)、要硬约束的 NMPC
SLQ iLQR 的连续时间变体 经增广拉格朗日 / 松弛障碍 近二阶 连续时间公式、实现复杂 OCS2(腿足 / 移动操作)

读这张表的要点:① iLQR 是 DDP 的"实用化简"——用一点收敛速度换数值稳定和实现简单,所以它成了主力;② SQP 是"带约束的那一支"——它相对 iLQR/DDP 的核心增量,是把硬约束塞进每步的 QP 子问题里原生处理(这正是 §9.3 ⑥"梯度式硬约束强"的来源);③ acados/OCS2 是工程化封装——它们把这些方法 + 实时迭代 + 高效 QP 求解器打包成可部署的工具。所以你在工程里很少"从零写 iLQR",而是用 acados/OCS2/Crocoddyl 这类库——但理解底下是 iLQR/DDP/SQP,你才知道它们要可微、为何快、怎么处理约束。

理论:iLQR 的一次迭代在做什么

iLQR 是理解梯度式 MPC 的最佳入口。它的一次迭代分两趟(pass),像一次"先想清楚怎么改、再去改"的过程:

第一趟·后向(backward pass)——算出"该怎么改控制"。 沿当前轨迹,从末端往回走,在每一步 \(t\): 1. 线性化动力学:算雅可比 \(A_t = \partial f/\partial x\)\(B_t = \partial f/\partial u\)(动力学在当前点附近近似成线性)。 2. 二次化代价:算代价的一阶、二阶导。 3. Riccati 递推:把"从 \(t\) 到末端的最优代价"近似成一个二次型(值函数 \(V\)),反向递推出它的梯度 \(V_x\) 和 Hessian \(V_{xx}\),并由此解出每一步的**控制修正**:一个前馈项 \(k_t\)("这一步该加多少控制")和一个反馈增益 \(K_t\)("如果状态偏了,该怎么纠正")。

第二趟·前向(forward pass)——真去改,并验证改好了。 从初始状态出发,用上一趟算出的 \(k_t, K_t\) 更新控制并 rollout 出新轨迹:\(u_t^\text{new} = \bar u_t + \alpha k_t + K_t (x_t^\text{new} - \bar x_t)\),其中 \(\alpha\) 是**线搜索**步长(从 1 往小试,找一个能真正降低代价的 \(\alpha\),保证每次迭代代价单调下降)。

两趟交替,重复到收敛。下面这个骨架展示 iLQR 一次迭代的结构(后向算增益、前向带线搜索):

def ilqr_iteration(x0, U, X, J, f, jac, cost, Qf, R, H):
    """iLQR 一次迭代: 后向算 (k,K), 前向带线搜索。返回更新后的 (X,U,J)。"""
    # ---- 后向: Riccati 递推 ----
    Vx = 2 * Qf @ X[-1]; Vxx = 2 * Qf          # 末端值函数的梯度/Hessian
    k = [None] * H; K = [None] * H
    for t in range(H - 1, -1, -1):
        A, B = jac(X[t], U[t])                  # 线性化动力学(雅可比)
        Qu  = 2 * R @ U[t] + B.T @ Vx           # Q 函数对 u 的梯度
        Quu = 2 * R + B.T @ Vxx @ B             # 对 u 的 Hessian
        Qux = B.T @ Vxx @ A
        Quu_inv = np.linalg.inv(Quu + 1e-6 * np.eye(Quu.shape[0]))
        k[t] = -Quu_inv @ Qu                    # 前馈修正
        K[t] = -Quu_inv @ Qux                   # 反馈增益
        Vx  = A.T @ Vx + K[t].T @ Quu @ k[t] + K[t].T @ Qu + Qux.T @ k[t]
        Vxx = A.T @ Vxx @ A + K[t].T @ Quu @ K[t] + K[t].T @ Qux + Qux.T @ K[t]
    # ---- 前向: 线搜索, 保证代价下降 ----
    for alpha in [1.0, 0.5, 0.25, 0.1, 0.05]:
        Xn = [x0.copy()]; Un = []
        for t in range(H):
            un = U[t] + alpha * k[t].flatten() + K[t] @ (Xn[-1] - X[t])
            Un.append(un); Xn.append(f(Xn[-1], un))
        Xn = np.array(Xn); Un = np.array(Un); Jn = cost(Xn, Un)
        if Jn < J:                              # 找到能降代价的步长就接受
            return Xn, Un, Jn
    return X, U, J                              # 没找到则保持(已收敛)

注意这一段代码里出现了 jac(求动力学雅可比)和代价的二阶导(QfR)——这就是 §9.1 说的"求导"。梯度式 MPC 的每一次迭代,都要对动力学和代价求导,这是它和采样式最本质的代码层面差别(采样式的主循环里永远不会出现 jac)。

一个能跑的对照:iLQR 把单摆从底部摆到顶部

把 iLQR 跑起来,亲眼看到"求导 + 迭代"的威力。任务:单摆从底部(\(\theta = \pi\))摆到竖直向上(\(\theta = 0\))并稳住,二次型代价。用上面的 iLQR 迭代,配一个数值雅可比(有限差分,稳健避免手推求导出错):

import numpy as np
dt, H = 0.05, 100
g, m, l, b = 9.81, 1.0, 1.0, 0.1
def f(x, u):                                    # 单摆离散动力学(可微)
    th, thd = x[0], x[1]
    thdd = (g/l)*np.sin(th) - b*thd + u[0]/(m*l*l)
    return np.array([th + dt*thd, thd + dt*thdd])
def jac(x, u, eps=1e-5):                         # 数值雅可比 A=∂f/∂x, B=∂f/∂u
    A = np.zeros((2,2)); B = np.zeros((2,1))
    for i in range(2):
        dx = np.zeros(2); dx[i] = eps
        A[:,i] = (f(x+dx,u) - f(x-dx,u)) / (2*eps)
    B[:,0] = (f(x,u+np.array([eps])) - f(x,u-np.array([eps]))) / (2*eps)
    return A, B
R, Qf = np.array([[0.01]]), np.diag([100.0, 10.0])
def rollout(x0, U):
    X=[x0.copy()]; [X.append(f(X[-1],U[t])) for t in range(H)]; return np.array(X)
def cost(X, U): return float(sum(U[t]@R@U[t] for t in range(H)) + X[-1]@Qf@X[-1])

x0 = np.array([np.pi, 0.0]); U = np.zeros((H,1))   # 从底部, 名义控制全 0
X = rollout(x0, U); J = cost(X, U)
for it in range(60):                                # 迭代调用上面的 ilqr_iteration
    X, U, J = ilqr_iteration(x0, U, X, J, f, jac, cost, Qf, R, H)
print(f"iLQR 单摆摆起: 最终代价 {J:.2f}, 末端 θ={X[-1,0]:.3f}rad (目标0), θ̇={X[-1,1]:.3f}")
# 典型输出: 最终代价 2.22, 末端 θ=0.009rad, θ̇=-0.026 —— 离竖直仅 0.5°, 成功摆起并稳定

结果:iLQR 在 60 次迭代内把单摆精确地摆到竖直向上(末端 \(\theta = 0.009\) rad,离竖直仅 \(0.5°\))、且角速度近零(稳住了),最终代价 \(2.22\)注意它的"精确"——末端几乎正好在目标点上,这是梯度式的招牌:靠导数信息,它能把解收敛到局部最优的高精度邻域。§9.3 会让 MPPI 来做同一个任务,你会看到 MPPI 撒上千样本也只能停在"差不多"(代价 7 左右、离竖直几度)——精度差一截。这个精度差别,正是"用导数精准走" vs "用采样大致靠"的直接体现。

一个能跑的对照(二):iLQR vs 朴素梯度下降——二阶/结构化的威力

§9.2 一直说 iLQR"二阶收敛、快"。快到什么程度?和一个**朴素的一阶梯度下降**(直接对整段控制序列 \(U\) 做数值梯度下降,不用 Riccati 那套结构)比一比,差距惊人。同一个光滑单摆摆起任务,两者都从零初值出发:

# 朴素梯度下降: 用数值梯度 ∂J/∂U 直接对整段 U 下降(不利用时序结构)
def grad_descent(iters, lr=0.02):
    U = np.zeros(H)
    for it in range(iters):
        U = U - lr * num_grad(U)        # num_grad: 对每个 u_t 做数值微分
    return U
# iLQR: 用动力学雅可比 + Riccati 后向递推(利用时序结构, §9.2 深一层)
_, hist_gd = grad_descent(200)          # 梯度下降跑 200 次迭代
_, hist_il = ilqr(20)                   # iLQR 只跑 20 次迭代

把每次迭代后的代价打出来对比:

for n in [1, 3, 5, 10, 20]:
    print(f"iLQR 第 {n:2d} 次迭代后代价: {hist_il[n]:.2f}")
print(f"朴素梯度下降 200 次迭代后代价: {hist_gd[-1]:.2f}")
# 典型输出:
#   iLQR 第  1 次迭代后代价: 121.54
#   iLQR 第  3 次迭代后代价:  90.22
#   iLQR 第  5 次迭代后代价:  11.02
#   iLQR 第 10 次迭代后代价:   2.56
#   iLQR 第 20 次迭代后代价:   2.23   ← 20 次就收敛到 2.23
#   朴素梯度下降 200 次迭代后代价:  7.07   ← 200 次还停在 7.07
#   → iLQR 约 6 次迭代即达代价<5; 梯度下降 200 次仍 7.1

差距一目了然:iLQR 约 6 次迭代就达到代价 \(<5\)、20 次收敛到 \(2.23\);朴素梯度下降跑了 200 次迭代还停在 \(7.07\)——iLQR 用约十分之一的迭代数达到了远更低的代价。为什么差这么多?两个原因,都在前面的深一层讲过:其一,iLQR 用**二阶信息**(代价曲率),像牛顿法一样能"一步跳到位",而朴素梯度下降只用一阶梯度、步步试探(§9.1 零阶 / 一阶 / 二阶的谱);其二,更关键的是 iLQR 利用了问题的**时序结构**(Riccati 后向递推一次性解出整条轨迹的反馈律),而朴素梯度下降把整段 \(U\) 当一个无结构的高维向量盲目下降(§9.2 深一层"利用结构")。这个 demo 让你亲手量到"二阶 + 结构化"相对"朴素一阶"的巨大效率差——也让你明白为什么梯度式 MPC 用的是 iLQR/DDP/SQP 这套精巧的方法,而不是简单地"对 \(U\) 求梯度下降"。

(注:这也顺带说明 §9.3 里 MPPI 在光滑问题上的"慢"是相对 iLQR 这种二阶结构化方法而言;若拿 MPPI 和这个朴素梯度下降比,反倒未必输——采样式至少不受"数值梯度噪声"困扰。真正碾压采样式的,是 iLQR 这种**会利用结构**的梯度式,不是朴素梯度下降。)

深一层:iLQR 为什么敢扔掉 DDP 的二阶项

§9.2 历史里说 iLQR 是"扔掉 DDP 二阶项"的简化,这个"扔"值得展开——它体现了一个重要的工程权衡。DDP 在二次化时会算**动力学的二阶导** \(\partial^2 f / \partial x^2\)(一个三维张量,因为 \(f\) 是向量、对向量求两次导)。这一项又大(张量)、又难算(数值不稳定)、还常常对收敛贡献不大。iLQR 的洞察是:对很多机器人问题,动力学的二阶曲率影响远小于代价的二阶曲率,所以把动力学二阶项扔掉(只保留一阶雅可比),用代价的二阶项撑起 Hessian 近似——这相当于把牛顿法换成**高斯-牛顿法**。

代价是:iLQR 的收敛理论上从"二次"降到"超线性"(略慢于 DDP)。但实践中,对绝大多数机器人问题,iLQR 的收敛几乎不输 DDP,却**省掉了算二阶张量的麻烦、数值上还更稳**。这是个典型的"用一点收敛速度,换实现的简洁和数值的稳健"的权衡——而且这笔买卖在机器人领域几乎总是划算,所以 iLQR 比 DDP 用得更广。

本质洞察:iLQR 扔掉 DDP 二阶项,揭示了优化方法设计里一个反复出现的智慧——不是用的导数信息越多越好,而是要在"导数信息的价值"和"算它的代价(计算量、数值稳定性)"之间权衡。二阶信息(Hessian)理论上能让你收敛更快(牛顿法),但算全二阶又贵又可能不稳;高斯-牛顿(只用一阶信息拼出近似 Hessian)放弃了一点理论收敛速度,换来实现简洁和数值稳健,在实践中往往是更优的工程选择。这个"高斯-牛顿优于全牛顿"的权衡,不只在 iLQR,在 SLAM 的捆绑调整、神经网络的二阶优化器里都反复出现。它给你一个一般性的判断:面对"要不要用更高阶的导数信息"时,别想当然地认为越高阶越好——要算上获取它的代价,很多时候一阶信息的巧妙利用(高斯-牛顿)就够了,还更稳。 这和 §9.1 的"假设-效率权衡"是一脉相承的:信息的利用也有"边际收益递减"和"获取成本"的权衡。

深一层:SQP 怎么处理硬约束——采样式做不好的事

iLQR/DDP 原生无约束,但真实问题常有硬约束(推力上限、避障、摩擦锥)。SQP 处理硬约束的方式,恰恰是采样式的软肋所在,值得展开。SQP 的核心思路:把"带非线性约束的非线性优化"在当前点**局部近似成一个带约束的二次规划(QP)**——目标函数二次化、约束函数线性化,然后用成熟的 QP 求解器(active-set 或 interior-point,如 HPIPM、qpOASES)**精确地**解这个带约束的 QP,得到一个**严格满足线性化约束**的下降方向,迭代逼近。

关键在于"精确地解带约束 QP"——QP 求解器能保证解出的方向严格满足(线性化的)约束(如 \(u \le u_\max\) 被当作 QP 的硬约束,解一定满足)。这让 SQP/NMPC 能给出**硬约束保证**:推力不会超限、关节不会越界(在模型准确的前提下)。

对比采样式:MPPI/CEM 处理约束只能**软化成高惩罚项**(撞障碍就代价很高),它无法"硬性禁止"——采样时总有非零概率采到违反约束的样本,加权后的结果也只是"倾向于"满足约束、不保证一定满足(第 8 章 §8.7 陷阱 3 讲过)。这是采样式的固有局限:它的机制(撒样本 + 加权平均)里没有"硬约束"这个概念的位置,约束对它而言只能是代价的一部分。

本质洞察:硬约束处理能力,是梯度式(尤其 SQP/NMPC)相对采样式的一个**结构性优势**——根源在于梯度式可以把约束交给 QP 求解器**精确满足**,而采样式只能把约束软化成代价、"倾向"满足。这个差别在安全关键场景(航空、自动驾驶的物理限制、机械臂的关节限位)极其重要:当你需要"绝对不能违反"的保证时,"倾向满足"是不够的。这也解释了为什么 §9.5 会有"MPPI + CBF"这种混合架构——用采样式出性能、用一个能给硬约束保证的机制(CBF 投影,本质是个小 QP)兜底安全,正是为了弥补采样式"没有硬约束位置"的固有缺陷。理解这点,你在安全关键问题上就会本能地警惕"纯采样式",转而考虑梯度式或"采样式 + 硬约束兜底"的混合。

深一层:iLQR 的后向递推到底在算什么——值函数与 Riccati

§9.2 的理论讲了 iLQR"线性化-二次化-后向-前向"的流程,但那个"后向递推"具体在算什么,值得再深一层——它算的是**值函数(value function)**,而这正是 iLQR 高效的数学核心。

回忆动态规划:最优控制的核心量是**值函数** \(V_t(x)\)——"从时刻 \(t\) 的状态 \(x\) 出发、之后都最优地控制,能达到的最小代价"。如果知道了每个时刻的 \(V_t\),最优控制就是"每步选让 \(\ell(x,u)+V_{t+1}(f(x,u))\) 最小的 \(u\)"。难点是 \(V_t\) 一般没有解析形式。iLQR 的招数是:在当前轨迹附近,把 \(V_t\) 近似成二次型 \(V_t(x)\approx \frac12 x^\top V_{xx} x + V_x^\top x + \text{const}\),用一对量 \((V_x, V_{xx})\)(值函数的一阶、二阶导)刻画。后向递推就是从终端 \(V_H\)(终端代价的导数)出发,一步步往前递推每个 \((V_x, V_{xx})\)——每一步把"线性化的动力学 + 二次化的代价 + 后一步的 \(V\)"组合成一个局部二次的 \(Q\) 函数,对 \(u\) 求极小,得到这一步的反馈增益 \((k, K)\) 和更新后的 \((V_x, V_{xx})\)。这个"\((V_{xx})\) 沿时间后向递推"的方程,正是经典的 Riccati 方程(LQR 里那个)的迭代版本。

所以 iLQR 的后向递推 = 在当前轨迹附近,用 Riccati 递推近似地解动态规划的值函数,从而一次性得到整条轨迹上每一步的最优反馈增益。它的高效正源于此——动态规划的"后向递推"让它一次后向 + 一次前向(\(O(H)\))就更新整条轨迹,而不必像朴素方法那样一个个时间步地试。

本质洞察:iLQR 的威力,根植于**动态规划 + 二次近似**——它在当前轨迹附近把值函数近似成二次型,用 Riccati 后向递推一次性解出整条轨迹的最优反馈律。这解释了梯度式 MPC"为什么不只是'对 \(U\) 做梯度下降'、而是快得多":它不是在 \(H\times m\) 维的控制空间里盲目下降,而是**利用了问题的时序结构(动态规划的后向递推),把一个高维优化分解成 \(H\) 个耦合的小问题逐步求解。这正是 §9.3 ⑧"梯度式能上高维"的更深原因——它不仅用导数,还用**时序结构(Riccati 递推)把高维问题结构化地拆开。而采样式不利用这个时序结构(它把整条 \(U\) 当一个向量盲撒),这是它在长时域 / 高维上吃力的又一层原因。理解"利用问题结构"是高效优化的关键——无论是空间结构、时序结构还是稀疏结构,能利用结构的方法总能碾压不利用的——这是贯穿优化乃至整个计算科学的主题。

深一层:把 iLQR 做稳的两个关键——正则化与线搜索

iLQR 的理论流程听起来干净,但**直接照搬往往不收敛、甚至发散**——让它真正稳定工作,靠两个工程上不可或缺的技巧:正则化和线搜索。理解它们,才算真懂 iLQR 为什么"理论简单、实现有坑"。

正则化(regularization):后向递推里要对 \(Q_{uu}\)(局部二次模型在控制上的 Hessian)求逆来算增益。但 \(Q_{uu}\) 可能**不正定**(非凸问题、或线性化误差大时),求逆会得到一个"上坡"方向或数值爆炸。解法是给它加一个正则项 \(Q_{uu}+\mu I\)\(\mu>0\)),把它"掰正定"——这本质是在"牛顿步(信赖局部二次模型)"和"梯度步(保守、只信一阶)"之间插值:\(\mu\) 小则接近牛顿步(激进、收敛快但可能不稳),\(\mu\) 大则接近梯度步(保守、稳但慢)。这正是 Levenberg-Marquardt 的思想。实现里 \(\mu\) 自适应调整:迭代成功就减小 \(\mu\)(更激进),失败就增大 \(\mu\)(更保守)——本章 demo 的 iLQR 正是这么做的(mu 在成功 / 失败时升降)。

线搜索(line search):算出下降方向(增益 \(k, K\))后,不能直接"走一整步"——因为局部二次模型只在小邻域内准,走太远可能反而让代价上升。线搜索是:沿这个方向试探不同的步长 \(\alpha\in\{1, 0.5, 0.25, \dots\}\),找一个**确实让总代价下降**的 \(\alpha\) 才接受(本章 demo 的 iLQR 前向阶段正是遍历 [1,0.5,0.25,...] 找下降的)。它保证每次迭代"只走能改进的那么远",是 iLQR 稳定收敛的安全带。

本质洞察:iLQR(乃至几乎所有二阶 / 牛顿型优化)"理论干净、实现有坑",坑就在于**局部二次模型只在小邻域内可信**——正则化(掰正 Hessian、在牛顿步与梯度步间插值)和线搜索(限制步长到模型可信的范围)这两个技巧,本质都是在**管理"对局部模型的信任程度":模型可信就大胆走(小正则、大步长),不可信就保守走(大正则、小步长)。这揭示了一个关于"基于模型的优化"的普遍真理——**任何用局部近似模型指导大步前进的方法,都必须配一套"信任管理"机制,否则会被模型在远处的失真带偏。这也反衬出采样式的一个"朴素的稳健":它不依赖任何局部模型(只求值),所以没有"模型失真"的问题,不需要正则化 / 线搜索这套——代价是它也享受不到二阶模型的快速收敛(§9.1 零阶 vs 二阶的谱)。"用模型换速度、但要管理模型的可信范围" vs "不用模型换稳健、但放弃速度",又是 §9.1 那个核心权衡的一次回响。

深一层:梯度式对"代价的条件数"敏感——病态代价会拖垮收敛

§9.2 说梯度式"二阶收敛、快",但这有个隐含前提常被忽略:代价的"条件数"要好。条件数差(病态代价)会让梯度式的快速收敛大打折扣,理解这点能解释一些"梯度式明明该快却慢"的困惑。

  • 什么是条件数:代价的 Hessian(二阶导矩阵)的最大特征值 / 最小特征值之比,叫条件数。直觉上它衡量代价"碗"的形状——条件数接近 1 是个圆碗(各方向曲率相近),条件数很大是个又长又窄的"山谷"(一个方向陡、另一个方向极平)。
  • 病态代价怎么拖垮梯度式:在又长又窄的山谷里,梯度式(即便是二阶的 iLQR)也会走得艰难——沿陡方向容易过冲、沿平方向进展极慢,迭代在山谷里来回折返。虽然 iLQR 的二阶信息能部分缓解(它用曲率校正方向),但当 Hessian 病态(接近奇异)时,求逆数值不稳,正则化(§9.2 深一层)又会把它拉回慢的梯度步。结果:理论上的二阶快速收敛,在病态代价上退化成缓慢挣扎。
  • 常见的病态来源:代价里不同项的权重量级差异巨大(如位置项权重 1、速度项权重 10000),会让 Hessian 各方向曲率天差地别(病态);或状态 / 控制的物理量纲差异大(米 vs 弧度 vs 牛顿)未做归一化。
  • 对比采样式:采样式对条件数**不那么敏感**——它不依赖 Hessian(不求逆),靠撒样本探索,病态山谷只是让它的采样效率略降,不会像梯度式那样数值不稳。这是采样式"朴素稳健"的又一面(§9.2 正则化深一层)。
  • 正确做法:用梯度式时,注意代价的条件数——给不同项的权重做合理的量级平衡、对状态 / 控制做量纲归一化(scaling),让 Hessian 接近良态。这往往比调其他东西更能改善梯度式的收敛。

本质洞察:梯度式的"二阶快速收敛"有一个常被忽略的前提——代价要良态(well-conditioned);病态代价(曲率各向极不均、Hessian 接近奇异)会让二阶方法退化成缓慢挣扎,因为它的"用曲率校正方向"在病态时失效或数值不稳。这揭示了"基于二阶信息的方法"的一个普遍脆弱性:它们的威力建立在'曲率信息可靠'之上,而病态 / 奇异的曲率会摧毁这个基础(这也是为什么数值优化里"预条件 / 缩放"如此重要)。对比之下,不用曲率的采样式对病态更宽容——这又是 §9.1 核心权衡的一个面相:梯度式用"更强的假设(可靠的二阶曲率)"换效率,病态代价正是这个假设被削弱的情形,于是它的效率优势缩水。实践启示:用梯度式前,先把代价调良态(权重量级平衡、量纲归一化)——这是发挥它二阶威力的前提,也是一个比"调求解器参数"更根本、却常被新手忽略的步骤。

多视角:iLQR 像"把弯路反复捋直"

给 iLQR 配个直觉。把当前的控制轨迹想象成一条**弯弯曲曲、不太好的路线**,目标是把它捋成"代价最低"的好路线。iLQR 的一次迭代像这样捋:先**站在当前路线上,逐段看清局部地形**(线性化动力学、二次化代价——搞清楚"这一段如果微调,代价会怎么变"),然后**从终点往回,算出每一段该怎么微调才能让整体代价下降**(后向 Riccati,得到前馈 + 反馈的修正),最后**真的按这个微调走一遍、看是否真的更好**(前向线搜索,代价没降就把步子迈小点)。一次捋直一点,反复捋,路线越来越接近最优。

像的地方:iLQR 是迭代地、局部地改进一条轨迹,"逐段看清局部、算出修正、谨慎应用"准确反映了线性化-二次化-Riccati-线搜索这套流程。不像的地方(边界):真实"捋路"你能看到全局,而 iLQR 每次只看**当前轨迹附近的局部**(线性化只在当前点附近准),所以它只能保证捋到**离当前路线最近的那条好路线**(局部最优)——如果有另一条完全不同、但更好的路线(另一个 basin),iLQR 自己跳不过去(这正是 §9.5 要用 MPPI 帮它找 basin 的原因)。别把"捋路"想象成"能看到所有路线挑最好"——iLQR 只会把你给它的那条路线局部捋到最优,给的路线在哪个 basin,它就捋到哪个 basin 的底。

深一层:单重打靶 vs 多重打靶——梯度式 MPC 的两种问题构造

讲 iLQR 时我们默认了一种问题构造:给定初始状态、只优化控制序列 \(U\)(状态由 \(U\) 前向 rollout 决定)。这叫**单重打靶(single shooting)。但梯度式 MPC 还有另一种更常用于带约束 NMPC(acados/OCS2)的构造——**多重打靶(multiple shooting),区别值得了解,它影响着工业实现的稳定性。

  • 单重打靶(iLQR 的默认):决策变量只有控制 \(U\);状态 \(X\)\(U\) 的函数(一路 rollout 出来)。优点:变量少、结构简单。缺点:长时域时数值敏感——初值的微小控制误差经过长 rollout 会指数放大(像把整条轨迹"串"在一根绳上,一端动全身动),导致优化对长时域不稳定。
  • 多重打靶:把状态 \(X\) 也作为决策变量,同时优化 \(U\)\(X\),再用"连续性约束" \(x_{t+1}=f(x_t,u_t)\) 把它们绑定(作为优化的等式约束)。优点:把一根长绳"切成多段",每段的敏感度独立、数值更稳,长时域表现好得多;且天然适合加约束(acados/OCS2 用它)。缺点:变量多(状态也成了变量)、要处理连续性约束(所以常配 SQP / 内点法解带约束 QP,这正是 §9.2 SQP / HPIPM 的用武之地)。
  • 联系采样式:采样式天然是"单重打靶"式的(撒控制、rollout 出状态)——它没有"多重打靶"那种把状态也作为变量、加连续性约束的构造,因为它不解约束优化(§9.3 ⑥)。所以"多重打靶 + 约束"是梯度式(尤其 SQP/acados)独有的、应对长时域和硬约束的利器。

本质洞察:单重 vs 多重打靶,是梯度式 MPC 在"变量怎么设、约束怎么加"上的一个核心设计选择——多重打靶用"更多变量 + 连续性约束"换取长时域的数值稳定性和原生加约束的能力。这解释了为什么工业级带约束 NMPC(acados/OCS2)几乎都用多重打靶 + SQP,而教学 / 短时域的 iLQR 用单重打靶就够。它也再次显示梯度式那一支的"丰富性"——它有一整套关于"问题怎么构造、约束怎么处理、数值怎么稳定"的工程积累(单/多重打靶、SQP、HPIPM、RTI、正则化、线搜索……),这是半个世纪沉淀的结果。采样式相比之下"构造单一"(就是撒控制 rollout),简单是它的优点也是它的局限。理解这点,你对"梯度式 MPC 不只是 iLQR 一个算法,而是一个有深厚工程体系的家族"会有更立体的认识——这也是为什么工业界在它的主场如此依赖它。

易错点:数值雅可比能用,但要警惕它的步长敏感与不可微陷阱

上面 demo 用了数值雅可比(有限差分)求 \(A, B\),这在动力学**光滑**时是个方便又稳健的做法(避免手推求导出错,第 7 章也提过自动微分/数值微分的便利)。但要警惕两点。其一,步长 \(\epsilon\) 要选得当:太大则差分不准(割线偏离切线),太小则浮点误差主导(两个相近的数相减损失精度)。一般取 \(\epsilon \sim 10^{-5}\)\(10^{-6}\)(如 demo 里 \(10^{-5}\)),且最好用**中心差分**(\((f(x+\epsilon) - f(x-\epsilon))/2\epsilon\),比单边差分精度高一阶)。其二,也是更致命的——数值雅可比会"假装"不可微函数可微(§9.1 陷阱 1):如果你的动力学有接触/不连续,有限差分照样会给你算出一个"雅可比",但那是垃圾(跨越不连续的割线斜率)。所以数值雅可比是"光滑动力学的便利工具",不是"把不可微问题变可微的魔法"——用它前,先确认你的动力学确实光滑。

⚠️ 常见陷阱

陷阱 1:iLQR 后向递推时不给 Quu 加正则,遇到非凸就崩 ⚠️ 编程陷阱 - 错误做法:后向递推里直接 Quu_inv = inv(Quu),不加正则项。 - 现象/后果:在代价非凸的区域,\(Q_{uu}\) 可能不正定(有负特征值或接近奇异),求逆得到的"下降方向"实际是上升方向或巨大的乱跳,iLQR 迭代发散或剧烈震荡。 - 根本原因:iLQR 的下降方向 \(k = -Q_{uu}^{-1} Q_u\) 只有在 \(Q_{uu}\) 正定时才是真正的下降方向。在非凸区域 \(Q_{uu}\) 可能非正定,求逆没有意义。这是牛顿类方法在非凸问题上的通病。 - 正确做法:给 \(Q_{uu}\) 加**正则**(如 demo 里 Quu + 1e-6*I,或更讲究的 Levenberg-Marquardt 式自适应正则——非凸时加大正则,退化为更保守的梯度下降方向)。自检:如果 iLQR 在某些初值下发散,先检查是否对 \(Q_{uu}\) 做了正则;打印 \(Q_{uu}\) 的特征值,若有负的或极小的,说明需要更强正则。

陷阱 2:以为 iLQR/DDP 能直接处理硬约束 ⚠️ 概念误区 - 错误想法:"iLQR 是优化方法,那我把'推力不超限''不撞障碍'这些硬约束直接加进去,它就会满足。" - 现象/后果:你发现标准 iLQR 根本没有"加硬约束"的接口——它的后向递推(无约束 LQR 子问题)里没有约束的位置;硬塞约束要么被忽略,要么需要大改算法。 - 根本原因:iLQR/DDP 原生是**无约束**轨迹优化(基于无约束 LQR 子问题)。硬约束需要的是**带约束的子问题**(QP),那是 SQP 的范畴,不是 iLQR 的。iLQR 最多能处理简单的控制边界(通过 box-QP 变体或控制 clip),处理一般的状态/非线性约束要上 SQP 或约束 DDP(如 AL-iLQR 用增广拉格朗日)。 - 正确做法:要硬约束,用 SQP/NMPC(acados 这类)或带约束的 iLQR 变体(增广拉格朗日 iLQR、box-DDP)。别指望标准 iLQR 处理硬约束。自检:你的问题有没有除"控制上下界"之外的硬约束(状态约束、避障、非线性约束)?有就别用裸 iLQR,用 SQP 或约束 DDP。

陷阱 3:把"梯度式收敛快"绝对化,忽视它对初值和光滑性的依赖 ⚠️ 思维陷阱 - 错误想法:"梯度式是二阶收敛、比采样式快,所以任何问题上梯度式都更快更好。" - 现象/后果:你在一个强非凸问题(多局部最优)上用 iLQR,它快速收敛到一个**糟糕的局部最优**(离初值最近的那个 basin 的底),你以为"收敛了就是最优了",实际上错过了好得多的全局最优(§9.5 双势阱 demo:iLQR 从某初值出发只到局部阱)。 - 根本原因:梯度式的"收敛快"是**局部**性质——它快速收敛到**离初值最近的局部最优**,但不保证那是全局最优。它的快和准都建立在"光滑 + 初值在好 basin 附近"的前提上。前提不满足(非凸 + 坏初值),它就快速地收敛到一个坏解。 - 正确做法:理解梯度式的"快"是"局部快",不等于"找到全局最优"。强非凸问题要么多初值重启(multi-start)、要么用全局方法(如 MPPI)找好 basin 再让梯度式精炼(§9.5 混合架构)。自检:你的问题是凸的还是非凸的(多局部最优)?非凸时,别只信 iLQR 一次收敛的结果——换几个初值看它是否收敛到不同的解,若是,说明有多个局部最优,需要全局搜索辅助。

练习

  1. (复现·iLQR 摆起,⭐⭐⭐) 把本节 iLQR 单摆 demo 敲一遍跑通,复现"摆到离竖直 0.5°、代价 2.22"。然后实验:(a) 把代价权重 Qf 调小(如 diag([10,1])),末端精度会怎样(提示:终端惩罚弱了,摆得没那么准);(b) 把迭代次数从 60 减到 10,看是否还能摆起、代价是多少(体会 iLQR 的收敛速度);(c) 把数值雅可比的步长 eps 改成 1e-21e-9,看对结果的影响(体会易错点讲的步长敏感)。
  2. (动手·iLQR vs 梯度下降,⭐⭐⭐) 在同一个单摆摆起问题上,实现一个**朴素的梯度下降**(用数值梯度 \(\partial J/\partial U\) 直接对整段 \(U\) 做梯度下降,不用 Riccati 那套),对比它和 iLQR 的收敛速度(迭代次数、最终代价)。你应该看到 iLQR 快得多——这道题让你亲手体会"二阶/结构化信息(Riccati)比朴素一阶梯度强在哪"。
  3. (思考·iLQR 与 LQR 的关系,⭐⭐⭐) LQR(线性二次调节器)解的是"线性动力学 + 二次代价"的最优控制,有闭式解。iLQR 名字里就有 LQR。请论证:(a) 为什么 iLQR 的每一次后向递推,本质是在解一个 LQR 子问题(线性化的动力学 + 二次化的代价);(b) 如果动力学本来就是线性的、代价本来就是二次的,iLQR 需要迭代吗,为什么(提示:一次就收敛,因为线性化是精确的);(c) 由此说明 iLQR 是"把非线性问题反复用 LQR 局部近似来解"。
  4. (思考·硬约束的代价,⭐⭐⭐⭐) 本节说"硬约束是梯度式(SQP)相对采样式的结构性优势"。请综合论证:(a) 为什么采样式的机制里"没有硬约束的位置"(从采样 + 加权的数学形式说);(b) 把硬约束软化成高惩罚项,会带来什么问题(提示:惩罚权重难调、仍可能违反、代价地形变陡影响采样);(c) 在什么样的应用里,"硬约束保证"是不可妥协的(必须用梯度式或加硬约束兜底),举两个具体例子并说明后果。
  5. (辨析·三种梯度式方法,⭐⭐⭐) 用本节 iLQR/DDP/SQP 对比表回答:(a) iLQR 相对 DDP"扔掉了什么、换来了什么",为什么它反而成了主力;(b) SQP 相对 iLQR/DDP 的核心增量是什么,它如何"原生"处理硬约束;(c) 给三个问题各选一个最合适的(无约束短时域轨迹优化 / 要硬约束的嵌入式 NMPC / 要极致收敛速度且能承受二阶导成本),并说明理由。
  6. (复现 + 探究·正则化与条件数,⭐⭐⭐⭐) 跑通本节 iLQR 单摆 demo。然后:(a) 把代价权重改得"病态"(如 Qf=diag([100000,0.001]),两维量级差极大),看 iLQR 收敛是否变慢 / 不稳,体会 §9.2 深一层"病态代价拖垮梯度式";(b) 试着关掉前向的线搜索(永远用 \(\alpha=1\)),看是否更容易发散,体会线搜索作为"安全带"的作用;(c) 把这两个观察和"梯度式理论简单、实现有坑"联系起来,写一段"让 iLQR 稳定工作需要注意什么"。

§9.3 九个维度的系统对比——以及光滑问题上梯度式的胜场 ⭐⭐⭐

动机

§9.1 给了你那颗种子(求值 vs 求导),§9.2 让你看清了梯度式那一家的机制。现在可以把两家放到一张表里,沿**九个维度**逐一对比——这九个维度不是随意罗列,它们全都是那颗种子的推论:因为"求导 vs 求值",所以对模型可微性的要求不同、对 GPU 的利用不同、收敛性质不同、能处理的约束不同、能上的维度不同……把这九个维度过一遍,你就有了一张"遇到具体问题该看哪些指标"的检查表。这一节还要兑现 §9.1 埋下的一个承诺:在一个**光滑、可微**的问题上,亲眼看看梯度式如何把采样式甩在身后——破除"采样式更先进所以更好"的迷思。

如果不这样做会怎样:对着"感觉"选求解器

设想你跳过这套维度对比,凭"感觉"选求解器。你会陷入两类典型困境。其一,只会一把锤子:你习惯了 MPPI,遇到任何问题都撒样本——碰到光滑的四旋翼轨迹优化(本该 acados 几毫秒解决),你撒上万样本还达不到精度、还吃满 GPU,却不知道问题出在"你没利用问题的光滑可微结构"。其二,被单一维度误导:你听说"梯度式能上百维",于是给一个代价来自 CNN 的视觉伺服问题硬上 iLQR——结果卡在"CNN 不可微"上寸步难行,因为你只看了"维度"这一个维度,忽略了"可微性"这个对你的问题更致命的维度。选求解器是个多维度的权衡,任何单一维度的直觉都可能把你带沟里——你需要的是一张把所有关键维度摆出来、让你逐一对照自己问题的表。这一节就给你这张表。

历史与理论:九个维度逐一对比

下面这张表是全章的"主对比表",把采样式(MPPI/CEM 家族)和梯度式(iLQR/DDP/SQP 家族)沿九个维度并排。先看表,再逐维解释:

维度 MPPI / 采样式 iLQR / DDP / SQP 梯度式
① 梯度需求 零(只需 rollout 求值) 一阶 + 二阶(\(\partial f\), \(\nabla\ell\), \(\nabla^2\ell\)
② 代价函数 任意(不连续 / CNN / 黑箱皆可) 需平滑可微(至少一阶,DDP 要二阶)
③ 动力学 黑箱 / 仿真器 / 神经网络皆可 需可微 / 解析(或可靠的雅可比)
④ GPU 利用 极高(K 条 rollout 天然并行) 低(迭代串行、矩阵分解为主)
⑤ 收敛性 概率 / 偏全局(撒得广) 确定 / 局部二次(快但局部)
⑥ 硬约束 弱(软化成惩罚 / 投影 / barrier) 强(QP / NLP 原生处理)
⑦ CPU-only 可行性 K 受限,勉强 优势场景(少量矩阵运算)
⑧ 适用维度 4–20 维控制(受维度灾难限制) 4–200 维控制(靠导数不靠覆盖)
⑨ 杀手场景 不连续 cost + 黑箱 sim 光滑约束优化 + CPU 平台

① 梯度需求——这是种子本身。采样式只需 rollout 求值,零梯度;梯度式需要动力学的雅可比 \(\partial f/\partial x, \partial f/\partial u\)、代价的梯度 \(\nabla\ell\) 和(DDP)Hessian \(\nabla^2\ell\)。这一维度直接决定了后面 ② ③(对代价和动力学的可微性要求)。

② 代价函数 & ③ 动力学——是 ① 的直接推论。因为梯度式要求导,它要求代价和动力学都**可微**(§9.2、§9.4 详述);采样式只求值,所以代价可以是不连续的 indicator、CNN 的打分、任意黑箱(第 8 章 §8.1),动力学可以是不可微的物理仿真器(MuJoCo 接触,第 7 章)、神经网络(第 6 章)。这是采样式最大的"普适性红利",也是它在腿足(接触不可微)和导航(感知代价不可微)成为主场的根本原因。

④ GPU 利用——也是 ① 的推论。采样式的 \(K\) 条 rollout 互相独立、天然数据并行,GPU 利用率极高(第 7 章 AutoRally、第 8 章),撒越多样本越能喂饱 GPU。梯度式以"沿轨迹的串行递推(Riccati 后向、QP 求解)+ 矩阵分解"为主,并行度低、更吃单核性能,所以它在 GPU 上反而占不到便宜(⑦ 它在 CPU 上是优势)。

⑤ 收敛性——梯度式是**确定 + 局部二次**:给定初值,它沿导数确定性地收敛,且在局部最优附近以二次速率快速逼近(§9.2 iLQR 摆起 0.5°);但只收敛到**离初值最近的局部最优**(§9.5 双势阱 demo)。采样式是**概率 + 偏全局**:因为撒得广,它更不容易被单个局部最优困住(§9.7 CartPole demo:采样式摆起、iLQR 卡底部),但每次结果有随机性、且精度受样本数限制。一句话:梯度式快而局部,采样式慢而偏全局。

⑥ 硬约束——这是梯度式相对采样式的**结构性优势**(§9.2 深一层、§9.4 详述)。梯度式(尤其 SQP)能把硬约束(如 \(u\le u_\max\)、避障、状态边界)作为 QP/NLP 的约束**原生处理**,保证解严格满足;采样式没有"硬约束的位置",只能把约束软化成高惩罚项(违反就代价高)或事后投影——是"倾向满足"而非"保证满足"。当你需要"绝对不能违反"的保证时(如机械臂关节限位、飞行器推力上限),这是梯度式不可替代的地方(也是 §9.5"MPPI + CBF"混合架构要补的)。

⑦ CPU-only 可行性——④ 的反面。梯度式以少量矩阵运算为主,在普通 CPU(甚至嵌入式 MCU)上就能实时跑(§9.6 acados 用于车载/嵌入式);采样式要撒大量样本,CPU 上 \(K\) 受算力限制(虽然 Nav2 证明了 CPU 上几十赫兹可行,第 8 章 §8.3,但 \(K\) 远小于 GPU 上的规模)。所以在**无 GPU 的嵌入式平台 + 光滑可微问题**上,梯度式往往是更自然的选择。

⑧ 适用维度——⑤ 和采样本质的推论。采样式靠"在解附近撒样本撒到更好的解",高维下样本覆盖指数级稀疏(维度灾难,第 7 章),所以擅长**中低维**(个位数到二十维左右的控制);梯度式靠导数(一个 \(H\times m\) 维梯度一次就含全部方向信息,不靠覆盖),能上到**几十甚至上百维**(全身腿足、大规模轨迹优化)。这是 §9.1 登山多视角里"高维的转折"的具体兑现。

⑨ 杀手场景——前八个维度的总结。采样式的杀手场景是"不连续 / 黑箱代价 + 不可微仿真器"(导航的 CNN 代价地图、腿足的接触仿真)——这里梯度式无能为力,采样式是唯一选择(§9.4)。梯度式的杀手场景是"光滑约束优化 + CPU 平台"(四旋翼、机械臂、过程控制)——这里采样式又慢又不保证约束,梯度式又快又精确又能管约束。认清你的问题落在谁的杀手场景里,选择就清楚了。

记住:这九个维度不是九个独立的考量,它们全是 ① 那颗种子(求值 vs 求导)的推论,彼此环环相扣。理解了种子,这张表你不用背——每一行都能从"因为求值/求导,所以……"推出来。

一个能跑的对照:光滑单摆上,iLQR 把 MPPI 甩在身后

§9.1 反复说"采样式更通用不等于更好",§9.3 表里 ⑤⑧ 也说梯度式在光滑问题上又快又准。光说不够,跑个 demo 亲眼看。任务:单摆摆起(从底部 \(\theta=\pi\) 到顶部),但这次是一个**对梯度式最友好**的设置——动力学解析可微、代价是光滑的二次型。让 iLQR 和 MPPI 同台竞技。先看动力学与代价(光滑、可微):

import numpy as np, time
rng = np.random.default_rng(0)
dt, H = 0.05, 100
g, m, l, b = 9.81, 1.0, 1.0, 0.1     # 单摆: 重力/质量/杆长/阻尼

def f(x, u):                          # 单摆动力学(解析、可微)
    th, thd = x[0], x[1]
    thdd = (g/l)*np.sin(th) - b*thd + u[0]/(m*l*l)
    return np.array([th + dt*thd, thd + dt*thdd])
def f_batch(X, U):                    # 批量版(给 MPPI 用)
    th, thd = X[:,0], X[:,1]
    thdd = (g/l)*np.sin(th) - b*thd + U[:,0]/(m*l*l)
    return np.stack([th+dt*thd, thd+dt*thdd], 1)

R, Qf = np.array([[0.01]]), np.diag([100.0, 10.0])   # 光滑二次型代价
def cost(X, U):
    return float(sum(U[t]@R@U[t] for t in range(H)) + X[-1]@Qf@X[-1])

iLQR 用解析可微动力学的雅可比(这里用有限差分近似,真实实现可用解析/autodiff 更快)做后向递推;MPPI 还是撒样本加权。两者跑同一个光滑摆起任务(核心循环略,与 §9.2 / 前几章一致),对比最终代价和耗时:

x0 = np.array([np.pi, 0.0])           # 从底部出发
Ji, ti = ilqr(x0)                     # iLQR: 梯度式
Jm, tm = mppi(x0, K=1000, iters=60)   # MPPI: 撒 1000 样本/迭代, 60 轮
print(f"iLQR(梯度式): 代价 {Ji:.2f}, 耗时 {ti*1000:.0f} ms")
print(f"MPPI(采样式): 代价 {Jm:.2f}, 耗时 {tm*1000:.0f} ms")
# 典型输出:
#   iLQR(梯度式): 代价  2.22, 耗时 453 ms
#   MPPI(采样式): 代价  7.11, 耗时 328 ms
#   → 光滑问题上 iLQR 代价更低(精度高得多), MPPI 撒上千样本仍停在"差不多"

结果印证了 §9.1 反复强调的:在光滑、可微的问题上,梯度式赢得明明白白。iLQR 最终代价 \(2.22\),MPPI 撒了 1000 个样本 × 60 轮(六万次 rollout)还停在 \(7.11\)——精度差了三倍多。为什么?因为 iLQR 利用了问题的结构:它知道动力学的雅可比、代价的曲率,靠这些导数信息精准地、二阶收敛地逼近最优;MPPI 不利用任何结构,只靠"撒样本看哪个低",没有导数的精确指引,所以只能大致聚到最优附近、踩不准那个点(§9.1 登山多视角里"探子没有坡度指引"的具体兑现)。这就是"瑞士军刀 vs 专用螺丝刀"——问题越光滑、越有好结构,专用的梯度式就越占优。(注:iLQR 这里的耗时被有限差分雅可比拖慢了;真实 iLQR 用解析或自动微分导数会快得多,耗时优势也会显现——但即便如此,这个 demo 的重点是**精度**,不是速度。)

把这个 demo 和 §9.7 的 CartPole 摆起 demo 对照看就完整了:光滑问题上梯度式赢(这里);非凸 / 需全局搜索的问题上采样式赢(§9.7 iLQR 卡局部)——没有哪家全面占优,全看问题的性质。

追加实验:堆样本能让 MPPI 追上 iLQR 吗? 一个自然的反驳是"MPPI 精度差是因为样本不够,加大 \(K\) 不就行了?"跑个样本数扫描验证一下——同一个光滑单摆,把 MPPI 的 \(K\) 从 500 一路加到 8000:

print("光滑单摆: MPPI 样本数 K 扫描 (iLQR 基准代价=2.22)")
for K in [500, 1000, 2000, 4000, 8000]:
    J = mppi(K)                          # 其余参数固定, 只变样本数 K
    print(f"K={K}: 代价 {J:.2f}")
# 典型输出:
#   K= 500: 代价 11.15
#   K=1000: 代价  7.11
#   K=2000: 代价  3.29
#   K=4000: 代价  3.44   ← 不再单调下降, 边际收益消失
#   K=8000: 代价  4.13   ← 更多样本反而略升(随机性 + 数值)
#   → 加大 K 代价先降后平, 始终难逼近 iLQR 的 2.22

结果很说明问题:加大 \(K\) 起初有效(500→2000 代价从 11 降到 3.3),但很快进入边际收益递减、甚至不再改进(4000、8000 反而略升),始终追不上 iLQR 的 \(2.22\)。这印证了 §9.1 的判断——采样式的精度天花板受限于"撒样本逼近"这个本质,不是"样本不够"那么简单:在光滑问题上,没有导数指引,再多样本也只能大致聚到最优附近、踩不准那个点,而且样本一多,随机性和数值因素还会让结果波动。想要 iLQR 那样的高精度,得靠"用导数 / 结构",而非"堆样本"——这也正是 §9.5 混合方案一(让 iLQR 来精炼 MPPI 的粗解)存在的理由:与其给 MPPI 堆到 8000 样本还停在 3–4,不如让它撒少量样本找到盆地、再让 iLQR 几步精炼到 2.2。

深一层:为什么梯度式能上百维,而采样式卡在二十维

§9.3 表里 ⑧ 说"采样式 4–20 维、梯度式 4–200 维",这个维度差异值得展开——它是采样式最硬的天花板,也是理解"何时必须用梯度式"的关键。

根源在两家**如何获取"往哪走"的信息**。采样式靠**采样覆盖**:在当前解 \(U\)(一个 \(H\times m\) 维向量)周围撒 \(K\) 个样本,靠"撒到更好的点"来改进。但高维空间的体积随维度指数增长——维度从 10 升到 100,要达到同样的"覆盖密度",需要的样本数指数级爆炸(维度灾难,第 7 章 §7.4 详述)。所以采样式在几十维以上,固定的 \(K\) 个样本覆盖得越来越稀疏,改进越来越慢,最终撒再多也找不到好方向。

梯度式靠**导数**:一次线性化就得到一个 \(H\times m\) 维的梯度向量,这个向量**一次就包含了所有维度上"往哪走"的信息**——不管是 10 维还是 200 维,算一次雅可比/梯度的成本只是线性或多项式增长(矩阵运算),不存在指数爆炸。所以梯度式天然适应高维:全身人形的力矩空间(几十维)、长时域大规模轨迹优化(上百维),梯度式都能从容处理(§9.6 OCS2 全身控制)。

本质洞察:采样式和梯度式的维度天花板差异,根源是**"获取搜索方向的信息成本随维度如何增长"——采样式靠覆盖,成本随维度**指数**增长(维度灾难);梯度式靠求导,成本随维度**多项式**增长。这解释了一个看似矛盾的现象:采样式"假设更弱、更通用",却在高维上**反而不如**假设更强的梯度式——因为它放弃的恰恰是"能高效获取高维方向信息"的导数。这再次印证 §9.1 的核心权衡:放弃求导(换普适)的代价,在高维上变得格外昂贵。实践启示很直接:**控制维度(\(H\times m\))是选求解器的一个硬指标——几十维以内采样式可用(配合降维 / warm-start / 好的采样分布,第 5、7 章),上百维就该认真考虑梯度式或重度降维,别指望靠加样本硬扛维度灾难。

一个能跑的对照(三):维度灾难——固定样本预算下 MPPI 随维度退化

"采样式随维度退化、梯度式不退化"(§9.3 ⑧、上面的深一层)值得跑出来量一量。构造一个最干净的对照:\(d\) 维点质量,动力学 \(x_{t+1}=x_t+\Delta t\, u\)(各维独立、光滑可微),终端代价是到一个 \(d\) 维目标点的距离 \(\|x_H-\text{goal}\|^2\)。这是个线性二次问题(梯度式 / LQR 能解析求到精确最优),把 MPPI 的样本数**固定**在 \(K=2000\),只把控制维度 \(d\) 从 2 加到 32,看两家末端到目标的误差:

print(f"{'控制维度 d':>10} | {'MPPI 误差':>10} | {'iLQR 误差':>10}")
for d in [2, 4, 8, 16, 32]:
    err_mppi, err_ilqr = run(d, K=2000)   # K 固定, 只变维度 d
    print(f"{d:>10} | {err_mppi:>10.3f} | {err_ilqr:>10.4f}")
# 典型输出:
#    控制维度 d |   MPPI 误差 |   iLQR 误差
#          2 |      0.011 |     0.0000
#          4 |      0.020 |     0.0000
#          8 |      0.014 |     0.0000
#         16 |      0.083 |     0.0000
#         32 |      0.222 |     0.0000
#   → MPPI 误差随 d 显著上升; iLQR 各维度都精确到达, 不随 d 退化

结果把维度灾难量化了:固定 \(K=2000\),MPPI 的末端误差随维度从 \(d{=}2\)\(0.011\) 一路涨到 \(d{=}32\)\(0.222\)(约 20 倍)——维度越高,固定的样本越覆盖不过来,精度越差(低维 \(d{=}2,4,8\) 间有些抖动是采样随机性,但 \(d{=}16,32\) 的恶化趋势明确)。而 iLQR(梯度式 / LQR 精确解)在所有维度上误差都是 \(0.0000\)——它靠导数为每一维都精确地求出最优控制,完全不随维度退化。这正是 §9.3 ⑧ "梯度式能上百维、采样式卡在二十维"的活样本:要让 MPPI 在 \(d{=}32\) 上也达到 \(d{=}2\) 的精度,得把 \(K\) 指数级加大(维度灾难,§9.3 深一层),而梯度式不需要——它对维度只多项式敏感(§9.3 复杂度深一层)。把这个 demo 和光滑摆起 demo(§9.3 demo 一)、K-扫描(demo 二)合起来看,"采样式在光滑 / 高维问题上不如梯度式"就有了从精度、样本边际收益、维度三个角度的完整实证。

深一层:GPU 与 CPU——硬件如何反过来影响求解器选择

表里 ④⑦ 是一对镜像:采样式吃 GPU、梯度式宜 CPU。这个"硬件维度"值得展开,因为它常被算法人忽视,却实实在在地左右真实系统的选择(第 7、8 章反复出现)。

采样式的计算是"\(K\) 条独立 rollout"——这是**数据并行**的典范,GPU 几千个核同时各算一条,利用率极高(第 7 章 AutoRally GPU、STORM)。所以**有 GPU**时,采样式能把样本数 \(K\) 开到很大(几千上万),搜索质量随之提升,GPU 越强它越强。

梯度式的计算是"沿轨迹的串行后向递推(Riccati / QP)+ 矩阵分解"——这些以**串行依赖和稠密线性代数**为主,并行度低,GPU 帮不上太多忙,反而更吃单核主频和缓存。所以梯度式在**普通 CPU(甚至嵌入式 MCU)**上就能高效实时跑(§9.6 acados 在车载芯片上跑四旋翼 NMPC)。

这带来一个常被忽略的"反向"逻辑:不只是"问题决定求解器",硬件平台也反过来约束求解器选择。同样一个光滑可微问题,若你有强 GPU,采样式和梯度式都可用(§9.4 决策树会说"有 GPU 都可、MPPI 更灵活");若你是无 GPU 的嵌入式平台,梯度式的 CPU 友好就成了决定性优势。

本质洞察:求解器选择是**问题特性与硬件平台的联合函数**,不是只看问题。采样式与梯度式在硬件上的镜像(GPU 友好 vs CPU 友好),源于它们计算模式的根本不同(大规模并行求值 vs 串行稠密线性代数)。这给你一条实践纪律:选求解器时,把"我的目标平台有没有 GPU、算力多少"和"我的问题可不可微、多少维"一起放进决策——一个在 GPU 工作站上最优的选择(大 \(K\) 的 MPPI),搬到无 GPU 的嵌入式控制器上可能完全不可行,这时即便问题不那么光滑,也可能要为了平台改用更省算力的方法(或重度降低 \(K\)、或换梯度式)。这正是第 7 章"按 rollout 特性选硬件"的反向补充:硬件也会反过来选求解器。

深一层:GPU 上采样式也未必"碾压"——三个被夸大的"采样优势"

§9.3 ④ 说采样式"GPU 利用极高",这常被过度解读成"只要有 GPU,采样式就全面碾压梯度式"。这个印象有三处夸大,澄清它们能让你更冷静地看待采样式的 GPU 优势:

  • 夸大一:"GPU 上 K 可以无限大,所以采样式能解任意难的问题。" 实情:GPU 让 \(K\) 大,但**维度灾难是指数的**(§9.3 ⑧)——维度一高,再大的 \(K\) 也是杯水车薪(指数 vs 多项式,§9.3 深一层)。GPU 缓解的是"低维下撒更多样本",治不了"高维下覆盖指数稀疏"。
  • 夸大二:"GPU 上采样式比梯度式快。" 实情:在**光滑问题**上,梯度式靠二阶收敛几次迭代就到高精度,采样式撒再多样本还在"差不多"(§9.3 demo:MPPI 7.11 vs iLQR 2.22)——这里"快"的是梯度式(达到同精度所需的计算),不是采样式。GPU 让采样式的每轮更便宜,但改不了它"需要很多轮才能逼近精度"的本质。
  • 夸大三:"有 GPU 就该用采样式。" 实情:有 GPU 只是让采样式**可行 / 更强**,不等于它**更优**——若问题光滑、要高精度 / 硬约束,即便有 GPU,梯度式仍可能是更好的选择(§9.6 决策树"都可行"分支后仍要分高下,§9.6 陷阱 3)。GPU 是采样式的"使能条件",不是"选它的理由"。

本质洞察:GPU 对采样式是"使能"而非"封神"——它把采样式从"CPU 上 \(K\) 受限、勉强能用"提升到"\(K\) 充足、在它的主场(不可微 / 黑箱 / 中低维)大放异彩",但**改变不了采样式的两条根本短板:高维的维度灾难、光滑问题上对结构的不利用**。把"GPU 让采样式更强"误读成"GPU 让采样式全面碾压",是对硬件作用的过度乐观。这给你一个更普遍的清醒:一项使能技术(GPU、大数据、大模型)能放大某类方法的优势,但放大不了它的根本局限——维度灾难、对结构的不利用,是采样式的"原理性"短板,不是"算力不够"造成的,再多算力也补不上。判断一项技术进步能带来什么,要区分"它放大了什么(使能)"和"它改变不了什么(原理局限)"——前者是机会,后者是必须用别的思路(如混合、降维、换范式)才能突破的墙。

多视角:九维对比像一张"求解器体检表"

给这套九维对比配个直觉:它像给你的控制问题做一次**体检**,每个维度是一项体检指标。

你拿着自己的具体问题,逐项"化验":动力学可微吗(指标 ③)?代价光滑吗(②)?多少维(⑧)?有 GPU 吗(④⑦)?有硬约束吗(⑥)?要不要全局最优、能接受随机性吗(⑤)?每一项"化验结果"都把你往某一家推一点。最后综合所有指标,得出"这个问题适合哪家"的诊断——就像医生不会只看一项指标下结论,而是综合血压、血糖、心电图等一起判断。

像的地方:体检的"综合多项指标下结论",正是选求解器该有的多维度权衡(呼应 §9.3 反面"别被单一维度误导")。不像的地方(边界):体检指标大多独立,而这九个维度高度相关(全是"求值 vs 求导"那颗种子的推论,彼此环环相扣)——所以你往往不需要真的逐项打分,抓住种子(可微性)+ 两三个最关键的指标(维度、硬约束、有无 GPU),结论通常就出来了。别把它当成"九项独立打分求和"的机械流程,而是"以可微性为主、其余为辅"的综合判断(§9.6 决策树会把这个判断流程化)。

深一层:计算复杂度的并排——MPPI 的 \(O(KHd)\) vs iLQR 的 \(O(Hd^3)\)

九维表的 ④⑦⑧ 都和"计算量"有关,但没量化。把两家单次迭代的计算复杂度并排算一算,能让你对"它们各自贵在哪、随什么增长"有定量的直觉(这决定了它们在不同规模问题上的实际可行性)。记状态维 \(d\)、控制维 \(m\)、时域 \(H\)、样本数 \(K\)

方法 单次迭代主要成本 复杂度 随什么爆炸
MPPI \(K\) 条 rollout,每条 \(H\) 步、每步 \(O(d{+}m)\) \(O(K H (d{+}m))\) \(K\) 线性(但 \(K\) 需随维度指数增长才够覆盖)
iLQR 每步线性化 \(O(d^2 m)\) + Riccati 矩阵运算 \(O(d^3{+}m^3)\),共 \(H\) \(O(H(d^3{+}m^3))\) \(d, m\) 立方(矩阵求逆 / 分解)

读这张表的关键洞察:

  • MPPI 单次迭代对 \(K\) 线性、对维度低阶(每步只是前向算一下,\(O(d{+}m)\))——所以它**单次迭代很便宜**,且天然并行(\(K\) 条 rollout 各算各的,§9.3 ④)。它的贵不在单次迭代,而在"需要的 \(K\) 随维度指数增长"(维度灾难,§9.3 深一层)——低维 \(K\) 小就够、高维 \(K\) 要爆炸。
  • iLQR 单次迭代对维度立方(Riccati 要矩阵求逆 / 分解,\(O(d^3)\))——所以**单维度高时单次迭代变贵**,且串行(Riccati 后向递推有时序依赖,难并行,§9.3 ④)。但它的迭代数少(二阶收敛,几次到几十次),且**不需要随维度指数增长的样本**——靠导数,一次就拿全方向信息。
  • 谁更便宜取决于规模:低维(\(d\) 小)时 iLQR 的 \(d^3\) 不可怕、且迭代少,往往更省;高维(\(d\) 大但仍可控)时 iLQR 的 \(d^3\) 变贵但仍多项式可承受,而 MPPI 要的 \(K\) 已指数爆炸——这就是 §9.3 ⑧"梯度式能上百维、采样式卡二十维"的复杂度根源。

本质洞察:两家的计算成本"长在不同的地方"——MPPI 的成本对维度低阶、但对"所需样本数"随维度指数敏感;iLQR 的成本对维度立方、但对维度只多项式敏感(不需指数样本)。所以"谁更省算力"没有普适答案,取决于维度规模:低维 iLQR 的立方不可怕、迭代又少,常更省;高维 MPPI 的样本需求指数爆炸,而 iLQR 的立方仍多项式可控,于是 iLQR 反而省。这把 §9.3 ⑧ 的维度差异落到了定量的复杂度上,也给你一个估算工具:面对一个新问题,先粗算 \(d, m, H\) 和"采样需要的 \(K\) 大概多少",就能估出两家各自的计算量量级,从而判断在你的算力预算下谁可行。"算复杂度的量级"是工程选型里一个朴素却极有用的习惯——它把"感觉哪个快"变成"算出哪个在预算内"。

深一层:warm-start——两家如何在连续控制周期间"接着上次的解算"

前面把两家当"一次性求解器"对比。但 MPC 是**滚动时域**的(第 8 章 §8.1)——每个控制周期都要重新解一次优化,周期间隔可能只有几毫秒。这时一个对两家都关键的技巧是 warm-start(热启动):用上一周期的解作为这一周期优化的初值,而非每次从零开始。理解两家如何 warm-start,能让你明白它们在真实 MPC 闭环里的实际表现。

  • 为什么 warm-start 有效:相邻控制周期的最优解变化不大(系统连续、世界只前进了一小步),所以上一周期的解已经"很接近"这一周期的解——从它出发,只需少量计算就能修正到位,比从零快得多。
  • 梯度式的 warm-start:把上一周期的控制序列(去掉已执行的第一步、末尾补一个)作为这一周期 iLQR/SQP 的初值。效果**极显著**——梯度式对初值敏感(§9.7 暖启动实验),好初值让它几次迭代(甚至 RTI 的一次迭代,§9.6)就收敛。这正是 acados RTI"每步只迭代一次也够"的前提:有 warm-start,一次迭代就够把上一步的解修正到位。
  • 采样式的 warm-start:把上一周期的解作为这一周期采样分布的均值(在它周围撒样本),而非从零均值撒。效果**有帮助但不如梯度式戏剧化**——采样式对初值本就不那么敏感(全局撒样本,§9.7),warm-start 主要是"让采样集中到已知的好区域、省点探索",而非"决定成败"。
  • 一个有趣的不对称:warm-start 对梯度式是"雪中送炭"(没有它,梯度式在每周期从零可能陷局部 / 慢;有了它才实时可行),对采样式是"锦上添花"(没有它采样式也能从零找到解,有了它更省)。这又一次体现两家对初值的敏感度差异(§9.7 调参旋钮深一层)。

本质洞察:warm-start 揭示了 MPC 闭环里一个常被忽略、却决定实时可行性的事实——滚动时域的连续性让"上一步的解"成为"这一步的极好初值",而能多大程度利用这个初值,两家不同:梯度式靠它才实时可行(好初值让它一次迭代就收敛,是 RTI 的基础),采样式靠它锦上添花(本就对初值宽容)。这把"一次性求解"的对比,修正到了"连续闭环求解"的真实场景——在真实 MPC 里,你几乎总会 warm-start,所以梯度式"对初值敏感"的短板被 warm-start 大幅缓解(连续周期里它几乎总有好初值),这也是为什么梯度式在四旋翼 / 腿足这类高频 MPC 里如此成功(高频 = 相邻周期变化更小 = warm-start 更好)。一个一般启示:评价一个方法,要在它真实的使用场景(这里是连续闭环 + warm-start)里评,而非孤立的一次性场景——脱离了 warm-start 谈"梯度式对初值敏感",会高估这个短板在真实 MPC 里的影响。

易错点:对比表是"典型情况",别当成不可逾越的铁律

这张九维对比表给的是**典型情况**,不是绝对铁律——把它当成铁律会让你错过一些有用的"越界"做法。比如:表说"采样式适合 4–20 维",但配合重度降维(第 7 章腿足把全身降到质心 + 足端)、好的采样分布(第 5 章扩散启发)、warm-start,采样式也能间接处理更高维的问题(只是不如梯度式直接)。又如:表说"梯度式需要可微",但对**部分**不可微的问题,可以把可微的部分用梯度式、不可微的部分用别的手段,或用平滑近似(把 indicator 换成陡峭的 sigmoid)让梯度式勉强能用(虽然有 §9.1 陷阱 1 的风险)。再如:表说"采样式硬约束弱",但 §9.5 的"MPPI + CBF"恰恰是给采样式补上硬约束的越界做法。这张表的价值是给你一个快速的"默认判断",但真实工程里常有针对具体问题的越界优化——记住典型情况,也要知道边界可以被技巧推动。自检:当你说"这个问题采样式做不了/梯度式做不了"时,先想一下"有没有降维 / 平滑近似 / 混合架构这类越界技巧能让它勉强可行",再下结论。

⚠️ 常见陷阱

陷阱 1:在光滑可微问题上习惯性用采样式,浪费结构 ⚠️ 编程陷阱 - 错误做法:手头是个动力学解析可微、代价光滑的问题(四旋翼轨迹、机械臂到点),但你因为熟悉 MPPI 就直接撒样本,没考虑梯度式。 - 现象/后果:撒上万样本、吃满 GPU,还达不到 iLQR/acados 几次迭代就能达到的精度(本节 demo:MPPI 7.11 vs iLQR 2.22);若还要满足硬约束(推力上限),采样式更是只能"软化"、不保证满足。事倍功半。 - 根本原因:采样式不利用问题的光滑可微结构(不挑结构是它的普适性来源,也是它在好结构问题上的劣势,§9.1 易错点)。光滑问题有"导数"这个免费的精确向导,采样式偏偏不用,等于守着金矿挖土。 - 正确做法:问题光滑可微(尤其还要精度 / 硬约束 / 在 CPU 上跑)时,优先考虑梯度式(iLQR/acados/OCS2)。判断标准:动力学能解析求导吗?代价是光滑的(二次型 / 可微)吗?都是 → 梯度式大概率更优。自检:你用 MPPI 解一个问题,若发现"动力学和代价其实都可微、且要高精度",停下来想想是不是该换梯度式。

陷阱 2:只用"适用维度"一个维度选求解器 ⚠️ 概念误区 - 错误想法:"梯度式能上百维、采样式只能几十维,所以高维问题一定用梯度式、低维问题随便。" - 现象/后果:你给一个低维(如 6 维)但代价来自 CNN 的视觉伺服问题选了梯度式(因为"维度不高梯度式也行"),结果卡在"CNN 不可微"上根本跑不起来——你被"维度"这一个维度误导,忽略了对你的问题更致命的"可微性"维度。 - 根本原因:九个维度不是同等重要的,对**具体问题**而言,往往有一两个维度是决定性的、其余次要。可微性(②③)常常比维度(⑧)更早地"一票否决"——一个低维但不可微的问题,维度再低梯度式也用不了。 - 正确做法:综合多个维度判断,且优先看"一票否决"型维度(可微性:不可微直接排除梯度式;硬约束刚需:软约束不够直接倾向梯度式)。自检:选求解器时别只问"几维",先问"可微吗、有硬约束刚需吗"——这两个常常先于维度决定成败(§9.6 决策树正是按这个优先级组织的)。

陷阱 3:把对比表当成"采样式 vs 梯度式二选一",忘了还能混合 ⚠️ 思维陷阱 - 错误想法:"这张表是在帮我从两家里选一家——要么纯采样式、要么纯梯度式。" - 现象/后果:遇到一个"既非凸(需全局搜索)、又光滑(梯度式能精炼)"的问题,你纠结于"到底选哪家",非此即彼,结果要么陷局部(纯梯度式)、要么精度不够(纯采样式),没想到两家可以**组合**取长补短。 - 根本原因:把"对比"误解为"互斥选择"。但 §9.1 陷阱 3 已说两家是互补的——互补就意味着可以组合(§9.5 四种混合架构)。对比表帮你理解两家各自的长短,恰恰是为了知道"在哪个环节用哪家的长处"来组合。 - 正确做法:把对比表当成"理解两家长短"的工具,进而想"能不能用 A 的长处补 B 的短处"(如 MPPI 全局搜索 + iLQR 局部精炼,§9.5 方案一)。自检:当你在"采样式 vs 梯度式"之间纠结时,多问一句"能不能两个都用、各管一段"——很多真实系统的答案正是混合(§9.5、§9.6 工业案例)。

练习

  1. (应用·给问题做体检,⭐⭐⭐) 对下面三个控制问题,用本节九维对比表逐项"化验",给出"该用采样式还是梯度式"的诊断及理由:(a) 四旋翼穿越已知的窗户序列,动力学解析、要满足推力上限,车载嵌入式芯片无 GPU;(b) 一台带视觉的机械臂,代价部分来自一个判断"抓取是否成功"的 CNN,6 自由度,有 GPU;(c) 全身人形机器人做一个新的、含复杂接触的翻滚动作,几十维力矩空间。
  2. (复现 + 探究·光滑问题上的两家,⭐⭐⭐) 跑通本节光滑单摆 demo,复现"iLQR 2.22、MPPI 7.11"。然后:(a) 把 MPPI 的样本数 K 从 1000 加到 5000,看代价能否逼近 iLQR(体会"采样式靠堆样本也难追上梯度式的精度");(b) 把代价里的终端权重 Qf 调大,看两家的差距如何变化;(c) 给单摆动力学加一个**不可微**的扰动(如 \(\theta\) 过某阈值时突然加一个常力),看 iLQR 是否开始出问题、而 MPPI 不受影响(预告 §9.4)。
  3. (思考·维度灾难与导数,⭐⭐⭐⭐) 本节深一层说"采样式获取方向信息的成本随维度指数增长,梯度式多项式增长"。请论证:(a) 为什么"在 \(d\) 维空间撒样本达到固定覆盖密度"所需的样本数随 \(d\) 指数增长(从高维球 / 立方体的体积角度);(b) 为什么"算一次 \(d\) 维梯度"的成本只随 \(d\) 多项式增长(从雅可比的规模角度);(c) 由此解释一个反直觉现象——为什么"假设更弱、更通用"的采样式,在高维上反而不如"假设更强"的梯度式。这道题把 §9.1 的核心权衡推到高维的极端情形。
  4. (复现 + 探究·样本数与维度,⭐⭐⭐) 跑通本节的 K-扫描 demo(demo 二)和维度扩展 demo(demo 三)。然后:(a) 在 K-扫描里,把单摆问题换成一个更难的(如更长 horizon),看"加大 \(K\) 的边际收益递减"是否更明显;(b) 在维度扩展里,对每个维度 \(d\),试着把 \(K\) 也加大(如 \(K=2000\to 20000\)),看 MPPI 误差能否随之回落——体会"要在高维保持精度,\(K\) 得跟着涨",并估算大致要涨多少(指数还是多项式);(c) 把两个 demo 的结论合起来写一段话:"为什么光滑高维问题该用梯度式"。
  5. (估算·复杂度量级,⭐⭐⭐) 用本节复杂度深一层的公式(MPPI \(O(KHd)\)、iLQR \(O(Hd^3)\)),对一个具体问题估算两家的单次迭代计算量量级:状态维 \(d=20\)、控制维 \(m=6\)、时域 \(H=50\)、MPPI 用 \(K=1000\)。(a) 分别算出两家的量级;(b) 若维度涨到 \(d=200\)(人形全身),两家量级各变多少倍,谁更吃不消;(c) 讨论这对"该用谁"的提示。

§9.4 采样式的杀手场景——不可微、非光滑、黑箱 ⭐⭐⭐

动机

§9.3 让你看到了梯度式的胜场:光滑、可微、要精度和约束的问题,它又快又准。但这一节要展示天平的另一端——当问题不可微、非光滑、或是个黑箱时,梯度式那套"用导数精准走每一步"的威力会彻底失效,而采样式是唯一能跑的选择。这正是采样式的"杀手场景",也是它在前八章(腿足的接触、导航的代价地图)成为主场的根本原因。把 §9.3 和 §9.4 合起来看,你就有了完整的图景:两家各有一片对方无法染指的领地——这正是它们互补、而非互相淘汰的根基(§9.1 陷阱 3)。

如果不这样做会怎样:硬把梯度式塞进不可微的问题

设想你没认清"不可微"这道坎,习惯性地想用梯度式(毕竟它在 §9.3 表现那么好)。你会撞上一堵看不见的墙。比如:你的代价里有一个"撞了障碍就罚一大笔"的 indicator 项,你用 iLQR——它跑得飞快、还"收敛"了,但你一看轨迹,它直直地穿过了障碍(本节 demo 会让你看到这一幕)。你百思不得其解:"代价里明明罚了撞障碍,为什么它还往里撞?"根本原因是:indicator 的梯度处处为零,iLQR 求导时**根本看不见这个障碍**——它优化的是一个"障碍不存在"的世界。又比如:你的动力学是个 MuJoCo 接触仿真器,你想用 iLQR,于是用有限差分造雅可比(§9.1 陷阱 1)——接触切换处的雅可比要么爆炸要么为零,iLQR 发散或剧烈震荡。这些失败不是因为你 iLQR 写错了,而是因为问题本身违反了梯度式的铁打前提(可微)。不认清这道坎,你会浪费大量时间调一个原理上就不该用的方法。这一节就讲清这道坎在哪、为什么采样式能跨过去。

历史与理论:三类"求导失效"的场景

"求导失效"不是一种情况,而是三类,各有不同的成因。把它们分清楚,你才能准确判断"我的问题是否落入了梯度式的禁区"。

第一类:代价非光滑 / 不连续。 最典型的是 indicator 代价——"在障碍内就罚 1000,否则 0"这种阶跃函数。它的梯度在平的地方(障碍内或障碍外)处处为零、在跳变的边界上无定义。梯度式求出来的"导数"全是零,等于**告诉优化器"往哪走都一样"**——它完全感知不到障碍的存在(本节 demo)。这类代价在机器人里无处不在:第 8 章的占据栅格代价地图(占了就是高代价、空了就是低代价,是阶梯状的)、"碰撞/不碰撞"的二值判断、"任务成功/失败"的稀疏奖励。还有一类是 CNN / 神经网络打分的代价——它名义上可微(网络是可微的),但梯度往往剧烈震荡、充满虚假的局部极值,对优化的指引很差(第 8 章 §8.6 讲过感知代价的"脏")。

第二类:动力学不可微。 最典型的是**接触**——腿足落地、机械臂抓取、物体碰撞,这些时刻动力学是不连续的(接触力瞬间出现/消失,第 7 章详述)。在接触切换的瞬间,\(\partial f/\partial x\) 要么不存在、要么数值上爆炸。梯度式需要这个雅可比来线性化动力学,接触一来,线性化就失真甚至发散。这就是为什么腿足全身控制(接触密集)是采样式的主场——梯度式在接触不连续上吃尽苦头(虽然有可微仿真、接触平滑等研究在努力让接触可微,但远未成熟)。

第三类:黑箱——根本没有解析形式。 有时动力学或代价干脆是个**黑箱**:一个闭源的物理引擎、一个只能"输入查输出"的仿真器、一个学出来的神经网络世界模型(第 6 章)。你能 f(x, u) 求值,但拿不到 \(\partial f/\partial x\) 的解析式(黑箱不暴露内部)。梯度式无米下锅;采样式只需要 f(x,u) 能求值,黑箱照用不误(第 6 章 Neural-MPPI、第 7 章 MuJoCo MPC)。

这三类的共同点,正是 §9.1 那颗种子的反面:它们都破坏了"求导"的前提(导数存在且有意义),但都不破坏"求值"——indicator 你能算它的值(在不在障碍内)、接触仿真你能 rollout 求值、黑箱你能查询求值。所以这三类全是采样式的杀手场景:求导此路不通,求值畅通无阻,采样式成了唯一选择

本质洞察:梯度式的禁区,统一地是"求导的前提被破坏"——而求导的前提(处处可微、有解析雅可比)比求值的前提(能算出值)强得多。这就是 §9.1 核心权衡的"另一半账":梯度式用"更强的假设"换"更高的效率",那么**当问题无法满足这个更强的假设时,梯度式付出的代价是"完全不可用"——不是慢一点,是原理上跑不了。而采样式用"更弱的假设(只需求值)"换普适,它的回报正是在这些场景里**独此一家。一个深刻的认识是:现代机器人问题越来越多地落入这些禁区——感知驱动的代价(不可微的代价地图、CNN)、接触丰富的操作与运动(不可微动力学)、学习出来的黑箱模型——这正是采样式近十年崛起的根本动力,不是因为它"更先进",而是因为**问题的形态变了**,变得越来越"脏"、越来越黑箱,而采样式恰好是为"脏问题"而生的工具。理解这一点,你就懂了采样式不是要取代梯度式,而是**接管了一片梯度式原理上够不着的新大陆**。

一个能跑的对照:障碍挡路时,iLQR 直穿、MPPI 绕行

把"indicator 代价让梯度式失明"这件事跑出来看。任务极简:一个 2D 点质量从 \((0,0)\) 走到 \((4,0)\)动力学是线性可微的\(x_{t+1}=x_t+\Delta t\cdot u\),对梯度式最友好),但代价里加了一个**非光滑的障碍 indicator**——正方块障碍 \(x\in[1.5,2.5], y\in[-0.8,0.8]\) 正好挡在起点到目标的直线上。注意:唯一的"不友好"就是这个 indicator,动力学是完全可微的。先看代价(光滑趋目标 + 非光滑障碍 + 控制):

import numpy as np
rng = np.random.default_rng(0)
dt, H = 0.1, 40
START = np.array([0.0, 0.0]); GOAL = np.array([4.0, 0.0])
# 障碍方块: x∈[1.5,2.5], y∈[-0.8,0.8](挡在直线路径上)
def in_obs(p):
    return (p[...,0]>1.5)&(p[...,0]<2.5)&(p[...,1]>-0.8)&(p[...,1]<0.8)
def step_cost(p, u):
    c = 0.1*((p-GOAL)**2).sum(-1)            # 趋目标(光滑二次)
    c = c + 1000.0*in_obs(p).astype(float)   # 障碍 indicator(非光滑!)
    c = c + 0.05*(u**2).sum(-1)
    return c

iLQR 求代价梯度时,那个 1000*in_obs(p) 项的梯度处处为零(阶跃函数),所以 iLQR 的后向递推里**根本没有这个障碍的信息**——它优化的是一个"只有趋目标项、障碍不存在"的世界。MPPI 则在 step_cost 里直接求值,撞障碍的样本代价 +1000、被指数加权压到极低权重,于是自然避开。两者跑同一个任务(iLQR / MPPI 核心循环略,与前几节一致),统计"轨迹穿过障碍的步数":

Xi = ilqr()        # 梯度式: indicator 梯度=0, "看不见"障碍
Xm = mppi(K=2000)  # 采样式: 只求值, "看得见"障碍
def obs_hits(X): return int(in_obs(X).sum())
print(f"iLQR(梯度式): 穿过障碍步数 {obs_hits(Xi)}, 末端离目标 {np.linalg.norm(Xi[-1]-GOAL):.2f}")
print(f"MPPI(采样式): 穿过障碍步数 {obs_hits(Xm)}, 末端离目标 {np.linalg.norm(Xm[-1]-GOAL):.2f}")
# 典型输出:
#   iLQR(梯度式): 穿过障碍步数 3, 末端离目标 0.00   ← 直直穿过障碍(看不见它)
#   MPPI(采样式): 穿过障碍步数 0, 末端离目标 0.05   ← 绕开了障碍(看得见它)

结果一目了然:iLQR 直直穿过障碍 3 步(它到达了目标、代价里趋目标项满足了,但完全无视障碍——因为 indicator 梯度为零,它"看不见"),MPPI 绕开障碍 0 步穿越(它只求值,撞障碍的样本代价飙升被压权重,自然避开)。注意一个关键细节:iLQR 这里跑得很顺、还"收敛"了——它不是报错崩溃,而是**安静地给出一个穿墙的错误答案**,这比崩溃更危险(你以为它工作正常)。这就是 §9.1 陷阱 1 和本节反面警告的活样本:给本质不可微的项硬上梯度式,它会"假装"在优化、却优化了一个错误的(障碍不存在的)问题。而这个障碍,对只求值的 MPPI 来说,从来不是问题。

把这个 demo 和 §9.3 的光滑摆起 demo 对照,两家的版图就完整了:§9.3 光滑可微 → 梯度式赢(精度高三倍);§9.4 非光滑 indicator → 采样式赢(梯度式直接失明)。同一个"求值 vs 求导"的种子,在两种问题上结出截然相反的果。

深一层:把 indicator "抹平"成 sigmoid,能救梯度式吗

看到 indicator 让梯度式失明,一个自然的念头是:把阶跃的 indicator 用一个陡峭但光滑的函数(如 sigmoid)近似,不就有梯度了吗? 这个想法有道理、有时也确实用,但它是一把双刃剑,值得展开看清它的代价。

1000*in_obs(p)(阶跃)换成 1000*sigmoid(k*(障碍距离))(光滑陡峭),确实让代价处处可微、梯度式能"看见"障碍了。但你立刻面对一个两难:陡峭度 \(k\) 怎么选? \(k\) 太小(抹得太平),障碍边界变成一个宽阔的"软墙",梯度式会被它过度推开、绕很大的远路,且障碍内外的区分变模糊(不该撞的地方也躲、该精确贴边的地方贴不住)。\(k\) 太大(抹得太陡,逼近真 indicator),梯度在边界附近变成一个极窄、极陡的"悬崖"——离边界稍远梯度几乎为零(又看不见障碍了),到边界又梯度爆炸(数值不稳,迭代震荡)。换句话说,sigmoid 近似只是把"梯度为零"的问题,转化成了"梯度要么为零要么爆炸、且陡峭度极难调"的问题——治标不治本。而且这只对"能写出光滑近似"的简单 indicator 有效;对一个 CNN 代价或黑箱仿真器,你根本无从"抹平"。

本质洞察:把不可微的东西"抹平"成可微,是一类常见但有限的补救——它的本质是**用一个可微的代理(surrogate)替换不可微的真目标,从而把问题塞回梯度式的框架**。代价是双重的:其一,代理和真目标有偏差(sigmoid 软墙 ≠ 硬障碍),你优化的是代理、不是真问题;其二,代理的"陡峭度 / 平滑度"成了一个极难调的新超参数,调不好则梯度要么消失要么爆炸。这揭示了一个一般原则:当问题本质不可微时,强行可微化往往是把一个困难(没有梯度)换成另一个困难(坏的梯度 + 代理偏差),而非真正解决它。相比之下,采样式直接在真目标上求值、不需要任何代理,反而更干净。所以"抹平"不是不能用(简单障碍、需要梯度式的其他优势如硬约束时,它是个权宜之计),但要清醒:你为可微付出了"优化代理而非真目标"的代价。很多时候,与其费力抹平再用梯度式,不如直接用本就不挑可微性的采样式。

深一层:黑箱时代——为什么"求值即可"越来越值钱

§9.4 第三类"黑箱"值得单独展开,因为它正是采样式在当下(而非二十年前)崛起的时代背景,理解它能让你看清这场对比的历史纵深。

二十年前,机器人的模型大多是**人手写的解析方程**(刚体动力学、自行车模型)——这种模型天然可微,梯度式如鱼得水。但今天,机器人系统里越来越多的组件是**黑箱**:感知是一个 CNN(输入图像、输出代价或检测),动力学可能是一个学出来的神经网络世界模型(第 6 章 TD-MPC),或一个闭源的高保真物理引擎,代价可能来自一个判断"任务成功与否"的学习模型。这些组件的共同特点是:你能高效地"查询"它(求值),但拿不到、或不好用它的导数——CNN 可微但梯度脏、世界模型可微但多步求导误差累积、物理引擎闭源根本无导数。

在这个"组件越来越黑箱"的时代,"只需要能求值"这个看似谦卑的要求,变成了一项极其值钱的特性:它意味着采样式可以**即插即用**任何黑箱组件——把 CNN 代价、神经网络动力学、闭源仿真器直接拿来 rollout,不需要它们可微、不需要导出梯度、不需要任何适配(第 6、7、8 章反复出现的"采样不挑模型")。梯度式则要为每个黑箱组件想办法"弄出梯度"(可微化、有限差分、伴随法),工程上既麻烦又脆弱。

本质洞察:采样式"只需求值"的要求,在"模型解析可写"的旧时代只是个不起眼的特性,但在"模型越来越黑箱(学习的、闭源的、不可微的)"的新时代,变成了**决定性的工程优势**——它让采样式能无缝吃进现代机器人栈里的任何黑箱组件。这解释了一个时间上的现象:为什么 MPPI 这类采样法在 2015 年后才"火"起来,而它的数学(路径积分、CEM)其实早就存在?不是方法变好了,是世界变黑箱了——GPU 让大规模求值变廉价、深度学习让黑箱组件无处不在,这两个时代条件同时成熟,才让"只需求值 + 大规模并行"的采样式找到了它的黄金时代。反过来,这也提醒你:技术选择往往不只取决于方法本身的优劣,更取决于**时代提供了什么条件、问题呈现什么形态**。当你判断"该用哪类方法"时,不仅要看方法,还要看你所处的技术环境(有没有 GPU、组件是不是黑箱、模型是学的还是手写的)——环境变了,最优选择也会变。

深一层:稀疏奖励与长时序——另一类"脏",连采样式也会吃力

§9.4 讲了采样式的主场(不可微 / 黑箱)。但要诚实:有一类"脏",连采样式也会吃力——理解它能让你不把采样式当万能,也预告了它和梯度式都需要外部帮助的场景。

  • 稀疏奖励(sparse reward):代价 / 奖励只在"任务完成"那一刻给一个信号、其余时刻全为零(如"把方块放进盒子才 +1,否则 0")。这对采样式是噩梦:撒出的样本**绝大多数代价都一样(都没完成任务),加权时无从区分优劣(权重几乎均匀),采样失去了指引——它能"求值",但求出的值全一样,等于没信息。这和梯度式遇到 indicator(梯度全零)异曲同工:**信息太稀疏,无论求值还是求导都"看不见方向"
  • 长时序(long horizon):当 \(H\) 很大(几百上千步),采样式要在一个 \(H\times m\) 的超高维空间撒样本(维度灾难,§9.3 ⑧),且 rollout 的误差会逐步累积(第 8 章 §8.6 多步误差累积)——撒到"恰好整条长轨迹都好"的样本概率极低。梯度式靠 Riccati 后向递推处理长时序更从容(§9.2 深一层利用时序结构),但长时序的非凸性也会让它陷局部。
  • 共同的解药:这类"脏"往往不能靠纯采样或纯梯度硬扛,要靠**额外的结构 / 信息**——终端价值函数(第 6 章,给长时序的远端一个"代价估计",缩短有效时域)、子目标 / 课程(把稀疏奖励的长任务拆成密集反馈的短段,第 8 章 GP 子目标)、奖励塑形(给稀疏奖励加密集的引导项)。这正是第 6 章"学习价值函数补远见"和混合架构存在的更深理由。

本质洞察:采样式不是万能的——它的"求值即可"在**信息稀疏**(稀疏奖励:求出的值都一样)和**超长时序 / 超高维**(维度灾难 + 误差累积)面前同样会失效。这揭示了一个比"求值 vs 求导"更底层的真相:任何优化方法的有效性,最终取决于"问题能提供多少有用的方向信息"——梯度式要梯度有意义,采样式要"不同样本的代价有区分度",两者都怕"信息稀疏"(梯度全零 / 代价全等)。所以稀疏奖励、长时序这类"信息稀疏"的问题,解药不在"换更好的优化器",而在**给问题注入更多结构 / 信息**(价值函数、子目标、奖励塑形、课程学习)——把"信息稀疏"变成"信息密集"。这是一个深刻的视角转换:当两类优化方法都卡住时,问题往往不在方法,而在"问题本身提供的信息不够",该去改造问题(加信息),而非死磕方法。这也是为什么强化学习、规划领域有大量工作在做"奖励塑形 / 子目标 / 课程"——它们都是在对抗"信息稀疏"这个比"求值 vs 求导"更根本的敌人。

多视角:两家的版图像"陆地与海洋"

把 §9.3 和 §9.4 合起来,给两家的适用版图配个直觉:它们像**陆地与海洋**,各自统治一片对方无法生存的疆域。

梯度式是陆地动物:在坚实、规则的陆地上(光滑、可微、解析的问题),它跑得飞快、动作精准(二阶收敛、高精度、能管硬约束)。但它无法下海——一旦问题变成"水"(不可微、黑箱、接触),它就像陆地动物入水,立刻失能(梯度失明、雅可比爆炸)。

采样式是海洋动物:它在水里(不可微、黑箱、接触)游刃有余——不管水多浑浊(代价多脏),它都能"求值"着前进。但它上不了精细的陆地:在光滑可微的高精度问题上,它笨拙(精度差三倍、高维吃力),就像海洋动物上岸,动作迟缓。

像的地方:两类动物各有不可替代的疆域,准确反映了 §9.3+§9.4 揭示的"两家各有对方够不着的领地"。不像的地方(边界):陆地和海洋泾渭分明,但真实控制问题常是"海岸线"——部分光滑、部分不可微(如 §9.1 练习里"光滑趋目标 + indicator 碰撞"的混合代价)。在这片海岸线上,纯陆地或纯海洋动物都不完美,最好的办法是**两栖**——这正是 §9.5 混合架构的用武之地(用梯度式处理光滑部分、采样式处理不可微部分,或两者接力)。别把"陆地 vs 海洋"想成非此即彼,真实世界有大片海岸线,需要两栖的智慧。

深一层:可微仿真——让接触"可微"的尝试,以及它现在能不能用

§9.4 把接触归为"不可微动力学",让它成了采样式的腹地。但学界一直在尝试**让接触可微**(可微仿真,differentiable simulation)——若成功,梯度式就能反攻这片腹地。了解它的思路和现状,能让你判断"现在能不能靠它用梯度式做接触"。

  • 思路:用**光滑近似**替换硬接触——把"接触力在接触瞬间突变"近似成"接触力随穿透深度光滑地变化"(软接触 / 松弛接触模型),或用专门的可微物理引擎(如一些可微仿真框架)让 \(\partial f/\partial x\) 在接触处也有定义。这样梯度式(iLQR/DDP)就能拿到接触的"梯度"。
  • 现状与障碍:① 平滑度两难(§9.4 sigmoid 那个深一层的接触版)——接触平滑得太软,仿真就不真实(物体会"陷进"地面);平滑得太硬,梯度又回到"要么消失要么爆炸"。② 梯度可能误导——即便算出了接触梯度,它在接触切换附近可能剧烈、不连续地变化,对优化的指引未必好(穿过接触模式边界时梯度会跳)。③ 计算昂贵——高保真可微仿真比纯前向仿真贵得多。所以**到目前为止,可微仿真用于接触丰富的腿足 / 操作控制仍未成熟**,采样式(不挑接触可微性)在这片领域仍是更稳妥的主力(第 7 章)。
  • 怎么看它:它是一个**有潜力但尚未成熟**的方向——值得关注(一旦成熟会改变 §9.6 的接触类问题选型),但现在做工程,接触问题还是优先采样式,别押注尚不成熟的可微接触。

本质洞察:可微仿真试图把"接触"从采样式的腹地夺回给梯度式,但它撞上的,正是 §9.4 那个普遍困难的接触版——让本质不连续的东西(接触)变得"可微",本质是用一个光滑代理替换真实的不连续,而代理的"平滑度"是一个治标不治本、难以两全的旋钮(太软不真实、太硬梯度坏)。这再次印证 §9.4 深一层的判断:强行可微化常是"把一个困难换成另一个困难"。它给你一个看待前沿技术的清醒姿态:一个方向"有潜力"不等于"现在能用"——要区分"原理上可能"和"工程上成熟"。可微仿真原理上能让梯度式处理接触,但工程上的平滑度两难、梯度误导、计算成本,让它现在还不能可靠替代采样式。做工程选型时,押注成熟的方案(接触→采样式),把不成熟的前沿(可微接触)当成"值得跟踪、暂不依赖"——这是务实与前瞻的平衡。

深一层:感知驱动的代价为什么"最脏"——它同时踩中三个雷

§9.4 把"求导失效"分成三类。但有一类代价格外棘手——来自感知(相机 / 激光 + 神经网络)的代价,它往往**同时踩中多个雷**,是采样式主场里最典型、也最"脏"的一类。值得单独剖析,因为它正是第 8 章(导航 / 自驾)和现代机器人最常见的代价形态。

  • 雷一:非光滑 / 不连续。占据栅格地图是阶梯状的(占 / 空二值,§9.4 第一类、第 8 章 §8.3),SDF 在物体边界处不光滑——这些代价本身就不可微。
  • 雷二:黑箱。代价常经过一个 CNN(输入图像 / 点云、输出代价或检测,§9.4 第三类、第 8 章 §8.2)——你能查询它,但它的内部对你是黑箱,导数即便有也不好用(§9.4 陷阱 1:可微≠梯度好用)。
  • 雷三:噪声 / 不确定。感知是带噪的(传感器噪声、检测误差、地图的不确定性,第 8 章 §8.6)——代价值本身在抖动,即便能求导,导数也会被噪声淹没(噪声的梯度放大问题)。
  • 三雷叠加的后果:这三个特性叠在一起,让梯度式**彻底没法用**——不可微(雷一)、黑箱(雷二)、就算勉强求导也被噪声毁掉(雷三)。而采样式**对三雷都免疫**:它只求值(不在乎可微 / 黑箱),且大量采样 + 加权天然对单次求值的噪声有平滑作用(雷三也扛得住)。这就是为什么感知驱动的机器人(导航、自驾、视觉操作)几乎清一色用采样式(第 8 章)——它们的代价是"三雷叠加"的最脏代价,是采样式独有的领地。

本质洞察:感知驱动的代价是"非光滑 + 黑箱 + 带噪"三雷叠加的产物,它把梯度式的三道前提(可微、白盒、低噪)一次性全部破坏,却**完全不破坏采样式的唯一前提(能求值)——这解释了为什么"感知 + 控制"的现代机器人栈是采样式崛起最强的推力(§9.4 黑箱时代深一层)。更深一层看:**当一类问题同时违反某方法的多个前提时,它不是"难一点",而是"该方法的禁区中的禁区",必须换一个前提更弱的方法。感知代价对梯度式正是如此(三雷齐发)。这也给你一个识别"该用采样式"的强信号:只要你的代价里有'感知 + 神经网络'的成分,几乎可以直接判定采样式是主力——因为感知代价几乎必然三雷叠加,是梯度式的绝对禁区、采样式的绝对主场。这是一条比走完整决策树更快的"快速判据"(当然,走决策树会得到同样结论,但识别"感知代价=三雷"能让你一眼看穿)。

易错点:不可微的问题里,梯度式"不报错地给出错误答案"最危险

本节最该记住的一条警示:把梯度式用在不可微问题上,最危险的不是它崩溃,而是它不报错地、自信地给出一个错误答案。本节 demo 里 iLQR 穿墙就是典型——它跑得顺顺当当、还"收敛"了,输出一条到达目标的轨迹,你若不专门检查"是否穿过障碍",根本不会发现它优化的是一个"障碍不存在"的错误世界。这比一个会崩溃、报错的方法危险得多——崩溃会逼你停下来排查,而"安静的错误"会被你当成正确结果用下去,直到真机上撞了障碍才追悔莫及。根本原因是:梯度式对"梯度为零"的解读是"这个方向没有改进空间",它无法区分"真的到了最优"和"indicator 让梯度恒为零导致根本看不见目标项"——两者在它眼里都是"梯度为零、收敛了"。正确做法:当你的代价含任何不可微项(indicator、阶跃、二值判断)时,绝不能只看"梯度式是否收敛"——必须独立检查它的解是否真的满足那些不可微的要求(如显式统计"轨迹是否穿过障碍""是否违反二值约束")。更稳妥的是,对含不可微项的问题,直接用采样式(它在真代价上求值,不会"看不见"任何项)。自检:你的代价里有没有 indicator / 阶跃 / 二值项?有的话,梯度式"收敛了"绝不等于"解对了",务必独立验证不可微项是否被满足。

⚠️ 常见陷阱

陷阱 1:把 CNN / 神经网络代价当成"可微所以梯度式能用" ⚠️ 概念误区 - 错误想法:"神经网络是可微的(能反向传播),所以代价来自 CNN 的问题,梯度式也能用——直接对 CNN 求梯度指引优化就行。" - 现象/后果:你对 CNN 代价求梯度做轨迹优化,发现优化要么卡在虚假局部极值(CNN 的代价地形充满褶皱)、要么被对抗性的梯度带到一个"CNN 打分很低但物理上荒谬"的解(对抗样本现象)。结果远不如直接用 MPPI 在 CNN 上求值打分。 - 根本原因:"可微"不等于"梯度对优化有好的指引"。CNN 名义可微,但其代价地形极其崎岖(充满虚假极值、对抗方向),梯度的局部指引常常是误导性的——它告诉你的"下降方向"可能通向一个对抗性的、物理无意义的解。可微性是必要条件,不是充分条件。 - 正确做法:代价来自 CNN / 神经网络时,优先用采样式在网络上**求值打分**(撒一批物理上合理的候选、看网络给谁打分高),而非对网络**求梯度**优化(容易被脏梯度和对抗方向误导)。第 8 章 §8.6 的感知代价正是这么用的。自检:你的代价来自一个学出来的网络吗?是的话,警惕"可微≠梯度好用",优先求值而非求导。

陷阱 2:用有限差分硬给接触动力学造雅可比 ⚠️ 编程陷阱 - 错误做法:动力学是个含接触的仿真器(腿足落地、抓取),你想用 iLQR,于是用有限差分 \(\frac{f(x+\epsilon)-f(x-\epsilon)}{2\epsilon}\) 近似 \(\partial f/\partial x\) 喂给它。 - 现象/后果:在接触切换的时间步,有限差分跨越了接触不连续——算出的"雅可比"巨大(割线跨过了力的突变)或随 \(\epsilon\) 剧烈变化;iLQR 据此线性化,下降方向错误,迭代在接触附近震荡或发散。换个没接触的时间步又正常——结果时好时坏,极难调。 - 根本原因:有限差分假设函数在 \(\epsilon\) 邻域内近似线性,但接触切换处函数不连续,邻域内的割线斜率没有意义(§9.1 陷阱 1 的具体化)。给本质不连续的接触动力学"造"梯度,造出来的是垃圾,且垃圾只在接触步出现,更隐蔽。 - 正确做法:含接触的动力学(不可微)用采样式(第 7 章腿足 MPPI 的全部理由),它本就不需要雅可比。若坚持要用梯度式,需要专门的可微接触仿真(接触平滑、软接触模型),这是活跃研究、尚不成熟,别用朴素有限差分凑。自检:你的动力学有接触 / 碰撞 / 突变吗?有就别用有限差分给它造雅可比——要么用采样式,要么用成熟的可微接触工具(而非自己凑差分)。

陷阱 3:因为采样式能处理脏问题,就以为它"在脏问题上也能做到梯度式般的精度" ⚠️ 思维陷阱 - 错误想法:"采样式能处理不可微 / 黑箱问题,那它在这些问题上的表现应该也很好、很精确。" - 现象/后果:你用 MPPI 解一个不可微问题,期待它给出像 §9.3 iLQR 那样高精度的解,结果发现它只能给一个"大致可行、绕开了障碍但路径不够优、终点差一点"的解(如本节 MPPI 末端离目标 0.05、绕行路径不是最短),你失望地觉得"采样式不行"。 - 根本原因:混淆了"能解"和"解得精"。采样式在脏问题上的价值是"能给出一个可行的、合理的解"(梯度式在这里连可行解都给不出——它穿墙了),而不是"高精度最优"。采样式不利用结构(因为脏问题没有可利用的光滑结构),所以它的精度天花板就是"撒样本能逼近的程度",本就不如梯度式在光滑问题上的精度。在脏问题上,"能绕开障碍、大致到目标"已经是巨大的胜利(对比 iLQR 的穿墙)。 - 正确做法:对脏问题,把采样式的目标定位为"给出可行、合理的解",而非"高精度最优"——后者在脏问题上往往无从谈起(没有结构可榨)。若你既要处理脏问题、又要高精度,那就用混合架构(§9.5:采样式找到可行的好区域,再让梯度式在其中可微的部分做精炼)。自检:你在用采样式解脏问题时,是不是拿"梯度式在光滑问题上的精度"做不合理的对标?脏问题上"可行 + 合理"就是成功,要更高精度得靠混合或重新审视问题结构。

练习

  1. (辨析·我的问题落入哪类禁区,⭐⭐⭐) 对下面四个问题,分别判断它属于本节哪一类"求导失效"(非光滑代价 / 不可微动力学 / 黑箱),还是其实可微(梯度式能用),并说明理由:(a) 移动机器人用占据栅格代价地图避障;(b) 四旋翼跟踪一条光滑参考轨迹、动力学解析;(c) 机械臂在一个闭源商业物理引擎里做抓取;(d) 控制一个角色,代价是一个判断"动作是否自然"的神经网络打分。
  2. (复现 + 探究·障碍让梯度式失明,⭐⭐⭐) 跑通本节非光滑 demo,复现"iLQR 穿障碍 3 步、MPPI 绕开 0 步"。然后:(a) 把障碍 indicator 的惩罚从 1000 降到 10,看 iLQR 是否还穿墙(应该还穿——因为不管罚多少,indicator 的梯度都是零,惩罚大小不影响"梯度为零"这件事,这是个深刻的点);(b) 把 indicator 换成 §9.4 深一层说的 sigmoid 软近似 1000*sigmoid(k*dist),调不同的陡峭度 \(k\),观察 iLQR 能否绕开、绕得好不好(体会"抹平"的双刃剑);(c) 思考:为什么惩罚大小对 MPPI 有效(撞墙样本被压权重)、对 iLQR 无效(梯度恒零)?
  3. (思考·黑箱时代的方法选择,⭐⭐⭐⭐) 本节深一层论证"模型越来越黑箱,是采样式崛起的时代背景"。请综合论证:(a) 列举现代机器人栈里至少三个"能求值、但不好求导"的黑箱组件(提示:感知、学习的动力学、闭源仿真器);(b) 对每个,说明梯度式要用它需要克服什么工程困难、采样式为什么能即插即用;(c) 由此论证一个观点——"一项技术的兴起时机,往往由外部条件(这里是 GPU 普及 + 深度学习带来的黑箱组件)决定,而非仅由技术本身的优劣决定",并再举一个机器人 / AI 领域里"外部条件成熟才让某方法崛起"的例子(如深度学习等待算力和数据、Transformer 等待规模)。
  4. (辨析·感知代价的三雷,⭐⭐⭐) 本节深一层说感知驱动的代价"同时踩中非光滑 + 黑箱 + 噪声三个雷"。请:(a) 对一个"相机 + CNN 检测障碍 + 占据栅格"的避障代价,逐一指出它在哪里踩中这三个雷;(b) 解释为什么这三雷叠加让梯度式"彻底"没法用、而采样式对三雷都免疫(尤其说明大量采样 + 加权如何平滑掉雷三的噪声);(c) 由此提炼一条快速判据——"只要代价里有感知 + 神经网络的成分,几乎可直接判定采样式是主力",并说明这条快速判据和走完整决策树会得到一致的结论。

§9.5 混合架构——取两家之长 ⭐⭐⭐⭐

动机

§9.3 和 §9.4 让你看清:两家各有一片对方够不着的疆域(陆地与海洋)。但真实问题常落在"海岸线"上——既有需要全局搜索的非凸(采样式擅长),又有可以高精度精炼的光滑部分(梯度式擅长);既要采样式的灵活性能,又要硬约束的安全保证(梯度式 / CBF 擅长)。既然两家互补,最聪明的做法往往不是二选一,而是把它们组合起来,让每家干自己最擅长的那一段。 这一节讲四种经过工业 / 前沿验证的混合架构——它们是 §9.1 "两家互补"这一立场的最终兑现,也是你做真实系统时最常落地的形态(§9.6 工业案例里一半以上是混合)。

如果不这样做会怎样:在"海岸线"问题上死守纯方案

设想你信奉"纯粹",遇到海岸线问题也死守单一方案。你会两头吃亏。比如一个**非凸但光滑**的轨迹优化(多个局部最优 + 处处可微):纯 iLQR 会快速收敛——到离初值最近的那个**坏局部最优**(§9.5 demo 双势阱会演示),你以为收敛了就是最优,实则错过了好得多的全局解;纯 MPPI 能找到全局好区域,但因不利用光滑结构,精度只能"差不多"(§9.3 已证)。两个纯方案都不理想——而一个"MPPI 找全局好区域 + iLQR 精炼"的混合,既跳出局部、又拿到高精度,两全其美。又比如一个**要灵活性能 + 硬安全**的场景(无人机贴障碍飞):纯 MPPI 性能好但避障是软的(可能擦碰,§9.4);纯梯度式能保证硬约束但在感知驱动的脏代价上又使不上劲。最好的办法是"MPPI 出性能 + 一层硬安全滤波兜底"。死守纯方案,等于在该用两栖能力的地方,硬用陆地或海洋单一能力——这一节教你两栖。

历史与理论:四种混合架构

把两家组合的方式,业界沉淀出四种典型范式。它们的组合逻辑各不相同,分别解决不同的"海岸线"问题。

方案一:MPPI 全局初始化 + iLQR/DDP 局部精炼。 这是最直接的"接力"——用采样式的全局搜索找到一个好的"盆地"(basin),再用梯度式的局部精炼把解打磨到高精度。

阶段 1: MPPI(大 K, 充分探索) 全局搜索 → 得到粗解 U_init(找到好的 basin)
阶段 2: iLQR(以 U_init 为初值, 少量迭代) 局部精炼 → 高精度解 U*

适用场景:代价地形是**非凸但(至少局部)光滑**的——有多个局部最优(需要全局搜索找对盆地),但盆地内部光滑可微(梯度式能高效精炼)。这恰好补上了两家各自的短板:MPPI 的短板是精度(§9.3),iLQR 的短板是会陷最近的局部最优(§9.2、§9.5 demo)——一个管全局、一个管精度,接力解决。

方案二:MPPI + CBF 安全滤波——解耦性能与安全。 让 MPPI 自由地生成"想要的"控制(追求性能),再用一个**控制屏障函数(CBF)**做的安全滤波器,把这个控制"投影"到安全集合里。

MPPI 输出 u_mppi(追求性能, 但避障是软的) → CBF-QP 投影 → u_safe(保证安全)

CBF-QP:  min_u  ‖u − u_mppi‖²              // 尽量贴近 MPPI 想要的控制
         s.t.   ḣ(x,u) ≥ −α(h(x))          // CBF 安全约束(保证不进入危险集)
                u_min ≤ u ≤ u_max            // 控制约束

这是一个小的二次规划(QP),它找"离 \(u_\text{mppi}\) 最近、但满足 CBF 安全约束"的控制——在不违反安全的前提下,尽量满足 MPPI 的性能意图。它的妙处是**解耦了性能与安全**:MPPI 专心追性能(不用把安全编进它的软代价),CBF 专心保安全(一个有硬保证的小 QP)。这正好补上 §9.4 的痛点——采样式的避障是软的(可能擦碰),CBF 给它加上硬安全保证。Shield-MPPI(Yin & Tsiotras, Georgia Tech, IEEE RA-L 2023)更进一步:它把(离散)CBF 不是作为事后滤波,而是**作为增广的代价 / 惩罚项直接嵌入 MPPI 的 rollout**(并辅以 CBF 局部校正),从而在普通 CPU 上用**更少的样本**就实现鲁棒、安全的实时控制——把安全"内化"进采样过程,而非外挂。

方案三:RL 策略先验 + MPPI 微调(Biased-MPPI)。 用一个训练好的 RL 策略 \(\pi_\text{RL}\) 提供采样的"先验中心",MPPI 在它附近采样并加权。

采样均值 = π_RL(obs)          // RL 策略提供先验(把采样集中到好区域)
ε_k ~ N(0, Σ)
U_k = π_RL(obs) + ε_k          // 在 RL 策略附近采样
J_k = rollout(U_k)             // 标准 MPPI 求值
U* = Σ_k w_k · U_k             // 标准 MPPI 加权

逻辑是**优势互补**:RL 策略离线学到了"大致该怎么做"(把采样集中到好区域,大幅减少"浪费"在坏区域的 rollout,提升样本效率),但 RL 有 sim-to-real gap(仿真训的策略到真机会有偏差);MPPI 在线 rollout 微调,补偿这个 gap(在真实模型上实时纠偏)。Biased-MPPI(2024)正式化了这个思路——用辅助控制器(可以是 RL 策略,也可以是任何现成控制器)来"告知"(inform)采样分布的均值,让采样集中在有前途的区域。这把第 5 章"用学习改善采样分布"推到了"用 RL 策略做采样先验"。

方案四:MPPI 高层规划 + PD/WBC 底层跟踪——分层。 这是最常见的混合形态:MPPI 在一个**简化的、低维的空间**(如质心轨迹、足端位置)做高层规划(低频,如 10 Hz),输出参考轨迹;一个**底层跟踪器**(PD / 全身控制 WBC)在高频(如 1 kHz)把参考轨迹转成关节力矩。

MPPI(10 Hz, 简化空间) → 参考轨迹 x_ref(t)
WBC / PD(1 kHz, 力矩空间) → 关节力矩 τ

逻辑是**分层降复杂度 + 速率分离**(第 7 章 §7.5、第 8 章 §8.5 反复出现的母题):MPPI 不必在高维力矩空间采样(维度灾难,§9.3 ⑧),只在简化空间规划;底层跟踪器以高频保证执行的稳定与精度。这其实也是"采样式 + 非采样式"的混合(底层 WBC 常是基于模型的 QP / 梯度式)。第 7 章讲过,DIAL-MPC 的突破恰恰是证明了"直接在力矩空间做 MPPI 也可行"——挑战了"必须分层"的惯例,但分层至今仍是工程上最稳妥、最常用的形态。

这四种架构的共同精神,是 §9.1 "互补"立场的落地:找到问题里"采样式擅长的部分"和"梯度式/其他方法擅长的部分",让各家干各家最擅长的那一段,再拼起来——全局搜索归采样、局部精炼归梯度(方案一),性能归采样、安全归 CBF(方案二),先验归 RL、在线纠偏归采样(方案三),高层规划归采样、底层跟踪归 WBC(方案四)。

一个能跑的对照:双势阱上,MPPI 找盆地、iLQR 精炼、混合最优

把方案一(全局初始化 + 局部精炼)跑出来看。构造一个**真正多峰、但光滑**的代价:一维点质量,终端代价是一个**双势阱** \(W(x)=(x^2-4)^2-0.6x\)——它有两个极小:全局阱在 \(x\approx+2\)(更深,因为 \(-0.6x\) 让右边更低)、局部阱在 \(x\approx-2\)。起点 \(x_0=-1\)(靠近左边的局部阱)。这个代价处处光滑可微(对梯度式友好),但非凸(有两个盆地)——正是方案一的典型场景。先看代价与三种解法:

import numpy as np
rng = np.random.default_rng(1)
dt, H = 0.1, 30
def W(x):  return (x*x-4.0)**2 - 0.6*x      # 双势阱: 全局阱 x≈+2, 局部阱 x≈-2
x0 = -1.0; Rc = 0.02                          # 起点靠近局部阱
def rollout(U):
    xs=[x0]
    for t in range(H): xs.append(xs[-1]+dt*U[t])
    return np.array(xs)
def cost(U):
    xs=rollout(U); return float(Rc*np.sum(U**2) + W(xs[-1]))

三种解法:iLQR 从零初值出发(纯梯度式)、MPPI 全局采样(纯采样式)、MPPI 的解再喂给 iLQR 精炼(混合方案一):

U_il = ilqr(np.zeros(H))   # 纯梯度式: 从零初值, 沿梯度下降
U_mp = mppi()              # 纯采样式: 全局撒样本
U_hy = ilqr(U_mp)          # 混合: 以 MPPI 解为初值, iLQR 精炼
xi, xm, xh = rollout(U_il)[-1], rollout(U_mp)[-1], rollout(U_hy)[-1]
print(f"iLQR 从零      : 末端 x={xi:+.2f}, 代价 {cost(U_il):6.2f}  (滑入局部阱 -2)")
print(f"MPPI 全局      : 末端 x={xm:+.2f}, 代价 {cost(U_mp):6.2f}  (找到全局阱 +2)")
print(f"MPPI+iLQR 混合 : 末端 x={xh:+.2f}, 代价 {cost(U_hy):6.2f}  (全局阱+局部精炼)")
# 典型输出:
#   iLQR 从零      : 末端 x=-1.98, 代价   1.26  ← 陷局部阱(从x0=-1就近滑进左阱)
#   MPPI 全局      : 末端 x=+2.00, 代价  -0.58  ← 找到全局阱(撒得广, 跳过中间的山脊)
#   MPPI+iLQR 混合 : 末端 x=+2.01, 代价  -0.60  ← 全局阱 + 精炼到更低

三个结果讲了一个完整的故事:纯 iLQR(从 \(x_0=-1\) 出发)沿梯度就近滑进左边的**局部阱**(\(x=-1.98\),代价 \(1.26\))——它快速"收敛"了,但收敛到一个坏解,因为它跳不过中间那道分隔两阱的"山脊"(§9.2 易错点:梯度式只到最近的局部最优)。纯 MPPI 撒得广,样本跨过山脊、找到了右边更深的**全局阱**(\(x=+2.00\),代价 \(-0.58\))——全局搜索成功,但解是"粗"的(采样精度有限)。混合(MPPI 解 → iLQR 精炼)拿到两家之长:先靠 MPPI 落到全局阱(跳出局部),再靠 iLQR 在阱内精炼到更低的代价(\(-0.60\),比纯 MPPI 还低一点)。这就是方案一的价值——全局搜索(采样)找对盆地,局部精炼(梯度)打磨精度,1+1>2。

这个 demo 也呼应了 §9.7 的 CartPole 基准(iLQR 从零陷局部、采样式全局成功)——双势阱是那个现象最纯粹的"显微镜版":你能清清楚楚看到 iLQR 滑进哪个阱、MPPI 跳到哪个阱、混合如何兼得。

一个能跑的对照(二):CBF 安全滤波——软惩罚越界、硬滤波兜底

方案二(MPPI + CBF)前面只给了伪代码。用一个最小可跑的 1D 例子,亲眼看到"软惩罚不保证安全、CBF 硬滤波保证安全"的区别。系统极简:1D 位置 \(x\),控制是速度,\(x_{t+1}=x_t+\Delta t\, u\)安全集是 \(x\le 2\);任务故意把目标设在**边界之外**(\(x=4\)),逼着控制器"想冲过边界"——这正是考验避障的场景。先看 MPPI 的软惩罚版(越界才罚):

dt, H, XMAX = 0.1, 50, 2.0                    # 安全边界 x<=2; 目标 x=4 在界外
def mppi_unsafe(K=2000, pen=8.0, ...):        # 软惩罚: 越界给惩罚, 但仍可能越界
    ...
    J += (x - 4.0)**2 * 0.5                    # 趋目标(目标在界外, 拉力强)
    J += pen * np.maximum(x - XMAX, 0.0)       # 软惩罚: 只在越界时罚(软约束)
    ...

再看 CBF 安全滤波——1D 下 CBF-QP 有解析解:取 \(h(x)=2-x\)\(h\ge 0\) 即安全),离散 CBF 条件 \(h(x_{t+1})\ge(1-\alpha)h(x_t)\) 化简后给出控制上界 \(u\le \alpha(2-x)/\Delta t\),滤波就是把 MPPI 的控制投影到这个上界内:

def simulate(U, use_cbf, alpha=0.5):
    x = 0.0; xs = [x]
    for t in range(H):
        u = U[t]
        if use_cbf:
            u_max_safe = alpha * (XMAX - x) / dt   # CBF 给出的控制上界(解析)
            u = min(u, u_max_safe)                 # 投影: 取较小者, 保证不越界
        x = x + dt * u; xs.append(x)
    return np.array(xs)
U = mppi_unsafe()
x_soft = simulate(U, use_cbf=False)            # 纯软惩罚
x_cbf  = simulate(U, use_cbf=True)             # 软惩罚 + CBF 硬滤波
print(f"MPPI 软惩罚    : 最大 x={x_soft.max():.3f}")
print(f"MPPI + CBF 滤波: 最大 x={x_cbf.max():.3f}")
# 典型输出:
#   MPPI 软惩罚    : 最大 x=2.174   ← 越界! 为追界外目标冲过了 x=2
#   MPPI + CBF 滤波: 最大 x=1.758   ← 未越界(硬保证), 死死压在 x=2 内

结果干净利落:纯软惩罚的 MPPI 为了追界外的目标,把 \(x\) 冲到了 \(2.174\)——越界了(惩罚是软的,目标拉力够强时它宁可吃惩罚也要越界靠近目标);加上 CBF 硬滤波后,\(x\) 被死死压在 \(2.0\) 以内(最大 \(1.758\))——硬保证不越界。这正是 §9.5 方案二的核心价值,也印证了第 8 章 §8.7 反复强调的"软避障 ≠ 硬安全":软惩罚只是"让越界变贵",权衡之下仍可能越界;CBF 是"数学上保证不进危险集",这是质的区别。注意 CBF 滤波让 MPPI 的性能意图(冲向目标)受了限(停在 \(1.758\) 而非冲过去),但换来了硬安全——这正是"解耦性能与安全"的体现(§9.5 深一层):MPPI 尽力追性能,CBF 在安全前提下尽量满足它。这个 demo 把方案二从伪代码变成了你能亲手验证的"硬安全 vs 软惩罚"对照。

深一层:为什么"全局初始化 + 局部精炼"这个组合如此自然且普适

方案一(全局 + 局部接力)值得展开,因为它不只是 MPPI+iLQR 的一个技巧,而是优化领域一个**极其普适的元模式**,理解它能让你在远超本章的场景里复用。

这个模式的普适性,根源在于"全局搜索"和"局部精炼"是优化的**两个本质不同、且互补的子任务**。全局搜索要解决"在哪个盆地"——这是个离散的、组合的、需要广撒网的问题,怕的是陷局部,要的是探索广度(采样、随机重启、进化算法都擅长)。局部精炼要解决"盆地内的哪个点"——这是个连续的、可用梯度高效逼近的问题,怕的是慢,要的是收敛速度(梯度法、牛顿法擅长)。这两个子任务的"性格"截然相反(广度探索 vs 快速收敛),几乎没有哪个单一方法能同时把两者都做到最好——所以"用擅长探索的方法定盆地、用擅长收敛的方法定点"的接力,就成了自然的最优分工。

这个模式在机器学习和优化里反复出现:神经网络训练的"随机初始化(探索) + 梯度下降(精炼)"、超参数搜索的"随机 / 贝叶斯搜索(全局) + 局部微调"、运动规划的"采样式找路径(RRT,全局) + 轨迹优化平滑(局部)"、甚至 §9.6 会看到的工业 MPC 栈(全局规划器 + 局部梯度式 MPC)。

本质洞察"全局搜索定盆地 + 局部精炼定点"是优化的一个普适元模式,它的普适性源于"探索广度"和"收敛速度"是一对几乎不可兼得的性格——广撒网的方法(采样、随机、进化)擅长探索但精炼慢,靠导数的方法(梯度、牛顿)擅长收敛但易陷局部。把两者接力,正是用各自的长处补对方的短处。本章的 MPPI+iLQR 只是这个元模式在采样 / 梯度 MPC 上的一个实例。掌握这个元模式,你看任何"既要跳出局部、又要高精度"的优化问题,第一反应就该是:"能不能用一个全局方法定盆地、再用一个局部方法精炼?"——这个"分工接力"的思维,比记住任何单一算法都更有迁移价值。它也再次诠释了本章的核心:方法不是用来互相竞争淘汰的,而是用来**按各自所长组合分工**的。

深一层:CBF 安全滤波为什么是"解耦"的胜利

方案二(MPPI + CBF)值得展开,因为它体现了一个比"加个安全层"更深的设计思想——解耦(decoupling),这是工程里降低复杂度的核心武器。

朴素的做法是把安全"编进" MPPI 的代价——给撞障碍加一个高惩罚(§9.4 demo 就是这么做的)。但这有几个问题:其一,惩罚权重极难调(太小不管用、太大扭曲性能目标,第 8 章 §8.7 反复讲);其二,它只是"软"的——惩罚再高,采样仍可能给出违反的解(§9.4),没有硬保证;其三,安全和性能纠缠在一个代价里,调一个影响另一个。

方案二的思路是把安全**从性能里解耦出来**:MPPI 的代价只管性能(别再编安全进去),安全交给一个独立的、有硬保证的 CBF-QP 滤波器。这样:MPPI 专心追性能(代价简单、好调);CBF 专心保安全(数学上保证不进危险集);两者**各自独立、互不污染**——你调性能不影响安全保证,改安全集不影响性能目标。这正是"关注点分离"(separation of concerns)在控制里的体现。

本质洞察:方案二的深层价值不是"加了 CBF",而是**把"性能"和"安全"两个纠缠的关注点解耦成两个独立模块**——一个专心优化性能(MPPI)、一个专心保证安全(CBF-QP),各自可独立设计、调试、验证。解耦之所以强大,是因为它把一个"既要又要、互相牵制"的复杂问题,拆成两个"各管一头、互不干扰"的简单问题(这呼应第 8 章 §8.7 的"正交分解"母题)。这个思想远超 CBF:任何时候你面对"既要 A 又要 B、而 A 和 B 互相牵制"的设计,都该问"能不能把 A 和 B 解耦成两个独立模块,让一个专心做 A、一个专心做 B?"——能解耦,复杂度就从"A×B 的纠缠"降为"A + B 的相加"。Shield-MPPI 把 CBF 内化进 rollout(而非外挂滤波)是另一种权衡——牺牲一点解耦的纯粹性,换取用更少样本、更紧地集成安全与性能;这说明解耦不是教条,工程上也会按需在"解耦的清晰"和"集成的高效"之间取舍。但理解解耦这个默认武器,是设计安全关键系统的基本功。

深一层:混合架构的"接口"为什么必须简单——模块化的纪律

§9.5 多视角会说四种混合的"接口"是清晰、机械的。这个"接口简单"不是巧合,而是混合架构能可靠工作的**必要纪律**——值得展开,因为它决定了你的混合系统是"优雅可靠"还是"一团乱麻"。

  • 接口简单 = 单向、低维、语义清晰的数据传递:方案一的接口是"MPPI 输出一段控制序列 \(U_\text{init}\) → 传给 iLQR 当初值"(单向、就是一个数组);方案二是"MPPI 输出 \(u_\text{mppi}\) → 传给 CBF-QP"(单向、一个向量);方案四是"MPPI 输出参考轨迹 → 传给 WBC"(单向、一条轨迹)。都是**单向数据流 + 低维接口 + 明确语义**,没有双向纠缠、没有共享的可变状态。
  • 为什么必须简单:如果接口复杂(双向耦合、共享状态、隐式依赖),两个模块就**不再独立**——改一个会以难以追踪的方式影响另一个,调试时无法隔离问题(到底是 MPPI 的错还是 iLQR 的错?),各模块也无法独立替换 / 测试。复杂接口让"混合"退化成"耦合的单体",失去模块化的全部好处。
  • 简单接口换来的三个好处:① 可独立开发 / 测试(各模块对着接口单独验证);② 可独立替换(把 iLQR 换成别的精炼器、把 CBF 换成别的安全层,只要接口不变)——这正是 §9.7 累积项目 solver_backend 能"即插即换"的基础;③ 可独立推理(出问题时能按接口隔离定位)。
  • 代价 / 纪律:保持接口简单需要**克制**——抵抗"让两个模块多交换点信息也许能更好"的诱惑(那往往以接口复杂化为代价)。简单接口有时要牺牲一点理论最优(如方案二的 CBF 投影可能比"联合优化性能与安全"略保守),但换来的工程可靠性通常更值。

本质洞察:混合架构的可靠性,根植于**模块间接口的简单性(单向、低维、语义清晰)——这是软件工程"高内聚、低耦合"原则在控制架构上的体现。简单接口让"组合"成为真正的组合(各模块独立、可替换、可单独推理),而非"伪组合"(实为纠缠的单体)。这条纪律的迁移价值极大:**任何时候你把多个组件拼成一个系统,接口的简单性比单个组件的强大更决定系统的可维护性——一堆强大但接口复杂纠缠的组件,远不如一组适中但接口干净的组件可靠。这也解释了为什么 §9.7 的累积项目能把"求解器范式"做成一根可即插即换的旋钮:正因为各模块(采样内核、梯度精炼、鲁棒层)之间是简单的单向接口,才能像换零件一样替换。设计任何可组合、可演进的系统,"守住接口简单"都是第一纪律——这比追求单个模块的极致更重要。

多视角:四种混合像"专家团队的四种协作方式"

给四种混合架构配个直觉:把采样式和梯度式(及 RL、WBC)看成**不同专长的专家**,四种架构是他们的四种协作方式。

方案一像"先头部队 + 精修工匠":采样式专家像广撒网的侦察兵,先大致探明"宝藏在哪个区域"(找盆地);梯度式专家像精修工匠,在侦察兵指出的区域里精雕细琢(精炼到高精度)。方案二像"激进设计师 + 安全审查员":MPPI 像追求性能的激进设计师,大胆出方案;CBF 像安全审查员,在不否定设计意图的前提下,把方案改到安全合规(投影到安全集)。方案三像"老师傅带徒弟":RL 策略像有经验的老师傅,先给出"大致该怎么做"的示范(先验);MPPI 像在现场根据实况微调的徒弟,补上老师傅经验里没覆盖的实际偏差(sim-to-real)。方案四像"战略家 + 执行官":MPPI 像定大方向的战略家(高层、低频、简化空间);WBC/PD 像把战略落地为具体动作的执行官(底层、高频、力矩空间)。

像的地方:四种协作都体现"让最擅长某事的专家做某事"的分工智慧,准确反映了混合架构"各取所长"的本质。不像的地方(边界):真实的专家协作有沟通成本、责任边界的模糊,而这四种架构的"接口"是清晰、机械的(前一阶段的输出直接是后一阶段的输入)——别把它过度拟人化,以为混合架构像人类团队那样需要复杂协调。它们的优雅恰恰在于**接口简单、职责清晰**:方案一就是"U_init 传给 iLQR",方案二就是"u_mppi 传给 CBF-QP",没有模糊地带。这种"清晰接口的模块化组合"正是它们工程上可靠、易实现的原因(也是 §9.7 累积项目"求解器后端"能即插即换的基础)。

深一层:第五种"隐式混合"——把梯度信息喂进采样

§9.5 讲的四种混合,都是"两家分阶段 / 分层接力"的**显式**组合(一家的输出喂给另一家)。还有一种更"隐式"的混合也值得知道——在采样的内部就利用梯度信息,让采样本身变得"有方向感"。

  • 思路:标准 MPPI 撒的是各向同性的高斯噪声(盲撒)。但如果你能算出代价 / 动力学的(哪怕是局部、近似的)梯度,就可以用它**引导采样**——比如把采样分布的均值朝梯度下降方向偏移、或把协方差沿梯度方向拉长(在"更可能有改进"的方向多撒)。这样采样既保留了全局性(还是撒一片),又借了梯度的"方向感"(撒得更聪明)。代表性的思路包括用梯度信息构造更优的提议分布、Stein 变分等"梯度引导的采样"方法。
  • 它和四种显式混合的区别:四种显式混合是"两个独立模块接力"(接口清晰、§9.5 深一层),这第五种是"在采样这一个模块内部融入梯度"——梯度不是一个独立阶段,而是**改造了采样的撒法**。所以它是"隐式"的:你看到的还是一个采样器,只是它的采样分布被梯度塑形过。
  • 前提与代价:它要求能算梯度(至少局部、近似)——所以**只适用于(部分)可微的问题**(不可微问题回到纯采样)。它的回报是在可微问题上让采样更高效(少撒点也能找对方向),但实现更复杂、且引入了梯度的脆弱性(梯度坏时可能误导采样)。
  • 怎么定位它:它处在"纯采样(零阶)"和"纯梯度(一阶/二阶)"之间的**连续谱**上(§9.1 零阶/一阶/二阶的谱)——是"零阶为主、掺一点一阶"的混合点。前沿"学习采样分布"的一些工作也属于让采样更有方向感的努力(用学到的模型 / 梯度引导采样)。

本质洞察:除了"两家分阶段接力"的显式混合,还有"在采样内部融入梯度信息"的**隐式混合**——它把 §9.1 那条"零阶↔一阶↔二阶"的谱填得更满:不是只有两端(纯采样 / 纯梯度)和"接力",中间还有"用梯度塑形采样"的连续过渡带。这深化了本章的核心立场:采样式与梯度式不仅"可以接力组合",它们之间本就存在一个连续谱,你可以在谱上任意取点(用多少梯度信息来引导采样)。理解这个连续谱,你就彻底超越了"采样 vs 梯度"的二元对立——它们是一个连续体的两端,中间有无穷多种"掺多少梯度"的混合配方。这也预告了前沿方向(§前沿"学习采样分布""统一视角")的深层动机:把两家统一进一个连续的框架,按问题在谱上选最优的点,而非在两端二选一。框架思维(§9.7)的终极形态,正是这种"连续谱上的自由取点"。

深一层:混合架构的失败模式——当两家"打架"

§9.5 讲的混合都是"两家和谐协作"的成功图景。但混合也有它特有的失败模式——当两个组件的目标 / 假设不一致时,它们会"打架",结果比任一纯方案还差。认清这些失败模式,才能让你的混合系统真正可靠。

  • 失败模式一:精炼器把全局解"拉回"局部(方案一)。MPPI 找到了全局好盆地,但若 iLQR 精炼的迭代数太多 / 步长太大,或代价在盆地边缘有别的局部最优,iLQR 可能把解"精炼"出原盆地、滑进一个更差的近邻局部最优——你以为精炼会更好,它反而毁了 MPPI 的全局成果。处方:精炼"少量迭代、小步长"(只在盆地内微调,别让它跑远)。
  • 失败模式二:安全层和性能层"对着干"(方案二)。MPPI 一个劲往障碍冲(追性能),CBF 一个劲把它推开(保安全),两者在障碍附近**反复拉锯**——控制信号震荡、机器人在边界附近抖动、既不前进也不安全平滑。根源是 MPPI 完全不知道 CBF 的存在(它的代价里没编安全),输出的意图和 CBF 的约束严重冲突。处方:让 MPPI 的代价里也加一点"软避障"(让它的意图本就不太冲撞安全集),减少和 CBF 的拉锯——这也是 Shield-MPPI 把 CBF 内化进 rollout(让采样本身就考虑安全)的动机。
  • 失败模式三:RL 先验把采样"带偏"(方案三)。若 RL 策略的 sim-to-real gap 很大(仿真和真机差很多),它给的"先验中心"可能恰好是真机上的坏区域,MPPI 在这个坏中心附近撒样本,反而比从零撒更难找到好解——错误的先验比没有先验更糟。处方:给 MPPI 留足够的探索(采样幅度别太小),让它能在 RL 先验不可靠时"挣脱"先验、自己找到好区域。
  • 失败模式四:分层的两层"时间尺度打架"(方案四)。高层 MPPI(低频)的参考轨迹变化太快 / 不平滑,底层 WBC(高频)跟不上或被激励出震荡——两层的动态没协调好。处方:让高层输出平滑、可跟踪的参考(考虑底层的跟踪能力),别给底层一个它跟不动的参考。

本质洞察:混合的失败,几乎都源于**两个组件的"目标 / 假设 / 时间尺度"不一致而互相对抗**——精炼器和全局解抢方向、安全层和性能层抢控制、错误先验把采样带偏、两层时间尺度不匹配。这揭示了组合系统的一个普遍真理:把两个各自正确的组件拼在一起,整体未必正确——除非它们的目标和假设是相容的、且接口处的"交接"是协调的。这比"接口要简单"(§9.5 深一层)更进一层:接口简单是必要的(数据能干净传递),但还不够——还要保证两个组件"想要的东西不冲突"(目标相容)。设计任何混合 / 组合系统,除了守住接口简单,还要主动检查"这两个组件会不会打架"(目标冲突?假设矛盾?时间尺度不匹配?),并设计协调机制(让它们的意图趋于一致,如让 MPPI 也知道一点安全、让高层输出可跟踪的参考)。"1+1 可能小于 1"——组合的风险,正是成熟工程师在拼装系统时时刻警惕的;天真地以为"好组件拼起来一定是好系统",是组合系统失败的头号原因。

易错点:混合不是"叠加越多越好",每加一层都有成本

学到四种漂亮的混合架构,一个常见的冲动是"全都用上、叠得越多越强"。这是个要警惕的误区。每加一个混合层,都有实打实的成本:方案一加 iLQR 精炼,意味着要实现并维护一个梯度式后端(需要可微动力学 / 雅可比),还多一个"精炼几轮"的超参;方案二加 CBF 滤波,意味着要设计 CBF(选合适的屏障函数 \(h\)、调 class-K 函数 \(\alpha\),本身不简单)、每步多解一个 QP(增加计算和延迟);方案三加 RL 先验,意味着要先训一个 RL 策略(数据、训练、sim-to-real 的全套麻烦)。这些成本是叠加的——你混合的层越多,系统越复杂、越难调试、越多可能出错的环节、延迟越大。正确的心态是:只在"单一方案确实不够、且某个混合确实能补上关键短板"时,才加对应的混合层——按真实需求加,而非为了"更强"而堆砌(这正是第 8 章 §8.7 "别为灵活而灵活、简单是需要捍卫的美德"那条智慧在混合架构上的体现)。判断标准:你要加的这一层,补的是不是你的问题真正的、关键的短板?比如你的问题根本不是非凸的(只有一个盆地),那方案一的"全局初始化"就是多余的(iLQR 从零也能到那唯一的最优),加了纯属增加复杂度。自检:每想加一个混合层,先问"不加它会具体差在哪、加它的成本(实现 / 调试 / 延迟)值不值得补这个差"——值才加。

⚠️ 常见陷阱

陷阱 1:方案一里给 iLQR 精炼用的动力学/代价,其实不可微 ⚠️ 编程陷阱 - 错误做法:你想用方案一(MPPI 全局 + iLQR 精炼),但你的问题动力学含接触、或代价含 indicator(本就是因为这些"脏"才用 MPPI 的)——你却直接拿来给 iLQR 精炼。 - 现象/后果:iLQR 精炼阶段在不可微处发散 / 震荡(§9.4 陷阱 2 的重演),不仅没精炼好,还把 MPPI 找到的好解给"精炼坏"了——混合后反而不如纯 MPPI。 - 根本原因:方案一的"局部精炼"用的是梯度式,它要求**精炼阶段面对的动力学和代价是(至少局部)可微的**。如果你的问题整体不可微(接触、indicator),那它根本不满足方案一的前提——方案一适用的是"非凸但光滑"(盆地间需全局搜索、盆地内光滑可精炼),不是"非光滑"。 - 正确做法:用方案一前,确认"盆地内部"是光滑可微的(精炼阶段梯度式能用)。若问题处处不可微(如纯接触、纯 indicator),方案一不适用——这种问题用纯采样式,或考虑别的混合(如方案二加安全、方案四分层)。自检:你打算让 iLQR 精炼的那个目标,在 MPPI 找到的解附近是光滑可微的吗?不是的话,别用方案一精炼。

陷阱 2:把 CBF 安全滤波当成"万能安全保险",忽视它的前提 ⚠️ 概念误区 - 错误想法:"加了 CBF 安全滤波(方案二),系统就绝对安全了,MPPI 怎么浪都没事。" - 现象/后果:你依赖 CBF 兜底,结果在某些情况下仍然出事——比如 CBF 用的模型不准(CBF 的安全保证建立在动力学模型上,模型错了保证就破)、或控制约束 \(u\in[u_\min,u_\max]\) 太紧导致 CBF-QP 无解(没有可行的安全控制)、或安全集 / 屏障函数 \(h\) 设计得不对(没覆盖真正的危险)。 - 根本原因:CBF 的"硬安全保证"是**有前提的数学保证**——它假设动力学模型准确、控制权限足够、屏障函数正确刻画了安全集。这些前提一旦不满足,保证就失效。把"有前提的保证"误当成"无条件的万能保险",是安全关键系统里最危险的误区。 - 正确做法:清楚 CBF 保证的前提(模型准确性、控制权限、屏障函数正确性),并对前提本身做工程保障(模型辨识 / 留控制余量 / 仔细设计 \(h\))。CBF 是强大的安全工具,但不是无条件的(第 8 章 §8.7 "软避障≠硬安全"已铺垫,CBF 是"有前提的硬安全")。自检:你的 CBF 安全保证依赖哪些前提(模型、控制权限、\(h\) 的正确性)?这些前提在你的系统里真的成立吗、有没有兜底?

陷阱 3:以为混合架构是"前沿炫技",纯方案才是"实用主流" ⚠️ 思维陷阱 - 错误想法:"混合架构听起来复杂、像论文里的花活,真实工业系统应该都是简单的纯方案。" - 现象/后果:你在真实项目里排斥混合、死守纯方案,结果做出来的系统要么性能不足、要么不够安全、要么陷局部——而你的同行用混合架构(如分层 MPPI+WBC、或 MPPI+CBF)轻松超过了你。 - 根本原因:把"简单"等同于"实用",把"混合"误解为"炫技"。但事实恰恰相反——真实工业系统里,纯方案反而是少数,混合 / 分层才是主流(§9.6 工业案例里:腿足是 MPC+WBC 分层、自驾是全局规划+局部 MPC、很多系统是采样+梯度或学习+控制的组合)。因为真实问题几乎总落在"海岸线"上(多种需求并存),单一纯方案很难同时满足,混合才是常态。 - 正确做法:把混合架构当成**真实系统的常态和默认形态**,而非炫技——遇到真实问题,主动想"这个问题的不同部分分别适合哪家、怎么组合"。最常见、最该先想到的是方案四(分层)和方案一(全局+精炼)。自检:你设计一个真实系统时,是不是下意识排斥混合、只想用一个纯方法?真实世界的最优解往往是混合——别被"简单=实用"的直觉误导(这里的"简单"应是"接口清晰",而非"只用一个方法")。

练习

  1. (设计·给问题选混合架构,⭐⭐⭐) 对下面三个场景,分别说明四种混合架构里哪种(或哪几种组合)最合适,并说明理由:(a) 一个非凸但光滑的机械臂轨迹优化(多个局部最优、处处可微、要高精度);(b) 一架要贴着障碍激进飞行、但绝不能撞的无人机(要性能 + 硬安全);(c) 一个全身人形机器人,已有一个仿真训好但有 sim-to-real gap 的 RL 行走策略,想在真机上更鲁棒。
  2. (复现 + 探究·双势阱混合,⭐⭐⭐) 跑通本节双势阱 demo,复现"iLQR 陷局部 1.26、MPPI 全局 -0.58、混合 -0.60"。然后:(a) 把起点 x0 从 -1 改到 +1(靠近全局阱),看纯 iLQR 是否就能到全局阱了(体会"初值决定 iLQR 落哪个阱",也说明"问题若初值就在好盆地,方案一的全局搜索就多余",呼应易错点);(b) 把双势阱改得更"深沟"(如 W(x)=(x²-4)²*5-0.6x,山脊更高),看 MPPI 是否还能跨过山脊找到全局阱、需不需要加大 sigma/K;(c) 对比"纯 MPPI 撒很多样本"和"MPPI 少样本 + iLQR 精炼"哪个性价比高(体会方案一为什么省)。
  3. (思考·解耦的威力,⭐⭐⭐⭐) 本节深一层说方案二的本质是"解耦性能与安全"。请综合论证:(a) 为什么"把安全编进 MPPI 代价"(软惩罚)和"用 CBF 解耦"在工程上有本质区别(从权重调参、硬保证、关注点纠缠三方面);(b) 解耦的代价是什么(提示:多一个模块、CBF 的前提、可能的保守性);(c) 再举两个机器人 / 软件领域里"用解耦降低复杂度"的例子(如感知与控制解耦、第 8 章规划与执行解耦、软件的接口与实现解耦),说明它们各自解耦了什么、换来了什么。
  4. (复现 + 探究·CBF 硬安全,⭐⭐⭐) 跑通本节 CBF 安全滤波 demo,复现"软惩罚越界 2.17、CBF 硬滤波压在 2.0 内"。然后:(a) 把软惩罚 pen 从 8 加大到 50、200,看 MPPI 软惩罚是否仍越界(体会"惩罚大能减少越界,但理论上不保证不越界");(b) 调 CBF 的 alpha(0.1 / 0.5 / 0.9),看它如何影响"何时开始减速"(小 \(\alpha\) 更早更温和、大 \(\alpha\) 更晚更急);(c) 制造一个"控制权限不足"的情形(如把目标设得很远、需要的速度超过 CBF 允许的上界),观察会发生什么,并联系 §9.5 陷阱 2(CBF 的前提)。
  5. (思考·混合的失败模式,⭐⭐⭐⭐) 本节深一层列举了四种混合"打架"的失败模式。请:(a) 对方案二(MPPI + CBF),具体描述"性能层和安全层拉锯"会表现成什么(控制信号、机器人行为)、根因是什么、怎么缓解;(b) 论证一个一般观点——"两个各自正确的组件拼起来未必正确",并说明除了"接口简单",还需要保证什么(目标相容);(c) 举一个你知道的(机器人或软件)"好组件拼成坏系统"的例子。

§9.6 工业案例剖析与选型决策树 ⭐⭐⭐

动机

前面几节给了你"两家各自的长短(§9.3、§9.4)"和"怎么组合(§9.5)",这一节把它们落到地面:看七个真实的工业 / 前沿系统**实际上**选了什么、为什么这么选,再把这些选择背后的逻辑提炼成一棵**决策树**——给你一个"拿到新问题,照着走就能选对求解器"的可操作流程。这是本章从"理解两家"到"会选"的关键一跃。看完你会发现:真实系统的选择,几乎都能用 §9.3 那颗种子(求值 vs 求导)+ 几个关键维度(可微性、约束、平台、维度)解释清楚——理论不是空谈,它精确地预测了工业界的选择

如果不这样做会怎样:凭"潮流"或"手熟"选求解器

设想你不看真实案例、不走决策流程,凭"潮流"("现在流行端到端 / RL / MPPI,那就用它")或"手熟"("我只会 MPPI,那都用 MPPI")选求解器。你会做出系统性的错误选择。比如:你看到学术界 MPPI 论文很火,就给一个四旋翼轨迹跟踪(光滑可微、要硬约束推力、跑在无 GPU 的飞控上)也上 MPPI——而整个工业界(openpilot、无数四旋翼)在这类问题上用的是 acados(SQP-RTI),因为它在这个场景下又快又精确又能管硬约束、且 CPU 友好。你的选择不是基于问题特性,而是基于潮流,结果做出一个比同行差一截的系统。凭潮流 / 手熟选求解器,是把"我熟悉什么 / 什么流行"凌驾于"问题需要什么"之上——而这一节的案例和决策树,正是要把选择的依据扳回到"问题特性"上。看完真实工业界的选择,你会对"什么问题该用什么"有一个被实践检验过的、扎实的判断。

历史与理论:七个真实系统的选择剖析

下面这张表把七个有代表性的真实系统(横跨导航、驾驶、操作、飞行、腿足、人形)的求解器选择并排,再逐一剖析其背后的逻辑。这些系统前几章大多见过,这里换一个视角——从"它为什么这么选求解器"重新审视:

应用 选择的方案 根本原因(用本章维度解释)
Nav2 移动机器人导航 CPU 上的 MPPI(Nav2 控制器) 代价地图不可微(§9.4 第一类);CPU-only 平台;ROS2 生态成熟
AutoRally 激进驾驶 GPU 上的 MPPI CNN 代价地图不可微(§9.4);越野漂移要 agile 控制;有车载 GPU
Franka 机械臂抓取 STORM(GPU MPPI) 碰撞 / SDF 代价不可微(§9.4);GPU 可用;高维但可降
四旋翼轨迹跟踪 acados(SQP-RTI) 动力学解析可微(§9.3);要硬约束(推力上限,§9.3 ⑥);CPU 嵌入式飞控
Go2 四足行走 OCS2(SLQ/WBC) 已知周期步态(光滑可规划);CPU 实时;要硬约束(摩擦锥);几十维(§9.3 ⑧)
Go2 四足跳跃 DIAL-MPC / RL 非结构化剧烈运动;接触不可预测、不可微(§9.4 第二类);要全局搜索
人形全身运动 DIAL-MPC + RL 微调 高维力矩空间(§9.5 方案三 / 四);接触丰富;需全局搜索 + 先验

前三个(导航、驾驶、操作)都选了采样式(MPPI / STORM)——共同点是代价不可微。 Nav2 的代价来自占据栅格地图(阶梯状,§8.3),AutoRally 来自 CNN(§8.2),STORM 来自碰撞 / 符号距离场(SDF)——全是 §9.4 第一类"非光滑代价"。代价一旦不可微,梯度式直接出局(§9.4),采样式成了自然选择。它们的差别只在硬件:Nav2 跑在无 GPU 的移动机器人上(CPU MPPI,\(K\) 受限但够用),AutoRally 和 STORM 有 GPU(能撒大 \(K\))。这三个案例精确印证了 §9.4:代价不可微 → 采样式。

中间两个(四旋翼、四足行走)都选了梯度式(acados / OCS2)——共同点是问题光滑可微、要硬约束、且常在 CPU 上。 四旋翼跟踪光滑参考轨迹,动力学解析可微,要满足推力 / 姿态的硬约束,跑在嵌入式飞控(无 GPU)——这正是 §9.3 ⑨ 梯度式的杀手场景(光滑约束优化 + CPU),acados 的 SQP-RTI(每步只做一次 SQP 迭代以保实时,§9.2)在这里又快又精确又能管硬约束。Go2 周期行走有已知步态(结构化、可规划),要满足摩擦锥硬约束,是几十维问题,OCS2(用 SLQ / SQP 加全身控制)在 CPU 上实时处理这些——梯度式靠导数上几十维不费力(§9.3 ⑧),且原生处理硬约束(§9.3 ⑥)。这两个案例精确印证了 §9.3:光滑 + 硬约束 + CPU → 梯度式。

最后两个(四足跳跃、人形全身)转向采样式 / 混合 / RL——共同点是运动非结构化、接触不可预测、维度极高。 四足跳跃是剧烈的、非周期的、接触时刻不可预测的运动——接触不可微(§9.4 第二类),且没有现成的"步态结构"可供梯度式规划,DIAL-MPC(力矩空间 MPPI,第 7 章 CMU 2024)这类采样 / 混合方法更合适。人形全身是几十上百维的力矩空间,接触极丰富,常用"采样式 + RL 先验"(§9.5 方案三)或"采样高层 + WBC 底层"(方案四)的混合。这两个案例印证了 §9.4(接触不可微)+ §9.5(高维用混合 / RL 先验)。

把七个案例连起来看,一条清晰的规律浮现:问题越"脏"(不可微代价、不可预测接触)越偏采样式;问题越"干净"(光滑、结构化、要硬约束)越偏梯度式;问题越"难且高维"(剧烈接触、高维力矩)越偏混合 / 学习。工业界的选择,不是凭潮流,而是被问题特性精确地决定——这正是本章理论的力量:它能预测真实世界的选择

历史与理论:一棵可操作的选型决策树

把上面案例背后的逻辑提炼成一棵**决策树**——拿到一个新控制问题,从根节点照着问下去,就能选出合适的求解器。这棵树的每个分叉,都对应本章讲过的一个关键维度:

拿到一个新控制问题, 依次问:

动力学可微吗?  (能否得到可靠的 ∂f/∂x?)
├── 否(接触/黑箱仿真器) ──→ 【采样式 MPPI/CEM】(唯一选择, §9.4 第二三类)
└── 是 ↓
    代价函数光滑可微吗?  (有没有 indicator/CNN/阶梯状代价?)
    ├── 否(不可微代价) ──→ 【采样式 MPPI】(梯度式会失明, §9.4 第一类)
    └── 是 ↓
        有 GPU 吗?
        ├── 是 ──→ 【都可行, MPPI 更灵活】(GPU 喂得饱采样, §9.3 ④; 但梯度式精度更高, 看是否要硬约束)
        └── 否(CPU/嵌入式) ↓
            有硬约束刚需吗?  (推力/关节/安全, "绝不能违反"?)
            ├── 是 ──→ 【梯度式 MPC(acados/OCS2)】(原生硬约束, §9.3 ⑥⑦)
            └── 否 ──→ 【Predictive Sampling(最简采样基线)】(CPU 上够用又简单)

这棵树的设计逻辑,是按"一票否决的维度优先"排序的(§9.3 易错点):先问可微性(动力学、代价)——因为不可微会直接把梯度式一票否决(§9.4),这是最强的约束,必须先问;可微性过关后,再问平台(GPU)——有 GPU 则两家都可行(采样式不再受 \(K\) 限制);无 GPU 时,最后问硬约束——有硬约束刚需则梯度式(原生处理),否则最简的 Predictive Sampling 就够。

注意这棵树给的是"默认起点",不是终点:其一,很多真实问题的最优解是**混合**(§9.5),树只是帮你定"主力用哪家",混合是在主力之上叠加(如"采样式主力 + CBF 安全层");其二,维度(§9.3 ⑧)是个贯穿的旁路约束——任何分支下,若维度上百,都要额外向梯度式 / 重度降维倾斜。所以用法是:先用树定一个主力方向,再用 §9.3 的维度表和 §9.5 的混合架构做微调

历史与理论:一套四步选型方法论

把决策树包装成一套更完整的、可复用的**选型方法论**,给你一个面对任何新问题时的标准流程:

第一步:刻画问题(化验指标)。 老老实实回答 §9.3 体检表的几个关键问题:动力学可微吗(解析 / 接触 / 黑箱)?代价光滑吗(二次型 / indicator / CNN)?多少维(\(H\times m\))?有 GPU 吗?有硬约束刚需吗(绝不能违反的)?要不要全局最优、能接受随机性吗?——这一步是后面一切的基础,刻画错了,后面全错(§9.6 反面)。

第二步:走决策树,定主力。 用上面那棵树,依"可微性 → 平台 → 约束"的顺序,定出"主力求解器用采样式还是梯度式"。

第三步:判断是否需要混合,按需增强。 问:单一主力够吗?若问题落在"海岸线"(§9.4 多视角)——非凸但光滑(加方案一精炼)、要性能也要硬安全(加方案二 CBF)、有 RL 先验可用(方案三)、高维需分层(方案四)——则在主力上叠加相应的混合层(§9.5),但守住"按需而加、别堆砌"(§9.5 易错点)。

第四步:用维度和平台做最终校准。 回头用 §9.3 的维度表逐项校验:维度会不会太高(采样式吃力)?平台算力够不够(大 \(K\) 的 MPPI 在嵌入式上跑不动)?据此对前三步的结论做最后微调(如为了嵌入式平台把 \(K\) 砍小、或改用更省的梯度式)。

本质洞察:这套方法论的精髓,是把"选求解器"从一个**凭感觉 / 凭潮流的艺术**,变成一个**有依据、可复现、可解释的工程决策**——每一步都问具体的、可回答的问题(可微吗?多少维?有 GPU 吗?),每个结论都能追溯到问题的客观特性,而非"我喜欢 / 现在流行什么"。这呼应本章反复强调的核心立场:方法的选择应由问题特性决定,而非方法的新旧或时髦。掌握这套方法论,你面对任何新控制问题(甚至超出 MPC 的优化问题),都有一个不慌的、结构化的起手式:先刻画问题、再按一票否决的维度优先级走决策、最后按需混合和校准。这种"把模糊的选择艺术,拆解成一串可回答的具体问题"的能力,本身就是工程成熟度的标志——它远比记住"MPPI 好还是 iLQR 好"这种没有上下文的结论有用得多,因为**正确答案永远是"看问题",而这套方法论就是教你怎么系统地"看"。**

深一层:为什么 acados 用"实时迭代(RTI)"——实时性与最优性的妥协

四旋翼案例选了 acados 的 SQP-RTI,这个"RTI(Real-Time Iteration,实时迭代)"值得展开,因为它体现了一个工业实时控制里极重要、却常被教科书忽略的妥协思想。

理论上,每个控制周期梯度式 MPC 应该把优化问题**解到收敛**(迭代到最优)。但在高频实时控制里(四旋翼可能要几百赫兹),一个周期只有几毫秒,根本来不及把 SQP 迭代到收敛。RTI 的思路很"工程":每个控制周期只做一次(或极少数)SQP 迭代,不追求解到最优,立刻输出当前这一步的(次优)控制,进入下一周期。下一周期从上一周期的解 warm-start(热启动)继续——因为相邻周期的最优控制变化不大(系统是连续的),所以"每周期挪一小步"累积起来,闭环行为依然很好,且严格满足了实时性。

这是"最优性"与"实时性"的妥协:放弃"每步都解到最优"(理论理想),换取"每步都按时输出一个足够好的控制"(工程必须)。它依赖一个关键事实——闭环里,一步的次优不致命,因为下一步会继续优化、且系统连续使得次优解离最优不远。这正是 MPC"滚动时域"哲学(第 8 章 §8.1)的极致体现:反正每步都要重新规划,何必把当前这步解到完美?

本质洞察:RTI 揭示了实时控制里一条深刻的工程智慧——在闭环、滚动重规划的框架下,"每步及时给出足够好的解"往往胜过"每步追求最优但可能超时"。这是因为闭环有"自我纠正"的能力:这一步的次优,下一步会接着优化补上;而一旦超时(为追最优而错过控制周期),系统失去控制、可能直接失稳——超时的代价远大于次优。这条"及时的次优 > 迟到的最优"的智慧,呼应了第 8 章 §8.3 Nav2 把 iteration_count 设为 1(每步只迭代一次、宁可加 batch)的选择——殊途同归,都是"实时系统里,按时交付次优解比超时交付最优解更重要"。它也给你一个一般性的实时系统设计原则:当你在"解得更好"和"按时交付"之间纠结时,在闭环 / 可重复决策的场景下,优先保证按时交付——因为闭环会帮你纠正次优,但纠正不了超时失控。 这是 MPC、机器人、乃至一切实时系统的共同纪律。

深一层:为什么腿足领域同时存在 OCS2 和 DIAL-MPC 两条路线

案例表里,Go2 行走用 OCS2(梯度式),Go2 跳跃却转向 DIAL-MPC(采样式)——同一类机器人(四足),为什么有两条不同的求解器路线?这个对照值得展开,它精确地体现了"问题特性决定方法"。

差别全在**运动的"结构化程度"和接触的可预测性**。周期行走**是高度结构化的:步态是周期的、接触序列基本已知(哪条腿什么时候触地是规划好的)、运动相对平缓。这种"已知接触序列 + 平缓"让问题在每个接触模式内**近似光滑可微——梯度式(OCS2 的 SLQ / SQP)可以在已知的接触序列上高效地做约束优化(摩擦锥硬约束),几十维也不在话下(§9.3 ⑧)。剧烈跳跃**则相反:运动是非周期、非结构化的,接触时刻和方式**不可预测(落地点、翻滚中的碰撞难以预先规划),接触的不可微性赤裸裸地暴露(§9.4 第二类)——梯度式赖以工作的"已知光滑接触序列"前提崩塌,于是转向不挑接触可微性的采样式(DIAL-MPC 在力矩空间撒样本,第 7 章)。

本质洞察:OCS2(行走)与 DIAL-MPC(跳跃)的并存,是"同一硬件、不同任务,因任务特性不同而选不同求解器"的绝佳案例——它把本章"方法由问题决定"的立场推到了极致:连"求解器选择"都不是按机器人定的,而是按**具体任务**定的。这给你一个重要的认识纠偏:不要问"四足机器人该用什么求解器",要问"四足机器人做这个具体任务该用什么求解器"——周期行走(结构化、接触可预测)和剧烈跳跃(非结构化、接触不可预测)虽是同一台机器人,却落在求解器版图的两端。这也解释了为什么成熟的腿足控制栈往往**同时集成多种求解器**(OCS2 用于常规步态、采样 / RL 用于敏捷动作),按任务切换。推广开来:求解器选择的粒度,应细到"任务"而非"机器人 / 领域"——这是比"哪家更好"更精细、也更接近工程实践的认知。

深一层:决策树没明说的——当多个维度互相冲突,怎么权衡

§9.6 的决策树假设维度能"依次"判断,但真实问题里几个维度常**互相冲突**——一个维度指向采样、另一个指向梯度。决策树给的是"一票否决优先级",但冲突更微妙时怎么权衡?这是决策树没明说、需要你判断的部分。

常见的冲突场景与权衡思路:

冲突场景 一方指向 另一方指向 权衡思路
代价不可微,但要硬约束 采样(不可微) 梯度式(硬约束) 采样主力 + CBF/安全层补硬约束(§9.5 方案二)——别二选一
光滑可微,但维度只有几维、代价多变 梯度式(光滑) 采样(灵活、代价常改) 看"改代价的频率":常改→采样省去重推导;定型→梯度式更优
非凸需全局,但又要高精度 采样(全局) 梯度式(精度) 混合方案一(采样找盆地 + 梯度精炼,§9.5)——两全
高维,但接触不可微 梯度式(高维) 采样(不可微) 分层(方案四):高层简化空间采样 + 底层处理——降维 + 避开不可微

权衡的总原则有三条:① 一票否决项最高优先——不可微会让梯度式原理上不可用(§9.4),这种"硬不可用"压倒一切其他偏好;② 冲突常是混合的信号——两个维度各指一方,往往说明问题落在"海岸线"(§9.4 多视角),最佳解是混合(让各家管各自指向的那部分),而非在两家间二选一;③ 量化你的真实需求强度——"要高精度"到底多高(差三倍能接受吗)?"硬约束"是否真的"绝不能违反"?需求强度决定冲突中哪方更重。

本质洞察:决策树是"线性的一票否决流程",但真实选型常是**多个相互冲突维度的权衡**——而冲突恰恰是"该用混合"的最强信号。当你发现"这个维度指向采样、那个维度指向梯度"时,第一反应不该是"纠结二选一",而该是"这是不是个海岸线问题、能不能让采样管它擅长的部分、梯度管它擅长的部分"(§9.5)。这把"非此即彼的纠结"转化成了"各取所长的设计"。更一般地,当多个标准在一个决策上相互冲突、无法简单排序时,往往意味着不存在单一最优选项,而存在一个"组合 / 折中"的解——成熟的决策者不是在冲突中硬选一边,而是识别出"冲突暗示了组合解的存在",去设计那个让各方需求都得到照顾的组合。这是从"二选一思维"到"设计组合解思维"的升级,远超求解器选择本身。

深一层:选型的"可逆性"——先上最简基线,不行再升级

决策树和方法论让你"想清楚再选"。但真实项目还有一条互补的实践智慧:别一开始就追求"选到完美的方法",而是先上一个最简、能跑的基线,再按需升级——因为选型决策的"可逆性"和"试错成本"也该纳入考量。

  • 为什么先上最简基线:① 最简基线(如朴素 MPPI / Predictive Sampling,或一个现成的梯度式库)能最快让系统端到端跑起来,暴露真实问题(往往和你纸上分析的不一样);② 它给你一个**性能基准**,让后续升级有的放矢(升级后到底好了多少);③ 它**试错成本低**——简单方法实现快、改起来也快,选错了换掉不心疼。
  • 升级的触发:基线跑起来后,用真实表现而非想象**决定是否升级——基线精度不够?再上梯度式精炼(方案一)。基线不够安全?再加 CBF(方案二)。基线在高维上慢?再分层(方案四)。**每次升级都针对基线暴露出的真实短板,而非预先假想的需求(呼应 §9.5 易错点"按需而加")。
  • 这和"想清楚再选"不矛盾:决策树帮你避开"原理上就不该用"的选择(如给不可微问题选纯梯度式,这种错误基线都跑不通);"先上最简基线"则是在决策树筛过的合理选项里,从最简单的那个开始迭代。两者结合:用决策树排除原理性错误、用"最简基线 + 按需升级"处理"具体多复杂才够"的问题。
  • 反面教训:一开始就上最复杂的混合架构(精炼 + CBF + RL 先验 + 分层全堆上),结果系统复杂到根本调不通、问题暴露不出来、出了 bug 不知道是哪层的——过早的复杂化(premature complexity)和过早的优化(premature optimization)一样有害

本质洞察:好的选型不只是"一次性选到最优方法",更是一个**"先上可逆、低成本的最简基线,再用真实反馈按需升级"的迭代过程**——因为纸上分析永远不如真实运行暴露的问题准确,而简单基线的低试错成本让你能快速迭代、用证据驱动升级。这背后是工程方法论的一条核心智慧:面对不确定性,优先做可逆的、低成本的、能快速获得反馈的决策,把不可逆的、高成本的决策推迟到信息更充分时。它呼应了软件工程的"先让它跑起来,再让它变好"(make it work, then make it better)和"避免过早优化 / 过早复杂化"。具体到求解器选型:决策树定方向(排除原理错误),最简基线起步(快速验证),真实反馈驱动升级(按需复杂化)——这套"想清楚 + 迭代"的组合,比"一次性追求完美选择"既更务实、也更可靠。记住:最好的架构往往不是设计出来的,而是从一个简单基线迭代演进出来的(这也正是累积项目从玩具长成沙盘的方式,§9.7)。

多视角:选型决策树像"医院的分诊流程"

给选型方法论配个直觉:它像医院的**分诊(triage)流程**。

病人(控制问题)来了,分诊护士不会凭感觉或病人的"名气"安排,而是**按一套固定的、问最关键问题优先的流程**快速归类:先问最致命的(有没有生命危险——对应"可微性"这个一票否决的维度),再问次要的(哪个科室——对应平台、约束),最后定"该看哪个医生 / 做什么处理"(对应主力求解器 + 是否需要会诊 / 混合)。分诊的智慧在于**用最少的关键问题、按轻重缓急的顺序,快速做出可靠的初步判断**。

像的地方:分诊"按一票否决 / 轻重缓急排序、问关键问题、快速归类"的逻辑,正是选型决策树的设计(先问可微性这个一票否决项,再问平台、约束)。不像的地方(边界):医院分诊后通常是单一科室处理,而控制问题分诊后常常需要"多科会诊"(混合架构,§9.5)——很多真实问题不是"挂一个科"就解决,而是要多个求解器协作。别把决策树当成"分到一家就完事"——它定的是主力,复杂问题还要按 §9.5 做"会诊式"的混合。另外,分诊流程是为"快速初判"设计的、可能漏掉罕见情况,决策树同理——它覆盖常见情况,遇到罕见 / 越界问题(§9.3 易错点的那些"越界技巧")仍需专家判断,别把它当成覆盖一切的铁律。

历史与理论:常见问题类型的选型速查表

把决策树的结论铺开成一张"问题类型 → 推荐方案"的速查表,覆盖机器人里最常见的若干问题形态,供你快速对照(仍以"先定主力、再按需混合"为原则):

问题类型 关键特性 推荐主力 是否常配混合
移动机器人避障导航 代价地图不可微、CPU 采样式(Nav2 MPPI) 可配恢复行为 / 全局规划器
高速越野 / 漂移驾驶 CNN 代价、要 agile、有 GPU 采样式(GPU MPPI)
机械臂避碰到点 SDF 碰撞不可微、有 GPU 采样式(STORM) 可配 IK / 末端精修
四旋翼轨迹跟踪 解析可微、推力硬约束、嵌入式 梯度式(acados SQP-RTI)
四足周期行走 步态已知、摩擦锥硬约束、CPU 梯度式(OCS2) MPC + WBC 分层
四足 / 人形敏捷动作(跳跃 / 翻滚) 接触不可预测不可微、高维 采样式(DIAL-MPC)/ RL 分层 / RL 先验
非凸但光滑的轨迹优化 多局部最优、处处可微、要精度 混合(采样找盆地 + 梯度精炼) 方案一
要性能也要硬安全(贴障碍飞 / 行) 不可微感知 + "绝不违反" 采样式 + CBF 安全层 方案二(Shield-MPPI)
有仿真训好的 RL 策略、要上真机鲁棒 sim-to-real gap、高维 采样式 + RL 先验 方案三(Biased-MPPI)
过程控制(化工 / 能源) 光滑 ODE、多硬约束、无 GPU 梯度式(SQP-NMPC)
用学习的世界模型做规划 黑箱 NN 动力学(可微但多步误差累积) 采样式(不挑模型) 可配价值函数补远见
稀疏奖励 / 超长时序任务 信息稀疏、维度爆炸 先注入结构(价值 / 子目标 / 塑形) 再选主力

这张表不是要你死记(具体系统会变),而是给你一个"见过世面"的参照——当你的新问题和某一行相似时,可以从那行的推荐起步,再用决策树和维度表核对、按需调整。注意表里**一半以上的行都"常配混合"**,再次印证 §9.5:真实系统里混合是常态。

深一层:决策树外的一个现实因素——工具链成熟度与生态

九维表和决策树都基于"问题特性"。但真实工程选型还有一个**表里没有、却实实在在影响决策**的因素:可用工具链的成熟度与生态。这不是理论上的"该用哪家",而是工程上的"哪家有现成、可靠、好集成的轮子"。

  • 成熟工具能压倒"理论最优":假设理论上你的问题用梯度式略优,但该领域采样式有一个成熟、文档齐全、社区活跃、和你的技术栈(如 ROS2)无缝集成的工具(如 Nav2 MPPI),而梯度式没有现成的好用实现——这时选采样式(牺牲一点理论最优,换巨大的工程效率和可靠性)往往是对的。反之亦然(acados 在嵌入式 NMPC 上的成熟度,让它在四旋翼 / 车载领域几乎是默认选择)。
  • 各家的生态现状(粗略)
领域 / 范式 成熟工具 生态特点
移动机器人导航(采样) Nav2 MPPI ROS2 原生、部署量巨大、文档社区好
嵌入式实时 NMPC(梯度) acados C/Python、代码生成、工业级、openpilot 用
腿足 MPC(梯度) OCS2、Crocoddyl C++、和 Pinocchio / 全身控制集成
通用采样 MPC / 仿真(采样) MuJoCo MPC (MJPC)、STORM GPU / CPU、研究友好
机械臂运动(采样) STORM、cuRobo GPU 加速、和碰撞检测集成
  • 为什么这是真因素:成熟工具意味着**更少的坑、更快的开发、更可靠的部署、更好的社区支持**——这些在真实项目里(有 deadline、要稳定上线)的价值,常常不亚于"理论上谁更优"。一个能立刻用、被无数人验证过的工具,胜过一个理论更好但要你从零造、自己踩坑的方案。

本质洞察:选型不只是"问题特性 → 方法"的理论映射,还要叠加**"哪家有成熟可靠工具链"这个工程现实**——成熟的生态能(也应该)影响、有时甚至压倒纯理论的最优选择。这背后是一个常被学术训练忽视、却被工程实践反复印证的道理:一个方案的真实价值 = 理论最优性 × 工程可落地性(工具成熟度、集成难度、社区支持、维护成本),而非只看理论最优性。一个理论最优但无成熟工具、要从零造轮子的方案,在有 deadline 和可靠性要求的真实项目里,常常输给一个理论次优但有成熟工具链的方案。这给你的实践启示是:选型时,除了走决策树(理论该用谁),还要查"这个方向有没有成熟工具、好不好集成进我的栈"——把工程可落地性和理论最优性一起权衡。这也是为什么本章的工业案例(§9.6)里,选择往往和成熟工具链高度绑定(导航→Nav2、嵌入式→acados、腿足→OCS2)——它们不只是"理论上合适",更是"有成熟轮子可用"。理论指方向,工具定落地。

深一层:"没有银弹"——选型方法论的底层信念

走完决策树和方法论,值得点破支撑它们的那个底层信念——没有银弹(no silver bullet):不存在一个"对所有问题都最好"的求解器。这个信念是整章、乃至整个工程判断力的根基。

  • 为什么没有银弹:本章反复证明,每个方法的强项都伴随着对应的弱项,且强弱由"它对问题做了什么假设"决定(§9.1 核心权衡)——梯度式假设可微换效率,那它在不可微上就出局;采样式假设弱换普适,那它在高维 / 精度上就吃力。强项和弱项是同一个假设的一体两面,所以不可能有"只有强项、没有弱项"的银弹。
  • 银弹幻觉的危害:相信某个方法是银弹("MPPI 万能""端到端解决一切"),会让你在它的弱场硬用它、忽视更合适的工具、也停止思考"这个问题到底需要什么"。银弹幻觉是选型反模式(§反模式速查)的共同心理根源。
  • 没有银弹 → 必须"看问题":正因为没有银弹,选型才不能靠"记住一个万能答案",而必须靠"刻画问题 + 按特性匹配"(方法论)。"看问题"不是麻烦,而是"没有银弹"这个事实的必然要求——既然没有放之四海皆准的方法,就只能具体问题具体分析。
  • 这让选型成为一种持久技能:方法会更新(新算法、新混合),但"没有银弹、必须看问题"这个信念和"刻画 + 匹配"的方法论不会过时——它们是元层面的,独立于任何具体方法。

本质洞察:整章的选型方法论,建立在"没有银弹"这个朴素而深刻的信念上——不存在对所有问题都最优的方法,因为每个方法的强项与弱项是它所做假设的一体两面(§9.1)。这个信念是工程判断力的基石:承认没有银弹,你才会去"看问题"(具体分析)而非"找万能答案"(偷懒);才会把方法当成各有适用边界的工具(而非信仰);才会在方法更新时依然清醒(新方法也不是银弹,也有它的假设和边界)。它远超求解器选择——软件工程经典论文《没有银弹》讲的正是这个,而它适用于一切技术选择:编程语言、架构、算法、模型,没有哪个是银弹,都是"在某些假设下更好"的工具。把"没有银弹"内化成信念,你就不会被任何"X 解决一切"的炒作迷惑,而总会冷静地问:"X 对问题做了什么假设?我的问题满足这些假设吗?"——这一问,正是本章想教给你的、最持久的判断力。它也呼应了本章的标题"何时选谁":答案永远是"看问题",因为没有银弹。

易错点:决策树是"起手式"不是"终判决",别跳过问题刻画直接套树

学到一棵清晰的决策树,一个危险的用法是**把它当成"输入问题、输出答案"的自动机,跳过认真的问题刻画就急着套树**。这会出两类错。其一,刻画偷懒导致套错分支:你没认真判断"代价到底可不可微"(比如想当然觉得 CNN"可微所以光滑",§9.4 陷阱 1),就在决策树的"代价光滑吗"分叉走错了方向,后面全错。决策树的每个分叉都依赖一个**准确的问题刻画**——刻画错了,树再对也没用(垃圾进垃圾出)。其二,把树的输出当成不可改的终判决,忽略了它只是"主力起点"、真实问题常需混合(§9.5)和按维度 / 平台校准(方法论第四步)。正确做法:把决策树嵌在完整的四步方法论里用——先花力气认真刻画问题(第一步,这是最该下功夫的)、再走树定主力(第二步)、然后判断混合(第三步)、最后校准(第四步)。决策树只是第二步,不是全部。自检:你用决策树时,是不是认真回答了每个分叉的问题(尤其"可微性",做了实际判断而非想当然)?是不是记得树的输出只是主力、后面还要判断混合和校准?跳过刻画、把树当自动机,是最常见的误用。

⚠️ 常见陷阱

陷阱 1:照搬"别人在类似机器人上的选择",不管自己的具体任务 ⚠️ 概念误区 - 错误想法:"别人的四足机器人用 OCS2(梯度式)效果好,那我的四足机器人也用 OCS2。" - 现象/后果:你照搬 OCS2 去做一个剧烈跳跃 / 翻滚任务(接触不可预测),结果 OCS2 在不可预测的接触上水土不服(梯度式的"已知接触序列"前提崩塌),效果远不如该用的 DIAL-MPC / 采样式。 - 根本原因:把"求解器选择"按"机器人 / 领域"归类,而非按"具体任务"归类。但 §9.6 深一层已揭示——同一台四足机器人,行走(结构化)和跳跃(非结构化)该用完全不同的求解器。求解器选择的正确粒度是"任务",不是"机器人型号"。 - 正确做法:照搬别人的选择前,先确认"我的具体任务和他的具体任务,在本章关键维度上(可微性、接触可预测性、约束、维度)是否真的一致"——一致才可借鉴,不一致(哪怕同一台机器人)就要重新走决策流程。自检:你借鉴的那个成功案例,它的任务特性(接触可预测吗、代价可微吗)和你的任务真的一样吗?

陷阱 2:在决策树里把"动力学可微"和"有解析模型"混为一谈 ⚠️ 编程陷阱 - 错误做法:决策树第一问"动力学可微吗",你看到自己有一个写得出来的动力学方程(解析模型),就答"可微"、走向梯度式分支。 - 现象/后果:但你的解析模型里含接触 / 摩擦切换 / 饱和等不连续项(如带接触的刚体动力学方程"写得出来"但在接触切换处不可微),梯度式在这些不连续处出问题(§9.4 陷阱 2)——你以为"有方程=可微",其实方程里藏着不可微点。 - 根本原因:"有解析表达式"不等于"处处可微"。很多解析模型含不连续 / 不可微的项(接触、\(\text{sign}\)\(\max\)、饱和、indicator)——它们写得出公式,但在某些点导数不存在或跳变。决策树问的是"可微"(导数处处存在且有意义),不是"有没有公式"。 - 正确做法:判断"动力学可微吗"时,不是看"有没有解析式",而是看"解析式里有没有不连续 / 不可微的项(接触、\(\text{sign}/\max/\)饱和 / indicator)"——有就当不可微处理(至少在那些点附近梯度式不可靠)。自检:你的动力学方程里,有没有接触切换、绝对值、取最大、硬饱和、阶跃这类项?有的话,"有公式"不等于"可微",决策树第一问该谨慎答"否"或"部分否"。

陷阱 3:把决策树的"都可行"分支理解成"随便选都一样" ⚠️ 思维陷阱 - 错误想法:"决策树走到'有 GPU → 都可行'这个叶子,那采样式和梯度式随便选哪个都一样、无所谓。" - 现象/后果:你在"光滑可微 + 有 GPU"的问题上随手选了 MPPI(因为"都可行"),但其实你的问题还有"要高精度 + 有硬约束"的需求——这种情况下梯度式明显更优(精度高、原生硬约束),你的随手选择丢掉了梯度式的优势。 - 根本原因:"都可行"不等于"都同样好"。这个分支的意思是"两家都能跑得起来(没有一票否决项)",但在"都能跑"之内,仍有优劣之分——要高精度 / 硬约束 → 梯度式更好;要灵活 / 代价多变 / 想用学习模型 → 采样式更好。"都可行"是说没有硬性排除,不是说优劣不分。 - 正确做法:走到"都可行"分支时,别停在"随便选",继续用 §9.3 的维度(要不要高精度?有没有硬约束?代价会不会经常变?)和 §9.5(要不要混合)做精细选择。自检:你走到"都可行"了,是不是就随手选了一个?停一下,用"要精度 / 约束吗、代价多变吗"再分一次高下——"都可行"只是排除了硬约束,没免除你做精细权衡的责任。

练习

  1. (应用·走决策树,⭐⭐⭐) 用本节的决策树 + 四步方法论,为下面三个问题选求解器(写出每一步的判断和理由):(a) 一个室内配送机器人,用激光雷达建占据栅格地图避障,跑在无 GPU 的工控机上;(b) 一个化工反应器的温度控制,模型是光滑的常微分方程组、要满足温度 / 流量的硬约束、跑在工业 PLC(无 GPU)上;(c) 一个有 GPU 工作站、要做研究的机械臂,代价部分来自一个学出来的"抓取成功率"网络,6 自由度。
  2. (剖析·解释工业选择,⭐⭐⭐) 从本节七个案例里选三个,用本章学过的维度(可微性、约束、平台、维度、接触可预测性)**详细论证**它们为什么这么选——要能说清"换成另一家会差在哪"。特别地,论证为什么 Go2 行走(OCS2 梯度式)和 Go2 跳跃(DIAL-MPC 采样式)这对"同机器人不同任务"会选不同求解器。
  3. (思考·方法论的迁移,⭐⭐⭐⭐) 本节的"四步选型方法论"(刻画问题 → 走决策树定主力 → 判断混合 → 按维度平台校准)其实是一个通用的"技术选型"框架。请论证:(a) 为什么"先刻画问题、再按一票否决维度优先级决策"这个顺序是对的(而非一上来就比较候选方案);(b) 把这个框架迁移到另一个技术选型问题上(如"给一个项目选数据库 / 选机器学习模型 / 选通信协议"),说明它的四步分别对应什么;(c) 由此提炼:好的技术选型方法论,共同的特征是什么(提示:依据客观需求而非偏好、关键约束优先、给默认起点但允许微调)。
  4. (应用·用速查表 + 反模式自查,⭐⭐⭐) 挑一个你正在做或感兴趣的真实控制问题。(a) 在本节"常见问题类型选型速查表"里找到最接近的一行,从它的推荐起步;(b) 走一遍四步方法论核对这个起点是否合适,需要时调整;(c) 用"选型反模式速查"的八条逐一自查——你的选择有没有不小心踩中某条反模式(手熟 / 潮流 / 可微性误判 / 堆资源 / 堆砌 / 错粒度 / 过度外推 / 忽视工具链)?把自查结果写成一段"我为什么这么选、避开了哪些反模式"。
  5. (思考·工具链 vs 理论最优,⭐⭐⭐⭐) 本节深一层说"真实价值 = 理论最优性 × 工程可落地性"。请论证:(a) 给一个例子,说明"理论略优但要从零造、无成熟工具"的方案,可能输给"理论次优但有成熟工具链"的方案(从开发速度、可靠性、维护、社区支持几方面);(b) 这是否意味着"永远选成熟工具"?什么情况下值得为理论最优去造新工具(提示:性能是核心竞争力、现有工具确实不够、有足够资源);(c) 提炼一条平衡"理论最优"和"工程可落地"的实践原则。

§9.7 横向基准实战与累积项目收尾 ⭐⭐⭐

动机

前六节把两家的理论、失效模式、混合、选型都讲透了。这一节做两件收尾的事。其一,横向基准:把采样式(MPPI、iCEM)和梯度式(iLQR)放在**同一个任务、同一套 horizon / dt / 代价**上同台竞技,亲手量出它们的成功率、最终代价、wall-clock——让前面所有的"理论对比"落到一组可复现的硬数字上(这正是骨架要求的 [A 型·横向基准] 实战)。其二,累积项目收尾:给贯穿全书的统一规划器加上本章带来的最后一根维度旋钮——"求解器后端"(采样式 / 梯度式 / 混合),让你的规划器能像换零件一样切换求解范式,并亲眼对比"纯采样 vs 采样 + 梯度精炼"的差别。这一节是全章的"知行合一"——把"会选"变成"会量、会搭"。

如果不这样做会怎样:只在各自的"主场"评测,得出片面结论

设想你评测两家时,让它们各自在自己的主场跑——MPPI 在不可微问题上、iLQR 在光滑问题上,然后说"MPPI 行、iLQR 也行"。这种"各自主场"的评测得不出任何有用的对比结论:你没有在**同一个任务**上比过它们,就无法回答"对这个任务,谁更好、好多少"。横向基准的价值,正是**控制变量**——同一个任务、同一个 horizon、同一套代价,只换求解器,这样测出的成功率 / 代价 / 时间差异,才真正归因于"求解器本身",而非任务难度的不同。不做同台横向基准,你对两家的认识就停留在"各有所长"的定性层面,永远量不出"在某个具体任务上谁强多少、强在哪"的定量结论——而定量结论才是工程决策的依据。这一节就带你做一次严格控制变量的横向基准。

历史与理论:CartPole 摆起上的三方同台

选一个经典任务做横向基准:CartPole 摆起(小车上的杆从下垂 \(\theta=\pi\) 摆到竖直向上 \(\theta=0\) 并稳住)。这个任务有个关键特性——它是**非凸的**(要先反向摆动积累能量、再甩上去,代价地形有多个局部最优),同时动力学是光滑可微的。这种"非凸 + 光滑"恰好能同时考验两家:非凸考验全局搜索能力(采样式强、梯度式易陷局部),光滑则让梯度式本有发挥空间。三个参赛者:MPPI、iCEM(采样式,§5 章)、iLQR(梯度式,§9.2),统一 \(H=200\)\(\Delta t=0.02\)、同一套代价,都从零初始化出发。先看共享的动力学与代价:

import numpy as np, time
mc, mp, l, g, dt, H = 1.0, 0.1, 0.5, 9.81, 0.02, 200
s0 = np.array([0., 0., np.pi, 0.])           # 下垂(θ=π)起, 目标 θ=0(上方)
A = 12.0                                       # 控制幅值上限(裁剪)
def step(s, u):                                # 批量动力学(光滑可微)
    x,xd,th,thd = s[...,0],s[...,1],s[...,2],s[...,3]; si,co=np.sin(th),np.cos(th); tot=mc+mp
    thdd=(g*si+co*((-u-mp*l*thd**2*si)/tot))/(l*(4/3-mp*co**2/tot)); xdd=(u+mp*l*(thd**2*si-thdd*co))/tot
    return np.stack([x+dt*xd, xd+dt*xdd, th+dt*thd, thd+dt*thdd], -1)
def rollout_cost(U, s0):                        # 三法共用同一代价
    s=np.broadcast_to(s0,U.shape[:-1]+(4,)).astype(float); c=np.zeros(U.shape[:-1])
    for t in range(U.shape[-1]):
        c=c+2.0*(1-np.cos(s[...,2]))+0.1*s[...,3]**2+0.3*s[...,0]**2+0.01*U[...,t]**2; s=step(s,U[...,t])
    return c+40.0*(1-np.cos(s[...,2]))+4.0*s[...,3]**2+1.0*s[...,0]**2, s

三个求解器:MPPI(白噪声 + \(\sigma\) 退火 + 软加权)、iCEM(有色噪声 + 精英重拟合,更省样本)、iLQR(解析代价导数 + 有限差分动力学雅可比,从零初值)。核心循环与前几节一致,这里只看 MPPI 和 iCEM 的关键差别(采样分布的处理):

def mppi(iters=50, K=1000, lam=0.3, s_hi=4.0, s_lo=0.5, seed=0):
    rng=np.random.default_rng(seed); U=np.zeros(H)
    for it in range(iters):
        sig = s_hi + (s_lo-s_hi)*it/(iters-1)              # σ 退火: 先广探索后精收敛
        eps=rng.normal(0,sig,size=(K,H)); J,_=rollout_cost(np.clip(U+eps,-A,A),s0)
        w=np.exp(-(J-J.min())/lam); w/=w.sum()             # 软加权(用全部样本)
        U=np.clip(U+(w[:,None]*eps).sum(0),-A,A)
    return U

def icem(iters=50, K=600, elite=60, sig=3.0, floor=0.3, beta=1.5, keep=20, seed=0):
    rng=np.random.default_rng(seed); mean=np.zeros(H); std=np.full(H,sig); mem=None
    for it in range(iters):
        S=np.clip(mean+std*colored(K,H,beta,rng),-A,A)     # 有色(时间相关)噪声
        if mem is not None: S=np.vstack([S,mem])           # 精英记忆: 并入上轮精英
        J,_=rollout_cost(S,s0); idx=np.argsort(J)[:elite]; el=S[idx]; mem=el[:keep]
        mean=el.mean(0); std=np.maximum(el.std(0),floor)   # 精英重拟合(用前 elite 个)
    return np.clip(mean,-A,A)

跑 6 个随机种子,统计成功率(末态离上方 \(<30°\) 算摆起成功)、平均末角、平均代价、平均 wall-clock:

for name, fn in [('MPPI',mppi),('iCEM',icem),('iLQR',ilqr)]:
    angs,costs,ts=[],[],[]
    for sd in range(6):
        t0=time.time(); U=fn(seed=sd); ts.append((time.time()-t0)*1000)
        angs.append(angle_up(U)); costs.append(rollout_cost(U[None],s0)[0][0])
    print(f"{name}: 成功 {sum(a<30 for a in angs)}/6, 末角 {np.mean(angs):.1f}°, "
          f"代价 {np.mean(costs):.0f}, 耗时 {np.mean(ts):.0f}ms")
# 典型输出:
#   MPPI: 成功 5/6, 末角 10.7°, 代价 741, 耗时 ~1200ms   ← 全局搜索, 摆起且较准
#   iCEM: 成功 5/6, 末角 25.2°, 代价 868, 耗时 ~1025ms   ← 更省样本(30k vs 50k), 稍欠精度
#   iLQR: 成功 0/6, 末角 180°,  代价 880, 耗时  ~480ms   ← 从零初始化陷局部最优(卡在下垂!)

这组硬数字把前几节的理论一次性兑现了:

采样式(MPPI、iCEM)摆起成功(5/6),iLQR 完全失败(0/6,卡在下垂 180°)。 这正是 §9.5 双势阱 demo 的"真实任务版"——CartPole 摆起是非凸的,iLQR 从零初值出发沿梯度下降,就近滑进了"一直下垂、不摆动"这个局部最优(因为微小的控制扰动既不能立刻降低代价、梯度又指向"省力即不动"),它**确定性地、每个种子都**卡在那里(注意 iLQR 无随机性,6 个种子结果完全相同——这说明它的失败是结构性的、不是运气差)。采样式撒得广,样本里总有"先反向摆、再甩上去"的能量泵入轨迹,被加权选中,于是摆起成功。这就是 §9.3 ⑤ "采样式偏全局、梯度式局部"在一个真实任务上的铁证。

iCEM 比 MPPI 更省样本(30k vs 50k 次 rollout),但精度稍逊(末角 25.2° vs 10.7°)。 iCEM 用精英重拟合 + 有色噪声,确实用更少的总 rollout 达到了同样的成功率(5/6),印证了它"样本高效"的设计初衷(第 4 章);但它的精英重拟合机制比 MPPI 的软加权更容易在终端"收得不够紧"(末角偏大),鲁棒性也略逊(这在 §9.7 易错点里展开)。这是"采样高效 vs 鲁棒精确"的一个真实权衡点。

iLQR 单次最快(~480ms)却给出最没用的解。 别被它的"快"误导——它快是因为它很快就"收敛"到了那个局部最优(不动),然后无事可做;快速地得到一个错误答案,毫无价值(呼应 §9.4 易错点"不报错地给出错误答案最危险")。(注:iLQR 的 wall-clock 还被有限差分雅可比拖慢了;真实 iLQR 用解析 / 自动微分会更快——但这不改变它"陷局部"的结论,速度不是这里的重点。)

关于 Pareto 前沿:把三者画在"代价 vs 计算量(rollout 数 / wall-clock)"的平面上,MPPI 和 iCEM 落在有用的前沿上(iCEM 更省、MPPI 更准,各占前沿一段),iLQR 则**根本不在前沿上**(它的解不可用,谈不上"用更少计算换更好解"的权衡)——因为 Pareto 前沿只在"都给出可用解"的方法间才有意义。这本身是个教训:横向基准的第一关是"成功率"(能不能解出来),过了这关才谈"代价 vs 计算量"的 Pareto 权衡——一个根本解不出来的方法(这里的 iLQR),再快也排不进权衡。

追加实验:iLQR 真的"不行"吗?给它一个好初值看看。 iLQR 在基准里 0/6,但这是"从零初值"的结果。它的失败是"陷局部"(§9.5),不是"不会摆起"——验证一下:让 MPPI 先找到摆起的盆地,再用它的解给 iLQR 做**暖启动(warm-start)**:

U_zero = ilqr(np.zeros(H))   # iLQR 从零初值
U_mppi = mppi()              # MPPI 先全局找盆地
U_warm = ilqr(U_mppi)        # iLQR 以 MPPI 解为初值(暖启动)
print(f"iLQR 从零初值     : 末态离上方 {au(U_zero):.1f}°")
print(f"MPPI 全局         : 末态离上方 {au(U_mppi):.1f}°")
print(f"iLQR(MPPI 暖启动) : 末态离上方 {au(U_warm):.1f}°")
# 典型输出:
#   iLQR 从零初值     : 末态离上方 180.0°   ← 陷局部, 卡在下垂
#   MPPI 全局         : 末态离上方   0.2°   ← 摆起
#   iLQR(MPPI 暖启动) : 末态离上方   0.1°   ← 摆起 + 精炼到比 MPPI 更准!

结果点破了关键:iLQR 从零陷在 180°,但给它 MPPI 找到的好初值,它不仅能摆起、还精炼到比 MPPI 更准(0.1° vs 0.2°)。这有力地说明——iLQR 在基准里的"失败"不是"它不会摆起",而是"它从零初值陷在了局部最优";一旦有好初值(落在摆起的盆地里),它的局部精炼能力反而让它做得比纯 MPPI 更好。这正是 §9.5 混合方案一(全局采样 + 局部梯度精炼)在 CartPole 基准任务上的活样本:MPPI 管"找对盆地"(全局)、iLQR 管"盆地内精炼"(精度),各展所长、1+1>2。它也呼应 §9.7 易错点和后面的研究建议——对 iLQR 这种确定性局部方法,"失败"往往是初值问题,给它配一个全局搜索的"前级",它就活了。这个实验把"横向基准(§9.7)"和"混合架构(§9.5)"漂亮地缝在了一起:基准暴露了纯方法的短板,混合补上了它。

累积项目:给统一规划器加上"求解器后端"维度

贯穿全书的累积项目 UnifiedSamplingPlanner,到第 8 章已经攒了好几根正交旋钮:代价项权重 weight、采样幅度 noise/cov(第 4 章),退火日程 schedule(第 5 章),模型来源 model_source、终端代价 terminal(第 6 章),动作空间 action_space(第 7 章),代价来源 cost_source、外部鲁棒化层(第 8 章)。本章给它加上最后一根、也是最"跨范式"的一根旋钮——求解器后端 solver_backend:让规划器能在"纯采样""采样 + 梯度精炼(混合方案一)"之间切换。接口示意:

class UnifiedSamplingPlanner:
    def __init__(self, ...,                       # 前几章的旋钮: weight/noise/schedule/
                 solver_backend='sampling'):       #   model_source/action_space/cost_source/...
        self.solver_backend = solver_backend       # 'sampling' | 'hybrid'(采样找盆地+梯度精炼)
        # 'hybrid' 需要可微的动力学/代价(§9.5 方案一的前提); 'sampling' 无此要求

    def plan(self, x0):
        U = self._mppi_core(x0)                     # 采样式内核(永远先跑, 全局找盆地)
        if self.solver_backend == 'hybrid':
            U = self._ilqr_refine(x0, U_init=U)     # 可选: 梯度式局部精炼(需可微)
        return U

注意这根旋钮和第 8 章那根"外部鲁棒化层"的相似与不同:相似在都是**在采样内核之外加一段处理**(§8 外挂鲁棒层、本章外接梯度精炼),不同在**作用方向**——鲁棒化层管"对抗扰动 / 模型误差"(执行侧),求解器后端管"提升解的精度 / 跳出局部"(优化侧)。它们正交、可叠加:你可以同时用"混合后端(采样 + 梯度精炼)"和"外部 L1 鲁棒层"。用本章 §9.5 的双势阱任务对照两种后端,差别一目了然:

solver_backend='sampling' : 纯 MPPI         → 末端 x=+2.00, 代价 -0.58  (全局阱, 但粗)
solver_backend='hybrid'   : MPPI + iLQR 精炼 → 末端 x=+2.01, 代价 -0.60  (全局阱 + 精炼到更低)

'sampling' 后端靠全局搜索找到好盆地、但精度有限;'hybrid' 后端在此基础上用梯度精炼把解打磨得更优——这正是 §9.5 方案一的能力,现在被收进了统一规划器的一根旋钮里。至此,累积项目的旋钮谱系完整了:从"在解析代价上跑 MPPI"的玩具(第 4 章),到一个能调代价 / 采样 / 退火 / 模型 / 动作空间 / 代价来源 / 鲁棒层 / 求解器后端的"采样 MPC 全功能沙盘"——每一根旋钮都对应一章学到的一个正交能力。

本质洞察:把"求解器后端"做成一根可切换的旋钮,体现了本章乃至全书最想沉淀的工程思维——把"采样式 vs 梯度式 vs 混合"从"互斥的阵营选择",变成"统一框架下一个可配置的维度"。当你不再把它们看成"要么信采样、要么信梯度"的立场之争,而是看成"同一个规划器的一个旋钮,按问题特性拨",你就真正超越了"哪家更好"的幼稚问题,到达了"按需配置"的成熟境界。这呼应第 8 章 §8.7 的"正交分解"母题,并把它推到了极致:连"用什么范式求解"都成了一根正交旋钮。这种思维的迁移价值极大——任何时候你面对"几个互相竞争的技术方案",最高级的处理往往不是"选一个站队",而是"设计一个能容纳它们、按需切换的统一框架"。框架思维高于阵营思维:阵营思维让你在 A 和 B 之间二选一并互相攻击,框架思维让你把 A 和 B 都变成框架里可调的选项、按问题取用——后者才是真正掌握了一个领域的标志。

深一层:为什么"同一任务、控制变量"的基准如此重要、又如此难做对

横向基准看似简单(让几个方法跑同一个任务),但"做对"它出奇地难,值得展开——因为不公平的基准比没有基准更误导人。

公平基准的核心是**控制变量**:除了"求解器"这个被比较的变量,其他一切(任务、horizon、dt、代价函数、初值、成功判据、计算预算)都必须严格一致。这一节的基准就刻意做到了:三法共用同一个 rollout_cost、同一个 \(H\)/\(\Delta t\)、同一个 \(s_0\)、同一个成功阈值。但现实中,基准常在不知不觉中变得不公平:给 A 调了一周参数、给 B 只用默认参数(调参努力不对等);用对 A 友好的任务 / 代价(任务选择有偏);A 报"最好的一次"、B 报"平均"(统计口径不一致);甚至成功判据偏向某一方。这些都会让基准得出误导性的结论。

而且,即便控制了变量,基准结论也有**适用范围**:本节基准说"在 CartPole 摆起这个非凸任务上,采样式赢、iLQR 从零陷局部"——但这**不能**外推成"采样式总是比 iLQR 好"(§9.3 demo 在光滑问题上恰恰相反!)。一个基准只对它测的那个任务有效,换任务结论可能翻转。

本质洞察:横向基准的价值与陷阱是一体两面——严格控制变量的基准,是把定性直觉变成定量结论的唯一可靠途径;但不公平的基准(调参不对等、任务有偏、统计口径不一),比没有基准更危险,因为它给错误结论披上了"数据支撑"的外衣。这给你两条纪律:做基准时,死守控制变量(同任务、同预算、对等调参、统一统计口径),并诚实报告(多种子、报平均与方差、说清成功判据);读别人的基准时,警惕地审视"它公平吗(谁调参更努力、任务选得偏不偏、口径一致吗)、它的结论适用范围多大(换任务还成立吗)"。这种对"证据质量"的批判性审视,是科学素养的核心——数字本身不等于真相,产生数字的方法是否公平才决定数字是否可信。本章的基准刻意做成可复现、控制变量、多种子、诚实报告,正是想给你一个"好基准长什么样"的样板,也提醒你:对任何"我的方法比基线好 X%"的论断,先问"这个比较公平吗"。

深一层:累积项目的"旋钮谱系"回顾——一条从玩具到沙盘的成长线

本章给累积项目添上最后一根旋钮,正是回顾整条成长线的好时机——这条线本身蕴含着比任何单个旋钮都重要的设计哲学。

回看这根旋钮谱系:weight/noise(第 4 章,最基础的"代价怎么配、样本怎么撒")→ schedule(第 5 章,退火,"探索与收敛的节奏")→ model_source/terminal(第 6 章,"用什么模型 rollout、用什么终端代价补远见")→ action_space(第 7 章,"在哪个空间采样:力矩 / 位置 / 质心")→ cost_source/鲁棒层(第 8 章,"代价从哪来、怎么对抗扰动")→ solver_backend(第 9 章,"用什么范式求解")。每一根旋钮都是**正交**的——拧动一根不影响其他根的语义(改 cost_source 不影响 schedule 的含义),这让规划器可以**组合爆炸式地**适配各种问题(每根旋钮独立取值,组合数是各旋钮取值数的乘积),而代码却保持清晰(每根旋钮对应一个独立、可替换的模块)。

本质洞察:累积项目从"几行的 MPPI 玩具"长成"全功能采样 MPC 沙盘"的整个过程,演示的是一种**"正交维度增量积累"的系统成长方式**——不是一开始就设计一个庞大复杂的系统,而是从一个最小可用核心出发,每次沿一个**正交的新维度**添加一个**独立可替换的模块**,让系统的能力随维度数线性增长、而适配能力随维度组合指数增长,同时复杂度保持可控(因为每个模块正交、独立)。这是真实工程系统(从 Linux 内核到 ROS 到大型框架)健康演进的共同模式:用正交模块的增量积累,换取能力的指数增长和复杂度的线性可控。它的反面——把所有功能耦合进一个庞大单体——会让系统随功能增加而复杂度爆炸、最终无法维护。本书用八章把这个模式演给你看:每章加一根正交旋钮,到这里你拥有的不是八个孤立技巧,而是一个**有机的、可无限组合扩展的系统**。带走这个"正交增量"的成长哲学,比带走任何单根旋钮的用法都更有价值——它会指导你设计任何需要长期演进的复杂系统。

深一层:Pareto 前沿的正确读法——没有"最好",只有"非劣"

§9.7 提到画 Pareto 前沿,但"Pareto 前沿"常被误读。读懂它,是看懂任何多目标权衡(不只是求解器对比)的基本功。

  • 什么是 Pareto 前沿:当你同时关心多个互相冲突的目标(这里是"代价低"和"计算省"),通常**没有一个方案在所有目标上都最优**——降低代价往往要更多计算,反之亦然。Pareto 前沿是所有"非劣(non-dominated)"方案的集合:一个方案在前沿上,意味着"想在某个目标上再改进,必须在另一个目标上退让"(没有"免费的改进")。
  • "非劣"不等于"最好":前沿上的每个点都是"非劣"的——iCEM(更省计算、代价稍高)和 MPPI(计算多、代价更低)可能都在前沿上,谁更好取决于你的偏好权重(你更看重省计算还是低代价?)。前沿不告诉你"选哪个",它告诉你"这些是值得考虑的、互不支配的选项,从中按你的偏好挑"。
  • 被支配的方案要剔除:若一个方案在所有目标上都不如另一个(既费计算、代价又高),它被"支配",根本不该考虑——本节基准里 iLQR(0/6,解不可用)就是被支配的(它既没解出来、也谈不上省,被 MPPI/iCEM 全面支配),所以它压根不在前沿上。
  • 正确的读法三步:① 剔除被支配的方案(如失败的 iLQR);② 剩下的非劣方案构成前沿;③ 按你的真实偏好(计算预算多紧、精度要求多高)从前沿上挑——而非问"哪个绝对最好"。

本质洞察:Pareto 前沿教你一个深刻的多目标决策观——在互相冲突的多目标下,通常不存在"绝对最好",只存在"一组互不支配的非劣选项",最终选择取决于你的偏好权重。这把"哪个方法最好"这个常见但幼稚的问题,还原成了两个更清醒的问题:"哪些方法是非劣的(值得考虑的)?"和"我的偏好权重是什么(更看重哪个目标)?"。这个视角的迁移价值极大:面对任何多目标权衡(性能 vs 成本、精度 vs 速度、安全 vs 效率),都别问"哪个最好",而要先画出 Pareto 前沿(剔除被支配的、留下非劣的),再用自己的偏好从前沿上选。它还教你识别和剔除"被支配"的劣选项(既贵又差的)——这些在前沿之外,不配进入权衡。"没有最好、只有非劣 + 偏好"——这是成熟工程决策与天真"求最优"的分水岭。

深一层:累积项目为什么用"旋钮"组织,而非"继承 / 多态"

累积项目把各章能力做成"正交旋钮"(solver_backendcost_source……),而非给每种配置写一个子类(如 MPPIPlannerHybridMPPIPlannerCBFMPPIPlanner……)。这个设计选择背后有讲究,理解它能让你写出更可扩展的系统。

  • "继承 / 多态"的做法:给每种方法 / 配置定义一个子类,靠继承复用、靠多态切换。问题:配置是多维正交的(求解器后端 × 代价来源 × 动作空间 × ……),用继承表达会**类爆炸**——\(n\) 个维度、每维 \(k\) 种取值,要 \(k^n\) 个子类(如"力矩空间 + 代价地图 + 混合后端 + 鲁棒层"得专门一个类),完全不可维护。
  • "旋钮(组合 / 策略)"的做法:每个维度做成一个独立的可配置参数 / 策略对象,运行时**组合**它们。\(n\) 个维度、每维 \(k\) 种取值,只需 \(n\times k\) 个独立模块(而非 \(k^n\) 个类),组合出 \(k^n\) 种行为——线性的代码量、指数的配置空间。这正是 §9.7 深一层"正交维度增量积累"能成立的设计基础。
  • 设计模式的名字:这是"组合优于继承"(composition over inheritance)和"策略模式"(strategy pattern)——把"会变化的维度"封装成可替换的策略 / 参数,用组合而非继承来表达多维配置。它是应对"多个正交变化维度"的标准答案。
  • 代价:旋钮式需要前期设计好正交的接口(每个维度怎么抽象成一个旋钮),比随手继承更费思考;且要处理旋钮间的前提依赖(如 hybrid 需可微,§9.7 陷阱 2)。但换来的可维护性 / 可扩展性远值这个前期投入。

本质洞察:累积项目选"旋钮(组合)"而非"继承(子类)",是因为它的能力是**多维正交**的——而**继承擅长表达"is-a 的单维层级",组合擅长表达"多维正交的配置"。当变化的维度多且正交时,继承会类爆炸(\(k^n\) 个子类),组合则线性可控(\(n\times k\) 个模块组合出 \(k^n\) 种行为)。这是软件设计里"组合优于继承"原则的精确适用场景,也是本书累积项目能"加八根旋钮而不失控"的根本原因。这个洞察的迁移价值极大:**任何时候你的系统有多个正交的变化维度,第一反应该是"用组合 / 策略(旋钮)"而非"用继承(子类)"——前者让配置空间指数增长而代码量线性可控,后者会让你淹没在类爆炸里。识别"变化维度是否正交"是关键:正交的多维变化 → 组合;单维的层级特化 → 继承。把这个判断内化,你设计的可配置系统会优雅得多——这也是为什么现代框架(从游戏引擎的 ECS 到深度学习的模块化层)大量用组合而非深继承。架构的优雅,常常就藏在"组合还是继承"这个选择里。

深一层:为什么新旋钮 solver_backend 默认 'sampling'——向后兼容的设计

留意累积项目加 solver_backend 旋钮时的一个小而重要的细节:它**默认值是 'sampling'**(即前八章一直用的纯采样行为)。这不是随手设的,而是"向后兼容(backward compatibility)"的设计纪律,值得点破。

  • 为什么默认要保留旧行为:累积项目是逐章演进的——前八章写的所有代码 / 配置都假定"规划器就是纯采样"。如果新旋钮默认开启 'hybrid',那前面所有不带这个参数的调用,行为会**突然改变**(多了一道梯度精炼),可能在不可微问题上崩掉(§9.7 陷阱 2)——你"加了个新功能"却**悄悄破坏了所有旧用法**。
  • 正确做法:新旋钮默认值 = 旧行为('sampling'),这样**不带新参数的旧调用行为完全不变**,只有显式设 solver_backend='hybrid' 的新调用才启用新功能。加功能 = 纯增量,不破坏存量。
  • 这是一条通用纪律:每次给一个演进中的系统加新选项 / 参数,新选项的默认值都应让"不知道这个选项的人"得到和以前一样的行为——新功能"opt-in(选择性启用)",而非"opt-out(默认启用、要主动关)"。这保证了系统能持续加功能而不断打扰 / 破坏现有用户。
  • 联系累积项目的演进:八章加八根旋钮而系统不崩、旧章的 demo 仍能跑,靠的正是每根新旋钮都"默认旧行为"——这是"正交增量积累"(§9.7 深一层)能成立的隐形前提之一。

本质洞察:给演进中的系统加新能力时,"新选项默认保留旧行为(opt-in 而非 opt-out)"是一条保证"加功能不破坏存量"的关键纪律——它让系统能持续扩展而不断打扰现有用户 / 代码。这背后是"向后兼容"这个软件工程的核心价值:一个健康演进的系统,新版本应让旧用法继续работать,新功能让想用的人主动开启。违反它(新功能默认开启、改变旧行为)会让每次升级都成为"破坏性变更",最终没人敢升级。这条纪律的迁移性极强:设计任何 API、配置、框架的演进,都该让新参数默认等于旧行为。它也和 §9.7"组合优于继承"、"正交增量积累"一脉相承——共同构成了"如何让一个系统健康地长大"的设计智慧:正交(互不干扰)、组合(而非继承)、向后兼容(新功能 opt-in)。掌握这三条,你设计的任何可演进系统都会更经得起时间。

多视角:横向基准像"标准化考试",累积项目像"乐高积木"

给这一节的两件事各配一个直觉。

横向基准像一场标准化考试:所有考生(求解器)做同一份卷子(同任务)、同样的时间(同预算)、同一套评分标准(同成功判据 / 统计口径),这样分数才可比、才能真正区分高下。考试的公平性全系于"标准化"——卷子、时间、评分必须对所有人一致,否则分数无意义(呼应 §9.7 深一层"控制变量")。像的地方:标准化保证可比性,正是横向基准的灵魂。不像的地方(边界):标准化考试假设"一份卷子能衡量能力",但我们已知**一份卷子(一个任务)的结论不能外推到所有任务**(CartPole 上采样赢 ≠ 处处采样赢)——所以横向基准更像"单科考试",要全面评价得考多科(多任务基准)。别把单任务基准的结论当成"全能排名"。

累积项目像乐高积木:每根正交旋钮是一种标准接口的积木块,可以自由组合搭出各种结构(适配各种问题),而积木之间的接口是标准、清晰的(正交、可替换)。像的地方:乐高"标准接口 + 自由组合"的特性,正是累积项目正交旋钮的设计精髓。不像的地方(边界):乐高积木完全独立(任意块能接任意块),而累积项目的旋钮虽正交,却有**前提依赖**——如 solver_backend='hybrid' 要求动力学 / 代价可微(§9.5 方案一前提),不是任意组合都有意义(在不可微问题上用 hybrid 后端会出问题,§9.5 陷阱 1)。所以它比乐高多一层约束:组合自由,但要尊重每根旋钮的前提。别把"正交可组合"误解为"任意组合都行"——正交是指"语义不互相污染",不是"前提条件可以无视"。

深一层:两家的"调参旋钮"长得很不一样——以及这意味着什么

做基准、上工程,绕不开调参。采样式和梯度式的调参旋钮**性质迥异**,理解这点能让你预判"调一个新方法大概会踩什么坑"。

方面 采样式(MPPI/iCEM)的旋钮 梯度式(iLQR/SQP)的旋钮
核心旋钮 样本数 \(K\)、温度 \(\lambda\)、采样幅度 \(\sigma\)、退火日程、精英比例(iCEM) 正则化 \(\mu\)、线搜索步长集、迭代数、初值
旋钮的含义 调"探索 vs 利用"的平衡(撒多广、加权多尖) 调"对局部二次模型的信任"(\(\mu\) 大小、步长远近)
调错的后果 多为"性能差一点"(解粗 / 慢),少有灾难性失败 可能"发散 / 不收敛 / 陷局部",失败更剧烈
调参直觉 较直观(\(\sigma\) 大=更探索,\(\lambda\) 小=更贪心) 较隐晦(\(\mu\) 与收敛 / 稳定的关系不直观)
最敏感的 \(\sigma\) 和退火(影响能否跳出局部) 初值(决定收敛到哪个局部最优,§9.5)

几个值得记住的对比:

  • 采样式旋钮"温和",梯度式旋钮"剧烈":采样式调错通常只是解差一点、慢一点(它本来就靠大量样本兜底,鲁棒),梯度式调错(\(\mu\) 太小、初值太差)可能直接发散或陷死局部——失败更剧烈、更需要小心。
  • 梯度式有一个采样式没有的关键旋钮:初值。采样式从零初值也能靠全局撒样本找到好区域(对初值不敏感);梯度式对初值极敏感(决定落哪个盆地,§9.5、§9.7 暖启动实验)——所以用梯度式时,"给它一个好初值"往往比调其他旋钮更重要(这正是混合方案一的价值)。
  • 采样式的旋钮更"可解释"\(\sigma\) 控制探索范围、\(\lambda\) 控制贪心程度、退火控制探索→收敛的节奏——都有直观的物理意义,好上手。梯度式的 \(\mu\)、线搜索这些"信任管理"旋钮(§9.2 深一层)含义更隐晦,调好需要更多经验。

本质洞察:调参旋钮的性质,是方法内在机制的外显——采样式的旋钮调的是"探索-利用平衡"(温和、直观、调错不致命,因为大量采样本身鲁棒),梯度式的旋钮调的是"对局部模型的信任"(剧烈、隐晦、调错可能发散,因为它把命押在局部模型上)。这给你一条预判任何新方法"好不好调"的线索:看它依赖什么——依赖大量采样 / 冗余的方法通常调参温和鲁棒(错了有兜底),依赖精确局部模型 / 单点信息的方法通常调参剧烈敏感(错了就崩)。它也再次回响 §9.1 的核心权衡:梯度式用"强假设 + 精确局部模型"换效率,代价之一就是"调参更敏感、对初值更挑剔、失败更剧烈";采样式用"弱假设 + 大量冗余采样"换普适,回报之一就是"调参更温和、对初值更宽容、失败更平缓"。选方法时,别只看性能,也要把"好不好调、调错的后果多严重"算进去——这在快速迭代的真实项目里,常常和性能一样重要。

深一层:iCEM 的"有色噪声"为什么对摆起这类任务重要

基准里 iCEM 用了"有色噪声"(colored noise),demo 代码里也有一个 colored() 函数。这不是随意的选择——有色噪声是 iCEM 相对朴素 CEM 的关键改进之一,理解它能让你明白为什么它对摆起这类任务有效。

  • 白噪声 vs 有色噪声:白噪声(标准高斯)在时间上**独立**——每个时间步的控制扰动互不相关,整段控制序列看起来像"高频抖动"。有色噪声在时间上**相关**——相邻时间步的扰动相似,整段看起来"平滑、有持续的趋势"(低频成分多)。iCEM 用功率谱 \(\propto 1/f^\beta\) 的有色噪声生成这种时间相关的扰动(demo 里 beta=1.5)。
  • 为什么摆起需要有色噪声:摆起要"先持续往一个方向推、积累能量、再持续往另一方向甩"——这是一个**低频、有持续趋势**的控制模式。白噪声的高频抖动很难偶然撒出这种"持续推一阵"的样本(正负抵消了),而有色噪声天然产生"持续往一个方向"的平滑扰动,更容易撒中摆起需要的能量泵入模式。所以**有色噪声让采样在"需要持续、协调动作"的任务上效率高得多**(这也是 iCEM 论文的核心贡献之一,第 4 章)。
  • \(\beta\) 的选择\(\beta\) 控制"有多低频"——\(\beta\) 太大(如 2.5)噪声过于低频平缓、探索的多样性不足;太小(趋于 0)退回白噪声。基准里 \(\beta=1.5\) 是个折中(中低频),实测比 \(\beta=2.5\) 更可靠摆起(高频成分够、又有持续趋势)。
  • 联系 MPPI:基准里 MPPI 用的是白噪声 + \(\sigma\) 退火,靠"早期大 \(\sigma\) + 软加权"也能摆起(退火让它早期广探索)。两家用不同手段达到"撒出协调动作":iCEM 靠有色噪声(结构化的扰动),MPPI 靠大 \(\sigma\) 退火(量大 + 软加权兜底)——殊途同归。

本质洞察:iCEM 的有色噪声,本质是**给采样注入"时间结构"先验**——它编码了"好的控制往往是平滑、有持续趋势的"这个对许多物理任务成立的假设,从而让采样在"需要协调、持续动作"的任务(摆起、行走、抓取)上大幅提效。这是一个深刻的、可迁移的采样设计思想:采样不必盲目(各向同性白噪声),可以把关于"好解长什么样"的先验编进采样分布(时间相关性、平滑性、甚至学到的结构,§前沿"学习采样分布")。这呼应了 §9.5 第五种"隐式混合"(用梯度 / 学习塑形采样)和 §9.1 的谱——"白噪声盲撒"只是采样的最朴素形态,沿着"给采样注入越来越多结构 / 先验"的方向,采样可以变得越来越聪明、越来越接近"有方向的搜索"。理解这点,你看任何采样式方法时,都会多问一句:"它的采样分布里编了什么先验(白噪声?有色?学习的?)?"——这往往是它相对朴素采样的关键改进所在。

深一层:为什么基准要跑多种子、报方差,而不只报一个均值

本章基准跑了 6 个随机种子、报的是"成功 5/6"这样的统计,而非"跑一次的结果"。这不是形式主义——多种子 + 报方差是采样式(含一切带随机性的方法)基准的诚实底线,理解它能让你既做出可信的基准、也看穿不可信的。

  • 采样式有随机性,单次结果不可复现也不代表性能:MPPI / iCEM 每次跑的随机噪声不同,单次跑出的代价 / 成功与否有运气成分——跑一次"成功了"可能只是这颗种子运气好。只有多种子统计(成功率、均值、方差)才反映"它平均有多可靠、波动多大"。
  • 均值掩盖方差,方差才显鲁棒性:两个方法可能均值相同,但一个每次都稳定中等、另一个时好时坏(高方差)——对真实部署,"稳定中等"往往比"时好时坏"更可取(你要的是每次都能用,不是平均能用)。只报均值会把这个关键差异藏起来。本章基准里 iCEM 和 MPPI 都 5/6,但若看方差,能进一步区分谁更稳(§9.7 易错点提到 iCEM 鲁棒性略逊)。
  • 确定性方法(iLQR)则不需要多种子:iLQR 无随机性,同初值跑多少次结果都一样(本章 iLQR 6 个种子结果完全相同)——所以它的"失败"是结构性的、可复现的(§9.7:这正说明它陷局部是必然、非运气)。对确定性方法,要变的是初值 / 问题实例,而非随机种子。
  • 诚实报告的要素:多种子(足够多,如 ≥5)、报成功率 + 均值 + 方差(或分布)、说清成功判据、固定其他变量——这些让你的基准可信、可复现。

本质洞察:对带随机性的方法(采样式、随机优化、RL),单次运行的结果几乎没有意义,只有多次运行的统计(成功率、均值、方差)才反映真实性能——而方差尤其重要,它衡量"稳不稳",是真实部署里和均值同等关键的指标。这背后是实验科学的基本规范:衡量一个随机过程,必须用足够样本的统计量,并诚实报告不确定性(方差 / 置信区间),而非用单次观测下结论。这条规范的迁移价值极大——读任何"我的方法性能是 X"的论断,先问"跑了几次?是单次还是统计?报方差了吗?";做任何涉及随机性的评测(A/B 测试、模型评估、性能基准),都要多次运行 + 报不确定性。一个只报"最好一次"或"单次结果"的随机方法基准,是不可信的(甚至可能是 cherry-picking)。本章基准坚持多种子 + 报成功率,正是想给你示范"随机方法的基准该怎么做才诚实"——也提醒你警惕那些不报方差、用单次结果说事的"漂亮数字"。

易错点:基准里 iCEM"稍逊"不代表 iCEM 是更差的方法

本节基准里 iCEM 的末角(25.2°)比 MPPI(10.7°)大、看起来"差一点",一个常见的误读是"那 iCEM 就是比 MPPI 差的方法、没必要用"。这是错的。iCEM 在这个基准里"稍逊精度",恰恰伴随着它"更省样本"(30k vs 50k rollout)的优势——它是在"用更少计算换稍低精度",这在很多场景下是划算的(尤其计算预算紧、或要更高控制频率时)。更重要的是:这个基准的设置(开环轨迹优化、CartPole 摆起、这套参数)只反映了 iCEM 在这一个特定条件下的表现,不能外推成"iCEM 总体更差"。iCEM 的设计初衷是"实时规划里用尽量少的样本达到好性能"(第 4 章),在它擅长的"低样本预算 + 需要时间相关平滑动作"的场景(如高频 MPC),它可能反超 MPPI。把"某个基准里某指标稍逊"读成"这个方法更差",是对基准结论的过度外推(呼应 §9.7 深一层"基准结论有适用范围")。正确做法:看基准时,全面看多个指标的权衡(精度 vs 样本数 vs 鲁棒性),而非揪住单一指标排名;并清楚"这个基准测的是什么条件,结论只在该条件下成立"。自检:你说"A 比 B 差"时,是不是只看了一个指标、忽略了 A 在另一个指标(如样本效率)上的优势?是不是把单一基准的结论当成了普适排名?

⚠️ 常见陷阱

陷阱 1:基准里给不同求解器用了不同的代价 / horizon / 成功判据 ⚠️ 编程陷阱 - 错误做法:你比较 MPPI 和 iLQR,但给 MPPI 用了一套代价、给 iLQR 用了另一套(比如 iLQR 的代价更"光滑友好"),或 horizon、成功阈值不一致。 - 现象/后果:测出的"差异"混杂了"求解器不同"和"任务设置不同"两个因素,你无法归因——到底是求解器的差异,还是因为你给一方设了更友好的条件?结论不可信、甚至误导。 - 根本原因:违反了控制变量原则。基准要比的是"求解器"这一个变量,就必须固定其他一切(代价、horizon、dt、初值、成功判据、统计口径)。任何不一致都引入混杂因素,让结论失去意义。 - 正确做法:严格控制变量——让所有求解器共用**同一个** rollout_cost、同一个 \(H\)/\(\Delta t\)/\(s_0\)、同一个成功判据、同样的种子数和统计口径(本节基准正是这么做的:三法共用一个 rollout_cost)。自检:你的基准里,三个求解器是不是真的在用完全相同的任务定义和评测标准?有没有哪个变量在不知不觉中对某一方更友好?

陷阱 2:把 solver_backend='hybrid' 用在不可微问题上 ⚠️ 概念误区 - 错误想法:"混合后端(采样 + 梯度精炼)比纯采样更强,那我所有问题都用 hybrid 后端,反正多一道精炼总没坏处。" - 现象/后果:你在一个不可微问题(接触 / indicator 代价)上用 hybrid 后端,结果梯度精炼阶段(iLQR)在不可微处发散,把采样找到的好解"精炼坏"了,hybrid 反而不如纯 sampling(§9.5 陷阱 1 的重演)。 - 根本原因:hybrid 后端的精炼阶段是梯度式,要求**问题(至少在采样解附近)可微**。在本质不可微的问题上,这个前提不满足,精炼非但无益反而有害。这正是 §9.6 多视角"正交不等于任意组合可用"——solver_backend 旋钮虽正交,但 'hybrid' 取值有"可微"的前提。 - 正确做法:用 solver_backend='hybrid' 前,确认问题(盆地内部)可微;不可微问题(接触、indicator)老老实实用 'sampling'。把"hybrid 需要可微"当成这根旋钮的使用前提,写进文档 / 注释。自检:你要切到 hybrid 后端的那个问题,动力学和代价在采样解附近可微吗?不可微就别切。

陷阱 3:以为"基准跑赢了"就等于"这个方法在真实部署中也最好" ⚠️ 思维陷阱 - 错误想法:"MPPI 在我的 CartPole 基准上跑赢了 iLQR,那真实部署也用 MPPI 准没错。" - 现象/后果:你把基准(理想化的、开环的、玩具规模的)结论直接搬到真实部署,却忽略了真实部署有基准里没有的因素——实时性约束(基准不限时、真实要几百赫兹)、硬件平台(基准在工作站、真实在嵌入式)、模型误差(基准用真模型、真实有 sim-to-real gap)、硬约束(基准没要求、真实要绝不违反)——结果基准赢的方法在真实部署中反而不合适。 - 根本原因:基准是受控的简化环境,真实部署有大量基准未覆盖的约束和因素。基准结论是"在基准条件下"的,真实部署是另一组条件。把前者直接当后者,忽略了条件的巨大差异。 - 正确做法:把基准结论当成"一个受控条件下的参考点",部署前还要用真实的约束(实时性、平台、模型误差、硬约束)重新审视(这正是 §9.6 决策树 / 方法论要做的全面权衡)。基准帮你理解方法的特性,但不替代针对真实部署条件的完整选型。自检:你要把基准结论搬到真实部署时,真实部署有哪些基准里没有的约束(实时、平台、模型误差、硬约束)?这些约束会不会改变结论?

陷阱 4:横向基准里"耗时(wall-clock)"被当成纯粹的算法快慢来比 ⚠️ 编程陷阱 - 错误做法:你看到基准里 iLQR 耗时 ~480ms、MPPI ~1200ms,就下结论"iLQR 比 MPPI 快 2.5 倍",并据此选 iLQR。 - 现象/后果:① 这个 wall-clock 严重依赖**实现**——本章 iLQR 用有限差分雅可比(很慢),真实框架用解析 / 自动微分会快得多;MPPI 是纯 numpy 串行,真实用 GPU 会快几个数量级。两者的实现都不是"最优实现",比它们的绝对耗时没有意义。② 更糟的是,iLQR 的 480ms 是"快速地算出一个没用的解"(0/6 陷局部),快而无用。 - 根本原因:教学用纯 numpy 实现的 wall-clock 不反映两家的"真实算法效率"——它混入了"实现质量""有没有 GPU""有没有用解析雅可比"等与算法本身无关的因素。把教学实现的绝对耗时当算法快慢比,是张冠李戴。 - 正确做法:① 比 wall-clock 要在**对等、接近最优的实现**上比(如都用成熟库、同等硬件),否则只看"量级 / 趋势"(§9.3 复杂度深一层)而非绝对值;② 永远先看"成功率"(解出来没有),再谈耗时——快而无用的解(如这里的 iLQR)不配比快慢(§9.7 Pareto 深一层)。自检:你比的 wall-clock,两家是不是对等实现、同等硬件?有没有先确认"都给出了可用解"再比速度?

练习

  1. (复现 + 探究·横向基准,⭐⭐⭐) 跑通本节 CartPole 横向基准,复现"MPPI 5/6、iCEM 5/6、iLQR 0/6"。然后:(a) 给 iLQR 换一个**好的初值**(如先用 MPPI 跑几轮的解、或一个手工设计的"先反摆再上甩"的初值),看它能否摆起(验证"iLQR 不是不行、是从零初值陷局部",这正是 §9.5 混合方案一的动机);(b) 把 iCEM 的样本数 K 提到和 MPPI 一样(用更多样本),看它的末角能否追上 MPPI(体会精度与样本数的关系);(c) 把成功阈值从 30° 收紧到 10°,看三者成功率如何变化(体会"成功判据的松紧影响结论",呼应陷阱 1)。
  2. (实现·求解器后端旋钮,⭐⭐⭐⭐) 在你的累积项目 UnifiedSamplingPlanner 上实现 solver_backend 旋钮('sampling''hybrid')。在本章双势阱任务上验证:'sampling' 到全局阱但粗、'hybrid' 精炼到更低代价。然后做一个关键的**健壮性测试**:把任务换成一个**不可微**的(如加 indicator 障碍),确认 'hybrid' 后端在此会出问题(精炼阶段发散 / 变差)、而 'sampling' 不受影响——亲手验证 §9.7 陷阱 2,体会"这根旋钮的 hybrid 取值有可微前提"。
  3. (思考·框架思维 vs 阵营思维,⭐⭐⭐⭐) 本节本质洞察说"把求解器范式做成一根可切换旋钮,是框架思维超越阵营思维"。请综合论证:(a) 为什么"设计一个能容纳采样 / 梯度 / 混合、按需切换的统一框架"比"在采样 vs 梯度之间站队"更高级(从适配能力、认知成熟度两方面);(b) 这种"把竞争方案统一进可配置框架"的思维,在机器人 / 软件 / AI 领域还有哪些例子(如:统一各种优化器的库、统一各种神经网络层的框架、统一各种数据库的抽象层);(c) 由此提炼——当你面对一个"几种方法各有拥趸、互相争论谁更好"的领域时,"框架思维"会让你怎么做、它为什么往往优于"挑一个站队"。
  4. (复现 + 探究·暖启动让 iLQR 复活,⭐⭐⭐⭐) 跑通本节 CartPole 暖启动 demo,复现"iLQR 从零 180°、MPPI 0.2°、iLQR 暖启动 0.1°"。然后:(a) 把暖启动的初值从"MPPI 的解"换成"一个手工设计的先反摆再上甩的粗略控制",看 iLQR 是否也能摆起(验证"关键是好初值、不一定非得来自 MPPI");(b) 试着只用很少的 iLQR 迭代(如 5 次)做暖启动后的精炼,看它是否还能在 MPPI 解基础上改进(体会"精炼只需少量迭代",呼应方案一);(c) 把这个实验写成一段话:"为什么说 iLQR 在基准里的失败是初值问题、而非能力问题"。
  5. (思考·诚实基准的要素,⭐⭐⭐) 综合本节"控制变量""Pareto""多种子报方差"几个深一层 / 易错点,列出"一个诚实、可信的求解器横向基准"必须满足的要素清单(至少五条),并对每条说明"不满足会导致什么误导"。然后用这份清单审视一个你见过的(论文 / 博客里的)方法对比,指出它哪些做到了、哪些没做到。

本章横向对比:采样式 vs 梯度式 vs 混合

把全章的对比浓缩成一张总表,作为速查(这是 §9.3 九维表的"再升一层",加入了混合一列,并从"该怎么用"的角度重组):

比较项 采样式(MPPI/CEM) 梯度式(iLQR/DDP/SQP) 混合(§9.5 四方案)
对模型的要求 只需能求值(黑箱/不可微皆可) 需可微(解析或可靠雅可比) 取决于哪段用哪家
对代价的要求 任意(indicator/CNN/黑箱) 需光滑可微 不可微部分给采样、光滑部分给梯度
收敛性质 概率、偏全局、精度有限 确定、局部二次、高精度 全局(采样)+ 高精度(梯度精炼)
硬约束 弱(软惩罚/投影) 强(QP/NLP 原生) 用 CBF/梯度式补硬约束(方案二)
计算特性 大规模并行、吃 GPU 串行稠密线代、宜 CPU 两段分别用各自适合的硬件
适用维度 中低维(4–20,靠覆盖) 高维(可上百,靠导数) 高维用分层(方案四)降复杂度
最适问题 不可微/黑箱/感知驱动/接触丰富 光滑/解析/要精度与硬约束/CPU "海岸线"问题(多需求并存)
典型代表 Nav2、AutoRally、STORM、DIAL-MPC acados、OCS2 MPPI+iLQR、Shield-MPPI、分层 WBC
一句话 不挑结构、普适但欠精 榨取结构、高效但挑前提 各取所长、真实系统的常态

读这张表的正确方式(§9.6 反复强调):不是"选一列站队",而是先用问题特性(可微吗、要精度/约束吗、多少维、什么平台)定位到合适的列,且常常落到"混合"列。三列不是三个阵营,是同一套工具箱里按问题取用的三种配置。

前沿与开放问题

这场"采样 vs 梯度"的对比远未尘埃落定——下面几个方向正在重塑两家的边界,了解它们能让你看清这个领域的演进方向。

可微仿真与接触平滑——把梯度式带进"接触"这片采样式的腹地。 采样式在接触丰富的腿足 / 操作上占优,根本原因是接触不可微(§9.4 第二类)。但若能让接触**可微**(光滑近似接触力、或用可微物理引擎),梯度式就能反攻这片腹地。可微仿真(differentiable simulation)和接触平滑(contact smoothing)是活跃的前沿——它们试图给接触一个"有意义的梯度",让 iLQR/DDP 能处理接触。挑战在于:平滑后的接触梯度可能误导(§9.4 深一层 sigmoid 的双刃剑在接触上的版本),且高保真可微仿真计算昂贵。这个方向若成熟,会显著改变 §9.6 的案例选择(一些现在用采样式的接触问题可能转向梯度式或混合)。

学习采样分布——让采样式更"聪明"地撒样本。 采样式的效率瓶颈是"撒得盲目"(高维下覆盖稀疏,§9.3 ⑧)。一个活跃方向是**用学习改善采样分布**:用扩散模型生成更优的控制样本(第 5 章扩散启发)、用归一化流(normalizing flow)学习提议分布、用 RL 策略做采样先验(§9.5 方案三 Biased-MPPI)。核心思想是把"在哪儿撒样本"从"均匀盲撒"变成"学出来的、集中在有前途区域的撒法"——这能缓解维度灾难、提升样本效率,让采样式在更高维上可用。这是采样式自我进化、侵蚀梯度式"高维"优势的方向。

安全的采样 MPC——给采样式补上硬保证。 采样式的硬约束弱(§9.3 ⑥)是它相对梯度式的结构性短板。除了 §9.5 方案二的"CBF 事后滤波"和 Shield-MPPI(Yin & Tsiotras 2023,把离散 CBF 内化进 rollout),还有把控制屏障函数、可达性分析、约束采样等更紧地集成进采样过程的研究——目标是让采样式在保持灵活的同时,获得接近梯度式的安全 / 约束保证。这个方向若成熟,会削弱"要硬约束就得用梯度式"这条判据(§9.6 决策树的一个分支)。

统一视角与自动选择——超越"人工选求解器"。 本章教你"人工"走决策树选求解器(§9.6)。一个更前沿的想法是:能否让系统**自动**根据问题特性选择 / 切换求解器,甚至在一个统一的优化框架下让采样和梯度"连续地"融合(如把采样看成零阶梯度估计、与一阶梯度统一)?把采样式和梯度式统一进一个理论框架(如随机优化、变分推断的不同实例)也是理论上的活跃方向——它可能最终消解"两家之分",给出一个连续谱上的统一方法。

这些前沿的共同主题,是"侵蚀边界":可微仿真让梯度式侵蚀采样式的接触腹地,学习采样分布让采样式侵蚀梯度式的高维优势,安全采样 MPC 让采样式侵蚀梯度式的硬约束优势。本章给你的"两家边界"(§9.3、§9.4)是当下的、动态的——理解它们为何如此(那颗"求值 vs 求导"的种子),你才能在边界移动时依然判断准确:无论技术怎么进步,"这个问题能满足多强的假设、该用能利用这些假设的方法"这把尺子(§9.1 本质洞察)始终有效

本章常见误解汇总

把全章散落在各节的核心误区集中起来,一次性澄清——这些是学完本章最该牢记的"认知防线":

误解一:"采样式更新、随 GPU 和深度学习兴起,所以更先进、更好、应该优先用。" 纠正:方法的价值由它适合的问题决定,不由新旧决定(§9.1 陷阱 3)。采样式的兴起是因为问题形态变了(越来越黑箱、不可微,§9.4 深一层),而非它"更先进"。在光滑、可微、要精度和硬约束的问题上,梯度式至今无可替代(§9.3 demo)。两家互补,不是谁淘汰谁。

误解二:"采样式只求值、不挑可微性,所以对问题没有任何要求、什么都能很好地解。" 纠正:采样式不挑可微性,但挑"维度"(高维覆盖稀疏,§9.3 ⑧)和"代价地形的可采样性"(好解藏在窄缝里就难撒到)。它的真实强项是"中低维 + 不可微/黑箱",不是"万能"(§9.1 陷阱 2)。

误解三:"神经网络代价是可微的,所以梯度式能用——直接对它求梯度优化就行。" 纠正:"可微"不等于"梯度对优化有好的指引"。CNN 代价地形极崎岖、充满虚假极值和对抗方向,对它求梯度常被误导;该用采样式在它上面**求值打分**,而非求梯度(§9.4 陷阱 1)。可微是必要条件,不是充分条件。

误解四:"把不可微的 indicator 抹平成 sigmoid,梯度式就能用了,问题解决。" 纠正:抹平只是把"梯度为零"换成"梯度要么消失要么爆炸、陡峭度极难调 + 优化代理而非真目标"——治标不治本(§9.4 深一层)。很多时候不如直接用不挑可微性的采样式。

误解五:"梯度式收敛快,所以它收敛到的就是最优解。" 纠正:梯度式的"快"是**局部**的——它快速收敛到离初值最近的局部最优,非凸问题上可能是个坏解(§9.2、§9.5 双势阱 demo:iLQR 陷局部阱)。"收敛了"不等于"全局最优",非凸问题要靠全局方法(采样)找盆地(§9.5)。

误解六:"这是采样 vs 梯度的二选一。" 纠正:两家互补,最常见的真实形态是**混合**(§9.5 四方案、§9.6 工业案例一半以上是混合)。把它看成"统一框架里一根可切换的旋钮"(§9.7 累积项目),而非互斥的阵营选择——框架思维高于阵营思维。

误解七:"横向基准里某方法跑赢了,它就是更好的方法、真实部署也用它。" 纠正:基准结论只在"基准条件下"成立(特定任务、开环、玩具规模),不能外推成普适排名,更不能直接搬到有实时 / 平台 / 模型误差 / 硬约束的真实部署(§9.7 易错点、陷阱 3)。基准帮你理解特性,不替代针对真实条件的完整选型。

误解八:"求解器选择按机器人 / 领域定——四足机器人就该用某某求解器。" 纠正:求解器选择的正确粒度是"任务",不是"机器人型号"(§9.6 深一层:Go2 行走用梯度式 OCS2、Go2 跳跃用采样式 DIAL-MPC,同机器人不同任务选不同求解器)。

本章小结

本章是采样 MPC 方向的"对比与定位"章——它让你跳出前八章的"采样视角",站在整个最优控制版图上重新审视采样式 MPC:它从哪来、强在哪、弱在哪、何时该用、何时该把舞台让给梯度式、何时该两家合作。

核心的一颗种子(§9.1):采样式与梯度式的根本分野,是"只需求值"vs"需要求导"。 梯度式对问题求导(线性化动力学、二次化代价),用导数信息精准走每一步——快、准、能上高维、能管硬约束,但要求处处可微。采样式只对问题求值(rollout 算代价),用大规模并行的求值 + 加权近似最优——普适(黑箱 / 不可微都行)、吃 GPU、偏全局,但精度有限、高维吃力。这颗种子背后是一个普适的权衡:更强的假设(可微)换更高的效率,更弱的假设(只需求值)换更广的适用——没有免费的午餐。后面所有的维度差异,都是这颗种子的推论。

梯度式的机制(§9.2): iLQR/DDP/SQP 的一次迭代 = 沿轨迹线性化 + 二次化 + 解局部 LQR/QP 子问题得下降方向 + 线搜索更新。iLQR 用一阶动力学 + 二阶代价(扔掉 DDP 的动力学二阶项以省算力),SQP 用序列二次规划原生处理硬约束。它们快而局部、精而挑前提(可微)。

九维系统对比(§9.3)与梯度式的胜场: 沿梯度需求 / 代价 / 动力学 / GPU / 收敛性 / 硬约束 / CPU 可行性 / 维度 / 杀手场景九个维度,两家全面对比——而这九维全是种子的推论。在光滑可微问题上,梯度式赢得明明白白(demo:iLQR 代价 2.22 vs MPPI 7.11),因为它榨取了问题的光滑结构,而采样式的"普适"在这里成了"不利用结构"的劣势。维度上梯度式能上百维(靠导数)、采样式卡在二十维(靠覆盖,维度灾难)。

采样式的杀手场景(§9.4): 三类"求导失效"——非光滑 / 不连续代价(indicator、CNN)、不可微动力学(接触、黑箱仿真)、纯黑箱(无解析形式)。它们破坏求导前提、但不破坏求值,是采样式独占的领地(demo:indicator 障碍让 iLQR 失明直穿、MPPI 绕开)。现代机器人问题越来越黑箱、越来越脏,正是采样式崛起的时代背景(不是它更先进,是世界变黑箱了)。

混合架构(§9.5): 四方案各取所长——①全局采样初始化 + 梯度局部精炼(双势阱 demo:iLQR 陷局部 1.26、MPPI 全局 -0.58、混合精炼 -0.60);②MPPI 出性能 + CBF 保安全(Shield-MPPI, Yin & Tsiotras 2023,把离散 CBF 内化进 rollout);③RL 策略先验 + MPPI 在线微调(Biased-MPPI 2024);④MPPI 高层 + WBC/PD 底层分层。混合是真实系统的常态,不是炫技。

选型方法论(§9.6): 七个工业案例精确印证理论(脏 → 采样、干净 → 梯度、高维难 → 混合 / 学习);决策树按"可微性 → 平台 → 约束"的一票否决优先级走;四步方法论(刻画问题 → 走树定主力 → 判断混合 → 按维度平台校准)把选求解器从凭感觉变成可复现的工程决策。求解器选择的粒度应细到"任务"(Go2 行走 vs 跳跃用不同求解器)。

横向基准与累积项目(§9.7): CartPole 摆起上控制变量地同台竞技(MPPI/iCEM 5/6 摆起、iLQR 0/6 陷局部),把理论落到硬数字;累积项目加上"求解器后端"旋钮(sampling/hybrid),把范式选择变成统一框架里的一个可配置维度——框架思维高于阵营思维。

术语速查表

术语 英文 / 缩写 一句话定义 出处
求值 vs 求导 evaluation vs differentiation 本章核心分野:采样式只需求值、梯度式需求导 §9.1
iLQR iterative LQR 反复用 LQR 局部近似解非线性最优控制(线性化+二次化+Riccati) §9.2
DDP Differential Dynamic Programming iLQR 的二阶版本(额外用动力学的二阶导) §9.2
SQP Sequential Quadratic Programming 序列二次规划,原生处理硬约束的梯度式框架 §9.2
实时迭代 RTI (Real-Time Iteration) 每控制周期只做一次 SQP 迭代以保实时(acados) §9.6
二阶收敛 quadratic convergence 梯度式在局部最优附近的快速收敛性质 §9.2
局部最优 local optimum 梯度式从某初值出发收敛到的、未必全局的解 §9.2/§9.5
维度灾难 curse of dimensionality 高维下采样覆盖指数级稀疏,采样式吃力的根因 §9.3
indicator 代价 indicator cost 阶跃 / 二值代价(如撞障碍罚一大笔),梯度处处为零 §9.4
可微仿真 differentiable simulation 让接触等不可微动力学可微的研究方向 前沿
控制屏障函数 CBF (Control Barrier Function) 给系统硬安全保证的约束机制 §9.5
Shield-MPPI Yin & Tsiotras 2023,把离散 CBF 内化进 MPPI rollout §9.5
Biased-MPPI 2024,用辅助控制器 / RL 策略偏置采样均值 §9.5
安全滤波 safety filter 用 CBF-QP 把控制投影到安全集(方案二) §9.5
全局初始化+局部精炼 global init + local refine 采样找盆地、梯度精炼的混合元模式(方案一) §9.5
解耦 decoupling 把纠缠的关注点(如性能与安全)拆成独立模块 §9.5
分层架构 hierarchical architecture 高层规划(采样)+ 底层跟踪(WBC/PD)(方案四) §9.5
决策树 decision tree 按可微性→平台→约束选求解器的流程 §9.6
控制变量 controlled variable 横向基准里固定除求解器外的一切以保公平 §9.7
求解器后端 solver backend 累积项目里切换采样 / 混合范式的旋钮 §9.7
框架思维 framework thinking 把竞争方案统一进可配置框架,而非站队 §9.7
零阶 / 一阶 / 二阶 zeroth/first/second-order 优化用到几阶导数;采样零阶、iLQR 一/二阶 §9.1
值函数 value function "从某状态起最优控制的最小代价",iLQR 后向递推近似它 §9.2
单 / 多重打靶 single/multiple shooting 梯度式问题构造:只优化控制 vs 状态也作变量+连续性约束 §9.2
有色噪声 colored noise 时间相关的采样噪声,利于"持续协调动作"任务(iCEM) §9.7
组合优于继承 composition over inheritance 多维正交配置用组合(旋钮)而非继承(子类) §9.7
Pareto 前沿 Pareto front 多目标下互不支配的非劣方案集合 §9.7
可微仿真 differentiable simulation 让接触等不可微动力学可微的研究(未成熟) §9.4
反模式 anti-pattern 常见但错误的做法(这里指选型反模式) 反模式速查

知识点总表

知识点 关键内容 掌握标志
根本分野 求值 vs 求导;更强假设换更高效率 能从这颗种子推出九维差异
梯度式机制 iLQR/DDP/SQP 怎么工作、为何快而局部、为何挑可微 能讲清一次 iLQR 迭代在做什么
九维对比 梯度/代价/动力学/GPU/收敛/约束/平台/维度/杀手场景 拿到问题能逐维"化验"
梯度式胜场 光滑可微问题上梯度式又快又准 能解释 demo 里 iLQR 为何胜 MPPI
采样式杀手场景 非光滑代价/不可微动力学/黑箱三类求导失效 能判断问题落入哪类禁区
混合四方案 全局+精炼、CBF安全、RL先验、分层 能给问题选合适的混合架构
选型方法论 决策树 + 四步流程,可微性优先 能为新问题走完整选型流程
横向基准 控制变量、看成功率、Pareto、诚实报告 能设计公平基准、批判不公平基准
求解器后端旋钮 范式选择 = 统一框架的可配置维度 能实现 sampling/hybrid 切换并知前提
优化阶数谱 零阶(采样)/一阶/二阶(梯度),用导数越多越快越挑剔 能把任意优化法定位到谱上
计算复杂度 MPPI \(O(KHd)\) 对维低阶但需指数样本;iLQR \(O(Hd^3)\) 对维立方 能估两家在给定规模下的算量
warm-start 滚动时域里复用上一步解;梯度式靠它才实时可行 知道两家在真实闭环里的表现差异
CBF 硬安全 软惩罚≠硬安全;CBF-QP 投影保证不进危险集(有前提) 能用 CBF 给采样式补硬安全
混合失败模式 两家"打架":抢方向/抢控制/带偏/时间尺度不匹配 设计混合时会检查目标相容性
组合优于继承 多维正交配置用旋钮(组合)而非子类(继承)防类爆炸 能为可配置系统选对组织方式
工具链成熟度 真实价值=理论最优×工程可落地;成熟工具可压倒理论略优 选型时把工具生态算进来
选型反模式 手熟/潮流/误判/堆资源/堆砌/错粒度/过度外推/忽视工具 选型前能对照自查避坑

一句话速记

  • 求值 vs 求导——这一句话解释本章一切(采样只求值、梯度要求导)。
  • 更强假设换更高效率——梯度式假设可微换高效,采样式假设弱换普适,没有免费午餐。
  • 光滑用梯度、脏用采样、海岸线用混合——一句话的选型直觉。
  • 梯度式快而局部、采样式慢而偏全局——收敛性质的一句话。
  • 可微≠梯度好用、收敛≠全局最优、新≠更好——三条防误解的一句话。
  • 求解器选择细到任务、不是机器人——选型粒度的一句话。
  • 框架思维高于阵营思维——把范式做成旋钮,而非站队。
  • 零阶 / 一阶 / 二阶——用的导数越多越快越挑剔,采样在零阶端、iLQR 在一/二阶端。
  • 软避障 ≠ 硬安全——惩罚只是变贵,CBF 才保证不进危险集(有前提)。
  • 好组件拼起来未必是好系统——还要目标相容、接口简单,否则两家"打架"。
  • 多维正交用组合、单维层级用继承——累积项目用旋钮而非子类的原因。
  • 理论指方向、工具定落地——选型要把工具链成熟度和理论最优一起算。
  • 先上最简基线、按真实反馈升级——别一开始就追求完美选择 / 过早复杂化。
  • 随机方法只看统计、必报方差——单次结果不可信,成功率 + 方差才诚实。
  • 新功能默认旧行为(opt-in)——加能力不破坏存量,系统才能健康长大。

学完自检

读完本章,检查自己能否回答(不能则回对应小节):

  1. 用一句话说出采样式和梯度式最根本的区别,并解释为什么这个区别能推出"梯度式需可微、采样式不需要"(§9.1)。
  2. 描述 iLQR 一次迭代做的三件事,并解释它为什么"快而局部、精而挑可微"(§9.2)。
  3. 在光滑可微问题上,为什么梯度式通常胜过采样式?用 §9.3 demo 的数字说明(§9.3)。
  4. 为什么采样式能上的维度(20)远低于梯度式(200)?从"获取搜索方向信息的成本"解释(§9.3)。
  5. 列出三类"求导失效"的场景,各举一例,并解释为什么它们破坏求导却不破坏求值(§9.4)。
  6. 把 indicator 抹平成 sigmoid 能救梯度式吗?说出这个补救的两个代价(§9.4)。
  7. 描述四种混合架构各自的组合逻辑和适用场景(§9.5)。
  8. 为什么"全局初始化 + 局部精炼"是一个普适的优化元模式?(§9.5)
  9. 走一遍选型决策树,说明它为什么按"可微性 → 平台 → 约束"排序(§9.6)。
  10. 为什么 Go2 行走和 Go2 跳跃要用不同的求解器?这说明求解器选择的粒度应该是什么?(§9.6)
  11. 横向基准里 iLQR 为什么 0/6 失败?这和它在 §9.3 光滑问题上的胜场矛盾吗?(§9.7)
  12. "把求解器范式做成一根可切换旋钮"体现了什么思维?它为什么优于"在采样 vs 梯度间站队"?(§9.7)
  13. 把采样式、iLQR、DDP 放到"零阶 / 一阶 / 二阶"的优化谱上,各在哪一档?用的导数阶数越高,换来什么、要求什么?(§9.1)
  14. 写出 MPPI 和 iLQR 单次迭代的复杂度量级,说明各自"随什么爆炸",以及这如何解释维度上的强弱。(§9.3)
  15. warm-start 是什么?为什么它对梯度式是"雪中送炭"、对采样式是"锦上添花"?这如何改变你对"梯度式对初值敏感"的评价?(§9.3)
  16. 用"软惩罚 vs CBF"解释"软避障 ≠ 硬安全",并说出 CBF 硬保证的前提。(§9.5)
  17. 混合架构有哪几种"打架"的失败模式?除了"接口简单",可靠的组合还需要保证什么?(§9.5)
  18. 为什么累积项目用"旋钮(组合)"而非"子类(继承)"来组织多维配置?什么时候该用组合、什么时候该用继承?(§9.7)
  19. 除了问题特性,还有什么现实因素影响选型?为什么成熟工具链有时能压倒"理论略优"?(§9.6)
  20. 说出至少四个选型反模式,以及避开它们的总原则。(反模式速查)

承上启下

回望前八章:你在采样 MPC 的世界里一路深入——从路径积分理论(第 1 章)、MPPI 核心与 GPU(第 2 章)、六大变体(第 3 章)、CEM 家族(第 4 章)、学习模型(第 6 章)、腿足全身(第 7 章)、到导航自驾无人机(第 8 章)。本章是这条线的"抬头看路"——它让你第一次正面认识采样式之外的另一家(梯度式),从而真正理解采样式在整个最优控制版图里的位置:它不是"做 MPC 的唯一方式",而是"为某一类问题(不可微、黑箱、感知驱动)而生的、与梯度式互补的一支"。这个定位,让你对前八章学的一切有了更清醒的认识——你知道了它们的适用边界,也知道了边界之外该用什么。

眺望后续方向:本章埋下的几颗种子会在后续方向里发芽。控制屏障函数(CBF)(§9.5 方案二)只是这里的惊鸿一瞥——在"鲁棒规划与安全滤波"方向里,CBF、可达性分析、安全证书会被系统地展开,它们正是给采样式(乃至任何控制器)补上硬安全保证的核心工具。梯度式 MPC、硬约束、QP/NLP 求解(§9.2、§9.3 ⑥)会在那些需要严格约束保证的方向里继续深化。混合架构、分层、学习 + 控制的结合(§9.5)是几乎所有真实系统方向的共同主题。而本章最想留给你的——那把"按问题特性(能满足多强假设)选方法"的尺子、那套"刻画问题→定主力→判断混合→校准"的选型方法论、那种"把竞争方案统一进可配置框架"的框架思维——会在你面对任何新的规划 / 控制 / 优化问题时反复增值,远超采样 MPC 这一个领域。

累积项目:第九次扩展说明

本章给 UnifiedSamplingPlanner 添加的旋钮(详见 §9.7):

  • 新增旋钮 solver_backend(取值 'sampling' / 'hybrid'):'sampling' 是纯采样内核(前八章一直用的);'hybrid' 在采样内核找到盆地后,追加一段梯度式(iLQR)局部精炼(§9.5 方案一)。
  • 关键前提'hybrid' 要求动力学 / 代价在采样解附近可微(精炼阶段是梯度式);不可微问题(接触 / indicator)只能用 'sampling'(§9.7 陷阱 2)。
  • 与第 8 章旋钮的关系:与"外部鲁棒化层"正交可叠——鲁棒层管执行侧抗扰、求解器后端管优化侧精度,两者作用方向不同、互不干扰。
  • 验证:双势阱任务上,'sampling' 到全局阱 \(x=+2.00\) 代价 \(-0.58\)'hybrid' 精炼到 \(-0.60\)(§9.5、§9.7)。
  • 意义:至此累积项目旋钮谱系完整(weight/noise/schedule/model_source/action_space/cost_source/鲁棒层/solver_backend),是一个"正交维度增量积累"的全功能采样 MPC 沙盘(§9.7 深一层)。

完整旋钮谱系回顾

旋钮 引入章 控制什么
weight / noise / cov 第 4 章 代价项权重、采样幅度与协方差
schedule 第 5 章 退火 / warm-start 日程
model_source / terminal 第 6 章 rollout 用的模型、终端代价(补远见)
action_space 第 7 章 采样空间(力矩 / 关节 / 质心 / 足端)
cost_source 第 8 章 代价来源(解析 / 代价地图 / critic 栈)
外部鲁棒化层 第 8 章 执行侧抗扰(如 L1 自适应)
solver_backend 第 9 章 求解范式(纯采样 / 采样+梯度精炼)

延伸阅读

梯度式 MPC 的经典(§9.2) - Mayne, "A Second-order Gradient Method for Determining Optimal Trajectories of Non-linear Discrete-time Systems"(1966)—— ⭐⭐⭐ DDP 的源头,差分动态规划的奠基。 - Li & Todorov, "Iterative Linear Quadratic Regulator Design for Nonlinear Biological Movement Systems", ICINCO 2004 —— ⭐⭐⭐ iLQR 的提出,想懂 iLQR 读这篇。 - Tassa, Erez & Todorov, "Synthesis and Stabilization of Complex Behaviors through Online Trajectory Optimization", IROS 2012 —— ⭐⭐⭐ iLQG/DDP 在 MuJoCo 上做复杂行为,经典实践。 - Rawlings, Mayne & Diehl, Model Predictive Control: Theory, Computation, and Design(2nd ed., 2017)—— ⭐⭐⭐ MPC 的权威教材,梯度式 MPC 的理论大全。

嵌入式实时 MPC 工具(§9.6) - Verschueren, Frison, Kouzoupis 等, "acados—a Modular Open-source Framework for Fast Embedded Optimal Control", Mathematical Programming Computation 2022 —— ⭐⭐⭐ acados 框架论文,SQP-RTI + HPIPM,工业实时 NMPC 的事实标准之一(用于四旋翼、openpilot 等)。 - Farshidian 等(ETH leggedrobotics),OCS2 工具箱(github.com/leggedrobotics/ocs2)—— ⭐⭐⭐ 开关系统最优控制 C++ 工具箱(SLQ/SQP/IPM),腿足 / 移动操作的常用 MPC 后端。 - Diehl, Bock & Schlöder, "A Real-Time Iteration Scheme for Nonlinear Optimization in Optimal Feedback Control"(2005)—— ⭐⭐⭐ 实时迭代(RTI)的奠基,理解 acados 为何"每步只迭代一次"。

采样式与 CEM 家族(§9.7 基准) - Williams 等, "Information-Theoretic Model Predictive Control: Theory and Applications to Autonomous Driving", IEEE T-RO 2018 —— ⭐⭐⭐ MPPI 的信息论基础(前几章已引)。 - Pinneri, Sawant, Blaes, Achterhold, Stueckler, Rolínek & Martius, "Sample-efficient Cross-Entropy Method for Real-time Planning", CoRL 2020 —— ⭐⭐⭐ iCEM(有色噪声 + 精英 + 记忆,比基线少 2.7–22× 样本),本章基准里的 iCEM 出处(github.com/martius-lab/iCEM)。 - Rubinstein, "The Cross-Entropy Method for Combinatorial and Continuous Optimization"(1999)—— ⭐⭐ CEM 的源头。

混合架构与安全(§9.5) - Yin & Tsiotras(Georgia Tech), "Shield Model Predictive Path Integral: A Computationally Efficient Robust MPC Method Using Control Barrier Functions", IEEE RA-L 2023 —— ⭐⭐⭐ Shield-MPPI,把(离散)CBF 内化进 MPPI rollout,CPU 上少样本鲁棒安全(§9.5 方案二的关键文献,注意作者是 Yin & Tsiotras,非他人)。 - "Biased-MPPI: Informing Sampling-Based Model Predictive Control by Fusing Ancillary Controllers"(2024, RA-L)—— ⭐⭐⭐ 用辅助控制器 / RL 策略偏置采样均值(§9.5 方案三)。 - Ames 等, "Control Barrier Functions: Theory and Applications", ECC 2019 —— ⭐⭐⭐ CBF 的权威综述,理解方案二与后续"安全滤波"方向的基础。 - DIAL-MPC(CMU 2024,力矩空间 MPPI,第 7 章已引)—— ⭐⭐⭐ §9.5 方案四 / §9.6 案例里"直接力矩空间采样"的代表。

前沿方向 - 可微仿真 / 接触平滑、学习采样分布(扩散 / 归一化流)、安全采样 MPC 的近期论文 —— ⭐⭐ 关注这些方向看两家边界如何移动(见"前沿与开放问题")。

优化与数值基础(想更深理解机制时读) - Nocedal & Wright, Numerical Optimization(2nd ed.)—— ⭐⭐⭐ 优化的权威教材,牛顿法 / 线搜索 / 信赖域 / SQP 的理论基础,理解 §9.2 正则化 / 线搜索的根源。 - Boyd & Vandenberghe, Convex Optimization —— ⭐⭐ 凸优化与 QP 的经典,理解 SQP 子问题、CBF-QP 的求解基础。 - Bertsekas, Dynamic Programming and Optimal Control —— ⭐⭐⭐ 动态规划与值函数的权威,理解 §9.2 iLQR 后向递推(Riccati / 值函数)的本质。

软件设计(理解累积项目"旋钮 vs 继承"时读) - "组合优于继承"(composition over inheritance)、策略模式 —— ⭐⭐ 任何一本设计模式 / 软件架构资料,理解 §9.7 累积项目为何用旋钮组织多维配置。

贯穿主题 - 第 4 章(CEM / iCEM)、第 5 章(扩散采样)、第 6 章(学习模型与价值函数)、第 7 章(腿足全身 MPPI / DIAL-MPC)、第 8 章(导航 / 自驾 / 无人机采样 MPC)—— ⭐⭐⭐ 本章是对它们的对比与定位,回看这些章能让本章的"选型"落到具体方法上。

故障排查手册

下面是把本章方法用于实际选型 / 实现时的高频"症状—诊断—处方"。

症状一:用梯度式(iLQR)解一个含障碍 / 碰撞的问题,它"收敛"了但解明显违反障碍(穿墙)。 - 诊断:你的代价里很可能有不可微的 indicator / 阶跃项(障碍、碰撞惩罚),梯度式对它失明(梯度处处为零,§9.4)——它优化的是"障碍不存在"的世界,所以安静地给出穿墙解。 - 处方:① 确认代价里有无 indicator / 二值项(有就是病因);② 改用采样式(它在真代价上求值、看得见障碍);③ 若坚持用梯度式且障碍简单,可尝试 sigmoid 软近似(但注意陡峭度难调 + 优化代理的代价,§9.4 深一层);④ 关键:含不可微项时,绝不能只看梯度式"是否收敛",必须独立检查解是否真满足那些约束(§9.4 易错点)。

症状二:用 iLQR 解一个含接触的动力学(腿足落地 / 抓取),迭代发散或在接触步剧烈震荡。 - 诊断:接触动力学不可微(接触力突变,§9.4 第二类);你若用有限差分造雅可比,接触切换处的差分要么爆炸要么为零,下降方向是垃圾(§9.4 陷阱 2)。 - 处方:① 确认动力学里有无接触 / 碰撞 / 突变;② 含接触的动力学用采样式(第 7 章腿足 MPPI 的全部理由);③ 若必须用梯度式,需要成熟的可微接触仿真 / 接触平滑(活跃研究,别用朴素有限差分凑);④ 检查你的有限差分雅可比是否随步长 \(\epsilon\) 剧烈变化——是的话说明该点不可微,梯度式不适用。

症状三:用 MPPI 解一个光滑可微问题,精度上不去 / 吃满 GPU 还达不到要求。 - 诊断:你在梯度式的主场用了采样式(§9.3 陷阱 1)——采样式不利用光滑结构,精度天花板就是"撒样本能逼近的程度",在光滑问题上本就不如梯度式(demo:MPPI 7.11 vs iLQR 2.22)。 - 处方:① 确认动力学和代价是否都光滑可微;② 是的话,优先换梯度式(iLQR/acados/OCS2),尤其还要高精度 / 硬约束时;③ 若问题非凸(需全局搜索)又光滑,用混合方案一(MPPI 找盆地 + iLQR 精炼,§9.5);④ 若坚持用采样式,知道加样本的边际收益递减、很难追上梯度式精度(§9.3 练习 2)。

症状四:iLQR 在一个非凸问题上"收敛"得很快,但解明显不好(陷在一个坏解里)。 - 诊断:梯度式只收敛到离初值最近的局部最优(§9.2、§9.5)——非凸问题上从坏初值出发,它快速地收敛到一个坏局部最优,"收敛快"骗了你。 - 处方:① 确认问题是否非凸(多局部最优)——换几个初值跑,若收敛到不同解就是非凸;② 非凸用全局方法找盆地:纯采样式,或混合方案一(MPPI 初始化 + iLQR 精炼,§9.5);③ 或多初值重启(multi-start)iLQR 取最好;④ 牢记"iLQR 收敛 ≠ 全局最优",非凸时别只信一次收敛的结果。

症状五:横向基准测出"方法 A 比 B 好",但换个任务 / 上真机后结论反了。 - 诊断:① 基准可能不公平(调参不对等、任务对 A 友好、统计口径不一,§9.7 陷阱 1);② 或基准结论被过度外推——单任务结论不能当普适排名(§9.7 易错点);③ 或基准没覆盖真实部署的约束(实时 / 平台 / 模型误差 / 硬约束,§9.7 陷阱 3)。 - 处方:① 审查基准公平性(同任务 / 同预算 / 对等调参 / 统一口径 / 多种子);② 在多个代表性任务上测,别靠单任务下结论;③ 部署前用真实约束(§9.6 决策树 / 方法论)重新审视;④ 把基准当"受控参考点",不当"普适真理"。

症状六:用 MPPI + CBF 安全滤波(方案二),但 CBF-QP 偶尔无解 / 机器人卡住不动。 - 诊断:CBF-QP 在某些状态下找不到"既满足安全约束、又满足控制约束 \(u\in[u_\min,u_\max]\)"的控制——可能是控制权限不足(要避开危险需要的控制超出了 \(u_\max\))、CBF 参数(class-K 函数 \(\alpha\))太激进、或机器人已逼近危险集边界、安全余量耗尽。 - 处方:① 检查控制权限是否够(避险所需控制是否在 \([u_\min,u_\max]\) 内)——不够则需更大控制权限或更早介入;② 调缓 CBF 的 \(\alpha\)(让它更早、更温和地推开,而非临界才硬刹);③ 给 CBF-QP 加松弛变量(允许轻微违反 + 重罚),避免硬无解导致卡死;④ 牢记 CBF 的硬保证有前提(控制权限、模型准确),前提不满足时会失效(§9.5 陷阱 2)。

症状七:把一个采样式方案改成"求解器后端 hybrid"后,结果反而变差了。 - 诊断:大概率是问题(或在采样解附近)不可微——hybrid 后端的 iLQR 精炼阶段在不可微处发散 / 把好解带坏(§9.7 陷阱 2、§9.5 陷阱 1);或问题其实是凸的 / 只有一个盆地,纯采样已到最优,精炼无收益反添噪。 - 处方:① 确认问题在采样解附近可微(含接触 / indicator 就不可微,别用 hybrid);② 确认问题确实非凸 / 需精炼(若只有一个盆地,纯采样够了,hybrid 多余,§9.5 易错点);③ 不满足这两条就退回 solver_backend='sampling';④ 记住 hybrid 不是"免费增强",它有"可微 + 非凸值得精炼"的双重前提。

概念与 API 速查表

本章是对比 / 方法论章,"API"更多是关键的代码骨架与判断要点。下面分概念速查和代码骨架速查两部分。

关键概念速查

我想…… 看哪家 / 怎么做 出处
判断该用采样还是梯度 先问可微性(动力学 / 代价),再问平台、约束、维度 §9.6 决策树
解一个不可微 / 黑箱问题 采样式(唯一选择) §9.4
解一个光滑可微 + 要精度的问题 梯度式(iLQR/acados/OCS2) §9.3
解一个非凸但光滑的问题 混合方案一(采样找盆地 + 梯度精炼) §9.5
给采样式加硬安全保证 混合方案二(MPPI + CBF)或 Shield-MPPI §9.5
用 RL 策略加速采样 混合方案三(Biased-MPPI,RL 做采样先验) §9.5
在高维力矩空间控制 分层(方案四)或梯度式(靠导数上高维) §9.5/§9.3
在无 GPU 嵌入式上做光滑 MPC 梯度式(acados,CPU 友好 + 硬约束 + RTI) §9.6
公平地对比两个求解器 控制变量 + 多种子 + 看成功率 + 诚实报告 §9.7

关键代码骨架速查

骨架 核心几行 要点
iLQR 一次迭代 后向:Qu=lu+B'Vx; Quu=luu+B'VxxB; k=-Quu⁻¹Qu; K=-Quu⁻¹Qux;前向带线搜索 ∂f(雅可比);Quu 加正则保正定
MPPI 加权 w=exp(-(J-J.min())/λ); w/=w.sum(); U+=Σ w·ε 只需 rollout 求 J;软加权用全部样本
iCEM 重拟合 idx=argsort(J)[:elite]; mean=S[idx].mean; std=max(S[idx].std, floor) 有色噪声 + 精英 + 记忆;更省样本
CBF 安全滤波 min‖u−u_mppi‖² s.t. ḣ(x,u)≥−α(h(x)), u∈[u_min,u_max](小 QP) 解耦性能与安全;依赖模型 / 控制权限前提
求解器后端旋钮 U=_mppi_core(x0); if hybrid: U=_ilqr_refine(x0,U) hybrid 需可微;与鲁棒层正交可叠
\(\sigma\) 退火(采样) σ=σ_hi+(σ_lo−σ_hi)·it/iters 先广探索后精收敛;摆起类非凸问题关键

本章与后续章节的关系

本章在采样 MPC 方向里是"对比与定位"的收束章,它和后续方向(不确定性规划、博弈规划、时空联合规划等)的衔接,主要通过几条线索:

  • 梯度式 MPC + 硬约束(§9.2、§9.3 ⑥):本章只点出"梯度式能原生处理硬约束(QP/NLP)"。在需要严格约束保证的后续方向(如安全关键的规划)里,QP/NLP 求解、约束处理会被系统展开——本章给了你"为什么有时必须用梯度式 / 硬约束"的动机。
  • 控制屏障函数与安全滤波(§9.5 方案二):本章的"MPPI + CBF"是惊鸿一瞥。在"鲁棒规划与安全滤波"主题里,CBF、可达性、安全证书会被完整讲解——本章让你先建立"安全可以和性能解耦、用一个有硬保证的层兜底"的直觉。
  • 混合架构与分层(§9.5):本章的四种混合是所有真实复杂系统的共同骨架。后续方向里的多层规划、规划 + 控制的结合、学习 + 优化的结合,都是这些混合思想的延续——本章给了你"按各部分所长组合"的元思维。
  • 选型方法论与框架思维(§9.6、§9.7):本章最想留下的,是"按问题特性选方法"的尺子和"把竞争方案统一进可配置框架"的框架思维。这两样会在你面对任何新方向、新方法时反复用到——它们是方法论层面的、跨方向的财富。

换句话说,本章既是采样 MPC 方向的"终章"(对全方向的总结定位),又是通往后续方向的"序章"(埋下梯度式、硬约束、CBF、混合、框架思维等会在后续展开的种子)。

研究与实践建议

给做研究的你: - 提出新的采样 MPC 方法时,一定要和**梯度式基线**比(在它们都适用的问题上),别只和采样式基线比——否则你可能在重复发明梯度式早就能做好的东西(§9.3)。 - 警惕"在对自己方法友好的任务 / 设置上做基准"的诱惑——同行和读者会看穿不公平的基准(§9.7)。诚实地多任务、多种子、对等调参、报方差。 - 前沿三个方向(可微仿真、学习采样分布、安全采样 MPC)都在"侵蚀两家边界"——若你想做有影响力的工作,想想"我能不能让某一家侵入另一家的腹地"(如让梯度式处理接触、让采样式上更高维或获得硬约束)。 - 别陷入"采样 vs 梯度"的阵营之争——最有价值的工作往往是统一 / 融合两家(框架思维,§9.7),而非证明某一家"更好"。

给做工程的你: - 拿到新控制问题,先走 §9.6 的四步方法论(刻画 → 决策树 → 混合 → 校准),别凭手熟 / 潮流选——把选择的依据扳到问题特性上。 - 优先看"一票否决"维度(可微性、硬约束刚需)——它们常常先于维度 / 平台决定成败(§9.3 易错点、§9.6 决策树)。 - 真实系统八成要混合(§9.5、§9.6)——别死守纯方案。最常先想到分层(方案四)和全局 + 精炼(方案一)。 - 含不可微项时,绝不能只看梯度式"是否收敛"——独立验证解是否满足那些约束(§9.4 易错点),这是血泪教训。 - 用 CBF / 安全层时,清楚它的前提(模型准确、控制权限、屏障函数正确),别当无条件保险(§9.5 陷阱 2)。

动手前 checklist

把本章方法用于实际选型 / 实现前,逐项确认:

  • 我认真刻画了问题吗?(动力学可微吗 / 代价光滑吗 / 多少维 / 有 GPU 吗 / 有硬约束刚需吗 / 要全局最优吗)——这是后面一切的基础,别偷懒(§9.6 第一步)。
  • 我判断"可微性"时,是看"有没有不连续 / 不可微项"(接触、indicator、\(\max\)、饱和),而非"有没有公式"吗?(§9.6 陷阱 2)
  • 我走决策树时,按"可微性 → 平台 → 约束"的优先级了吗?(§9.6)
  • 我判断了是否需要混合吗?(问题落在"海岸线"吗——非凸但光滑 / 要性能也要安全 / 有 RL 先验 / 高维需分层)(§9.5、§9.6 第三步)
  • 若用混合,我确认了每根混合层的前提吗?(hybrid 后端需可微、CBF 需模型准确)(§9.5 陷阱、§9.7 陷阱 2)
  • 若我的代价含不可微项,我准备好独立验证解是否满足约束了吗(而非只看"收敛")?(§9.4 易错点)
  • 若做基准对比,我控制变量了吗(同任务 / 同预算 / 对等调参 / 统一成功判据 / 多种子)?(§9.7 陷阱 1)
  • 我清楚基准结论的适用范围吗(不外推成普适排名、部署前用真实约束重审)?(§9.7 易错点、陷阱 3)
  • 我是按"任务"而非"机器人 / 领域"选求解器吗?(§9.6 深一层)

版本信息速查

工具 / 方法 关键信息 备注
iLQR Li & Todorov 2004 一阶动力学 + 二阶代价;MPC 里最常用的梯度式
DDP Mayne 1966 iLQR 的二阶版本(额外用 ∂²f);更准但更贵
acados Verschueren/Frison 等, 2022 SQP-RTI + HPIPM;嵌入式实时 NMPC;C/Python 接口
OCS2 ETH leggedrobotics SLQ/SQP/IPM;C++;腿足 / 移动操作 MPC 后端
iCEM Pinneri 等, CoRL 2020 有色噪声 + 精英 + 记忆;martius-lab/iCEM
Shield-MPPI Yin & Tsiotras, RA-L 2023 离散 CBF 内化进 MPPI rollout;CPU 少样本
Biased-MPPI 2024, RA-L 辅助控制器 / RL 策略偏置采样均值
本章 demo 纯 numpy,无需 MuJoCo/JAX 五个 demo(iLQR 摆起 / 光滑基准 / 非光滑 / 双势阱 / CartPole 横向基准)均可独立跑通

说明:iLQR/DDP/SQP 是方法而非单一软件,各框架(acados、OCS2、Crocoddyl、Drake 等)实现细节不同;具体 API 以你所用框架的官方文档为准。本章 demo 为教学用纯 numpy 实现(iLQR 用有限差分雅可比,真实框架用解析 / 自动微分更快),重在演示原理与对比,不追求工业级性能。

跨章综合应用:从零为一个新问题选型并搭建

把本章和前八章的知识串起来,走一个完整的、贴近真实的综合案例——你会看到本章的"选型方法论"如何调动前八章的所有积累。

场景:你要给一架**室内自主无人机**做轨迹控制。需求:在一个用机载深度相机实时建图的、有障碍的室内环境里,从 A 飞到 B;要求**绝不能撞**(硬安全);机载是一块带小 GPU 的嵌入式计算板;环境是未知的(边飞边建图)。

第一步:刻画问题(§9.6 第一步,调动 §9.3 体检表)。 - 动力学:四旋翼动力学解析可微(§9.3 ③ 友好)。 - 代价:避障代价来自**实时建的占据 / ESDF 地图**——这是不可微的(阶梯状 / 感知驱动,§9.4 第一类,第 8 章 §8.1);趋目标代价是光滑的。所以代价是"光滑趋目标 + 不可微避障"的**混合**(§9.4 多视角的"海岸线")。 - 维度:四旋翼控制维度不高(位置 / 姿态,十几维以内,§9.3 ⑧ 采样式可接受)。 - 平台:有小 GPU(§9.3 ④ 采样式可用,但 GPU 小,\(K\) 不能太大)。 - 硬约束:要绝不撞(硬安全刚需,§9.3 ⑥)+ 推力上限(硬约束)。 - 全局性:环境未知、可能有局部最优的绕障,偏好全局搜索能力(§9.3 ⑤)。

第二步:走决策树定主力(§9.6 第二步)。 - 动力学可微吗?是(四旋翼解析)。 - 代价光滑吗?(避障代价来自不可微的占据 / ESDF 地图)→ 决策树在此判:采样式(梯度式会对不可微避障失明,§9.4)。 - 所以**主力求解器:采样式 MPPI**(呼应第 8 章——感知驱动避障正是采样式的主场)。

第三步:判断是否需要混合(§9.6 第三步,调动 §9.5)。 - 这个问题落在"海岸线"——有不可微避障(采样式擅长)、但也有"绝不能撞"的硬安全刚需(采样式弱、§9.3 ⑥)。所以纯采样式不够,需要**叠加硬安全层**。 - → 加 §9.5 方案二(MPPI + CBF 安全滤波):MPPI 在感知代价上出"想要的"避障轨迹(性能),CBF-QP 把控制投影到安全集(硬保证不撞),解耦性能与安全。或用 Shield-MPPI(把 CBF 内化进 rollout,Yin & Tsiotras 2023)——在小 GPU / 少样本下更高效。 - 环境未知、可能要跳出"绕不过去"的局部——可考虑第 8 章 §8.6 的 GP 引导子目标(帮 MPPI 跳出局部),这是另一种增强。

第四步:按维度 / 平台校准(§9.6 第四步)。 - GPU 小 → MPPI 的 \(K\) 不能开太大,可借 §5 章退火、§7 章降维 / warm-start、Shield-MPPI 的"少样本"特性来在小 GPU 上保实时。 - 推力硬约束 → 在 CBF-QP 里一并加上 \(u\in[u_\min,u_\max]\)(§9.5 方案二的 QP 本就含控制约束)。

最终方案:以**采样式 MPPI 为主力**(处理不可微的感知避障代价),叠加 CBF / Shield-MPPI 安全滤波(提供"绝不撞"的硬保证),辅以**退火 / 降维 / warm-start**(在小 GPU 上保实时),可选 GP 子目标(跳出局部)。在累积项目里,这对应:cost_source='costmap'(第 8 章)+ 外部安全层(CBF)+ solver_backend='sampling'(本章,因避障不可微,不能用 hybrid 精炼)+ 退火 schedule(第 5 章)。

复盘这个案例调动了哪些章:§9.6 选型方法论(主框架)、§9.3/§9.4 判断可微性定主力、§9.5 方案二加硬安全、第 8 章感知代价 / GP 子目标、第 5 章退火、第 7 章降维。这就是本书的"知识网络"在一个真实问题上的协同——你看到,选型不是孤立地"选一个算法",而是调动整个知识体系,按问题的每个特性匹配对应的工具,再组装起来。这种"用一张知识网解一个真实问题"的能力,正是学完九章该有的综合素养。

第二个对照案例(落到梯度式的一端):上面的无人机案例落到了"采样式主力"。换一个特性相反的问题,看方法论如何把你导向梯度式——一台四足机器人做周期性平地行走。需求:已知周期步态(trot),平整地面,要满足摩擦锥 / 关节力矩硬约束(绝不能打滑 / 超限),跑在机载 CPU(无 GPU),几十维。走一遍方法论:

  • 第一步刻画:动力学——刚体 + 接触,但**步态周期已知、接触序列预先规划好**,所以在每个接触模式内**近似光滑可微**(§9.6 深一层:行走的接触是结构化、可预测的,区别于跳跃);代价——光滑的跟踪 + 调节项(无 indicator / CNN);维度——几十维(§9.3 ⑧ 偏高,采样吃力);平台——CPU 无 GPU(§9.3 ⑦ 采样受限);硬约束——摩擦锥 + 力矩硬约束刚需(§9.3 ⑥)。
  • 第二步走决策树:动力学可微吗?(在已知接触序列下)近似是 → 代价光滑吗?是 → 有 GPU 吗?(机载 CPU)→ 有硬约束刚需吗?(摩擦锥)→ 决策树判:梯度式 MPC
  • 第三步判断混合:典型采用**分层**(§9.5 方案四的"梯度式版")——OCS2 这类 MPC(SLQ/SQP)在质心 / 全身层做带约束优化,下接全身控制(WBC)跟踪。这里"混合"主要是"MPC + WBC 分层",主力仍是梯度式。
  • 第四步校准:几十维 + CPU + 硬约束,全都指向梯度式(§9.6 案例里 Go2 行走正是 OCS2)——校准后维持梯度式主力。

两案例对照的启示:无人机(不可微感知代价 + 有 GPU)→ 采样式主力 + CBF;四足行走(结构化可微 + CPU + 硬约束)→ 梯度式主力(OCS2)+ WBC 分层。同一套方法论(刻画 → 决策树 → 混合 → 校准),因两个问题的特性不同,导向了完全相反的主力求解器——这正是 §9.6 反复强调的:"方法由问题决定"。把这两个对照案例放一起,你就完整体会了选型方法论的威力:它不偏袒任何一家,只忠实地把你导向"问题特性所要求的"那一家。

跨章综合思考题

这些题需要你把本章和前几章打通来想,没有标准答案,重在融会贯通:

  1. (采样的"全局"在哪些章反复出现) 本章说采样式"偏全局"(§9.3 ⑤、§9.7 摆起)。回看第 4–8 章,采样式的"全局 / 多模态"能力在哪些地方被利用过(提示:第 5 章多模态、第 7 章探索接触模式、第 8 章 GP 跳出局部)?把这些串成"采样式全局能力的应用谱",并说明它和本章"梯度式陷局部"形成的互补。
  2. ("规划-执行分离"与"全局-局部分工"的关系) 第 7、8 章反复出现"规划-执行分离"(MPPI 高层 + WBC/PD 底层),本章 §9.5 方案四也是它。同时本章 §9.5 方案一是"全局-局部分工"(采样找盆地 + 梯度精炼)。这两种"分工"在思想上有何异同(提示:一个按"时间尺度 / 频率"分、一个按"搜索阶段"分;但都是"让各部分干各自擅长的")?
  3. (可微性这条线贯穿全书) "可微 vs 不可微"在本书反复出现:第 6 章学习模型(可微但黑箱)、第 7 章接触(不可微)、第 8 章感知代价(不可微)、本章作为两家的分野根基。请把"可微性"作为一条主线,串起这几章,说明它如何一以贯之地决定了"为什么采样式是这些场景的主角"。
  4. (如果让你给全书设计第十章) 本章是"对比与定位"。如果让你设计采样 MPC 方向的第十章(实战 / 综合),你会让它讲什么、和本章如何衔接(提示:本书后面确实有"Mini-MPPI 实战"——你觉得它该综合哪些章、留下什么"做中学"的任务)?
  5. (把本章的"框架思维"用到全书) §9.7 说"把竞争方案统一进可配置框架"是框架思维。回看累积项目从第 4 章到本章加了 8 根正交旋钮——这本身就是框架思维的产物。请论证:这种"用正交旋钮统一各种能力"的设计,如何让你在面对一个全新的采样 MPC 变体(如某篇新论文)时,能快速判断"它在动哪根旋钮",从而把它纳入你的认知框架而非当成全新的东西。
  6. ("零阶 / 一阶 / 二阶"谱贯穿哪些章) §9.1 把方法按"用几阶导数"排成谱。回看全书:第 4–5 章 CEM / 扩散(零阶)、第 6 章学习模型(可微但黑箱)、本章 iLQR(一/二阶)——请把这条"用几阶信息"的谱作为主线,串起这些方法,说明"用的信息越多 → 越快越挑剔"如何一以贯之地解释它们的强弱。
  7. ("信息稀疏"是比"求值 vs 求导"更深的敌人) §9.4 深一层说稀疏奖励 / 长时序让采样和梯度都失效,根子是"信息稀疏"。请综合第 6 章(价值函数补远见)、第 8 章(GP 子目标、奖励塑形)论证:当两类优化方法都卡住时,为什么解药常在"给问题注入信息"而非"换更好的优化器"?再举一个 RL / 规划里对抗信息稀疏的例子。

可迁移的判断力

抛开 MPPI、iLQR 这些具体方法,本章真正想沉淀进你直觉的,是几条能迁移到远超采样 MPC 的判断力:

第一,"按问题能满足多强的假设来选方法"的尺子。 这是 §9.1 本质洞察的核心,也是本章最普适的财富。任何时候你在几个方法 / 工具间选择,先问"我的问题 / 数据能满足多强的假设?"——能满足强假设(可微、有序、独立、静态……)的,就用能榨取这些假设的专用方法(高效);只能满足弱假设的,就用不挑假设的通用方法(普适但欠效率)。这把尺子在算法选择(排序、搜索、优化)、模型选择(参数 vs 非参数)、乃至工程决策里处处适用。

第二,"先问一票否决维度"的决策优先级。 §9.6 决策树教你先问可微性(一票否决梯度式),再问次要维度。这种"先识别能直接排除某些选项的关键约束、再在剩余选项里精选"的决策顺序,比"一上来就全面比较所有候选"高效得多——它用最少的关键问题最快地缩小范围。这在任何多约束的选型 / 决策里都适用(选数据库、选架构、选技术栈)。

第三,"全局搜索 + 局部精炼"的优化元模式。 §9.5 深一层揭示的这个元模式(广撒网定盆地、靠导数定点),是优化领域的通用智慧。任何"既要跳出局部、又要高精度"的问题,都该想"能不能用一个全局方法定盆地、一个局部方法精炼"。它远超 MPC——神经网络训练、超参搜索、运动规划都是它的实例。

第四,"解耦"作为降复杂度的默认武器。 §9.5 深一层(CBF 解耦性能与安全)和第 8 章(正交分解)反复演示:面对"既要 A 又要 B、A 和 B 互相牵制"的复杂问题,先想"能不能把 A 和 B 解耦成独立模块"——能解耦,复杂度就从"A×B 的纠缠"降为"A+B 的相加"。这是工程里最强大、最该默认尝试的降复杂度武器。

第五,"框架思维高于阵营思维"。 §9.7 本质洞察的核心。面对"几种方法各有拥趸、互相争论"的领域,最高级的处理不是"挑一个站队",而是"设计 / 寻找一个能容纳它们、按需切换的统一框架"。框架思维让你把竞争方案都变成框架里的可调选项,按问题取用——这是真正掌握一个领域、而非停留在派系之争的标志。

第六,"证据质量 > 证据本身"的批判性。 §9.7(公平基准)教你:数字本身不等于真相,产生数字的方法是否公平才决定数字是否可信。面对任何"数据 / 基准支撑的结论",先审视"产生它的方法公不公平、结论适用范围多大"。这种对证据质量的批判性审视,是科学素养的核心。

这六条判断力,会在你的整个职业生涯里反复增值——它们不是关于 MPPI 或 iLQR 的,而是关于**如何选择、如何决策、如何设计、如何批判**的。这正是本章超越具体技术的、最想留给你的东西。

选型反模式速查

把工程师在"采样 vs 梯度"选型上最常踩的坑,集中成一份"反模式(anti-pattern)"清单——它们是前面各节陷阱 / 误区的"行动版",照着自查能避开大多数选错。每条给出"反模式 → 为什么错 → 正确做法"。

反模式一:手熟驱动选型——"我只会 MPPI,所以都用 MPPI"。 - 为什么错:把"我会什么"凌驾于"问题需要什么"(§9.6 反面)。光滑、要精度 / 硬约束、CPU 的问题上,硬上 MPPI 事倍功半(§9.3)。 - 正确做法:按问题特性走决策树(§9.6),需要时学一个新工具——别让自己的舒适区决定技术选择。

反模式二:潮流驱动选型——"现在流行 X(端到端 / RL / MPPI),所以用 X"。 - 为什么错:方法的价值由适合的问题决定,不由流行度决定(§9.1 陷阱 3、误解一)。流行的方法未必适合你的问题。 - 正确做法:忽略潮流,只问"我的问题落在谁的主场"。流行可以让你关注一个方法,但不能替你做选择。

反模式三:可微性误判——"有动力学方程 / 神经网络,所以可微,用梯度式"。 - 为什么错:有公式不等于处处可微(含接触 / indicator / 饱和,§9.6 陷阱 2);NN 可微不等于梯度好用(§9.4 陷阱 1)。 - 正确做法:判断可微性看"有没有不连续 / 不可微项",而非"有没有公式";NN 代价优先求值而非求导。

反模式四:堆资源代替选对方法——"MPPI 精度不够?加 GPU、堆样本"。 - 为什么错:维度灾难和"不利用结构"是原理性短板,算力补不上(§9.3 深一层、§9.3 K-扫描实验:8000 样本仍追不上 iLQR)。 - 正确做法:光滑要精度就用能利用结构的梯度式 / 混合精炼,而非给采样无脑堆资源。

反模式五:混合堆砌——"多加几层混合(精炼 + CBF + RL 先验)总更强"。 - 为什么错:每层都有成本(实现 / 调试 / 延迟),还可能两家打架(§9.5 易错点、"两家打架"深一层)。 - 正确做法:只在"单一方案确实不够、某混合确实补上关键短板"时加对应层,守住"简单是要捍卫的美德"。

反模式六:按机器人 / 领域选型——"四足机器人就用某某求解器"。 - 为什么错:选型粒度应是"任务"而非"机器人"(§9.6 深一层:Go2 行走 vs 跳跃用不同求解器)。 - 正确做法:按具体任务的特性选,同一台机器人的不同任务可能用完全不同的求解器。

反模式七:基准结论过度外推——"基准里 A 赢了,所有情况都用 A"。 - 为什么错:单任务、受控基准的结论不能当普适排名,更不能直接搬到真实部署(§9.7 易错点、陷阱 3)。 - 正确做法:基准当"受控参考点",多任务验证,部署前用真实约束重审。

反模式八:忽视工具链——"理论上梯度式略优,所以从零造一个梯度式求解器"。 - 为什么错:忽视了工程可落地性(成熟工具的可靠性 / 集成 / 维护,§9.6 工具链深一层)。从零造轮子的理论最优,常输给有成熟工具的理论次优。 - 正确做法:把"有没有成熟可靠工具链"和理论最优性一起权衡;理论指方向,工具定落地。

这八条反模式有一个共同的根:让"问题特性以外的东西"(手熟、潮流、误判、资源、堆砌惯性、错误的归类粒度、过度外推、忽视工程现实)主导了选型。避开它们的总原则只有一句——让选型回归问题特性,并把工程可落地性一起算进来。每次选型前,对照这八条自查一遍,能帮你避开绝大多数"选错工具"的陷阱。

收束语

本章是一面镜子——它让一直沉浸在采样 MPC 世界里的你,第一次照见另一家(梯度式),从而看清自己所学的真实位置。

你现在知道了:采样式不是"做 MPC 的唯一方式",也不是"最先进所以最好"的方式,而是"为某一类问题(不可微、黑箱、感知驱动、接触丰富)而生的、与梯度式互补的一支"。你知道了那颗解释一切的种子——求值 vs 求导,以及它背后"更强假设换更高效率"的普适权衡。你知道了两家各自的主场(光滑用梯度、脏用采样)、各自的失效模式(梯度式陷局部 / 失明、采样式欠精 / 高维吃力)、以及最聪明的做法往往是让它们合作(混合架构)。你还获得了一套把"选求解器"从凭感觉变成可复现工程决策的方法论,和一种"把竞争方案统一进可配置框架"的成熟思维。

但本章最想留给你的,不是这些关于两家的具体知识——那些会随技术演进而更新(可微仿真、学习采样、安全采样 MPC 正在移动两家的边界)。本章想沉淀进你直觉的,是那几把更持久的尺子:按问题能满足多强假设选方法、先问一票否决维度、全局搜索 + 局部精炼、解耦降复杂度、框架思维高于阵营思维、证据质量高于证据本身。这些判断力,无论方法怎么变、边界怎么移,都会指引你做出清醒的选择。

回到本章开头那个问题——"MPPI vs 梯度式 MPC,何时选谁?"现在你该明白,这个问题最好的答案不是"选某一个",而是**"看问题"**:看它能满足多强的假设、落在谁的主场、需不需要两家合作。学会了"看问题",你就不再需要别人告诉你"用哪个"——你自己就能判断。而这种"自己能判断"的能力,正是从"会用工具"到"懂得选择"的跃迁,也是这一章、乃至这一段采样 MPC 学习旅程,想带你抵达的地方。

愿你带着这把"看问题"的尺子,走向后续更广阔的规划与控制天地——在那里,会有更多的方法、更多的"两家之争"等你去判断。而你已经知道:答案永远在问题里。