第 13 章 MARL 与传统规控混合架构¶
性质:算法工程教学 | 难度跨度:⭐⭐ ~ ⭐⭐⭐⭐ | 预计精读:18-24 小时
本章性质:✅ 全方向共享——"学习负责适应、模型负责保证"的混合范式,对地面 AGV、足式编队、无人机蜂群、机械臂协作全部通用。它不是又一个新算法,而是一套**把多智能体强化学习(Multi-Agent Reinforcement Learning, MARL)的探索能力和传统规划-控制(规控)的可证明保证拼装在一起的工程方法论**。前 12 章里,你分别学了"纯学习"(MARL,第 10-11 章)和"纯模型"(分布式 MPC、MAPF、CBF,第 3-5 章)这两条腿。这一章告诉你:在真实多机器人系统里,这两条腿几乎从不单独走路——它们被组织成一个分层的混合体,让每条腿只做自己最擅长的事。
一句话定位:本章完整讲透多机器人系统里"MARL + 传统规控"混合架构的**为什么、是什么、怎么搭**——为什么纯 MARL 不敢上真机、为什么纯规控不够灵活、分层混合如何让 RL 在高层做"决策"而 MPC/CBF 在底层做"执行与安全"、安全过滤(safety filtering)如何把"学出来的不安全动作"投影回安全集、残差强化学习(residual RL)如何在一个可信基线上只学"修正量",以及这套范式如何收口整个多机器人方向。
前置自测¶
📋 答不出 ≥ 2 题 → 标 ① 的回第 10-11 章(MARL 全栈),标 ② 的回第 4-5 章(分布式 MPC),标 ③ 的回 CBF 基础,标 ④ 的回第 3 章(MAPF/任务分配),再来读本章。本章会**大量复用**这些前置,但不重新从零教它们——它教的是"如何把它们拼起来"。
-
(接第 10-11 章) 什么是**集中训练分散执行**(Centralized Training with Decentralized Execution, CTDE)?MAPPO 和 HAPPO 的核心区别是什么——为什么后者在异构智能体上更稳?一个训练好的 MARL 策略 \(\pi_\theta(a_i \mid o_i)\) 的输出,在真机上为什么**不能**直接当成电机力矩用? (答不出 → 回第 10 章 §MAPPO、第 11 章 §HAPPO)
-
(接第 4-5 章) 模型预测控制(Model Predictive Control, MPC)的"滚动时域"(receding horizon)是什么意思?为什么 MPC 每个控制周期只执行优化解的**第一步**就丢掉其余、下一周期重新优化?一个 MPC 的硬约束(如关节限位、摩擦锥)和软约束(代价惩罚)在数学形式上有什么本质区别? (答不出 → 回第 4 章 §MPC 基础、第 5 章 §分布式 MPC)
-
(接 CBF 基础) 控制屏障函数(Control Barrier Function, CBF)的核心不等式 \(\dot h(x,u) \ge -\alpha(h(x))\) 在保证什么?为什么满足这个不等式就能让系统**永远停留**在安全集 \(\mathcal{C} = \{x : h(x) \ge 0\}\) 内?相对度(relative degree)是什么——当 \(h\) 不显含 \(u\) 时为什么需要高阶 CBF(HOCBF)? (答不出 → 回 CBF 基础章节)
-
(接第 3 章) 多机路径规划(Multi-Agent Path Finding, MAPF)的顶点冲突和边冲突是什么?为什么 \(N\) 个机器人的联合状态空间搜索会随 \(N\) 指数爆炸?任务分配里"谁去做哪件事"这个离散决策,和"怎么走"这个连续控制,为什么要分成两层来解? (答不出 → 回第 3 章 §任务分配与 MAPF)
-
(综合) 假设你已经有一个能在仿真里完美协调 8 台无人机编队穿越障碍的 MARL 策略,现在要把它部署到真机。你最担心的**三件事**分别是什么?(提示:从"训练分布 vs 真实分布"、"安全保证"、"可解释性/可调试性"三个角度想。)想不清楚没关系——这正是本章 §13.1 要回答的核心动机。
参考答案要点(先自己答,再对照):
-
CTDE:训练时用全局信息(所有 agent 的观测、动作、甚至特权状态)来计算一个集中式 critic,降低非平稳性;执行时每个 agent 只用自己的局部观测 \(o_i\) 跑各自的 actor \(\pi_\theta(a_i \mid o_i)\),不需要中央节点。MAPPO 用**共享**的 actor 和集中 critic;HAPPO(Heterogeneous-Agent PPO)放弃参数共享,按**序贯更新**(sequential update)逐个 agent 改策略,并用一个单调改进的代理目标,所以异构机型(无人机+地面车混编)下不会互相破坏。MARL 输出不能直接当力矩:策略是在仿真动力学下训练的,存在 sim-to-real gap;且策略没有任何安全保证,一个分布外(out-of-distribution, OOD)观测可能让它输出灾难性动作。
-
滚动时域:每个周期在长度为 \(H\) 的预测窗口内求解一个最优控制问题(OCP),得到一串控制 \(u_0^*, \dots, u_{H-1}^*\),但只执行 \(u_0^*\),下个周期用新测量的状态重新求解。这样做是为了**用反馈对抗模型误差和扰动**——开环执行整串解会让误差累积。硬约束写成可行域 \(u \in \mathcal{U}, g(x,u)\le 0\),违反则问题不可行(infeasible);软约束写进代价 \(J = \sum \|x-x_{\text{ref}}\|_Q^2 + \dots\),违反只是代价升高、解仍存在。
-
CBF 不等式保证安全集的**前向不变性**(forward invariance):只要初始在 \(\mathcal{C}\) 内且每一时刻控制满足 \(\dot h \ge -\alpha(h)\),则 \(h(x(t)) \ge 0\) 对所有未来 \(t\) 成立——因为当 \(h\to 0^+\)(逼近边界)时 \(\alpha(h)\to 0\),不等式强制 \(\dot h \ge 0\),把状态"推回"内部。相对度是"\(h\) 对 \(u\) 显含前需要求几阶导";若 \(\dot h\) 不含 \(u\)(相对度 ≥ 2),单纯 CBF 不等式无法约束 \(u\),需要 HOCBF 构造一串嵌套函数把 \(u\) "逼"出来。
-
顶点冲突:两机器人同一时刻占同一格;边冲突:两机器人同一时刻交换相邻格(对穿)。联合搜索爆炸是因为联合状态是各 agent 状态的笛卡尔积,分支因子随 \(N\) 指数增长。分层解(先分配后规划、或先离散后连续)是因为离散决策(组合优化)和连续控制(数值优化)有完全不同的数学结构和时间尺度——混在一起既慢又难收敛。
-
三件事:(1) 分布偏移——真实世界的动力学、传感器噪声、延迟不在训练分布里,策略可能输出训练时从没见过的危险动作;(2) 无安全保证——MARL 的奖励是"软"的,碰撞惩罚再大也只是降低概率,不能保证碰撞概率为零,而真机一次碰撞就是硬件损毁;(3) 不可解释/难调试——黑盒策略出问题时,你无法定位"为什么它在这一帧让 3 号机撞墙",没有可检查的中间量。这三点正是混合架构要逐一化解的。
本章目标¶
学完本章后,你应该能够:
- 论证混合范式的必然性:从"探索-保证两难"(exploration-guarantee dilemma)出发,严格说清为什么纯 MARL 和纯传统规控各自都不够,以及"分层解耦"为什么是化解这个两难的工程主轴——而不是把它当成一句口号。
- 设计分层混合架构:把一个多机器人任务分解到"高层决策(RL,~10 Hz)→ 中层轨迹/MPC(~50 Hz)→ 底层 WBC/PD(~200-1000 Hz)→ 安全过滤层(CBF,叠加在中层之上)"四个层次,说清每层的输入输出、时间尺度、为什么放在这一层。
- 实现 RL 高层 + MPC/CBF 底层的接口:讲清 RL 策略输出(编队偏移、质心目标速度、子目标)如何变成 MPC 的参考/代价,以及为什么这个接口的"语义对齐"是整个系统能不能工作的关键,并能写出最小可运行的接口代码。
- 推导并实现安全过滤器:从 CBF-QP 出发,推导"最小修正安全过滤"\(u_{\text{safe}} = \arg\min \|u-u_{\text{nom}}\|^2 \ \text{s.t.}\ \dot h \ge -\alpha h\) 的 KKT 解,理解 GCBF+ 用 GNN 参数化 CBF 如何把安全保证扩展到上千 agent,并能用 OSQP 为多 integrator 实现 pairwise 碰撞避免过滤器。
- 掌握残差强化学习:讲清 residual RL 的核心公式 \(u = u_{\text{base}}(x) + u_{\text{res}}^{\theta}(x)\) 为什么比"从零学"样本效率高一个数量级、为什么继承了基线控制器的安全性下界,并能在一个 MPC/PD 基线上叠加一个残差策略。
- 公式化 Safe MARL:把混合系统的安全需求写成约束马尔可夫博弈(Constrained Markov Game, CMG),用 Lagrangian 松弛 + HAPPO 求解,理解"奖励最大化 s.t. 期望代价 ≤ 阈值"与"逐状态硬安全保证"两种安全语义的根本差异。
- 做出有依据的范式选型:面对一个真实多机器人问题,能沿"是否需要硬安全保证 × 是否有可靠模型 × 任务组合复杂度 × 是否上真机"四维,判断该用纯 MARL、纯规控、还是某种具体的混合形态,并把全章方法收进一张选型总表。
本章知识导航¶
一句话定位:本章把"多机协调"的两条技术路线——第 10-11 章的**学习路线**(MARL)和第 3-5 章的**模型路线**(MPC/CBF/MAPF)——焊接**成一个分层混合系统。核心主张只有一句话:**让 RL 在它最强的地方(高层、长程、难建模的协调决策)探索,让传统规控在它最强的地方(底层、实时、有模型的执行与安全)保证,两者通过一个语义清晰的接口解耦。
本章六条主线及其递进关系:
| 主线 | 解决的问题 | 关键工具 | 对应小节 |
|---|---|---|---|
| 为什么混合 | 纯 MARL 和纯规控各差在哪?混合凭什么更好? | 探索-保证两难、三种 sim-to-real gap、解耦原理 | §13.1 |
| 分层混合架构 | 一个任务怎么切成几层?每层放什么? | 四层架构、时间尺度分离、语义接口 | §13.2 |
| RL 高层 + MPC 底层 | RL 的输出怎么喂给 MPC?接口怎么对齐? | 命令空间设计、参考生成、warm-start | §13.3 |
| 安全过滤层 | 怎么保证学出来的动作永不违反硬约束? | CBF-QP、安全过滤、GCBF+、相对度 | §13.4 |
| 残差强化学习 | 不分层,能不能让 RL 只学"修正"? | residual RL、基线控制器、安全下界继承 | §13.5 |
| Safe MARL 与对比收口 | 安全怎么写进 MARL 目标?三范式怎么选? | 约束马尔可夫博弈、Lagrangian、选型框架 | §13.6 |
推荐阅读路径:§13.1 是**思想地基**(为什么要混合,必读,决定你是否真懂这一章在干什么)→ §13.2 给出**架构骨架**(四层分工,必读,后面所有内容都挂在这张图上)→ §13.3 是 RL 与 MPC 的**接合点**(接口设计,做分层混合必读、需动手)→ §13.4 是**安全的硬核**(CBF 过滤 + GCBF+,⭐⭐⭐⭐,做安全关键系统必读且需跟着搭一遍)→ §13.5 是**另一条混合路线**(residual RL,与分层互补,做精细操作/腿足必读)→ §13.6 把安全写进 MARL 目标并**收口选型**(建议最后通读、当索引常查)。§13.4 与 §13.5 是两个 ⭐⭐⭐⭐ 的硬核小节,值得花最多时间。
前置知识桥接¶
本章紧接第 3-5 章(模型路线)与第 10-11 章(学习路线),这里把最关键的前置点重新激活——你不必翻回去就能跟上:
- 回顾第 10-11 章:MARL 输出的是"软"决策。第 10 章我们用 MAPPO 训练共享策略、集中 critic 降低非平稳性;第 11 章用 HAPPO 处理异构智能体的序贯单调更新。关键要记住的是:MARL 学到的 \(\pi_\theta(a_i\mid o_i)\) 是一个**概率策略**,它通过奖励塑形(reward shaping)把"碰撞"惩罚成低概率事件,但**永远无法把碰撞概率压到零**——奖励是软的。本章正是要给这个"软决策"套上一层"硬保证"的外壳。
- 回顾第 4-5 章:MPC 是带模型的实时优化器。第 4 章我们把单体控制写成滚动时域 OCP,第 5 章用 ADMM/对偶分解把它分布式化。要记住的是:MPC 的力量来自**它知道动力学模型**——它能在预测窗口内"看到未来 \(H\) 步",并在硬约束(摩擦锥、关节限位)下求出物理上可行的控制。本章让 MARL 不再直接碰这些底层约束,而是把它们留给 MPC。
- 回顾 CBF 基础:安全 = 集合的前向不变性。CBF 把"安全"形式化为"状态永远留在 \(\mathcal{C}=\{h(x)\ge 0\}\) 内",并给出一个**逐时刻**的控制约束 \(\dot h \ge -\alpha(h)\) 来保证它。这是一个比"MPC 软约束"和"MARL 奖励惩罚"都更强的保证——它是**逐状态、可证明**的。本章 §13.4 的安全过滤层就建立在它之上。
- 回顾第 3 章:分层是对抗组合爆炸的标准手段。第 3 章我们已经把"谁去做"(任务分配)和"怎么走"(MAPF)分成两层,正是因为离散决策和连续控制混在一起会爆炸。本章把同样的"分层解耦"思想推广到"学习 vs 模型"这个新的切分维度上。
前向预告:本章的混合架构是整个多机器人方向的**收口**——它把前面所有章节(通信图、共识、任务分配、MAPF、编队、分布式 MPC、MARL、CBF)的成果组织成一个可部署的系统。读完本章,你应该能回答一个总览性问题:"给我一个真实的多机器人任务,我该用前面学的哪些模块、怎么拼?" §13.6 的选型框架会正面回答它。第 14 章(综合实战)则会把这套混合架构真正落到一个完整项目上。
如果跳过本章会怎样¶
跳过本章,你会卡在两个具体的地方。
场景一("仿真里完美,一上真机就撞")。你用第 10-11 章的 MARL 训出了一个能在仿真里漂亮协调 6 台无人机编队的策略,回放视频堪称完美。你满怀信心部署到真机——结果第一次飞行,2 号机在一个训练时从没出现过的风扰下输出了一个剧烈动作,直接撞向 3 号机。你不知道问题出在哪:是 sim-to-real gap?是 OOD 观测?还是策略本身就不安全?更要命的是,你**没有任何机制能阻止**这次碰撞——奖励里的碰撞惩罚只在训练时起作用,部署时策略输出什么就执行什么。本章 §13.1 会告诉你为什么"纯 MARL 上真机"是一个范式层面的错误,§13.4 会告诉你怎么用一个 CBF 安全过滤层从根本上杜绝这类碰撞——无论上层策略多离谱,过滤层都能保证物理安全。
场景二("纯 MPC 写不出协调策略,调参调到崩溃")。你反过来想:既然 MPC 有安全保证,那我全用 MPC 不就行了?于是你试图给 8 台异构机器人(无人机 + 地面车)写一个集中式分布式 MPC,让它们协同搬运一个大物体并避开动态障碍。你很快发现:协调策略(谁让谁、编队怎么变形、遇到狭窄通道谁先过)这种**高层、组合性、难以解析建模**的决策,根本写不进 MPC 的代价函数——你试图用一堆手工调的权重和启发式规则去逼近它,结果权重之间互相打架,调一个崩一个,永远调不出"既高效又鲁棒"的协调行为。本章 §13.1 会告诉你为什么这类"难建模的协调决策"恰恰是 MARL 的主场,§13.3 会告诉你怎么让 MARL 输出高层命令、MPC 只负责执行,从而把"该学的"和"该算的"各归其位。
预计阅读时间¶
| 模式 | 时长 | 适合 |
|---|---|---|
| 精读(跟着推完 CBF-QP 的 KKT 解、搭一遍分层接口、实现 pairwise CBF 过滤 + residual RL 基线叠加、推完 CMG 的 Lagrangian) | 18-24 小时 | 第一次系统学混合范式的工程师,建议分 5-6 次 |
| 速读(读懂四层架构、三种混合形态的适用边界、关键公式,跳过推导与代码细节) | 5-7 小时 | 已有 MARL + MPC 背景,建立全局图景 |
| 速查(架构图 + 安全过滤 KKT 解 + residual RL 公式 + 三范式对比表 + 选型决策框架 + 故障排查) | 50-70 分钟 | 设计混合系统时回查 |
科研发展脉络¶
在钻进具体方法前,先把这条研究线的来龙去脉理清。混合范式不是某一篇论文的发明,而是两条独立发展的技术路线(学习 vs 模型)在"都撞到自己的天花板"之后,被迫走向融合的结果。理解这条脉络,比孤立地记某个框架的名字有用得多。
| 年份 | 工作 | Venue / 来源 | 核心贡献 |
|---|---|---|---|
| 2017 | Johannink 等, "Residual Reinforcement Learning for Robot Control" | ICRA 2018 (arXiv 2017) | residual RL 奠基:\(u=u_{\text{base}}+u_{\text{res}}\),在传统控制器上只学修正量,样本效率与安全性双赢 |
| 2018 | Silver 等 / OpenAI 等多组 | 多篇 | **分层 RL + 控制**雏形:高层 RL 出子目标,底层用既有控制器执行 |
| 2019 | Ames 等, "Control Barrier Functions: Theory and Applications" | ECC 2019 (综述) | CBF 安全过滤范式定型:把安全写成 QP 约束,min-norm 修正 |
| 2021 | Brunke, Greeff 等, "Safe Learning in Robotics: From Learning-Based Control to Safe RL" | Annual Review of Control (arXiv 2108.06266) | 权威综述:系统梳理安全 RL 的三条路线(安全过滤 / 约束优化 / 可达性),混合范式的理论地图 |
| 2021 | Cheng 等 / 多组, "Safe MARL through Decentralized Multiple CBF" | arXiv 2103.12553 | MADDPG-CBF:多智能体 + 分散多 CBF,安全 MARL 的早期范式 |
| 2022 | ETH / 多组, "Sim-to-Lab-to-Real: Safe RL with Shielding" | AIJ 2022 | shielding + 泛化保证:训练-实验室-真机三段式安全过渡 |
| 2023 | Bjelonic 等, "Combining MPC and Predictive RL for Quadruped Locomotion" | arXiv 2307.07752 | MPC × predictive RL:RL 学 Q 函数当 MPC 尾代价,缓解长 horizon 计算爆炸 |
| 2024 | Zhang, Fan 等, "GCBF+: Neural Graph CBF for Distributed Safe Multi-Agent Control" | T-RO 2024 (arXiv 2401.14554) | GCBF+:GNN 参数化 CBF→256-1024 agent 安全保证,接受 LiDAR 点云,比手工 CBF 好 20% |
| 2024 | Mandi, Jain, Song, "RoCo: Dialectic Multi-Robot Collaboration with LLM" | ICRA 2024 | RoCo:LLM 做任务分解与协商→MPC 底层控制,混合范式向"语言高层"延伸 |
| 2025 | Zhang, Fan 等, "Discrete GCBF + PPO" | ICLR 2025 | CBF + PPO 端到端:把安全 CBF 与 RL 策略联合训练 |
| 2025 | Jose, Zhang, "Dual-Quadruped Safe RL" | arXiv 2025 | HAPPO + 约束马尔可夫博弈 + 代价分解:双四足协同搬运的 Safe MARL |
| 2025 | 多组, "Residual MPC / RL-Augmented MPC" | arXiv 2510.12717 / 2603.10878 | 残差与 MPC 深度融合:GPU 并行 MPC 基线 + RL 残差,非周期步态/混合运动 |
| 2025 | 多组, "CBF-RL: Safety Filtering RL in Training" | arXiv 2510.14959 | 训练期安全过滤:把 CBF 过滤放进训练循环,策略逐渐"内化"安全 |
| 2025 | 多组, "SHIELD: Safety on Humanoids via CBFs in Expectation" | arXiv 2505.11494 | 学习动力学上的期望 CBF:把硬 CBF 推广到学习模型 + 随机系统 |
关键脉络梳理:这条线有三股力量在汇流。
- 从"安全过滤"一侧:Ames 的 CBF(2019)把安全做成一个可以**叠加在任何控制器之上**的 QP 模块 → GCBF+(2024)用 GNN 把它扩展到上千 agent → CBF-RL / SHIELD(2025)把它从"部署期外挂"推进到"训练期内化"。主线是**安全保证的可扩展性和与学习的融合度不断提升**。
- 从"残差学习"一侧:Johannink 的 residual RL(2017)确立"在可信基线上只学修正"→ Residual MPC(2025)把基线从简单 PD 升级为 GPU 并行 MPC。主线是**基线越来越强,RL 只补"模型补不了的那一点"**。
- 从"分层混合"一侧:高层 RL + 底层控制的雏形(2018)→ MPC × predictive RL(2023,RL 出尾代价)→ RoCo(2024,LLM 出高层决策)。主线是**高层决策器越来越"聪明"(从策略网络到 LLM),底层执行器越来越"可靠"(精确 MPC)**。
看这三股力量,有一条清晰的共识:没有人再相信"纯学习"或"纯模型"能单独解决真实多机器人问题。分歧只在于"在哪个层次、用什么方式把两者缝合"。本章就是把这三股力量整理成一套可操作的工程框架。
本质洞察:混合范式的兴起不是因为某个算法的突破,而是因为两个社区(强化学习 vs 控制论)各自撞到了自己范式的天花板——RL 撞到"无法保证安全"的墙,控制论撞到"无法建模复杂协调"的墙。混合架构的本质,是**承认没有任何单一范式是万能的,转而设计一个让每种范式只在自己有比较优势的地方工作的系统**。这是工程成熟度的标志,而非理论的妥协。
本章符号约定¶
| 符号 | 含义 | 首见 |
|---|---|---|
| \(N\) | 智能体(机器人)数量 | §13.1 |
| \(o_i, a_i\) | 第 \(i\) 个 agent 的局部观测 / 动作 | §13.1 |
| \(\pi_\theta(a_i\mid o_i)\) | 参数为 \(\theta\) 的 MARL 策略 | §13.1 |
| \(u_{\text{cmd}}\) | RL 高层输出的命令(目标速度/编队偏移/子目标) | §13.2 |
| \(u_{\text{nom}}\) | 名义控制(来自 MARL 或 MPC,未经安全过滤) | §13.4 |
| \(u_{\text{safe}}\) | 安全过滤后的控制 | §13.4 |
| \(u_{\text{base}}\) | 基线控制器输出(residual RL 中) | §13.5 |
| \(u_{\text{res}}^\theta\) | 残差策略输出 | §13.5 |
| \(h(x)\) | 控制屏障函数(CBF),\(h\ge 0 \Leftrightarrow\) 安全 | §13.4 |
| \(\mathcal{C}\) | 安全集 \(\{x : h(x)\ge 0\}\) | §13.4 |
| \(\alpha(\cdot)\) | 扩展 \(\mathcal{K}\) 类函数(CBF 的"放松率") | §13.4 |
| \(f(x), g(x)\) | 控制仿射系统 \(\dot x = f(x)+g(x)u\) 的漂移项/输入项 | §13.4 |
| \(H\) | MPC 预测时域(步数) | §13.2 |
| \(h_\theta\) | GNN 参数化的 CBF(GCBF+) | §13.4 |
| \(c_{i,t}\) | 第 \(i\) agent 在 \(t\) 时刻的安全代价(碰撞/翻转/限位) | §13.6 |
| \(\delta\) | 累积代价的安全阈值(CMG 约束右端) | §13.6 |
| \(\mu\) | Lagrangian 乘子(约束 RL 的对偶变量) | §13.6 |
| \(\gamma\) | 折扣因子 | §13.6 |
| \(\rho\) | 残差幅值上限(residual RL 的安全额度) | §13.5 |
| \(L_f h, L_g h\) | \(h\) 沿漂移项/输入项的李导数 | §13.4 |
| \(\psi_0,\psi_1,\dots\) | HOCBF 的嵌套函数链 | §13.4 |
§13.1 为什么要混合:探索-保证两难 ⭐⭐⭐¶
这一节解决什么问题:在写任何代码、画任何架构图之前,必须先回答一个根本问题——我们为什么不能只用一种范式? 这一节把"纯 MARL"和"纯传统规控"各自的能力边界讲透,揭示它们之间存在一个无法在单一范式内调和的"探索-保证两难",并论证"分层解耦"为什么是化解这个两难的工程主轴。这一节是整章的思想地基:不真正理解这里的动机,后面的架构和代码都只是机械模仿。
动机:一个无法两全的真实困境¶
设想一个具体任务:8 台异构机器人(4 架无人机 + 4 台地面车)要在一个有动态障碍的仓库里协同把一批货物从 A 区搬到 B 区。这个任务里同时存在两类截然不同的子问题。
第一类是"高层协调决策":哪台车配合哪架无人机?遇到一个只能容一台车通过的狭窄通道,谁先谁后?某架无人机电量低了,编队怎么动态重组把它的任务分给别人?这些决策有三个特征——长程(一个决策的好坏要很多步之后才看得出)、组合性强(选择空间随机器人数和任务数组合爆炸)、难以解析建模("什么样的让行顺序最好"没有干净的数学表达式,依赖大量难以枚举的情境)。
第二类是"底层执行控制":每台机器人怎么精确跟踪自己的目标轨迹?怎么在摩擦锥、关节限位、电机力矩上限内算出可行的控制?怎么保证两台机器人在物理上**绝不相撞**?这些问题有完全相反的特征——短程(控制是逐周期的反馈)、连续(在实数控制空间里优化)、有精确模型(机器人动力学、碰撞几何都可以写出方程)。
现在问题来了:你能用同一种方法把这两类子问题都解好吗? 答案是不能——这正是混合范式存在的根本原因。让我们看看两种"纯"方案各自怎么失败。
如果用纯 MARL 会怎样¶
纯 MARL 的思路是:把整个任务(从高层协调到底层力矩)都交给一个端到端的多智能体策略 \(\pi_\theta\),输入每台机器人的局部观测,直接输出电机力矩,用一个精心设计的奖励函数(搬运成功 + 不碰撞 + 省电)训练它。这条路在仿真里常常能跑出惊艳的结果,但一旦面对真机,会在三个地方系统性地失败。
失败点一:没有任何硬安全保证。 这是最致命的。MARL 的安全是通过**奖励塑形**实现的——你在奖励里加一个"碰撞 = -1000"的惩罚项。但奖励是"软"的:它让策略**倾向于**避免碰撞,把碰撞变成低概率事件,却**永远无法把碰撞概率压到零**。在仿真里 99.9% 不碰撞听起来很好,但真机上 0.1% 的碰撞概率意味着平均每 1000 次操作就损毁一次硬件——这在工业部署里完全不可接受。
本质洞察:MARL 的奖励惩罚和 CBF 的安全约束之间,存在一个范式层面的鸿沟。奖励惩罚是**期望意义**的优化目标("平均而言少碰撞"),CBF 约束是**逐状态**的硬保证("这一帧绝不越界")。你无法通过把碰撞惩罚调到无穷大来把前者变成后者——惩罚再大,只要它是奖励的一部分,策略就有可能为了某个更大的奖励而"赌一把"。安全不能是优化目标的一项,它必须是优化的**约束**。
失败点二:分布偏移(distribution shift)下的灾难性失效。 MARL 策略是在仿真动力学下训练的。真实世界存在三类系统性的分布偏移(我们在下面"理论"部分会做穷举式分类),任何一类都可能把策略推到一个它在训练时从未见过的观测——即分布外(out-of-distribution, OOD)状态。黑盒神经网络策略在 OOD 输入上的行为是**完全不可预测**的:它可能输出一个剧烈的、危险的动作。而且更糟的是,多智能体系统里一个 agent 的异常动作会通过交互**传染**给其他 agent,引发连锁失效。
失败点三:不可解释、难以调试、无法认证。 当真机上出问题时(比如 2 号机莫名其妙撞墙),你面对的是一个有几百万参数的黑盒。你无法回答"它为什么在这一帧做这个动作",因为没有任何可检查的中间量——没有"它认为的目标轨迹"、没有"它估计的障碍位置"。这让调试变成玄学。在安全关键(safety-critical)领域,这还意味着**无法通过认证**——你没法向监管机构证明这个系统是安全的,因为你自己都说不清它的行为边界。
如果用纯传统规控会怎样¶
那反过来,全用传统规控(MPC + CBF + MAPF + 手工协调规则)行不行?传统规控恰好补上了 MARL 缺的三块——它有硬安全保证(CBF/MPC 硬约束)、它在模型准确时行为可预测、它的每个中间量都可解释。但它在另一个地方系统性失败:它无法处理"难以解析建模"的高层协调决策。
失败点一:高层协调写不进代价函数。 传统规控的核心是"把问题写成一个优化问题然后求解"。但"8 台异构机器人遇到狭窄通道时的最优让行策略"这种决策,没有干净的数学表达式。你只能用两种笨办法逼近它:要么写一大堆 if-else 启发式规则("如果通道宽度 < X 且车 A 比车 B 近,则 A 先过……"),要么往 MPC 代价函数里堆一堆手工调的权重项。前者在情境一复杂就漏洞百出(你永远枚举不完所有情况),后者会陷入"权重打架"——你调高"编队保持"的权重,"避障灵活性"就崩了,反之亦然,永远调不出一个全局协调的好行为。
本质洞察:传统规控的力量来自"把问题写成优化问题",但这也正是它的天花板——有些决策本质上无法被简洁地写成优化问题。最优让行顺序、最优编队重组、最优任务再分配,这些决策的"最优"依赖于海量难以枚举的情境,它们的价值函数是高度非线性、非凸、甚至不连续的。强行用手工代价去逼近,本质上是在用人脑做策略网络该做的事——而人脑做不好这件事。这恰恰是"学习"的主场:RL 能从经验中**自动发现**这个复杂价值函数的形状。
失败点二:组合爆炸。 我们在第 3 章已经见过:\(N\) 个机器人的联合规划(谁去做什么、谁走哪条路)随 \(N\) 指数爆炸。MAPF 的最优求解是 NP-难的。传统方法靠各种近似(优先级规划、CBS 的次优变体)来扩展,但这些近似要么牺牲最优性、要么牺牲完备性。而且关键是:最好的近似策略本身也是难以手工设计的——什么样的优先级排序最好?这又回到了"难以解析建模"的问题。
失败点三:对未建模动态束手无策。 MPC 的力量来自模型,但这也是它的软肋——模型之外的东西它一概看不见。地面接触的复杂摩擦、柔性物体的形变、空气动力学的细微扰动、其他机器人的真实(而非假设的)行为……这些"残差动力学"无法精确建模,纯 MPC 只能把它们当噪声忽略,导致跟踪精度下降。这恰恰又是学习的主场——RL 能从数据中**学到模型没有的那部分**。
历史:两条路线如何被迫走向融合¶
这两条路线的融合不是某个人的灵光一现,而是两个社区在各自撞墙后的必然汇流。
控制论一侧:从经典控制(PID)到现代控制(LQR/MPC)再到鲁棒/自适应控制,控制论几十年来一直在"如何在有模型的前提下做出有保证的控制"上深耕。它的方法论极其成熟可靠,但有一个根本前提——你得有模型。当机器人任务变得越来越复杂(高维、接触丰富、多体协调),"写出准确模型"本身变成了不可能完成的任务,控制论撞上了"建模天花板"。CBF(Ames 等,2014-2019)是这一侧的关键进展:它把"安全"做成一个可以**模块化叠加**在任何控制器之上的 QP 约束——这个"可叠加"的性质,恰恰为后来"叠加在 RL 之上"埋下了伏笔。
强化学习一侧:从 DQN(2013)到 AlphaGo(2016)再到各类机器人 RL,强化学习证明了它能从经验中学到**人类无法手工设计**的复杂策略。但它有一个根本软肋——它没有任何安全和可解释保证,且样本效率低(需要海量试错)。当人们试图把 RL 用到真机(尤其多机器人)时,立刻撞上"安全天花板":你不能让机器人在真实世界里靠"试错"来学习避免碰撞——一次碰撞就是硬件损毁。
两个社区在 2017-2019 年前后几乎同时意识到:对方手里正好有自己缺的东西。RL 缺的"安全保证",控制论有(CBF/MPC);控制论缺的"复杂决策学习能力",RL 有。于是三条融合路线几乎同时出现——residual RL(在控制基线上学修正,2017)、safe RL via shielding(用控制安全过滤器保护 RL,2018-2019)、hierarchical RL+control(RL 出高层、控制管底层,2018)。本章后续小节就是这三条路线的展开。
理论:解耦原理与三种 sim-to-real gap¶
现在我们把上面的"故事"提炼成可操作的理论。混合范式的核心理论支柱只有一条——解耦原理(decoupling principle):把一个复杂系统沿着"特征维度"切分成若干层,让每一层只处理它有比较优势的子问题,层与层之间通过一个**窄而清晰的接口**通信。
混合架构沿哪个维度解耦?关键是识别出"学习"和"模型"各自的比较优势维度,它们恰好在多个维度上互补:
| 维度 | 适合学习(MARL)的一端 | 适合模型(规控)的一端 |
|---|---|---|
| 时间尺度 | 慢(10 Hz,决策不需要高频) | 快(50-1000 Hz,控制需要实时反馈) |
| 抽象层次 | 高层(编队、让行、任务分配) | 底层(力矩、轨迹跟踪) |
| 建模难度 | 难建模(协调价值函数无解析式) | 易建模(动力学/碰撞有方程) |
| 决策类型 | 探索性(需要从经验发现策略) | 保证性(需要可证明的安全/稳定) |
| 空间结构 | 组合/离散(谁配合谁、谁先过) | 连续(实数控制空间优化) |
解耦的工程含义:把"难建模、高层、慢、探索性、组合"的部分交给 MARL,把"易建模、底层、快、保证性、连续"的部分交给规控。两者通过一个**语义清晰的命令接口**(如"目标质心速度"、"编队偏移"、"子目标位置")通信。这个接口必须满足:MARL 输出的命令,无论多离谱,底层规控都能**安全地**尝试执行(哪怕执行不到,也不会违反硬约束)。这个"安全可执行"的性质,正是 §13.4 安全过滤层要保证的。
本质洞察:解耦原理的深层价值在于**它把"sim-to-real gap"局部化了**。在纯 MARL 里,sim-to-real gap 弥漫在从感知到力矩的整条链路上,无处不在、无法隔离。而在分层混合里,MARL 只负责高层决策(10 Hz 的编队/让行命令),底层执行用的是基于真实模型的 MPC。于是 sim-to-real gap 被压缩到"高层决策"这一个窄接口上——而高层决策对底层动力学细节天然不敏感("让 2 号机靠左一点"这个决策,在仿真和真机里含义几乎一样)。这就是为什么混合架构的 sim-to-real 迁移比纯 MARL 容易得多:你只需要让一个低维、抽象、对动力学不敏感的决策迁移,而不是让整条感知-控制链路迁移。
为了让"分布偏移"这个抽象概念变得可操作,我们对 sim-to-real gap 做**穷举式的维度分类**(这是认知工具 E 系统性分类的应用,目的是给你一个"思考框架"而非"记忆清单"):
| 维度 | 具体来源 | 对纯 MARL 的威胁 | 混合架构如何缓解 |
|---|---|---|---|
| 动力学 gap | 质量/惯量/摩擦系数估计误差、接触模型简化 | 策略在错误动力学下学的动作在真机上失效 | 底层 MPC 用真实标定模型,gap 不影响高层决策 |
| 感知 gap | 传感器噪声、延迟、视野遮挡、点云稀疏 | OOD 观测让策略输出危险动作 | 高层决策对感知细节不敏感;安全过滤用实时局部感知 |
| 执行 gap | 电机延迟、量化误差、力矩饱和 | 策略假设的理想执行在真机上打折 | 底层 WBC/PD 在真实执行约束内求解 |
| 多体交互 gap | 其他 agent 的真实行为 ≠ 训练时的假设行为 | 一个 agent 异常通过交互传染全队 | CBF 过滤保证 pairwise 安全,切断传染链 |
理解这张表的关键是:纯 MARL 必须独自承受全部四类 gap,而混合架构把每一类 gap 都甩给了最适合处理它的层。动力学 gap 甩给 MPC(用真实模型),感知 gap 甩给安全过滤(用实时局部感知),执行 gap 甩给 WBC(在真实约束内求解),多体交互 gap 甩给 CBF(保证 pairwise 安全)。MARL 只需要处理它最擅长的"高层协调决策",而这一层对所有四类 gap 都相对鲁棒。
三种混合形态的预览¶
基于解耦原理,混合范式在工程上结晶出三种主要形态。这里先给一个全景预览,后续小节逐一展开——你现在只需要记住"有这三种,它们解耦的方式不同":
| 形态 | 核心思想 | 解耦方式 | 本章小节 | 典型代表 |
|---|---|---|---|---|
| 分层混合(hierarchical) | RL 出高层命令,规控管底层执行 | 按抽象层次纵向切分 | §13.2-13.3 | RL+MPC 四足、RoCo |
| 安全过滤(safety filtering / shielding) | RL 出名义动作,CBF 过滤成安全动作 | 按"决策 vs 安全"切分 | §13.4 | GCBF+、CBF-RL、SHIELD |
| 残差学习(residual) | 控制器出基线,RL 只学修正量 | 按"基础 vs 残差"叠加 | §13.5 | residual RL、Residual MPC |
这三种形态不是互斥的——一个成熟系统往往**同时用上多种**(比如:分层混合的高层是 RL、底层是 MPC,同时在 MPC 输出上叠一个 CBF 安全过滤,甚至 MPC 本身还带一个 residual RL 修正)。§13.6 会教你如何根据任务特征组合它们。
本质洞察:"分层、过滤、残差"这三种形态,本质上是同一个解耦原理沿三个不同维度的切分:分层沿**抽象层次**(上/下)切,过滤沿**职能**(决策/安全)切,残差沿**贡献**(基础/修正)切。它们都在回答同一个问题——"让 RL 做什么、让模型做什么、两者怎么对接"——只是切分的刀法不同。理解了这一点,你就不会把它们当成三个孤立的技巧,而会看到它们背后统一的设计哲学。
⚠️ 常见陷阱¶
陷阱 1(概念误区):以为"把碰撞惩罚调大"就能让 MARL 安全 - 错误做法:在 MARL 奖励里把碰撞惩罚设成 -10000 甚至 -1e9,认为这样策略就"绝对不会"碰撞。 - 现象/后果:训练时碰撞率确实下降,但永远不为零;部署时仍会偶发碰撞,且惩罚过大还会导致策略过度保守(为躲一个远处的障碍而完全不动)或训练不稳定(梯度爆炸)。 - 根本原因:奖励是**期望意义**的软目标,碰撞是它优化的一个**项**而非**约束**。无论惩罚多大,策略都可能为了某个更大的累积奖励而接受一个小概率碰撞——这是优化的数学本质决定的,不是调参能解决的。 - 正确做法:把安全从"奖励项"提升为"硬约束"——要么用 CBF 安全过滤层(§13.4)在动作执行前强制投影到安全集,要么用约束马尔可夫博弈(§13.6)把安全写成显式约束 \(E[\text{cost}]\le\delta\)。安全和性能必须在**不同的数学层次**上处理。
陷阱 2(思维陷阱):以为"纯 MPC 更安全所以应该尽量多用 MPC" - 错误做法:因为 MPC 有安全保证,就试图把高层协调决策也塞进 MPC,用手工代价 + 启发式规则逼近。 - 现象/后果:代价权重之间互相打架,调一个崩一个;启发式规则在复杂情境下漏洞百出;最终得到一个既不灵活又难维护的庞大规则系统。 - 根本原因:混淆了"安全"和"决策质量"两个正交的维度。MPC 在"有模型的执行"上确实更安全,但在"难建模的协调决策"上它**根本没有优势**——它只是把"学习策略"这件事换成了"人脑手工设计代价",而人脑做不好这件事。 - 正确做法:让 MPC 只做它有比较优势的事(底层执行 + 硬约束),把高层协调决策交给 RL。"安全"由专门的安全层(CBF)保证,与"决策"解耦——这样既有安全,又有好的协调。
陷阱 3(思维陷阱):把"混合架构"理解成"先跑 MARL 再跑 MPC"的简单串联 - 错误做法:以为混合就是"MARL 算一个结果,喂给 MPC 再算一遍"这种流水线式的串联,不考虑接口语义和时间尺度。 - 现象/后果:接口语义不对齐(MARL 输出的"动作"MPC 不知道怎么用),或时间尺度错配(MARL 10 Hz 的命令被 MPC 50 Hz 反复执行导致行为抖动),系统行为混乱。 - 根本原因:没理解解耦原理的核心是"沿正确的维度切分 + 设计语义清晰的窄接口",而不是简单地把两个模块前后接起来。接口设计(命令空间的语义、频率匹配、安全可执行性)才是混合架构的真正难点。 - 正确做法:先想清楚解耦维度(抽象层次?职能?贡献?),再设计接口语义(RL 输出什么物理量?MPC 怎么解释它?),最后处理频率匹配(高层慢、底层快,中间如何衔接)。§13.2-13.3 会详细讲这个接口设计。
练习¶
-
【概念辨析】 用你自己的话向一个只懂纯 MARL 的同学解释:"为什么把碰撞惩罚调到无穷大也不能让 MARL 真正安全?" 要求:(a) 从"优化目标项 vs 优化约束"的角度论证;(b) 举一个具体的反例情境,说明策略可能为了更大奖励而"赌"一次小概率碰撞;(c) 说明 CBF 安全约束在数学形式上和"无穷大惩罚"的本质区别(提示:一个是软的、在期望意义上,一个是硬的、逐状态)。
-
【设计分析】 回到本节开头"8 台异构机器人仓库搬运"的任务。请你把这个任务里的所有子问题**显式列出**,并为每个子问题判断它应该交给 MARL 还是传统规控,并说明你的判断依据(沿"时间尺度/抽象层次/建模难度/决策类型/空间结构"五个维度分析)。至少列出 6 个子问题。这道题没有唯一答案,重点是练习"解耦维度"的思维。
-
【反事实推理】 本节论证了"分层混合把 sim-to-real gap 局部化到高层决策接口上"。请你做一个反事实分析:如果把切分点放错位置——比如让 MARL 直接输出**关节力矩**(而不是高层命令),底层只做一个简单的力矩限幅——这个"混合"还能享受到 sim-to-real gap 局部化的好处吗?为什么?(提示:思考力矩这个输出对动力学 gap 的敏感度。)这道题帮你理解"切分点的位置"为什么是混合架构成败的关键。
§13.2 分层混合架构:四层分工 ⭐⭐⭐¶
这一节解决什么问题:§13.1 论证了"必须混合",但没说"怎么搭"。这一节给出混合架构最主流的形态——纵向分层(hierarchical),把一个多机器人系统切成"高层决策 → 中层轨迹/MPC → 底层 WBC/PD → 安全过滤层"四个层次。本节回答三个问题:每一层放什么、为什么放在这一层、层与层之间的时间尺度如何衔接。这张四层图是本章后续所有内容的骨架——§13.3 细讲高层到中层的接口,§13.4 细讲安全过滤层,你都要回头对照这张图。
动机:从"两类子问题"到"多层流水线"¶
§13.1 我们把任务粗分成"高层协调决策"和"底层执行控制"两类。但真实系统里,从"编队怎么变"到"电机出多少力矩"之间,其实横跨了好几个抽象层次和时间尺度——直接从 10 Hz 的"编队偏移命令"跳到 1000 Hz 的"关节力矩",中间缺了好几环。
想象一个具体的指令链:MARL 决定"3 号无人机应该向左偏移 0.5 米以避让"(这是一个**抽象的高层意图**)。但电机不认识"向左偏移 0.5 米"——它只认识"力矩 = 0.37 N·m"。从前者到后者,需要逐层翻译:
- "向左偏移 0.5 米" → 一条**平滑可行的目标轨迹**(什么速度过去、什么时候到);
- 目标轨迹 → 一串**满足动力学和约束的控制参考**(在摩擦锥、推力上限内);
- 控制参考 → 具体的**关节力矩 / 电机指令**;
- 在第 2、3 步之间,还要有一道**安全检查**——万一上层的命令会导致碰撞,要在这里拦下来。
这四步对应四个层次。每一层都有自己最合适的方法、最合适的运行频率。把它们清晰分开,是混合架构工程化的核心。
历史:分层控制的思想源流¶
分层控制(hierarchical control)不是机器人学的新发明。它的思想源头可以追溯到 1970-80 年代的**分层智能控制**(Saridis 的"组织-协调-执行"三级智能机器理论)和经典的**串级控制**(cascade control,外环慢、内环快,化工/航空里用了几十年)。这些经典思想确立了一条原则:用时间尺度分离(time-scale separation)来解耦一个复杂的多频率系统——慢的外环管"目标",快的内环管"跟踪",只要内环比外环快足够多(一般 5-10 倍),就可以近似认为内环"瞬间"达到外环给的目标,从而把一个耦合系统拆成两个独立设计的子系统。
机器人学把这个思想发扬光大:经典的足式机器人控制就是"步态规划(慢)→ MPC(中)→ 全身控制 WBC(快)"的三层结构。混合范式做的事,是在这个成熟的分层骨架的**最顶层**插入 RL——用学习替换掉原来最难手工设计的那一层(高层决策/步态/协调),而保留下面成熟可靠的模型层。
本质洞察:分层混合架构最聪明的地方,不是"发明了分层",而是**精准地识别出整个控制栈里"唯一一层最适合用学习替换"的位置**——即最顶层的高层决策。底层(力矩、轨迹跟踪)有成熟的模型方法且要求实时和安全,不该动;唯有顶层的协调/步态决策既难建模又不要求高频,正好是学习的甜区。混合架构是"外科手术式"地把 RL 植入到一个成熟控制栈的恰当位置,而不是推倒重来。
理论:四层架构详解¶
下面给出多机器人 MARL + 规控混合的标准四层架构。这张图请记牢——它是本章的骨架。
┌─────────────────────────────────────────────────────────────┐
│ Level 3:MARL 高层决策策略 运行频率 ~10 Hz │
│ ─────────────────────────────────────────────────────── │
│ 输入:每个 agent 的局部观测 oᵢ(自身状态 + 邻居 + 任务) │
│ 输出:高层命令 u_cmd │
│ · 质心目标速度 v_cmd / 目标位置 │
│ · 编队偏移 Δp(相对编队中心的偏移) │
│ · 子目标 / 任务再分配 / 让行优先级 │
│ 方法:MAPPO / HAPPO(CTDE 训练,分散执行) │
│ 为什么在这层:决策长程、组合、难建模 → 学习的甜区; │
│ 10 Hz 足够(决策不需要高频) │
└─────────────────────────────────────────────────────────────┘
│ u_cmd(语义命令,见 §13.3)
▼
┌─────────────────────────────────────────────────────────────┐
│ Level 2:单体 MPC(轨迹优化) 运行频率 ~50 Hz │
│ ─────────────────────────────────────────────────────── │
│ 输入:MARL 的高层命令 u_cmd + 当前状态 x │
│ 输出:足端力参考 / 关节轨迹 / 期望加速度 │
│ 方法:滚动时域 OCP(OCS2 的 SQP-RTI / acados) │
│ 为什么在这层:有精确动力学模型,能在硬约束(摩擦锥、 │
│ 关节限位)内求物理可行的控制;50 Hz 平衡 │
│ 实时性与计算量 │
└─────────────────────────────────────────────────────────────┘
│ u_mpc(控制参考)
┌─────────────┴─────────────┐
▼ │
┌──────────────────────────┐ │
│ 安全过滤层:CBF-QP │ │ (安全过滤叠加在 Level 2 输出上)
│ ────────────────────── │ │
│ 输入:u_mpc + 邻居状态 │ │
│ 输出:安全修正 u_safe │ │
│ 方法:CBF-QP(OSQP)/ │ │
│ GCBF+(GNN 参数化)│ │
│ 为什么:逐状态硬安全保证 │ │
│ (§13.4 详解) │ │
└──────────────────────────┘ │
│ u_safe │
▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ Level 1:WBC + PD(全身控制) 运行频率 ~200-1000 Hz │
│ ─────────────────────────────────────────────────────── │
│ 输入:安全修正后的力参考 u_safe │
│ 输出:关节力矩 τ │
│ 方法:QP-WBC(零空间投影分层任务)+ 关节 PD │
│ 为什么在这层:把"力参考"翻译成满足整机动力学的关节力矩, │
│ 需要最高频率以保证执行精度与稳定性 │
└─────────────────────────────────────────────────────────────┘
│ τ
▼
机器人本体
逐层解读——为什么每一层是现在这个频率、用现在这个方法:
Level 3(MARL,~10 Hz):这是混合架构里**唯一的学习层**。它接收局部观测,输出抽象的高层命令。为什么 10 Hz 就够?因为"编队怎么变、谁让谁"这类决策的**时间常数本来就慢**——人开车做"变道决策"也就每秒一两次,不需要每秒一千次。低频还带来三个额外好处:(1) 推理算力压力小(可以用更大的网络);(2) sim-to-real gap 被压缩在低维慢变的决策接口上;(3) 一个决策能维持多个底层周期,行为更连贯。
Level 2(MPC,~50 Hz):这是**主执行层**。它拿到高层命令("目标速度 v_cmd"),结合精确动力学模型,在预测时域 \(H\) 内求解一个 OCP,输出物理可行的控制参考。为什么是 MPC 而不是别的?因为 MPC 能**显式处理硬约束**(摩擦锥、关节限位)并**预见未来**(在 \(H\) 步窗口内提前规避)。为什么 50 Hz?这是实时性(需要快到能反馈扰动)和计算量(每周期解一个 QP/NLP 有开销)的折中——再快算不过来,再慢反馈不及时。
安全过滤层(CBF-QP,与 Level 2 同频或更高):这是**安全守门员**。它叠加在 MPC 输出之上,对 \(u_{\text{mpc}}\) 做最小修正使其满足 CBF 安全约束。注意它是一个**横切层**而非纵向的一环——它可以拦截来自 MARL 的命令,也可以拦截 MPC 的输出,本质是"在控制下发到电机之前的最后一道硬安全检查"。§13.4 整节都在讲它。
Level 1(WBC + PD,~200-1000 Hz):这是**底层执行层**。它把"力参考"通过全身控制(whole-body control, WBC,用零空间投影把多个任务分层)翻译成满足整机动力学的关节力矩,再经关节 PD 输出到电机。为什么最高频?因为执行精度和闭环稳定性对延迟最敏感——底层跟踪环必须足够快才能压住高频扰动。
时间尺度分离的数学依据:相邻两层的频率比一般保持在 5-10 倍(10→50→200/1000)。这个比例不是随意的,它来自串级控制的经典原则——只有当内环比外环快足够多时,外环设计才能假设内环"瞬间响应"。如果两层频率太接近(比如都是 30 Hz),时间尺度分离假设失效,两层会互相"看见"对方的暂态,产生耦合振荡。
本质洞察:四层架构的频率阶梯(10 / 50 / 200-1000 Hz)不是工程师拍脑袋定的,而是**时间尺度分离原理的直接体现**。每相邻两层差一个数量级,保证上层可以把下层近似当成"理想的瞬时执行器"来设计——这正是"分层"之所以能"解耦"的数学根基。如果你在自己的系统里发现两层频率太接近导致振荡,第一反应应该是"时间尺度分离假设被破坏了",而不是去调 PID 参数。
理论-工程桥接:这张图对应到真实代码栈¶
这套四层架构在真实开源栈里有清晰的对应物,理解这个对应能帮你把抽象图落地:
| 层次 | 抽象职能 | 典型开源实现 | 接口数据 |
|---|---|---|---|
| Level 3 | MARL 高层决策 | 自训策略(MAPPO/HAPPO,基于 HARL 库) | ROS topic:/cmd_formation(v_cmd, Δp) |
| Level 2 | 单体 MPC | OCS2(SQP-RTI)/ acados | /mpc_reference(足端力 / 关节轨迹) |
| 安全层 | CBF 过滤 | 自实现 CBF-QP(OSQP)/ GCBF+(JAX) | /u_safe(修正后控制) |
| Level 1 | WBC + PD | OCS2 的 WBC 模块 / 自实现 QP-WBC | /joint_torque(τ) |
关键工程点:层与层之间用消息队列(如 ROS topic)解耦,各层跑在独立的实时线程/进程里,按各自频率运行。上层命令以"最新值"被下层采样(下层频率高,会重复用同一个上层命令多次,直到上层更新)。这种"异步多频率"结构正是时间尺度分离在软件工程上的落地——它让你可以独立开发、测试、替换每一层。
一个常被忽略的设计点:层间的"降级安全"¶
成熟的混合架构还有一个容易被初学者忽略的设计——每一层都要能在"上层失效"时优雅降级。比如:如果 MARL 推理超时没给出新命令,Level 2 该怎么办?正确做法是 Level 2 保持上一个有效命令(或退回一个安全的默认命令,如"原地悬停/停车"),而不是用一个过期或空的命令。同理,如果 MPC 求解失败(infeasible),Level 1 应有一个安全回退(如重力补偿 + 阻尼)。
这个"分层降级"设计的价值在于:它把单点故障隔离在层内。上层(学习层,最不可靠)的失效不会直接传导成物理事故,而是被下层(模型层,更可靠)的降级逻辑接住。这也是混合架构相比纯 MARL 的一个隐性安全优势——纯 MARL 没有"下层"可以降级,策略失效就是系统失效。
⚠️ 常见陷阱¶
陷阱 1(思维陷阱):让相邻两层频率太接近,破坏时间尺度分离 - 错误做法:为了"让系统响应更快",把 MARL 高层提到 50 Hz,和 MPC 同频。 - 现象/后果:高层和中层互相"看见"对方的暂态过程,产生耦合振荡——机器人出现莫名其妙的周期性抖动,且调任何单层参数都按下葫芦浮起瓢。 - 根本原因:分层解耦依赖时间尺度分离假设(内环比外环快 5-10 倍),频率太接近时这个假设失效,两层从"独立设计"退化成"强耦合系统"。 - 正确做法:保持相邻层 5-10 倍的频率比(10→50→200/1000)。如果确实需要高层更快响应,应该是优化高层决策的内容(让单个决策更鲁棒),而不是提高它的频率去和下层抢时间尺度。
陷阱 2(概念误区):把安全过滤层当成纵向的一环而非横切层 - 错误做法:把 CBF 安全过滤放在"MARL → MPC → CBF → WBC"的串联链条里,认为它只过滤 MPC 的输出。 - 现象/后果:MARL 直接发给某些旁路通道的命令、或 MPC 内部已经违反安全的中间决策,没有被过滤层覆盖,安全保证出现漏洞。 - 根本原因:没理解安全过滤的本质是"控制下发到执行器前的最后一道硬检查",它应该是一个**横切所有控制路径**的守门员,而不是流水线上的一个工位。 - 正确做法:把安全过滤层定位在"所有控制信号汇聚、即将下发到底层执行器"的那个咽喉点上,保证**任何**进入底层的控制都经过它。§13.4 会讲它的具体接入位置。
陷阱 3(编程陷阱):层间用同步阻塞调用而非异步消息,导致最慢层拖垮全系统
- 错误做法:把四层写成一个大循环里的四个同步函数调用,cmd = marl(); ref = mpc(cmd); safe = cbf(ref); tau = wbc(safe);,整个循环跑在一个线程里。
- 现象/后果:整个系统的频率被最慢的层(MARL 推理或 MPC 求解)拖到 10 Hz,底层 WBC 无法以 1000 Hz 运行,执行精度和稳定性崩溃。
- 根本原因:同步串联强制所有层同频,违背了分层架构"各层独立频率"的根本设计——它把多频率系统压成了单频率系统。
- 正确做法:各层跑在独立的实时线程/进程,用无锁消息队列(或 ROS topic)通信,每层按自己的频率运行,下层采样上层的"最新可用值"。这才是时间尺度分离在软件上的正确落地。
练习¶
-
【架构设计】 给定一个"3 台 Go2 四足机器人协同搬运一根长杆"的任务,请你画出完整的四层架构图,并为每一层明确写出:(a) 输入是什么;(b) 输出是什么(具体物理量);(c) 运行频率;(d) 用什么方法。特别地,思考"协同搬运一根刚性长杆"这个任务的高层决策(Level 3)具体要输出什么命令——是各自的目标位置,还是相对于长杆的抓持点偏移?为什么后者可能更好?
-
【降级设计】 为练习 1 的系统设计完整的"分层降级"逻辑:分别说明当 (a) MARL 推理超时、(b) MPC 求解 infeasible、(c) 某台机器人通信中断 这三种故障发生时,每一层应该如何优雅降级以保证物理安全。要求降级逻辑能保证"长杆不被摔落、机器人不相撞"。这道题练习"分层降级把单点故障隔离在层内"的设计思维。
-
【时间尺度分析】 假设你的 MPC 求解平均耗时 25 ms(即最高 40 Hz),而你希望底层 WBC 跑 500 Hz。请计算:(a) MPC 和 WBC 的频率比是多少?是否满足时间尺度分离?(b) 在两次 MPC 更新之间,WBC 会用同一个 MPC 参考运行多少次?(c) 如果 MPC 偶尔耗时飙到 50 ms,会发生什么?你会如何设计 WBC 端的逻辑来平滑这种 MPC 输出的"卡顿"(提示:参考插值 / 保持上一参考)?
§13.3 RL 高层 + MPC 底层:接口设计 ⭐⭐⭐⭐¶
这一节解决什么问题:§13.2 的四层架构图里,Level 3(MARL)和 Level 2(MPC)之间有一根箭头标着"u_cmd"。这一节就专门讲这根箭头——RL 输出的高层命令,到底是什么物理量?MPC 怎么把它变成自己的参考/代价?为什么这个接口的语义设计是整个混合系统能不能工作的关键? 这是分层混合最容易做错、文献里也最少讲清楚的地方。本节给出命令空间设计的原则、三种典型接口形态、以及最小可运行的接口代码。
动机:一根箭头背后的魔鬼细节¶
回到那根箭头。MARL 决定"3 号无人机向左偏 0.5 米",MPC 要把它执行出来。听起来简单,但魔鬼藏在细节里——"向左偏 0.5 米"这个命令,MPC 到底该怎么用?
有好几种完全不同的解释方式:
- 解释 A:把它当成 MPC 的**终端目标位置**——在预测时域末端 \(x_H\) 处惩罚"离目标点的距离"。
- 解释 B:把它当成 MPC 的**参考轨迹**——生成一条从当前位置平滑过渡到目标的轨迹,逐点跟踪。
- 解释 C:把它当成 MPC 代价函数里某个项的**权重调整**——比如提高"向左"方向的代价梯度。
- 解释 D:把它当成一个**约束**——要求轨迹必须经过某个区域。
这四种解释会导致**完全不同的机器人行为**。更要命的是,MARL 是在某一种解释下训练的——如果训练时 MPC 用解释 A,部署时却用解释 B,那么 MARL 学到的策略和 MPC 的实际响应**对不上**,整个系统行为崩坏。这就是"接口语义对齐"问题:MARL 必须和 MPC 对"命令的含义"达成一致,否则学习层和执行层各说各话。
本质洞察:分层混合架构的真正难点不在"RL 怎么训"或"MPC 怎么解"——这两件事各自都有成熟方案。难点在**两者之间那个窄接口的语义设计**。接口设计得好,RL 学到的策略能被 MPC 忠实执行,sim-to-real gap 被局部化;接口设计得差,RL 和 MPC 互相误解,系统在仿真里都未必稳。可以说,混合架构的成败,90% 取决于接口设计,10% 取决于各层算法本身。这也是为什么这一节是 ⭐⭐⭐⭐。
如果接口设计不当会怎样¶
让我们看三个真实会发生的接口失败模式,理解"为什么接口这么重要"。
失败模式一:命令空间维度爆炸,RL 学不动。 一个初学者常犯的错误是让 MARL 直接输出**整条参考轨迹**(比如未来 2 秒、每 50 ms 一个点、每点 6 维位姿 = 240 维输出)。结果 RL 的动作空间高达几百维,探索效率极低,训练根本收敛不了。正确的做法是让 MARL 只输出**低维的抽象意图**(如 3 维目标速度),把"意图 → 轨迹"的展开交给 MPC——MPC 有模型,生成平滑可行轨迹是它的强项,不需要 RL 来学。
失败模式二:命令语义对动力学敏感,sim-to-real gap 没被局部化。 如果让 MARL 输出"期望加速度"或"期望力",这些量**强依赖于动力学**——仿真里产生 1 m/s² 加速度需要的命令,和真机里不一样(质量、阻力不同)。于是 sim-to-real gap 又渗回到接口里了,违背了 §13.1 "局部化 gap"的初衷。正确的做法是让命令尽量是**运动学层面的抽象意图**(目标位置/速度/编队偏移),这些量对动力学细节不敏感——"去 A 点"这个意图在仿真和真机里含义完全一样,动力学差异由下面的 MPC 用各自的模型去吸收。
失败模式三:命令不在 MPC 的"可执行能力"范围内,导致 MPC 频繁 infeasible 或剧烈饱和。 如果 MARL 输出一个 MPC 根本做不到的命令(比如要求瞬间反向、超出推力极限的加速),MPC 要么 infeasible(无解),要么输出饱和的剧烈控制。正确的做法是**约束 MARL 的命令空间到 MPC 的可执行包络内**(比如目标速度限幅在机器人最大速度内),或者在接口处做软化(把不可行命令投影到最近的可行命令)。
历史:从"RL 出动作"到"RL 出命令"的认知演进¶
早期的 RL+控制混合(2016-2018)确实常让 RL 直接输出底层动作(力矩/速度),把控制器当成一个简单的限幅或滤波。但人们很快发现这样做没有充分利用模型——RL 还是要独自承受大部分 sim-to-real gap。
转折点是**分层 RL(hierarchical RL, HRL)思想与控制的结合。HRL 里"高层策略出子目标、低层策略达成子目标"的思想(如 FeUdal Networks、HIRO,2017)被迁移到"高层 RL 出命令、低层 MPC 达成命令"——区别只是低层从"另一个学习策略"换成了"一个模型 MPC"。这个替换带来巨大好处:低层 MPC 有保证、有模型、不需要训练。RoCo(2024)把这个思想推到极致——高层甚至不是策略网络而是 LLM,输出自然语言级别的子目标,底层用 MPC 执行。而 MPC × predictive RL(2023)则走了另一条路:RL 不出"位置命令",而是出 MPC 的**尾代价(terminal cost)Q 函数——让 RL 学"超出 MPC 预测时域之后的长期价值",补上 MPC"看不远"的短板。
这条认知演进的主线是:RL 的输出越来越"高层、抽象、对动力学不敏感",把越来越多的"模型能干的活"还给模型。
理论:命令空间设计的三原则¶
把上面的失败模式提炼成正面的设计原则。一个好的 RL→MPC 命令接口,其命令空间应满足三条:
| 原则 | 内容 | 违反的后果 |
|---|---|---|
| 低维性 | 命令维度尽量低(通常 ≤ 6 维/agent),把"展开成轨迹"留给 MPC | 维度爆炸,RL 训练不收敛 |
| 运动学抽象性 | 命令是运动学意图(目标位置/速度/编队偏移),不是动力学量(力/加速度) | sim-to-real gap 渗回接口,迁移失败 |
| 可执行性 | 命令空间约束在 MPC 的可执行包络内(限幅 / 投影到可行集) | MPC 频繁 infeasible 或剧烈饱和 |
基于这三原则,三种典型的命令接口形态如下:
形态一:目标速度接口(velocity command)——最常用,适合移动/编队。 - MARL 输出:每个 agent 的期望质心速度 \(v_{\text{cmd},i} \in \mathbb{R}^{2\text{或}3}\)。 - MPC 解释:把 \(v_{\text{cmd}}\) 当成参考速度,代价函数惩罚 \(\|v - v_{\text{cmd}}\|^2\),在动力学和约束下跟踪。 - 优点:维度极低(2-3 维),运动学抽象,对动力学不敏感,天然限幅(限制在最大速度内)。
可以用一个类比帮助理解目标速度接口(注意边界):它就像**给汽车装了自适应巡航(ACC)后,司机只需用油门踏板表达"想多快",由 ACC 去管油门开度、换挡、跟车距离**。相似之处:司机(MARL)只下达高层意图("快一点/慢一点"),底层系统(MPC/ACC)负责把意图翻译成具体的、可行的、安全的执行细节,司机不必操心发动机转速这种底层量。不同之处:ACC 的"翻译"是固定规则,而 MPC 的翻译是一个带完整动力学模型的在线优化;且 ACC 只管纵向速度,而我们的目标速度接口是多维(含方向)的协调命令。不要把这个类比延伸到"司机和 ACC 各自独立"——在我们的系统里 MARL 是被训练得专门适配某个特定 MPC 的(接口语义训练部署须一致,见本节陷阱 2),而司机换辆车照样能开。
形态二:编队偏移接口(formation offset)——适合保持编队的协同。 - MARL 输出:每个 agent 相对编队中心(或某个虚拟领队)的偏移 \(\Delta p_i\)。 - MPC 解释:编队中心按预设轨迹走,每个 agent 的目标位置 = 中心位置 + \(\Delta p_i\),MPC 跟踪这个目标。 - 优点:把"队形"和"整体运动"解耦,MARL 只学"队形怎么动态调整"(避障时压扁、过通道时排成一列),整体路径由上层给定。
形态三:子目标 / 航点接口(subgoal / waypoint)——适合长程导航 + 局部规划。 - MARL 输出:每个 agent 的下一个子目标位置 \(g_i\)(一个相对较远的航点)。 - MPC 解释:MPC(或局部规划器)负责从当前位置安全到达 \(g_i\),处理局部避障。 - 优点:MARL 做长程、组合的"去哪"决策,MPC 做局部、连续的"怎么到",分工最清晰。
理论-工程桥接:最小可运行的 RL→MPC 接口¶
下面用代码把"目标速度接口"落地。我们遵循 R8 的四步法:先讲为什么这样写、给正确写法、给错误写法、给对比。
Step 1:为什么接口要这样写?
为什么 RL 只输出 3 维 v_cmd,而不是整条轨迹?
因为 MPC 已经有动力学模型,"把目标速度展开成一条平滑、可行、满足约束的
轨迹"恰恰是 MPC 的看家本领——它在预测时域 H 内求解 OCP,自动得到平滑轨迹。
让 RL 去学这件 MPC 本就擅长的事,是双输:RL 动作空间爆炸到几百维(训练
不收敛),而且学出来的轨迹还不如 MPC 算的可行。
正确的分工:RL 决定"想往哪个方向、多快走"(3 维意图,难建模、需学习),
MPC 决定"具体怎么走才平滑可行"(有模型、不需学习)。
规则:接口处只传"低维运动学意图",把"展开成可行控制"留给 MPC。
Step 2:正确写法
import numpy as np
class RLToMPCInterface:
"""RL 高层 → MPC 底层的命令接口(目标速度形态)。
职责:把 MARL 策略输出的归一化动作,翻译成 MPC 能直接消费的
参考速度,并保证它落在 MPC 的可执行包络内。
"""
def __init__(self, v_max: float, a_max: float, ctrl_dt: float):
self.v_max = v_max # 机器人最大速度(可执行包络)
self.a_max = a_max # 最大加速度(用于命令平滑限速)
self.ctrl_dt = ctrl_dt # 高层控制周期(10 Hz → 0.1 s)
self.v_cmd_prev = np.zeros(3) # 上一周期命令,用于平滑
def policy_action_to_vcmd(self, action: np.ndarray) -> np.ndarray:
"""把策略输出的归一化动作 a∈[-1,1]^3 翻译成参考速度 v_cmd。
关键设计:
1. 动作归一化到 [-1,1](RL 训练友好),在接口处映射回物理量;
2. 限幅到 v_max(可执行性原则——绝不发 MPC 做不到的命令);
3. 限制相邻周期的速度变化率(≤ a_max·dt),避免命令跳变
导致 MPC 输出剧烈饱和。
"""
# 1. 归一化动作 → 物理速度(运动学抽象量,对动力学不敏感)
v_target = action * self.v_max # [-1,1]^3 → [-v_max, v_max]^3
# 2. 速度幅值限幅(落在 MPC 可执行包络内)
speed = np.linalg.norm(v_target)
if speed > self.v_max:
v_target = v_target * (self.v_max / speed)
# 3. 命令平滑:限制加速度,避免命令跳变(保护 MPC 不饱和)
dv = v_target - self.v_cmd_prev
dv_max = self.a_max * self.ctrl_dt
if np.linalg.norm(dv) > dv_max:
dv = dv * (dv_max / np.linalg.norm(dv))
v_cmd = self.v_cmd_prev + dv
self.v_cmd_prev = v_cmd
return v_cmd # 3 维,直接喂给 MPC 代价
def build_mpc_cost(v_cmd: np.ndarray, Q_v: np.ndarray):
"""MPC 端如何消费 v_cmd:把它放进代价函数的速度跟踪项。
MPC 的 OCP(简化记法):
min Σ_k ||v_k - v_cmd||²_{Q_v} + ||u_k||²_R
s.t. x_{k+1} = f(x_k, u_k) # 真实动力学模型
u_k ∈ U, g(x_k,u_k) ≤ 0 # 硬约束(摩擦锥/限位)
这里只展示代价项的组装;完整 OCP 由 OCS2/acados 求解。
"""
# 速度跟踪项的权重矩阵 Q_v 决定"多努力地跟上 v_cmd"
# 注意 v_cmd 进入的是【代价】而非【硬约束】——
# 这样即使 v_cmd 暂时不可达,MPC 仍有解(输出尽力接近的控制)
return lambda v_k: (v_k - v_cmd).T @ Q_v @ (v_k - v_cmd)
Step 3:错误写法及为什么错
# ❌ 错误 1:RL 直接输出整条参考轨迹(维度爆炸)
class BadInterface_FullTrajectory:
def policy_action_to_ref(self, action):
# action 是 240 维:未来 2 秒 × 20 个点 × 6 维位姿 × 2(pos+vel)
return action.reshape(20, 12) # MPC 逐点跟踪这条轨迹
# 问题:RL 动作空间 240 维,探索效率极低,训练几乎不可能收敛。
# 而且 RL 学出的轨迹未必满足动力学,MPC 跟踪时频繁 infeasible。
# 正确做法是只输出 3 维意图,让 MPC 展开轨迹。
# ❌ 错误 2:RL 输出动力学量(期望力),sim-to-real gap 渗回接口
class BadInterface_ForceCommand:
def policy_action_to_force(self, action):
return action * self.f_max # 输出期望力 [-f_max, f_max]
# 问题:达到同样运动效果所需的"力"强依赖质量/阻力等动力学参数,
# 仿真和真机不同。于是 RL 学的"力命令"在真机上产生不同运动,
# sim-to-real gap 没有被局部化。应输出运动学意图(速度/位置)。
# ❌ 错误 3:把 v_cmd 当 MPC 的硬约束而非代价(导致频繁 infeasible)
def bad_mpc_with_hard_velocity_constraint(v_cmd):
# s.t. v_k == v_cmd for all k ← 把命令当硬等式约束!
# 问题:当 v_cmd 因障碍/动力学暂时不可达时,MPC 直接 infeasible 无解,
# 系统失去控制输出。命令应进【代价】(软),保证 MPC 永远有解。
pass
# ❌ 错误 4:命令无限幅、无平滑,直接透传(MPC 剧烈饱和)
class BadInterface_NoClamp:
def policy_action_to_vcmd(self, action):
return action * 1e3 # 不限幅、不平滑,直接放大
# 问题:RL 偶尔输出极端动作 → v_cmd 跳到不可执行的巨大值 →
# MPC 输出饱和的剧烈控制 → 真机抽搐甚至失稳。
# 必须限幅到 v_max 且限制变化率(见正确写法 Step 2)。
Step 4:三种接口形态的对比
# === 三种 RL→MPC 命令接口的选型对比 ===
#
# | 接口形态 | RL 输出维度 | 适用场景 | MPC 端解释 |
# |-------------|-----------|------------------|--------------------|
# | 目标速度 | 2-3 维 | 移动/编队/避障 | 代价惩罚 ||v-v_cmd|||
# | 编队偏移 | 2-3 维/agent| 保持队形的协同 | 目标=中心+Δp,跟踪 |
# | 子目标/航点 | 2-3 维 | 长程导航+局部规划 | 局部规划器到达 g |
#
# 共同点(三者都遵守命令空间设计三原则):
# - 低维(≤6 维):把"展开"留给 MPC
# - 运动学抽象:对动力学不敏感,gap 被局部化
# - 可执行:限幅 + 平滑,落在 MPC 包络内
#
# 选型口诀:
# 纯移动协调 → 目标速度;要保队形 → 编队偏移;长程+组合决策 → 子目标
一个进阶接口:RL 出 MPC 的尾代价(terminal cost)¶
除了"RL 出命令、MPC 跟踪"这种主流形态,还有一种更精巧的接口值得了解——RL 学习 MPC 的尾代价(MPC × predictive RL,2023)。
MPC 的一个根本局限是**预测时域有限**(只看未来 \(H\) 步)。它对"\(H\) 步之外会发生什么"一无所知,只能用一个手工设计的尾代价 \(V_f(x_H)\) 来近似"末端状态的长期价值"。但这个长期价值恰恰**难以手工设计**——它本质上是一个最优值函数(value function),而值函数正是 RL 的看家本领。
于是这个接口让 RL 学一个 Q 函数当 MPC 的尾代价:
这样 MPC 的短时域优化"接上了"RL 学到的长期价值,既保留 MPC 的硬约束保证和短期精确性,又通过 RL 的尾代价获得长程的全局视野。这是"RL 补 MPC 看不远的短板"的精妙体现——和"RL 出命令"形成互补:前者 RL 在**时间维度**上补 MPC(看更远),后者 RL 在**决策维度**上补 MPC(出难建模的命令)。
本质洞察:RL→MPC 的接口可以建在不同的"语义位置"上——可以是 MPC 的**输入**(命令/参考),也可以是 MPC 的**代价**(尾代价 Q 函数),甚至是 MPC 的**约束**或**模型残差**。每个位置对应一种"让 RL 补 MPC 不同短板"的方式:补"难建模的决策"(命令)、补"看不远的长期价值"(尾代价)、补"模型误差"(残差,见 §13.5)。理解了这一点,你就不会把"RL+MPC 混合"当成一个固定模板,而会根据"MPC 到底缺什么"来选择接口的接入点。
⚠️ 常见陷阱¶
陷阱 1(思维陷阱):让 RL 直接输出底层动作,浪费了 MPC 的模型能力 - 错误做法:让 MARL 直接输出关节力矩或整条参考轨迹,MPC/控制器只做简单限幅。 - 现象/后果:RL 动作空间维度过高训练不收敛,或 RL 独自承受全部 sim-to-real gap 迁移失败,MPC 的模型优势完全没用上。 - 根本原因:没理解分层混合的核心是"让 RL 出高层抽象意图、让 MPC 用模型展开成可行控制"。RL 出底层动作等于把 MPC 降级成一个滤波器,丢掉了它最值钱的能力——基于模型的约束满足和轨迹生成。 - 正确做法:RL 只输出低维运动学意图(≤6 维的目标速度/偏移/子目标),把"意图→可行控制"的展开完全交给 MPC。
陷阱 2(概念误区):训练和部署用不同的命令语义,导致 RL 和 MPC 对不上 - 错误做法:训练 MARL 时 MPC 把 v_cmd 当终端目标位置(解释 A),部署时却当参考速度跟踪(解释 B)。 - 现象/后果:MARL 学到的策略和 MPC 的实际响应行为对不上,仿真训练好的策略部署后行为诡异,甚至在仿真换了 MPC 解释后就崩。 - 根本原因:MARL 是在某一种"命令→行为"的映射下学的,这个映射由 MPC 如何解释命令决定。换了解释 = 换了环境,策略自然失效。接口语义必须训练和部署严格一致。 - 正确做法:在训练**之前**就冻结接口语义(命令是什么物理量、MPC 怎么解释它、限幅平滑规则),训练和部署用**完全相同**的接口代码。把接口当成环境的一部分来对待。
陷阱 3(编程陷阱):v_cmd 进 MPC 硬约束导致 infeasible
- 错误做法:在 MPC 里写 v_k == v_cmd 作为硬等式约束,强制速度等于命令。
- 现象/后果:当命令因障碍或动力学暂时不可达时,MPC 求解 infeasible,控制输出中断,系统失控。
- 根本原因:混淆了"命令是期望"和"命令是约束"。RL 的命令是一个**期望/参考**,本身不保证可达;把它当硬约束会让 MPC 在命令不可达时无解。
- 正确做法:v_cmd 永远进**代价函数**(软跟踪 \(\|v-v_{\text{cmd}}\|^2_{Q_v}\)),保证 MPC 在任何命令下都有解(输出"尽力接近"的可行控制)。硬约束只留给真正不可违反的物理约束(摩擦锥、关节限位)。
练习¶
-
【接口实现】 基于本节的
RLToMPCInterface,实现一个"编队偏移接口"FormationOffsetInterface:MARL 为每个 agent 输出归一化偏移动作,接口把它翻译成相对编队中心的偏移 \(\Delta p_i\),并保证 (a) 偏移幅值不超过max_offset(避免编队散架),(b) 任意两个 agent 的目标位置间距不小于min_sep(避免目标本身就冲突)。给出可运行代码框架,并说明 (b) 这个约束为什么应该在接口层做、而不是留给下游 CBF。 -
【接口调试】 给你一个有 bug 的混合系统现象描述:"仿真里训练好的 8 机编队策略,部署到真机后整体能协调,但每台机器人都在高频抖动。" 请你列出**至少三个**可能的接口层根因(从本节讲的失败模式和陷阱里找),并为每个根因给出一个具体的排查方法和修复方案。这道题练习"从现象反推接口 bug"的调试能力。
-
【设计扩展】 本节讲了"RL 出命令"和"RL 出尾代价"两种接口。请你设计第三种接口——RL 动态调整 MPC 代价函数的权重(比如 RL 输出"此刻应该更看重避障还是更看重跟踪"的权重比)。写出:(a) RL 的输出是什么、维度多少;(b) MPC 端如何消费这个权重;(c) 这种接口相比"RL 出命令"的优劣(提示:思考它对哪类任务有独特价值,以及它会不会让 MPC 行为变得难以预测)。
§13.4 安全过滤层:CBF-QP 与 GCBF+ ⭐⭐⭐⭐¶
这一节解决什么问题:前面所有小节都在讲"怎么让混合系统行为好",这一节讲**怎么让它绝对安全**。核心思想是安全过滤(safety filtering / shielding):上层(MARL 或 MPC)随便输出一个名义控制 \(u_{\text{nom}}\),安全过滤层在它执行前做一次**最小修正**,把它投影到"保证不违反硬约束"的安全集里,得到 \(u_{\text{safe}}\)。本节从 CBF 出发推导 CBF-QP 的解析解,讲清为什么它能提供**逐状态的硬安全保证**,然后讲 GCBF+ 如何用 GNN 把这个保证扩展到上千 agent。这是本章的安全基石,⭐⭐⭐⭐。
动机:给黑盒策略套一个"安全外壳"¶
§13.1 我们反复强调:MARL 的奖励惩罚是软的,无法保证安全。那怎么办?一个绝妙的思路是——不要试图让策略本身安全,而是在策略和执行器之间插一道"安全过滤器"。
打个比方(注意边界):这就像给一个莽撞的新手司机配一套**自动紧急制动(AEB)系统**。新手(MARL 策略)想怎么开就怎么开,但只要 AEB(安全过滤器)检测到"再这样下去要撞了",它就**最小限度地介入**——能不踩刹车就不踩,一旦要撞就强制干预,且只干预到"刚好不撞"为止。相似之处:两者都是"让主控制器自由发挥,只在危险时最小介入"。不同之处:AEB 是基于规则的离散触发(撞前一刻全力刹车),而 CBF 过滤是**连续、平滑、逐时刻**的修正(持续地、温和地把控制往安全方向掰),且有**数学可证明**的安全保证——这是 AEB 这个类比的边界,不要把 CBF 想成"危险时才触发",它是**时刻都在**工作的。
这个思路的革命性在于:它把"安全"和"性能"彻底解耦了。MARL 全力优化性能(协调、效率),完全不用操心安全;安全过滤层全力保证安全,完全不用操心性能。两个目标在两个独立的模块里、用两种不同的数学(RL 的期望优化 vs CBF 的逐状态约束)各自处理。这正是 §13.1 "安全必须是约束而非目标项"那个本质洞察的工程落地。
如果不做安全过滤会怎样¶
不做安全过滤,你只剩两个糟糕的选择。
选择一:信任 MARL 的软安全。 我们已经反复论证过——这等于接受一个非零的碰撞概率,真机上迟早出事。而且更阴险的是,这个概率在 OOD 情况下会突然飙升(训练时 0.1%,遇到没见过的风扰可能瞬间变成 50%),你完全无法预测什么时候会出事。
选择二:把所有安全约束塞进 MPC 硬约束。 这看起来可行——MPC 确实能处理硬约束。但问题是:(1) MPC 是有限时域的,它只保证未来 \(H\) 步安全,\(H\) 步之外不管;(2) 多机器人的 pairwise 碰撞约束数量随 \(N^2\) 增长,全塞进一个 MPC 会让 QP 规模爆炸、求解超时;(3) 分布式时,每个 agent 的 MPC 看不到全局,难以协调避碰。CBF 过滤恰好补上这三点:它保证**无限时域**的前向不变性(不是只看 \(H\) 步),它**计算极轻**(每个 agent 一个小 QP),它**天然分布式**(每个 agent 只用局部邻居信息)。
历史:从 CBF 到 GCBF+¶
控制屏障函数(CBF)的现代形式由 Ames 等人在 2014-2019 年间确立。它的思想源头是控制李雅普诺夫函数(Control Lyapunov Function, CLF)——CLF 用一个能量函数保证**稳定性**(系统收敛到目标),CBF 用一个屏障函数保证**安全性**(系统永不离开安全集)。Ames 的关键贡献是把"安全"写成一个**仿射于控制 \(u\) 的不等式约束**,从而可以用一个二次规划(QP)在每个控制周期实时求解——这就是 CBF-QP,一个可以叠加在任何名义控制器之上的"安全过滤器"。
但经典 CBF 有一个致命的可扩展性问题:手工设计 CBF 函数 \(h\) 对多智能体几乎不可行。两个 agent 的碰撞避免 CBF 还能手写(\(h = \|p_i - p_j\| - 2r\)),但当 agent 数到几百、每个 agent 的安全依赖于动态变化的邻居集合时,手工设计一个全局有效的 \(h\) 成了不可能完成的任务。
GCBF+(Zhang, Fan 等,T-RO 2024,MIT-REALM 实验室)的突破正在于此:用图神经网络(GNN)参数化一个 CBF,让它天然可扩展到任意数量的 agent。GNN 的置换等变性(permutation equivariance)和对邻居数量的不敏感性,恰好匹配多智能体安全问题的结构——agent 的安全只依赖于它的邻居"集合"而非具体编号或数量。GCBF+ 在 256-1024 个 agent 上验证了可扩展安全保证,比手工 CBF 好 20%,比纯 RL 方法好 40%,且能直接接受 LiDAR 点云输入(不需要理想状态估计)。
理论:CBF 与前向不变性(先复习)¶
我们先把 CBF 的核心快速复活一遍(R14 跨章桥接)。考虑一个**控制仿射系统**:
其中 \(f(x)\) 是漂移项(drift,不受控制影响的自然演化),\(g(x)\) 是输入项(控制如何影响状态)。定义**安全集**为某个函数 \(h(x)\) 的超水平集:
直觉上,\(h(x)\) 是一个"到危险的距离"——\(h>0\) 安全(在集合内部),\(h=0\) 危险边缘,\(h<0\) 已违反。比如碰撞避免里 \(h = \|p_i-p_j\|^2 - (2r)^2\)(两 agent 距离平方减去安全半径平方)。
CBF 条件:\(h\) 是一个 CBF,如果存在一个扩展 \(\mathcal{K}\) 类函数 \(\alpha\)(严格增、\(\alpha(0)=0\)),使得对所有 \(x\in\mathcal{C}\),存在控制 \(u\) 满足
这里 \(L_f h = \frac{\partial h}{\partial x} f(x)\) 和 \(L_g h = \frac{\partial h}{\partial x} g(x)\) 是李导数(Lie derivative),分别是 \(h\) 沿漂移项和输入项的变化率。
为什么这个不等式保证安全? 关键在边界附近的行为。当状态逼近安全边界时 \(h \to 0^+\),于是 \(\alpha(h) \to 0\),不等式变成 \(\dot h \ge 0\)——它**强制 \(h\) 不再下降**,把状态"挡"在边界内侧。而在内部深处(\(h\) 大),\(\alpha(h)\) 大,不等式很宽松(允许 \(\dot h\) 取较大负值,即允许朝边界移动),但不会越界。这就是**前向不变性**(forward invariance):
本质洞察:CBF 不等式 \(\dot h \ge -\alpha(h)\) 的精妙之处在于 \(\alpha(h)\) 这个"自适应的放松率"。它让约束在安全深处**宽松**(不必要地限制控制是浪费)、在边界附近**收紧**(必须阻止越界)。如果你把 \(-\alpha(h)\) 换成一个固定常数(比如 \(\dot h \ge 0\),要求 \(h\) 永不下降),系统会过度保守——明明离危险很远也不许靠近。\(\alpha(h)\) 用一个随距离自适应的边界,在"安全"和"不保守"之间取得了最优平衡。这是 CBF 远胜于简单"距离阈值刹车"的根本原因。
相对度与高阶 CBF(HOCBF):上面的推导假设 \(L_g h \ne 0\),即 \(\dot h\) 显含 \(u\)。但很多情况下不是这样——比如 \(h\) 是位置的函数(\(h=\|p_i-p_j\|^2-(2r)^2\)),而控制 \(u\) 是加速度/力,那么 \(\dot h\) 只含速度、不含 \(u\),要再求一次导 \(\ddot h\) 才出现 \(u\)。这种"\(h\) 对 \(u\) 的相对度(relative degree)≥ 2"的情况,需要**高阶 CBF(High-Order CBF, HOCBF)**:构造一串嵌套函数 \(\psi_0 = h\),\(\psi_1 = \dot\psi_0 + \alpha_1(\psi_0)\),\(\psi_2 = \dot\psi_1 + \alpha_2(\psi_1)\),直到 \(\psi_k\) 显含 \(u\),然后约束 \(\dot\psi_{k-1} \ge -\alpha_k(\psi_{k-1})\)。这是多机器人(二阶/三阶动力学)必然遇到的——力控机器人的碰撞避免几乎都是相对度 2 的问题,必须用 HOCBF。
理论:CBF-QP 安全过滤器的推导¶
现在把 CBF 变成一个"过滤器"。给定一个名义控制 \(u_{\text{nom}}\)(来自 MARL 或 MPC),我们要找一个**尽量接近 \(u_{\text{nom}}\)、但满足 CBF 安全约束**的 \(u_{\text{safe}}\)。这自然写成一个二次规划(QP):
目标函数 \(\|u-u_{\text{nom}}\|^2\) 是"最小修正"——尽量少改动名义控制(当名义控制本就安全时,不做任何修改);约束是 CBF 安全条件。这是一个**单约束的 QP**,对单个安全约束有**闭式解**,我们来推导它(R1 要求展示每一步)。
把约束改写成标准形式 \(a^\top u \le b\),其中 \(a = -L_g h(x)^\top\),\(b = L_f h(x) + \alpha(h(x))\)(移项:\(L_g h \cdot u \ge -\alpha(h) - L_f h\) 即 \(-L_g h \cdot u \le L_f h + \alpha(h)\))。问题变成:
情况一:\(u_{\text{nom}}\) 已满足约束(\(a^\top u_{\text{nom}} \le b\))。则约束不激活,最优解就是 \(u_{\text{safe}} = u_{\text{nom}}\)——安全控制时过滤器透明,零修正。
情况二:\(u_{\text{nom}}\) 违反约束(\(a^\top u_{\text{nom}} > b\))。则约束激活(取等号),用 Lagrangian 求解。构造 \(\mathcal{L} = \tfrac12\|u-u_{\text{nom}}\|^2 + \lambda(a^\top u - b)\),\(\lambda \ge 0\)。KKT 条件:
代入激活约束 \(a^\top u = b\):
于是闭式解为(合并两种情况):
其中 \(a = -L_g h^\top\),\(b = L_f h + \alpha(h)\)。这个解有极清晰的几何意义:当 \(u_{\text{nom}}\) 违反约束时,把它沿约束法向量 \(a\) 投影到约束超平面上——\(\max(0,\cdot)\) 保证只在违反时修正,\(\frac{\cdot}{\|a\|^2}a\) 是投影到超平面的最小位移。这就是"最小修正"的数学本质:正交投影到安全半空间的边界。
本质洞察:CBF-QP 的闭式解 \(u_{\text{safe}} = u_{\text{nom}} - \frac{\max(0, a^\top u_{\text{nom}}-b)}{\|a\|^2}a\) 揭示了安全过滤的几何本质——它就是一个**到安全半空间的欧氏投影**。安全集在控制空间里是一个半空间 \(\{u : a^\top u\le b\}\);过滤器做的事,就是把落在外面的名义控制"拉"回到最近的边界点。这个视角解释了为什么安全过滤几乎不损害性能:投影是"最小改动",它只在你真要越界时、且只把你拉回到刚好不越界的位置。性能损失被压到了数学上的最小值。
一个手算的数值例子(让闭式解从抽象变具体)。考虑一个最简单的一阶 integrator 单机避障:\(\dot x = u\)(\(x,u\in\mathbb{R}^2\)),机器人在原点 \(x=(0,0)\),要避开位于 \(p_{\text{obs}}=(2,0)\)、半径 \(r=1\) 的圆形障碍。安全函数 \(h(x) = \|x - p_{\text{obs}}\|^2 - r^2\),当前 \(h = \|(0,0)-(2,0)\|^2 - 1 = 4 - 1 = 3 > 0\)(安全)。取 \(\alpha(h)=h\)(线性 \(\mathcal{K}\) 类函数)。
名义控制 \(u_{\text{nom}} = (3, 0)\)——MARL 想让机器人**直接冲向障碍**(正 \(x\) 方向,速度 3)。我们来算过滤器怎么修正它。
- 对一阶 integrator,\(f(x)=0\),\(g(x)=I\),所以 \(L_f h = 0\),\(L_g h = \frac{\partial h}{\partial x} = 2(x-p_{\text{obs}}) = 2(0-2, 0-0) = (-4, 0)\)。
- 约束系数 \(a = -L_g h^\top = (4, 0)^\top\),\(b = L_f h + \alpha(h) = 0 + 3 = 3\)。
- 检查名义控制是否违反:\(a^\top u_{\text{nom}} = (4,0)\cdot(3,0) = 12\)。而 \(b=3\)。\(12 > 3\) → 违反约束,需要修正。
- 代入闭式解:\(\lambda = \frac{a^\top u_{\text{nom}} - b}{\|a\|^2} = \frac{12 - 3}{16} = \frac{9}{16} = 0.5625\)。
- \(u_{\text{safe}} = u_{\text{nom}} - \lambda a = (3,0) - 0.5625\cdot(4,0) = (3 - 2.25,\ 0) = (0.75,\ 0)\)。
解读这个结果:过滤器没有把机器人完全拦停(\(u_{\text{safe}}\) 仍是 \((0.75, 0)\),还在朝障碍方向走),而是把朝向障碍的速度从 3 减到 0.75——刚好让 \(\dot h = -\alpha(h)\) 这个边界条件满足(验证:\(\dot h = L_g h\cdot u_{\text{safe}} = (-4,0)\cdot(0.75,0) = -3 = -\alpha(h) = -h\) ✓)。这正是"最小修正"的精髓:它不过度干预(没有强制停止或反向),只把违反的分量削减到刚好不越界。随着机器人继续靠近、\(h\) 减小,\(b=\alpha(h)\) 也减小,允许的朝向速度会持续下降,最终在边界处降到零——平滑、连续、绝不越界。把这个手算过程和 Step 2 的代码对照,你就能彻底打通"公式↔几何↔代码"三者。
多个安全约束的情况:多机器人系统里,一个 agent 通常对多个邻居都有碰撞约束,于是有多个 CBF 不等式同时约束 \(u\)。此时 QP 变成多约束:
多约束 QP 一般没有简单闭式解(除非只有一个约束激活),需要用数值 QP 求解器(如 OSQP、qpOASES)。但它仍然极轻量——典型 agent 的邻居数有限(几个到十几个),QP 规模很小,单个 agent 在亚毫秒级就能求解。
理论-工程桥接:用 OSQP 实现 pairwise CBF 碰撞避免¶
下面把上面的理论落地成可运行代码。场景:\(N\) 个 2D 双积分器(double integrator)agent,控制是加速度,要保证任意两 agent 永不碰撞。注意双积分器里 \(h\)(位置函数)对 \(u\)(加速度)的相对度是 2,所以要用 HOCBF。我们遵循 R8 四步法。
Step 1:为什么要这样写?
为什么碰撞避免要用 HOCBF(高阶 CBF)而不是普通 CBF?
因为双积分器 ẍ = u(u 是加速度)。安全函数 h = ||p_i - p_j||² - (2r)²
是位置的函数。求一次导:ḣ = 2(p_i-p_j)·(v_i-v_j) —— 只含速度,不含 u!
再求一次导:ḧ 才出现加速度 u。所以 h 对 u 的相对度是 2。
普通 CBF 不等式 ḣ ≥ -α(h) 无法约束 u(因为 ḣ 不含 u),
必须用 HOCBF:构造 ψ₁ = ḣ + α₁(h),再约束 ψ̇₁ ≥ -α₂(ψ₁),
展开后 ψ̇₁ 含 ḧ 即含 u,这才"逼出"了对 u 的约束。
规则:控制是力/加速度、安全是位置函数 → 相对度≥2 → 必须 HOCBF。
Step 2:正确写法
import numpy as np
import osqp
from scipy import sparse
def pairwise_cbf_filter(p, v, u_nom, r_safe, alpha1=2.0, alpha2=2.0):
"""N 个 2D 双积分器的 pairwise HOCBF 碰撞避免安全过滤器。
系统:每个 agent ẍ_i = u_i (u_i ∈ R²,加速度)
安全:任意 i≠j,||p_i - p_j|| ≥ 2·r_safe(不碰撞)
输入:
p: (N,2) 位置
v: (N,2) 速度
u_nom: (N,2) 名义加速度(来自 MARL/MPC)
r_safe: 单个 agent 安全半径
输出:
u_safe: (N,2) 安全修正后的加速度
"""
N = p.shape[0]
nu = 2 * N # 总控制维度
# QP: min 1/2 ||u - u_nom||² s.t. A u ≤ b
# 目标 = 1/2 uᵀ P u + qᵀ u,其中 P=I, q=-u_nom
P = sparse.eye(nu, format='csc')
q = -u_nom.flatten()
A_rows, b_vals = [], []
for i in range(N):
for j in range(i + 1, N): # 每对 (i,j) 一个 HOCBF 约束
pij = p[i] - p[j] # 相对位置
vij = v[i] - v[j] # 相对速度
# h = ||pij||² - (2r)²
h = pij @ pij - (2 * r_safe) ** 2
# ḣ = 2 pij·vij (不含 u)
h_dot = 2.0 * pij @ vij
# ψ₁ = ḣ + α₁ h (一阶 HOCBF 中间量)
psi1 = h_dot + alpha1 * h
# ψ̇₁ = ḧ + α₁ ḣ,其中 ḧ = 2||vij||² + 2 pij·(u_i - u_j)
# 含 u 的部分:2 pij·(u_i - u_j)
# HOCBF 约束:ψ̇₁ ≥ -α₂ ψ₁
# ⟺ 2 pij·(u_i-u_j) + 2||vij||² + α₁ ḣ ≥ -α₂ ψ₁
# 写成 A u ≤ b 形式(移项取负):
# -2 pij·u_i + 2 pij·u_j ≤ 2||vij||² + α₁ h_dot + α₂ psi1
a_row = np.zeros(nu)
a_row[2 * i: 2 * i + 2] = -2.0 * pij # 对 u_i 的系数
a_row[2 * j: 2 * j + 2] = +2.0 * pij # 对 u_j 的系数
b_val = 2.0 * (vij @ vij) + alpha1 * h_dot + alpha2 * psi1
A_rows.append(a_row)
b_vals.append(b_val)
if not A_rows: # 无约束(如 N=1)
return u_nom
A = sparse.csc_matrix(np.array(A_rows))
b = np.array(b_vals)
# OSQP 求解:l ≤ A u ≤ u_upper,这里只有上界 b,下界设 -∞
prob = osqp.OSQP()
prob.setup(P=P, q=q, A=A, l=-np.inf * np.ones(len(b)), u=b,
verbose=False, eps_abs=1e-6, eps_rel=1e-6)
res = prob.solve()
if res.info.status_val not in (1, 2): # 求解失败 → 安全降级
return np.zeros_like(u_nom) # 退回零加速度(保守但安全)
return res.x.reshape(N, 2)
Step 3:错误写法及为什么错
# ❌ 错误 1:对双积分器用一阶 CBF(相对度搞错)
def bad_first_order_cbf(p, v, u_nom, r_safe, alpha=1.0):
pij = p[0] - p[1]
h = pij @ pij - (2 * r_safe) ** 2
h_dot = 2.0 * pij @ (v[0] - v[1]) # ḣ 不含 u!
# 试图用 ḣ ≥ -α h 约束 u —— 但 ḣ 里根本没有 u,
# 这个约束对 u 不起任何作用,过滤器形同虚设,碰撞照样发生。
# 问题:相对度是 2,必须用 HOCBF(见正确写法)。
pass
# ❌ 错误 2:QP 无解时直接用 u_nom(放弃安全)
def bad_no_fallback(prob, u_nom):
res = prob.solve()
return res.x if res.info.status_val == 1 else u_nom.flatten()
# 问题:QP infeasible 往往恰恰发生在"危险逼近"时(约束最紧),
# 此时退回 u_nom 等于在最危险的时刻关闭安全保护,必撞。
# 正确做法是降级到一个保守安全动作(零加速度/最大减速)。
# ❌ 错误 3:α 取太大,安全约束被"放松"到失效
def bad_huge_alpha(h, h_dot):
alpha = 1e6 # α 巨大
# CBF 约束 ḣ ≥ -α·h:α 极大时右端 -α·h 是一个巨大负数,
# 约束 ḣ ≥ (巨大负数) 几乎总是满足 → 约束形同虚设。
# 现象:agent 冲到离边界极近才"突然"刹车,常常已经来不及。
# 问题:α 控制"多早开始减速"。太大 = 太晚减速(不安全);
# 太小 = 太早减速(过度保守)。需要按动力学整定。
pass
Step 4:CBF 过滤 vs MPC 硬约束 vs MARL 奖励 三种安全机制对比
# === 三种"安全"机制的对比 ===
#
# | 机制 | 保证强度 | 时域 | 计算量 | 可扩展性(N) |
# |--------------|---------------|----------|-----------|-----------|
# | MARL 奖励惩罚 | 软(期望意义) | — | 训练期 | 好但无保证 |
# | MPC 硬约束 | 硬(但有限时域)| 未来 H 步 | 大(全局QP) | 差(N² 约束)|
# | CBF-QP 过滤 | 硬(无限时域) | 逐时刻+前向不变| 极小(局部QP)| 极好(分布式)|
#
# 关键差异:
# - MARL:碰撞概率 > 0,OOD 时飙升 —— 不能单独用于安全关键
# - MPC :只保证 H 步内,且 N² 约束让全局 QP 爆炸
# - CBF :前向不变性保证"永远"安全,每 agent 独立小 QP,天然分布式
#
# 工程实践:三者叠加用——MARL 出高层(性能),MPC 出参考(执行),
# CBF 做最后一道硬安全门(保证)。各管一段,互不替代。
GCBF+:用 GNN 把安全过滤扩展到上千 agent¶
pairwise CBF 过滤有一个隐患:手工 CBF 在密集场景下会过度保守甚至 infeasible。当一个 agent 被很多邻居包围时,各 pairwise 约束可能互相冲突(往左躲 A 就撞 B,往右躲 B 就撞 A),QP 无解。手工设计一个能协调所有邻居、永远可行的 CBF,对大 \(N\) 几乎不可能。
GCBF+ 的解法是**学一个 CBF**。它用 GNN 把"agent 的安全值"参数化为其局部邻居图的函数:
为什么 GNN 是天作之合?因为多智能体安全问题有两个结构性质,恰好是 GNN 的强项:
| 性质 | 含义 | GNN 为何匹配 |
|---|---|---|
| 置换等变性 | agent 的安全不依赖它们的编号顺序 | GNN 的消息传递天然置换等变 |
| 邻居数不变性 | 同一个 CBF 要能处理"3 个邻居"和"30 个邻居" | GNN 的聚合(aggregation)对邻居数不敏感 |
| 局部性 | agent 的安全只依赖近邻 | GNN 的有限跳消息传递 = 局部感受野 |
GCBF+ 的训练损失同时优化"CBF 的有效性"(违反时惩罚)和"CBF 条件的满足":
部署时,每个 agent 用学到的 \(h_\theta\) 跑一个本地 CBF-QP(和上面的 pairwise 过滤同构,只是 \(h\) 从手工公式换成 GNN 输出)。GCBF+ 的关键工程亮点:
- 可扩展:在 256 agent 上比手工 CBF 好 20%,在 1024 agent(Crazyflie 仿真)上比纯 RL 好 40%;
- 接受原始感知:直接吃 LiDAR 点云,不需要理想的邻居状态估计(这对真机至关重要——真机没有上帝视角);
- 考虑执行约束:用 look-ahead 机制把 actuator 限制(力矩饱和)纳入 CBF 训练,避免学出"理论安全但执行不了"的 CBF。
本质洞察:GCBF+ 把 CBF 从"手工设计的安全证书"变成"学习得到的安全证书",但**它学的不是策略,而是约束**——这是它和纯 RL 的根本区别。纯 RL 学一个"倾向于安全的策略"(软),GCBF+ 学一个"定义安全集边界的函数"(硬,因为部署时仍用 QP 强制满足 CBF 条件)。所以 GCBF+ 既有学习的可扩展性(GNN 处理任意 N),又有 CBF 的硬保证(QP 投影)。它站在"学习"和"模型"的交叉点上,是混合范式在安全维度的最佳代表。当然,由于 \(h_\theta\) 是学出来的,它的安全保证是**概率性**的(依赖训练覆盖),如何走向 formal certification 仍是开放问题——这是它诚实的局限。
一个关键的工程权衡:过滤的"保守性"¶
安全过滤不是没有代价的——它有一个根本的权衡轴:保守性(conservativeness)vs 任务性能。\(\alpha\) 函数和安全半径 \(r\) 的选择直接控制这个权衡:
- \(\alpha\) 小 / \(r\) 大 → 过滤器**保守**:很早就开始减速避让,绝对安全但任务效率低(机器人畏首畏尾,在密集场景里可能完全卡死)。
- \(\alpha\) 大 / \(r\) 小 → 过滤器**激进**:贴近边界才修正,任务效率高但容错小(一旦模型误差/延迟稍大就可能越界)。
这个权衡没有免费午餐,但混合架构提供了一个缓解思路:让 GCBF+ 这类学习式 CBF 自动找到比手工 CBF 更不保守的安全边界——这正是 GCBF+ "比手工 CBF 好 20%"的来源。手工 CBF 为了保证可行性往往把安全集划得过大(过保守),学习式 CBF 能学到一个"刚好够安全又不过分保守"的紧致边界。
⚠️ 常见陷阱¶
陷阱 1(概念误区):对二阶/三阶系统用一阶 CBF,过滤器形同虚设 - 错误做法:机器人是力控/加速度控制(二阶动力学),却用一阶 CBF 不等式 \(\dot h \ge -\alpha h\) 直接约束控制。 - 现象/后果:\(\dot h\) 里根本不含控制 \(u\),约束对 \(u\) 不起作用,过滤器"通过"了所有控制,碰撞照常发生——而你以为有安全保护。 - 根本原因:没检查 CBF 的相对度。当 \(h\) 是位置函数、\(u\) 是加速度/力时,相对度 ≥ 2,\(\dot h\) 不显含 \(u\),一阶 CBF 失效。 - 正确做法:先确定相对度(\(h\) 对 \(u\) 求几次导才出现 \(u\)),相对度 ≥ 2 时必须用 HOCBF,构造嵌套函数链 \(\psi_0,\psi_1,\dots\) 直到显含 \(u\)(见 Step 2 代码)。
陷阱 2(编程陷阱):QP infeasible 时退回名义控制,在最危险时刻关闭保护
- 错误做法:CBF-QP 求解失败时,return u_nom(用未过滤的名义控制)。
- 现象/后果:QP infeasible 通常恰好发生在多个约束冲突的"危险密集逼近"时刻,此时退回 u_nom 等于在最该保护的瞬间撤掉保护,几乎必撞。
- 根本原因:把 infeasible 当成"无约束"处理,方向完全反了——infeasible 意味着"找不到安全控制",应该触发最保守的安全行为,而非放弃安全。
- 正确做法:QP infeasible 时降级到保守安全动作——零加速度、最大减速、或原地悬停/急停。宁可任务失败,不可安全失守。更进一步可用软约束 CBF(加松弛变量)保证 QP 始终可行,但松弛要带巨大惩罚。
陷阱 3(思维陷阱):以为安全过滤可以完全替代上层的安全意识 - 错误做法:因为有了 CBF 过滤层,就让 MARL 完全不管安全(奖励里去掉所有碰撞惩罚),认为"反正过滤器会兜底"。 - 现象/后果:MARL 学出极度激进的策略(总是把控制顶到极限,反正过滤器会拉回来),导致过滤器持续满负荷工作、频繁触及边界,系统在安全边缘反复横跳,效率极低且对模型误差极敏感。 - 根本原因:安全过滤保证的是"不越界",但不保证"行为优雅"。如果上层完全不考虑安全,过滤器会被迫做大量剧烈修正,破坏任务性能,且把系统推到安全裕度的最边缘(最脆弱处)。 - 正确做法:上层(MARL)仍应保留**温和的**安全意识(适度的碰撞惩罚,让策略"大致避让"),过滤器只做"最后一道硬保证"。两者配合——上层负责"通常安全且高效",过滤器负责"绝对不越界"。这样过滤器大部分时间透明(零修正),只在极端情况下介入。
陷阱 4(概念误区):忽略 CBF 与名义控制器目标的潜在冲突导致"卡死") - 错误做法:CBF 过滤只看安全,名义控制只看任务,两者方向持续相反时不做任何协调。 - 现象/后果:机器人卡在某处来回微动(deadlock / livelock)——名义控制要往前(去目标),CBF 要往后(避障),合力为零,永远到不了目标。 - 根本原因:CBF 保证安全(前向不变性),但**不保证活性(liveness,即任务能完成)**。安全和活性是两个独立的性质,CBF 只管前者。 - 正确做法:意识到 CBF 过滤可能引入死锁,需要上层(MARL/规划)提供"绕行"的高层决策来打破对称(这正是 §13.2 让 MARL 做高层协调的价值之一——它能学会"谁让谁"来避免死锁);或在 CBF 设计中引入旋转分量/优先级打破对称。
练习¶
-
【实现题】 基于本节的
pairwise_cbf_filter,为 3 个 2D 双积分器实现完整的碰撞避免仿真:3 个 agent 初始在等边三角形顶点,名义控制让每个 agent 直奔对面顶点(必然交叉于中心)。用 CBF 过滤后运行仿真,验证:(a) 任意时刻任意两 agent 距离 ≥ 2r;(b) 画出 \(\min_{i\ne j}\|p_i-p_j\|\) 随时间的曲线,确认它始终 ≥ 2r 且在交汇时刻"贴着"2r(说明过滤是最小修正)。然后做对比实验:去掉 CBF 过滤,确认 agent 在中心相撞。 -
【调试挑战】 给你一段有 bug 的 HOCBF 代码,现象是"agent 总是冲到离障碍极近(几乎贴上)才急刹,偶尔来不及就撞了"。已知代码逻辑结构正确。请你判断最可能的 bug 在哪(提示:从本节陷阱 3 关于 \(\alpha\) 的讨论想),并说明 \(\alpha_1, \alpha_2\) 应该往哪个方向调、调整背后的物理含义是什么(\(\alpha\) 如何控制"多早开始减速")。
-
【设计扩展 + 跨章综合】 综合本章 §13.2(分层架构)、§13.4(CBF 过滤)和第 3 章(MAPF)的知识,为"10 台 AGV 在仓库里执行终身取送货(lifelong pickup-and-delivery)"设计一套**两级安全**方案:(a) 离散级——用第 3 章的 MAPF/优先级规划做无碰撞的全局路径(粗粒度、离散时空);(b) 连续级——用本节的 CBF 过滤处理"离散计划无法覆盖的连续执行误差和动态障碍"(细粒度、逐时刻)。请说明这两级各自保证什么、为什么需要两级(提示:离散 MAPF 假设"同步、单位步、点机器人",真机违反这些假设时谁来兜底),以及 MARL 在这套方案里可以承担什么角色。
§13.5 残差强化学习:在可信基线上学修正 ⭐⭐⭐⭐¶
这一节解决什么问题:§13.2-13.4 讲的是"纵向分层"和"安全过滤"两种混合形态——它们都把 RL 和模型放在**不同的层/模块**。这一节讲第三种、也是哲学上最优雅的混合形态——残差强化学习(residual RL):不分层,而是让传统控制器和 RL 在**同一个控制空间里叠加**,控制器出一个可信的基线 \(u_{\text{base}}\),RL 只学一个修正量 \(u_{\text{res}}\)。本节讲清为什么"只学修正"能带来样本效率和安全性的双赢,并能在一个 MPC/PD 基线上叠加残差策略。这是 ⭐⭐⭐⭐ 的硬核小节。
动机:从零学 vs 站在巨人肩上¶
设想你要训一个 RL 策略让机械臂精确插孔(peg-in-hole),或让四足在不平地面稳定行走。纯 RL 的做法是**从零开始**——策略初始时是随机的,机械臂一开始会乱挥、四足会立刻摔倒,要经过几百万步试错才能学会基本的站立/移动,再慢慢精进到任务完成。
这有两个致命问题:(1) 样本效率极低——大量样本浪费在学习"如何不摔倒"这种早就被经典控制解决了的基础能力上;(2) 训练初期极度危险——随机策略在真机上就是灾难,几乎只能在仿真里训,又带回 sim-to-real gap。
但是——我们明明已经有一个还不错的控制器了! 四足有成熟的 MPC/步态控制器(能走,只是地形适应性差一点),机械臂有阻抗控制器(能大致对准,只是精细力控差一点)。这些经典控制器解决了 90% 的问题,只在最后 10%(未建模的接触、复杂地形、精细力控)上力不从心。
残差 RL 的核心洞察就是:与其让 RL 从零学那 100%,不如让它站在经典控制器的肩膀上,只学那缺失的 10%。 控制器出基线 \(u_{\text{base}}\)(搞定 90%),RL 学残差 \(u_{\text{res}}\)(补足 10%),最终控制 \(u = u_{\text{base}} + u_{\text{res}}\)。
本质洞察:残差 RL 体现了一种深刻的工程哲学——不要丢弃已有的、可信的知识,而要在它之上增量学习。经典控制器是几十年控制论积累的"先验知识",它虽不完美但极其可靠。从零训 RL 等于假装这些知识不存在、让神经网络从随机权重重新发现它们——这是巨大的浪费和风险。残差 RL 把"已知的可靠部分"交给控制器、把"未知的困难部分"交给学习,让两者各自做最擅长的事。这和 §13.1 解耦原理一脉相承,只是这次的切分维度是"已知 vs 未知"、"可靠基础 vs 困难修正",且切分发生在**同一个控制空间的叠加**上,而非不同的层。
如果从零训练 RL 会怎样¶
让我们具体看"从零训"相比"残差"差在哪,理解残差的价值。
差距一:样本效率差一个数量级。 残差 RL 的探索是围绕一个**已经不错的基线**展开的——策略初始时残差为零(或接近零),系统行为就是基线控制器的行为(已经能完成大部分任务)。RL 只需在这个"good enough"的起点附近做小幅探索去优化最后那点性能。而从零训练的探索是在整个动作空间里盲目游荡,绝大部分探索都撞在"完全不可行"的区域。Johannink 等(2017)的实验显示残差 RL 在多个操作任务上样本效率比从零训提升数倍到一个数量级。
差距二:训练全程的安全性。 残差 RL 通常对残差做**幅值限制**(\(\|u_{\text{res}}\| \le u_{\text{res}}^{\max}\))——这意味着无论 RL 学成什么样,最终控制都不会偏离基线控制器太远。如果基线控制器是安全的(比如一个保守的 MPC),那么"基线 + 有界残差"也大致安全。这给了残差 RL 一个"安全性下界":它的最坏情况不会比基线差太多。而从零训练没有这个保护——随机策略可以输出任意灾难性动作。
差距三:可解释性与可调试性。 残差 RL 的输出可以分解为"基线贡献 + 学习贡献",你能清楚看到 RL 到底在每个状态修正了多少、往哪个方向修正。这比纯黑盒策略可解释得多——如果出问题,你能判断是基线的锅还是残差的锅。
历史:残差学习的思想脉络¶
"残差"这个思想在机器学习里有深厚根基。最著名的是 ResNet(残差网络,2015)——它让网络层学习"相对于恒等映射的残差" \(F(x) = H(x) - x\) 而非直接学 \(H(x)\),因为学"偏离恒等的修正"比学"完整映射"容易得多(当最优映射接近恒等时,残差接近零,极易学)。
残差 RL(Johannink 等,2017;Silver 等同期)把这个思想搬到控制:让 RL 学"相对于基线控制器的修正"而非完整控制策略。其数学动机和 ResNet 完全一致——当基线控制器已经接近最优时,最优残差接近零,RL 极易学到。
这条线后来不断深化:基线从简单走向复杂。早期残差 RL 的基线是 P 控制器或手工策略(简单但弱);Residual MPC(2025)把基线升级为 GPU 并行的 MPC(强大且实时),RL 只补 MPC 模型误差导致的那点偏差;RL-Augmented MPC(2025)则用残差处理 MPC 难以建模的非周期步态、混合运动。主线是:基线越强,RL 要学的残差越小、越容易、越安全——但 RL 的价值也越聚焦于"模型真正搞不定的那一小部分"。
本质洞察:残差 RL 和 ResNet 的深层共性,是都在利用"最优解接近一个已知的好猜测"这个结构。ResNet 假设最优层映射接近恒等,残差 RL 假设最优控制接近基线控制器。在这个假设成立时,"学残差"把一个困难的学习问题(学完整映射/策略)转化成一个容易的学习问题(学一个接近零的小修正)。这也揭示了残差 RL 的适用边界——当基线控制器很差(离最优很远)时,残差就不"小"了,残差 RL 的优势会消失。所以残差 RL 的前提是"你已经有一个还不错的基线"。
理论:残差 RL 的公式化¶
残差 RL 的核心公式简洁到只有一行:
其中 \(u_{\text{base}}(x)\) 是固定的基线控制器(PD、阻抗控制、MPC 等,不参与训练),\(u_{\text{res}}^\theta(x)\) 是参数为 \(\theta\) 的 RL 策略输出的残差。RL 通过标准的策略梯度(PPO/SAC 等)优化 \(\theta\),奖励是任务奖励。
虽然公式简单,但有几个关键的设计点决定成败:
设计点一:残差的初始化与幅值约束。 训练初期残差应接近零(让系统从"纯基线行为"出发),通常通过**初始化策略网络最后一层权重为接近零**实现。同时对残差做幅值限制 \(u_{\text{res}} \in [-u_{\text{res}}^{\max}, u_{\text{res}}^{\max}]\)(通过 tanh 激活 + 缩放),这个上限控制"RL 能在多大程度上偏离基线"——上限越小越安全(越贴近基线)但修正能力越弱,上限越大修正能力越强但安全性下界越松。这是残差 RL 最重要的超参数。
设计点二:残差作用的空间。 残差可以加在不同的控制语义上——加在力矩上(最底层)、加在 MPC 的参考上(中层)、加在目标位置上(高层)。加得越底层,RL 的修正越直接但越需要承受动力学 gap;加得越高层,越抽象但修正越间接。这又回到 §13.3 接口设计的逻辑。
设计点三:基线是否随状态切换。 高级用法里基线本身可以是状态相关的(不同地形用不同步态基线),RL 残差在所有基线之上统一学修正。
残差 RL 的"安全性下界":设基线控制器在所有状态下满足某个安全性质 \(S\)(比如"输出有界、不会发散"),残差幅值限制为 \(\|u_{\text{res}}\|\le \rho\)。则总控制 \(u=u_{\text{base}}+u_{\text{res}}\) 满足"偏离基线不超过 \(\rho\)"。如果基线的安全裕度大于 \(\rho\)(即基线"离危险还有 \(\rho\) 以上的余量"),则残差 RL 全程不会越过安全边界。这是一个**可量化的安全下界**——它把"RL 的不可控性"限制在一个由 \(\rho\) 控制的小邻域内。这正是残差 RL 比纯 RL 安全的数学根据。
把这个下界和 \(\rho\) 的选择联系起来,看一个具体直觉:假设基线 MPC 输出的力矩总在执行器极限 \(\tau_{\max}=10\) N·m 内,且留有 2 N·m 的裕度(即基线最多用到 8 N·m)。若把残差限幅设为 \(\rho = 2\) N·m,则总力矩 \(\le 8 + 2 = 10 = \tau_{\max}\)——残差恰好"吃掉"裕度但不超限,安全下界成立。若贪心地把 \(\rho\) 设成 5 N·m(想要更强的修正能力),则总力矩可能到 \(8+5=13 > \tau_{\max}\),残差能把系统推出执行器极限(饱和、失稳)——安全下界被打破。这就是为什么 \(\rho\) 必须**按基线的实际裕度来定**,而非越大越好:\(\rho\) 是"借给 RL 的自由度额度",借出去的不能超过基线攒下的安全余量。这也解释了一个反直觉的现象——基线越保守(裕度越大),能安全分配给残差的额度 \(\rho\) 反而越大,RL 的修正空间越大。保守的基线和强力的残差,在安全下界这个约束下是相互成全的。
理论-工程桥接:在 PD/MPC 基线上叠加残差策略¶
下面用代码实现残差 RL 的核心结构。遵循 R8 四步法。
Step 1:为什么要这样写?
为什么残差策略要初始化成"输出接近零",且要限制残差幅值?
初始接近零:训练第一步,残差≈0 → 总控制 u ≈ u_base → 系统行为就是
基线控制器的行为(已经能完成大部分任务、且安全)。RL 从这个"好起点"
开始小幅探索,而不是从"随机乱动"开始。如果残差初始很大,第一步就把
系统踹到混乱状态,等于丢掉了基线的全部价值。
限制幅值:u = u_base + clip(u_res, -ρ, ρ)。这保证无论 RL 学成什么样,
总控制偏离基线不超过 ρ。只要基线安全裕度 > ρ,系统全程安全。
ρ 是安全性和修正能力的权衡旋钮:小ρ=更安全但修正弱,大ρ=修正强但
安全下界松。
规则:基线管"可靠的大头",残差管"困难的小头",且残差要"小且有界"。
Step 2:正确写法
import torch
import torch.nn as nn
import numpy as np
class ResidualPolicy(nn.Module):
"""残差策略:输出一个【小且有界】的修正量,叠加在基线控制器上。"""
def __init__(self, obs_dim, act_dim, res_max, hidden=256):
super().__init__()
self.res_max = res_max # 残差幅值上限 ρ(安全性下界的关键)
self.net = nn.Sequential(
nn.Linear(obs_dim, hidden), nn.ELU(),
nn.Linear(hidden, hidden), nn.ELU(),
nn.Linear(hidden, act_dim),
)
# 关键:最后一层权重初始化为接近零 → 初始残差≈0 → 初始行为=基线
nn.init.uniform_(self.net[-1].weight, -1e-3, 1e-3)
nn.init.zeros_(self.net[-1].bias)
def forward(self, obs):
raw = self.net(obs)
# tanh 限幅到 [-res_max, res_max]:保证残差有界(安全性下界)
u_res = self.res_max * torch.tanh(raw)
return u_res
class ResidualController:
"""残差控制器:u = u_base(x) + u_res^θ(x)。
基线 u_base 可以是 PD、阻抗控制、或 MPC——它不参与训练,
提供可靠的"大头"控制 + 安全裕度。RL 只学残差"小头"。
"""
def __init__(self, baseline_fn, residual_policy: ResidualPolicy):
self.baseline = baseline_fn # 固定的基线控制器(不训练)
self.policy = residual_policy # 可训练的残差策略
def act(self, obs, state):
u_base = self.baseline(state) # 基线贡献(可靠的大头)
with torch.no_grad():
u_res = self.policy(torch.as_tensor(obs, dtype=torch.float32))
u = u_base + u_res.numpy() # 叠加:基线 + 残差
return u, u_base, u_res.numpy() # 返回分解,便于可解释/调试
# 示例基线:一个简单的 PD 控制器(也可换成 MPC.solve(state))
def pd_baseline(state, kp=20.0, kd=2.0, target=None):
"""PD 基线:搞定'大致跟踪目标'这个 90% 的活。"""
if target is None:
target = np.zeros(3)
pos, vel = state['pos'], state['vel']
return kp * (target - pos) - kd * vel # 经典 PD 力
# 训练时的关键:奖励只看任务,残差的"小且有界"由结构保证
def compute_reward(state, task_done, u_res):
r_task = 10.0 if task_done else -0.01 * np.linalg.norm(state['pos_err'])
# 可选:轻微惩罚大残差,鼓励"能用基线就用基线"(让 RL 只在必要时介入)
r_res_penalty = -0.001 * np.linalg.norm(u_res) ** 2
return r_task + r_res_penalty
Step 3:错误写法及为什么错
# ❌ 错误 1:残差策略最后一层随机初始化(破坏"从基线出发")
class BadResidual_RandomInit(nn.Module):
def __init__(self, obs_dim, act_dim):
super().__init__()
self.net = nn.Sequential(nn.Linear(obs_dim, 256), nn.ELU(),
nn.Linear(256, act_dim))
# 没有把最后一层初始化为接近零!
# 问题:训练第一步残差就很大 → u = u_base + (大残差) → 系统行为
# 完全不是基线行为,而是被一个随机大残差推到混乱状态。
# 丢掉了基线的全部价值,退化成"带偏置的从零训练"。
# ❌ 错误 2:残差不限幅(丢掉安全性下界)
class BadResidual_NoClip(nn.Module):
def forward(self, obs):
return self.net(obs) # 直接输出,无 tanh 限幅
# 问题:残差可以无界增长,u = u_base + (任意大残差) 可以偏离基线
# 任意远 → 基线的安全裕度被突破,残差 RL 退化成不安全的纯 RL。
# 必须用 tanh*res_max 把残差锁在安全邻域内。
# ❌ 错误 3:把基线也加进训练(基线参数被 RL 梯度污染)
class BadResidual_TrainableBaseline:
def __init__(self, baseline_net, residual_net):
# 把 baseline_net 的参数也放进优化器!
self.opt = torch.optim.Adam(
list(baseline_net.parameters()) + list(residual_net.parameters()))
# 问题:基线的价值在于它"可信、固定、有保证"。一旦让 RL 梯度去改
# 基线参数,基线就不再可信了——它会被 RL 往"高奖励但可能不安全"
# 的方向带偏,残差 RL 退化成纯 RL,丢掉安全性下界。
# 基线必须冻结(detach / 不放进优化器)。
# ❌ 错误 4:基线太弱(残差不"小",优势消失)
def bad_too_weak_baseline(state):
return np.zeros(3) # 基线恒为零(等于没有基线)
# 问题:基线 u_base=0 时,u = 0 + u_res = u_res,完全退化成从零训练。
# 残差 RL 的前提是"基线已经不错",残差才"小且易学"。基线太弱时
# 残差要承担全部控制,既不小也不易学,优势荡然无存。
Step 4:残差 RL vs 分层混合 vs 安全过滤 三种形态的对比
# === 三种混合形态的对比(同一个解耦原理的三种切法)===
#
# | 形态 | 切分维度 | RL 的角色 | 模型的角色 | 安全机制 |
# |------------|-------------|----------------|---------------|---------------|
# | 分层混合 | 抽象层次(上/下)| 高层决策(出命令) | 底层执行(MPC) | 另加 CBF 层 |
# | 安全过滤 | 职能(决策/安全)| 名义动作 | 安全证书(CBF) | CBF-QP 硬保证 |
# | 残差学习 | 贡献(基础/修正)| 学修正(小残差) | 基线(大头) | 残差限幅+基线裕度|
#
# 何时用哪个:
# - 任务有清晰的"高层决策 vs 底层执行"分界 → 分层混合(编队/导航)
# - 已有不错的控制器,只想补"模型搞不定的一点" → 残差学习(精细操作/腿足)
# - 核心诉求是"绝对不越界的硬安全" → 安全过滤(碰撞避免/安全关键)
#
# 三者可组合:分层混合的底层 MPC 上叠残差 RL(补模型误差),
# 最后再过一道 CBF 过滤(兜底硬安全)—— 成熟系统常如此。
残差 RL 在多机器人场景的特殊价值¶
前面的讨论以单机为主,但残差 RL 在**多机器人**场景有额外的独特价值——这正是本章关心的。
价值一:多体交互的"残差"恰是难建模的部分。 单机控制器(MPC)对单个机器人的动力学建模很准,但它**看不见、也难以建模其他机器人对自己的真实影响**(气流耦合、协同搬运时的力交互、密集编队的尾流)。这些"多体交互残差"恰恰是单机 MPC 的盲区,而 MARL 残差能从多机交互数据中学到它。于是结构变成:每台机器人用单机 MPC 作基线(搞定自身动力学),用一个 MARL 残差策略补"多体交互"那部分——基线管"我自己怎么动",残差管"考虑到队友我该怎么微调"。
价值二:残差天然继承单机控制器的成熟度。 多机器人系统的单机控制(足式 MPC、无人机几何控制)往往已经非常成熟。从零训一个多机策略等于把这些成熟成果全扔掉重学。残差 RL 让你复用每台机器人成熟的单机控制器,只在多机协同层面增量学习——工程上务实得多。
价值三:残差限幅提供多机安全的一层保障。 多机场景一个 agent 的异常会传染。残差限幅保证每台机器人都不会偏离其单机基线太远,从而限制了"单点异常"的幅度,配合 §13.4 的 CBF 过滤形成双重保障。
本质洞察:在多机器人场景,残差 RL 和分层混合其实可以"合体"——把分层混合底层的单机 MPC 当作残差 RL 的基线,让 MARL 同时承担两个角色:在高层出协调命令(分层混合的 RL 角色),在底层出多体交互残差(残差 RL 的 RL 角色)。这揭示了一个重要事实:三种混合形态不是非此即彼的菜单,而是可以沿不同维度同时切分、叠加使用的正交技巧。一个成熟的多机器人混合系统,往往同时是"分层的 + 残差的 + 带安全过滤的"——这正是 §13.6 选型框架要帮你组织的。
⚠️ 常见陷阱¶
陷阱 1(编程陷阱):残差策略最后一层随机初始化,第一步就破坏基线
- 错误做法:残差策略网络用默认随机初始化,训练初期残差幅值很大。
- 现象/后果:训练第一步系统行为就完全偏离基线(被一个随机大残差推到混乱状态),残差 RL 退化成"带一个固定偏置的从零训练",丢掉了基线的全部样本效率和安全优势。
- 根本原因:残差 RL 的核心前提是"从基线行为出发,小幅探索"。残差初始必须接近零,系统初始行为才等于基线行为。随机初始化破坏了这个前提。
- 正确做法:把残差策略网络**最后一层**的权重初始化为接近零(如 uniform(-1e-3, 1e-3))、偏置为零。这样训练第一步残差≈0,系统从纯基线行为开始演化。
陷阱 2(思维陷阱):残差不限幅,退化成不安全的纯 RL
- 错误做法:残差策略直接输出无界的修正量,不做幅值限制。
- 现象/后果:残差可以无限增长,总控制偏离基线任意远,基线的安全裕度被突破,残差 RL 失去"安全性下界",和纯 RL 一样不安全。
- 根本原因:残差 RL 的安全性来自"总控制不会偏离可信基线太远"。这个"太远"必须用残差幅值上限 \(\rho\) 显式约束。不限幅 = 放弃这个保证。
- 正确做法:用 tanh 激活 × res_max 把残差锁在 \([-\rho,\rho]\) 内。\(\rho\) 按"基线安全裕度"来定——确保基线裕度 > \(\rho\),则系统全程不越界。\(\rho\) 是安全性和修正能力的核心权衡旋钮。
陷阱 3(概念误区):把基线控制器也加进训练,污染其可信性
- 错误做法:为了"让基线也变得更好",把基线控制器的参数也放进优化器一起训。
- 现象/后果:基线被 RL 梯度往"高奖励"方向带偏,可能牺牲它原本的安全/稳定保证,残差 RL 退化成纯 RL,丢掉安全性下界。
- 根本原因:基线的全部价值在于它"可信、固定、有理论保证"。它是残差 RL 的"安全锚点"。一旦让它可训练,锚点就漂移了,整个安全论证失效。
- 正确做法:基线控制器必须**冻结**(参数不放进优化器,或对其输出 detach)。只训练残差策略。如果确实想改进基线,应该在 RL 之外用控制论方法单独改进,改完再冻结。
练习¶
-
【实现题】 实现一个完整的残差 RL 训练循环(可用 SAC 或 PPO),任务是"2D 点质量精确到达目标",基线是一个**故意调得偏弱**的 PD 控制器(增益偏低,会有稳态误差和缓慢响应)。验证:(a) 训练初期(残差≈0)系统行为就是 PD 基线行为;(b) 训练后残差学会补偿 PD 的稳态误差和响应迟缓;(c) 画出"基线贡献 \(u_{\text{base}}\)"和"残差贡献 \(u_{\text{res}}\)"随训练进程的幅值变化,观察残差如何从零增长到补足基线的不足。
-
【对比实验】 用同一个任务和同一个 RL 算法,对比"从零训练"(基线恒为零)vs "残差 RL"(PD 基线)的样本效率:画出两者的"奖励 vs 训练步数"曲线。然后做一个关键的消融——把残差 RL 的基线从"还不错的 PD"换成"很差的 PD"(增益极低),观察残差 RL 的优势如何随基线质量下降而消失。这道题让你亲手验证本节的本质洞察:"残差 RL 的优势依赖基线质量"。
-
【设计扩展 + 跨章综合】 综合本章 §13.3(接口)、§13.5(残差)和第 4-5 章(MPC),为"4 架无人机密集编队穿越障碍"设计一个**分层 + 残差**的混合控制器:(a) 每架无人机用单机几何控制/MPC 作基线(搞定自身飞行);(b) 一个 MARL 策略同时输出"高层编队命令"(§13.3 接口)和"底层多体交互残差"(§13.5,补气流耦合)。请画出数据流图,明确 MARL 的两个输出分别加在哪里、为什么"多体交互"适合用残差而"编队决策"适合用分层命令。再说明你会如何用 §13.4 的 CBF 过滤给这个系统兜底硬安全。
§13.6 Safe MARL 与三范式对比收口 ⭐⭐⭐¶
这一节解决什么问题:前面三节给了三种把"安全/模型"缝进 RL 的工程形态。这一节做两件收尾的事:(1) 从**学习目标本身**的角度,讲清如何把"安全"写进 MARL 的优化问题——约束马尔可夫博弈(Constrained Markov Game, CMG)+ Lagrangian 松弛,这是和"安全过滤"互补的另一条安全路线("训练时就让策略学会约束" vs "部署时硬过滤");(2) 把纯 MARL、纯传统规控、混合三大范式收进一张对比表和一个选型决策框架——这是整个多机器人方向的**收口**。
动机:安全能不能"训"进策略里?¶
§13.4 的安全过滤是一种"外挂式"安全——策略该怎么训怎么训,部署时在外面套一个 CBF 过滤器兜底。这很有效,但有一个微妙的不足:策略本身从未"意识到"安全约束的存在,它学到的是"在没有约束的世界里最优"的策略,过滤器在外面"硬掰"它的输出。这会导致策略和过滤器持续"对抗"(策略想越界,过滤器拉回来),既损失性能又把系统推到安全边缘(§13.4 陷阱 3)。
一个互补的思路是:能不能在训练时就把安全约束告诉策略,让它学会"在约束下最优"? 这样策略本身就"知道"该避让,过滤器(如果还用的话)大部分时间无需介入。这就是 Safe MARL 的核心——把安全写进**优化目标的约束**,而不是事后过滤。
注意这和 §13.1 "安全必须是约束而非目标项"的洞察一脉相承——只不过这次的"约束"作用在**训练优化**上(让策略学会满足期望意义的约束),而 §13.4 的"约束"作用在**逐时刻执行**上(硬保证)。两者是安全的两个层次,互补而非替代。
如果安全只靠"奖励惩罚"会怎样¶
我们在 §13.1 已经论证过纯奖励惩罚的根本缺陷(软、概率非零、调参打架)。这里从"约束优化"的视角再深化一层,理解为什么"约束公式化"比"惩罚公式化"更好。
把安全写成奖励里的惩罚项 \(r = r_{\text{task}} - \lambda \cdot c_{\text{safety}}\),\(\lambda\) 是手工权重。问题在于 \(\lambda\) 是**固定的、手调的**:
- \(\lambda\) 太小 → 策略为了任务奖励牺牲安全(碰撞频繁);
- \(\lambda\) 太大 → 策略过度保守(为躲一切风险而不完成任务),且训练不稳定;
- 更糟的是没有"正确的 \(\lambda\)"——不同任务阶段、不同状态需要的安全-性能权衡不同,一个固定 \(\lambda\) 无法适应。
约束公式化的精妙在于:它让 \(\lambda\)(现在叫 Lagrangian 乘子 \(\mu\))自动、自适应地调整——当策略违反安全约束时 \(\mu\) 自动增大(更重视安全),当策略安全裕度充足时 \(\mu\) 自动减小(更重视性能)。这把"手调一个固定权重"变成"自动求解一个约束优化",从根本上解决了 \(\lambda\) 选择难题。
历史:从 CMDP 到约束马尔可夫博弈¶
约束强化学习的理论根基是**约束马尔可夫决策过程(Constrained Markov Decision Process, CMDP)(Altman, 1999)——在标准 MDP 上加一个"累积代价的期望 ≤ 阈值"的约束。求解 CMDP 的主流方法是 **Lagrangian 松弛(把约束用乘子吸进目标)和 CPO(Constrained Policy Optimization, 2017)(在信赖域内保证每步更新都满足约束)。
把 CMDP 推广到多智能体,就得到**约束马尔可夫博弈(Constrained Markov Game, CMG)——每个 agent 既要最大化自己的累积奖励,又要满足自己的累积安全代价约束。Jose & Zhang(2025)的双四足协同搬运工作就是把任务公式化为 CMG,用 **HAPPO + Lagrangian 求解,并对安全代价做**分解**(碰撞代价 + 翻转代价 + 关节限位违反分别约束)。这条线和 GCBF+(安全过滤一侧)、residual RL(残差一侧)在 2024-2025 年汇成了"Safe MARL"这个活跃方向。
理论:约束马尔可夫博弈与 Lagrangian 松弛¶
我们正式写出 CMG 并推导 Lagrangian 求解(R1 要求展示推导)。回顾标准 MARL 的目标——每个 agent \(i\) 最大化期望累积折扣奖励:
CMG 在此基础上加一个**安全约束**——每个 agent 的期望累积安全代价不超过阈值 \(\delta\):
其中安全代价 \(c_{i,t}\) 是可分解的(这是工程上的关键设计):
为什么用约束而非惩罚? 约束 \(J^{\text{cost}}\le\delta\) 直接表达了"我能容忍多少不安全"(\(\delta\) 有清晰的物理含义——比如"期望碰撞代价不超过 0.01"),而惩罚权重 \(\lambda\) 没有这种直接含义。\(\delta\) 是可解释、可设定的;\(\lambda\) 是需要试凑的。
Lagrangian 松弛求解:把约束用乘子 \(\mu \ge 0\) 吸进目标,构造 Lagrangian:
这变成一个 min-max(鞍点)问题:\(\max_\theta \min_{\mu\ge 0} \mathcal{L}\)。用**原始-对偶(primal-dual)**交替优化求解:
逐行理解这个更新(R1 每步解释为什么):
- 策略更新:用 HAPPO(异构 agent 序贯更新)优化一个**组合优势** \(A^{\text{reward}} - \mu A^{\text{cost}}\)——既追求奖励优势,又(被 \(\mu\) 加权地)压低代价优势。\(\mu\) 越大,策略越重视降低安全代价。
- 乘子更新:\(\mu\) 朝"约束违反量" \(J^{\text{cost}}-\delta\) 的方向走。如果当前策略**违反**约束(\(J^{\text{cost}}>\delta\)),\(\mu\) 增大→下一步策略更重视安全;如果**满足**约束(\(J^{\text{cost}}<\delta\)),\(\mu\) 减小→下一步策略可以更重视性能。\(\max(0,\cdot)\) 保证 \(\mu\ge 0\)(不等式约束的乘子非负)。
本质洞察:Lagrangian 乘子 \(\mu\) 的自适应更新,本质上是一个**自动的安全-性能权衡控制器**——它实时测量"当前策略离安全约束有多远",并据此动态调整对安全的重视程度。这正是它优于固定惩罚权重 \(\lambda\) 的根本原因:固定 \(\lambda\) 是"开环"地设定权衡,\(\mu\) 是"闭环"地调节权衡(用约束违反量做反馈)。把这个洞察和你学过的控制论联系起来——\(\mu\) 的更新就是一个积分控制器(integral controller),它积累"约束违反量"并据此调节,直到约束恰好满足(违反量为零)。安全约束优化和反馈控制在这里殊途同归。
两种安全语义的根本差异¶
现在我们能清晰地对比本章出现的两种安全机制了,它们有**根本不同的安全语义**:
| Safe MARL(CMG + Lagrangian) | 安全过滤(CBF-QP / GCBF+) | |
|---|---|---|
| 安全语义 | 期望意义(\(\mathbb{E}[\text{cost}]\le\delta\)) | 逐状态硬保证(每帧 \(h\ge 0\)) |
| 作用时机 | 训练时(策略学会约束) | 部署时(执行前过滤) |
| 保证强度 | 软(期望满足,单次仍可能违反) | 硬(前向不变性,永不违反) |
| 是否需运行时模块 | 否(约束已内化进策略) | 是(部署时 QP 必须在环) |
| 对模型的依赖 | 不需要动力学模型 | 需要 \(f,g\)(控制仿射模型) |
| 典型适用 | 安全偏好(少碰撞但非零容忍) | 安全关键(绝对不可碰撞) |
本质洞察:Safe MARL 和安全过滤不是竞争关系,而是**安全的两道防线**。Safe MARL 让策略"通常很安全"(期望意义,训练内化),把安全代价压到很低——这减轻了过滤器的负担;安全过滤做"绝对兜底"(逐状态硬保证,部署强制)——它接住 Safe MARL 漏掉的极端情况。最强的安全架构是**两者叠加**:用 Safe MARL 训出一个安全裕度很大的策略(让过滤器大部分时间透明),再用 CBF 过滤兜底(保证万无一失)。这呼应了 §13.5 末尾的洞察——成熟系统总是多种安全机制叠加,因为没有单一机制能同时做到"高性能 + 期望安全 + 硬保证"。
三大范式对比与选型框架(多机器人方向收口)¶
现在我们站到最高处,把整个多机器人方向学过的东西收口。面对一个真实的多机器人任务,你有三大范式可选——纯 MARL、纯传统规控、混合。下面这张总表是它们的"全身像":
| 维度 | 纯 MARL | 纯传统规控 | 混合(分层/过滤/残差) |
|---|---|---|---|
| 安全保证 | ✗ 软(概率非零) | ✓ 硬(CBF/MPC 约束) | ✓ 硬(CBF 过滤兜底) |
| 难建模决策 | ✓ 强(自动学习) | ✗ 弱(手工代价/规则) | ✓ 强(RL 出高层) |
| 样本效率 | ✗ 低(从零试错) | — 无需训练 | ◐ 中-高(残差/分层缩小学习面) |
| 可解释/可调试 | ✗ 黑盒 | ✓ 每步可查 | ◐ 中(底层可查,高层黑盒) |
| sim-to-real | ✗ 难(gap 弥漫全链) | ✓ 易(用真实模型) | ✓ 较易(gap 局部化到高层接口) |
| 可扩展性(N) | ◐ 中 | ✗ 差(N² 约束/联合爆炸) | ✓ 好(GCBF+/分布式 MPC) |
| 工程复杂度 | ◐ 中(训练管线) | ◐ 中(建模+调参) | ✗ 高(多模块+接口) |
| 典型场景 | 纯仿真、研究、难建模博弈 | 模型准确、单一任务、安全关键 | 真实多机器人系统(绝大多数) |
读这张表的关键结论:对绝大多数真实多机器人任务,混合是默认答案——因为真实任务几乎总是同时需要"硬安全保证 + 难建模决策能力 + sim-to-real 可迁移性 + 可扩展性",而只有混合能同时给出这四样。纯 MARL 和纯规控各自缺了其中一两样。混合的唯一代价是工程复杂度高(多模块、多接口)——这是为"兼得各家之长"付的工程税。
这一点在工业界已经成为共识,值得用一句反事实来锚定(R6B):如果某个团队声称用"纯端到端 MARL"解决了一个真实部署的安全关键多机器人任务,且没有任何模型化的安全层,那么大概率要么是任务其实不安全关键(碰一下没关系),要么是他们在某处偷偷藏了一个传统规控的兜底而没明说。原因正是前面反复论证的——纯 MARL 在数学上无法提供硬安全保证,这不是工程努力能弥补的,而是范式本身的边界。反过来,如果一个团队用"纯传统规控"做出了灵活的多机协调,那大概率是因为他们的"协调"其实很规整(能写成清晰的优化/规则),一旦任务的协调决策真正进入"难以解析建模"的开放领域,纯规控就会撞墙。所以"混合是默认"不是一句口号,而是由两种范式各自的数学边界**逼**出来的必然——这也是本章把 §13.1 的"两难"放在最前面讲的原因:理解了边界,选型就成了顺理成章的事。
选型决策框架:沿四个问题逐层判断,给你一个可操作的决策树:
问题 1:任务是否要求"硬安全保证"(一次违反就是灾难,如碰撞=硬件损毁)?
├─ 是 → 必须有安全层。排除"纯 MARL"。继续问 2。
└─ 否(软安全偏好即可,如游戏/仿真)→ 纯 MARL 可考虑。继续问 2。
问题 2:是否存在"难以解析建模的高层协调决策"(让行/编队重组/任务再分配)?
├─ 是 → 需要学习层。排除"纯传统规控"。→ 倾向【分层混合】(RL 出高层)。
└─ 否(决策能写成清晰优化/规则)→ 纯传统规控可能够用。继续问 3。
问题 3:是否已有一个"还不错的单机/基线控制器",只想补它的不足?
├─ 是 → 倾向【残差 RL】(在基线上学修正)。
└─ 否 → 看问 2 结论(分层混合 or 纯规控)。
问题 4:N 是否很大(几十到上千)且需要分布式安全?
├─ 是 → 安全层用【GCBF+】(GNN 参数化,可扩展);高层用分布式 MARL。
└─ 否(N 小)→ 安全层用手工 CBF-QP 即可;高层 MAPPO/HAPPO。
综合:真实系统的答案常常是"以上皆是"的组合——
分层混合(RL 高层 + MPC 底层)
+ 残差 RL(MPC 上叠多体交互残差)
+ 安全过滤(GCBF+ 兜底硬安全)
+ Safe MARL(训练时约束让策略学会安全)
各机制沿不同维度切分、叠加,各管一段。
本质洞察(全章收口):学完整个多机器人方向,最重要的一个认识是——没有银弹,只有组合。通信图、共识、任务分配、MAPF、编队、分布式 MPC、MARL、CBF……这些不是相互竞争的"流派",而是一个工具箱里互补的工具。一个真实的多机器人系统,是把这些工具沿"离散/连续"、"学习/模型"、"高层/底层"、"决策/安全"、"基础/修正"等多个正交维度切分、组装出来的。本章的混合范式,正是这个"组装"的方法论——它教你的不是某个具体算法,而是**如何判断每个工具的比较优势、如何沿正确的维度切分问题、如何设计模块间的接口**。这才是从"会用算法"到"会设计系统"的关键一跃。
⚠️ 常见陷阱¶
陷阱 1(概念误区):把 Safe MARL 的"期望安全"误当成"硬安全保证" - 错误做法:用 CMG + Lagrangian 训出一个满足 \(\mathbb{E}[\text{cost}]\le\delta\) 的策略,就认为它"安全了",直接上安全关键场景,不加任何运行时过滤。 - 现象/后果:期望意义的约束只保证"平均而言安全代价低",单条轨迹、单个时刻仍可能违反——在安全关键场景下偶发碰撞,硬件损毁。 - 根本原因:混淆了期望约束(\(\mathbb{E}[\cdot]\le\delta\),软)和逐状态硬约束(每帧 \(h\ge 0\),硬)。Lagrangian 求解的是前者,它从不保证后者。 - 正确做法:安全关键场景下,Safe MARL 只是"第一道防线"(让策略通常安全),必须再叠加 §13.4 的 CBF 过滤做"硬兜底"。两道防线缺一不可。
陷阱 2(思维陷阱):迷信"混合一定比纯方案好",过度工程化 - 错误做法:不管任务多简单,一律上"分层 + 残差 + CBF + Safe MARL"的全套混合,认为越复杂越先进。 - 现象/后果:对一个本可以用纯 MPC 干净解决的简单任务(如单机轨迹跟踪),堆了一大套混合架构,引入大量接口 bug、调试噩梦、维护成本,性能反而不如简单方案。 - 根本原因:没理解混合的代价是"工程复杂度"。混合的价值在于"任务确实同时需要多种范式的优势"——如果任务只需要一种范式,用纯方案更好。 - 正确做法:用选型决策框架诚实评估任务真正需要什么。如果任务模型准确、无难建模决策、N 小——纯传统规控就够了,别画蛇添足。复杂度要花在刀刃上:只为任务真正需要的能力引入对应的混合机制。
陷阱 3(编程陷阱):Lagrangian 乘子 \(\mu\) 学习率与策略学习率不匹配导致振荡 - 错误做法:\(\mu\) 的更新步长 \(\eta_\mu\) 设得和策略学习率同量级或更大。 - 现象/后果:\(\mu\) 剧烈震荡(约束一违反就猛增、一满足就猛降),导致策略在"过度保守"和"过度激进"之间反复横跳,训练不收敛。 - 根本原因:原始-对偶优化要求对偶变量(\(\mu\))更新比原始变量(\(\theta\))慢(时间尺度分离!又一次),让策略有时间在固定 \(\mu\) 下收敛,\(\mu\) 再缓慢调整。\(\eta_\mu\) 太大破坏了这个分离。 - 正确做法:\(\eta_\mu\) 通常比策略学习率小 1-2 个数量级,让 \(\mu\) 缓慢平滑地调整。这又是一次时间尺度分离的应用(和 §13.2 的分层频率、与 \(\mu\) 作为积分控制器的洞察一脉相承)——慢变量调节快变量的边界条件。
练习¶
-
【推导题】 从 CMG 的约束优化问题出发,自己完整推导一遍 Lagrangian 原始-对偶更新公式。然后回答:(a) 为什么 \(\mu\) 的更新方向是 \(J^{\text{cost}}-\delta\)(而不是 \(\delta - J^{\text{cost}}\))?(b) 为什么要 \(\max(0,\cdot)\)?(c) 把 \(\mu\) 的更新和"积分控制器"类比——它积分的是什么量、调节的是什么、稳态(收敛)时 \(\mu\) 和约束的关系是什么?
-
【选型实战】 给定下面三个真实任务,分别用本节的"选型决策框架"判断该用哪种(组合)范式,并完整说明你沿四个问题的判断过程:(a) 1000 架无人机的灯光秀编队(密集、需绝对不撞、队形复杂);(b) 单台机械臂在已知工件上的精密装配(模型准确、有成熟阻抗控制器、只差精细力控);(c) 5 台异构机器人在未知灾后环境的协同搜救(难建模决策多、动态障碍、需安全)。
-
【综合设计 + 全章串联】 这是本章的压轴综合题。请你为"8 台异构机器人(4 无人机 + 4 地面车)在动态仓库协同搬运"(即 §13.1 开头的任务)设计一套**完整的混合系统**,要求串联本章所有小节:(a) 画出完整的分层架构(§13.2);(b) 设计 RL→MPC 的命令接口(§13.3);(c) 设计 CBF/GCBF+ 安全过滤层(§13.4);(d) 指出哪里可以用残差 RL(§13.5);(e) 用 CMG 写出训练时的安全约束(§13.6);(f) 说明每一类 sim-to-real gap(§13.1)被哪个模块吸收。这道题没有标准答案,重点是展示你能把整章的模块组织成一个自洽的系统。
§13.7 前沿延伸:LLM 作为高层决策层(RoCo 范式)⭐⭐⭐⭐¶
这一节解决什么问题:§13.2-13.6 的混合架构里,高层决策器一直是一个 MARL 策略网络。但 2024 年以来一个引人注目的方向是——把高层决策器从"策略网络"换成"大语言模型(Large Language Model, LLM)"。这看起来是个大跳跃,但从本章的解耦原理看,它其实是同一个框架的自然延伸:LLM 只是另一种"高层决策器",底层仍是 MPC/CBF。本节以 RoCo(Mandi et al., ICRA 2024)为例,讲清这个延伸的动机、架构、与 MARL 高层的异同,以及它带来的新机遇与新风险。这是一个 ⭐⭐⭐⭐ 的前沿话题,理解它能让你看到混合范式的边界正在被推向何处。
动机:高层决策器还能更"聪明"吗¶
回顾 §13.2 的四层架构——Level 3 是 MARL 策略,输入局部观测、输出高层命令。MARL 高层很强,但它有几个固有局限:
- 需要大量训练:每个新任务/新场景都要重新训练或微调策略,训练成本高;
- 难以利用常识:MARL 从奖励中学协调策略,但它不"懂"任务的语义——它不知道"易碎品要轻拿轻放"、"先搬大件再搬小件更高效"这类人类常识,除非这些被显式编码进奖励;
- 难以接受自然语言指令:你没法直接告诉 MARL"这次优先保证 3 号货架的货先到",只能通过改奖励/改观测间接实现;
- 难以解释决策理由:MARL 出一个命令,但说不出"为什么"。
而 LLM 恰好在这几点上有惊人的互补优势——它内置海量人类常识,能理解自然语言指令,能"说出"决策理由(思维链)。一个自然的想法浮现:能不能让 LLM 来做高层协调决策?
本质洞察:从"MARL 高层"到"LLM 高层"的跳跃,本质上没有改变本章的解耦原理——它改变的只是"高层决策器用什么实现"。MARL 高层是"用强化学习从奖励中学出协调策略",LLM 高层是"用预训练语言模型从常识和指令中推理出协调策略"。两者都是 §13.2 四层架构里的 Level 3,都通过同一个命令接口(§13.3)连接到底层 MPC。这说明本章的架构骨架有强大的**通用性**——高层决策器是可替换的插件,无论它是策略网络还是 LLM,底层的执行与安全机制(MPC/CBF)保持不变。理解了这一点,你就不会被"LLM + 机器人"的新潮表象迷惑,而能看清它在混合范式里的准确位置。
如果让 LLM 直接控制机器人会怎样¶
在看 RoCo 怎么做之前,先看一个错误的做法——让 LLM 直接输出底层控制。
有人可能想:LLM 这么强,能不能让它直接输出每个关节的力矩,或者每一步的速度指令?这是一个灾难性的想法,原因和 §13.3 "RL 不应直接出底层动作"如出一辙,但更严重:
- 频率完全不匹配:LLM 推理一次要几百毫秒到几秒,根本无法满足底层控制的 50-1000 Hz 要求;
- 没有任何动力学概念:LLM 不"懂"物理,它生成的"力矩"只是符合语言模式的数字,毫无动力学依据;
- 没有安全保证:LLM 会"幻觉"(hallucinate),它可能自信地输出一个完全错误的指令;
- 数值精度差:LLM 对精确数值的处理是出了名的不可靠。
所以正确的做法必然是——LLM 只做最高层的语义决策(慢、抽象、符号化),把所有连续控制留给底层 MPC。这正是 RoCo 的设计。
历史:从符号规划到 LLM 协商¶
让"高层符号决策 + 底层连续控制"分层,这个思想在机器人学里很古老——经典的 TAMP(Task and Motion Planning,任务与运动规划) 就是"高层用符号规划器(如 PDDL)决定动作序列,底层用运动规划器执行"。但经典 TAMP 的高层符号规划器是**人工设计规则 + 搜索**,难以处理开放、模糊、需要常识的任务。
LLM 的出现给这个古老分层注入了新活力——用 LLM 替换符号规划器,让高层决策能理解自然语言、利用常识、处理开放任务。SayCan(2022)是早期代表(LLM 提议动作、用价值函数评估可行性)。RoCo(Mandi, Jain, Song, ICRA 2024)则把它推向**多机器人**:多个 LLM agent 通过"辩证对话"(dialectic)协商任务分配和动作,再交给底层 MPC 执行——这是 LLM 高层与多机规控混合的代表作。
理论:RoCo 的三层架构¶
RoCo 的架构本质上是本章四层架构的一个变体——把 Level 3(MARL)换成了"LLM 协商层 + LLM 决策层"两个子层,底层仍是 MPC:
┌──────────────────────────────────────────────────────┐
│ LLM 决策层(每个机器人一个 LLM agent) │
│ 输入:自然语言任务 + 场景描述(文本化的环境状态) │
│ 输出:每个机器人的子目标序列(符号化,如"抓取红块") │
└──────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────┐
│ LLM 协商层(Dialectic,多 agent 对话) │
│ 多个 LLM agent 互相"讨论"各自的计划 │
│ 通过多轮自然语言对话发现并解决冲突 │
│ (如:"我要先过通道"——"不行,我的货更急,你等等") │
│ 输出:协商一致、无冲突的联合子目标 │
└──────────────────────────────────────────────────────┘
│ 子目标(符号 → 几何,需 grounding)
▼
┌──────────────────────────────────────────────────────┐
│ 控制层(MPC,每个机器人独立) │
│ 输入:协商后的几何子目标 │
│ 输出:连续轨迹/控制,到达子目标 + 局部避障 │
│ 方法:标准 MPC(本章 Level 2) │
└──────────────────────────────────────────────────────┘
逐层解读:
- LLM 决策层:每个机器人配一个 LLM agent,它读取文本化的任务和场景,输出自己的子目标计划。这一层利用 LLM 的常识和语言理解——它"知道"任务该怎么分解。
- LLM 协商层(Dialectic):这是 RoCo 的核心创新。多个 LLM agent 不是各自独立决策,而是通过**多轮自然语言对话**互相协商——一个 agent 提出计划,其他 agent 检查是否与自己冲突,有冲突就"辩论",直到达成无冲突的联合计划。这本质上是用"语言对话"实现了 §13.1 说的"难建模的高层协调决策"——只不过协调机制从 MARL 的奖励优化换成了 LLM 的对话推理。
- 控制层(MPC):和本章 Level 2 完全一样——拿到几何子目标,用 MPC 跟踪并局部避障。
符号-几何接地(grounding)问题:LLM 输出的是符号子目标("抓取红块"),但 MPC 需要几何目标("末端执行器移动到坐标 \((0.3, 0.2, 0.1)\)")。这中间需要一个**接地(grounding)**步骤,把符号映射到几何——这通常由感知模块(物体检测 + 位姿估计)完成。这个接地接口的可靠性是 LLM 混合系统的一个关键工程点(也是新的失败来源)。
本质洞察:RoCo 的"辩证协商"和 MARL 的"集中训练"是解决同一个问题(多机协调)的两种范式,它们的根本差异在于**协调知识的来源**。MARL 的协调知识来自**海量交互数据 + 奖励信号**(从经验中学);LLM 的协调知识来自**预训练语料 + 常识推理**(从人类知识中迁移)。前者需要为每个任务训练、但能精确优化;后者零样本就能用、能理解语义、但不保证最优。这揭示了一个深刻的趋势——混合范式的"高层决策器"正在从"任务专用的学习模型"走向"通用的基础模型(foundation model)",从"为每个任务训练"走向"用一个通用模型零样本处理多任务"。
LLM 高层 vs MARL 高层:何时用哪个¶
LLM 高层和 MARL 高层各有适用场景,下表对比帮你选型:
| 维度 | MARL 高层 | LLM 高层(RoCo) |
|---|---|---|
| 协调知识来源 | 交互数据 + 奖励 | 预训练常识 + 推理 |
| 是否需训练 | 是(每任务训练/微调) | 否(零样本/少样本) |
| 决策频率 | 快(~10 Hz 可达) | 慢(秒级,LLM 推理延迟) |
| 常识利用 | 弱(需编码进奖励) | 强(内置海量常识) |
| 自然语言指令 | 难 | 易(原生支持) |
| 决策可解释 | 弱(黑盒) | 较强(思维链/对话可读) |
| 最优性保证 | 较强(优化奖励) | 弱(推理非最优) |
| 数值精度 | 好 | 差(LLM 弱项) |
| 适用任务 | 高频协调、需精确优化、任务固定 | 低频符号决策、需常识/语义理解、任务开放多变 |
选型口诀:需要**高频精确协调**(如密集编队避障)→ MARL 高层;需要**理解开放语义指令 + 利用常识做符号级决策**(如"帮我把桌子收拾干净"这类开放任务)→ LLM 高层。两者甚至可以叠加——LLM 做最顶层的任务级符号决策(慢、开放),MARL 做中层的运动级协调(快、精确),MPC 做底层执行。这就是混合范式向"三层决策器"的延伸。
新机遇与新风险¶
LLM 高层带来令人兴奋的新能力,但也引入了本章前面没出现过的新风险——理解这些风险对工程落地至关重要:
| 新风险 | 描述 | 缓解思路 |
|---|---|---|
| 幻觉(hallucination) | LLM 可能自信地输出错误/不存在的指令(如让机器人抓取一个场景里没有的物体) | 接地步骤做合法性检查;底层 MPC 对不可达目标降级;CBF 兜底物理安全 |
| 延迟 | LLM 推理秒级,无法高频决策 | 只用于最高层低频符号决策;中层用 MARL/规则补充高频协调 |
| 接地脆弱性 | 符号→几何的接地依赖感知,感知错误会让正确的符号决策执行到错误的几何目标 | 接地接口加置信度阈值;感知不确定时请求 LLM 重新决策 |
| 不可证明 | LLM 的决策完全不可形式化验证 | LLM 只做"建议",所有安全约束仍由 CBF/MPC 硬保证——LLM 永远不碰安全层 |
本质洞察:无论高层决策器多"聪明"(从 MARL 到 LLM),本章的一条铁律始终不变——安全永远不能交给高层决策器,必须由底层的 CBF/MPC 硬保证。MARL 会输出 OOD 危险动作,LLM 会幻觉出错误指令,它们的失效模式不同,但应对之策相同:让它们只做"建议性"的高层决策,把"绝对不可违反的物理安全"牢牢锁在底层的模型化安全层里。这呼应了 §13.4 的核心——安全过滤层是横切所有控制路径的守门员,它不关心上面是策略网络还是 LLM,只保证任何下发到执行器的控制都不越界。这就是混合范式的安全哲学:高层可以任意聪明也任意会犯错,底层保证它的错误永远不会变成物理灾难。
⚠️ 常见陷阱¶
陷阱 1(思维陷阱):以为 LLM 强大就能让它直接控制机器人底层 - 错误做法:让 LLM 直接输出关节力矩、速度指令或高频控制信号。 - 现象/后果:频率完全不匹配(LLM 秒级 vs 控制毫秒级),LLM 无动力学概念输出物理上荒谬的控制,幻觉导致危险动作,系统无法运行或失控。 - 根本原因:和"RL 不应出底层动作"同理但更严重——LLM 是符号/语言推理器,不是连续控制器。它在频率、动力学理解、数值精度、安全保证上全面不适合底层控制。 - 正确做法:LLM 只做最高层的低频符号决策(任务分解、协商),把符号子目标经接地变成几何目标,交给底层 MPC 做连续控制。LLM 永远不碰底层。
陷阱 2(概念误区):把 LLM 的决策当成可信的,不做合法性检查和安全兜底 - 错误做法:直接执行 LLM 输出的子目标,认为"LLM 这么聪明应该不会错"。 - 现象/后果:LLM 幻觉出一个不存在的物体/不可达的目标,系统盲目执行导致行为异常甚至危险。 - 根本原因:LLM 会幻觉,且它的输出完全不可形式化验证。把它当可信源 = 把安全寄托在一个会犯错且不可验证的黑盒上。 - 正确做法:LLM 输出只当"建议"——接地步骤做合法性检查(目标是否存在、是否可达),底层 MPC 对不可达目标降级,CBF 兜底物理安全。安全永远不依赖 LLM 的正确性。
练习¶
-
【架构分析】 把 RoCo 的三层架构对齐到本章 §13.2 的四层架构上:RoCo 的哪几层对应四层架构的 Level 3?控制层对应哪一层?RoCo 缺少了四层架构的哪一层(提示:想想底层执行频率),如果要把 RoCo 部署到真实的力控机器人上,你需要补上什么?
-
【对比辨析】 针对下面两个任务,分别判断该用 MARL 高层还是 LLM 高层,并沿本节对比表的维度说明理由:(a) 50 架无人机表演密集队形变换(需要高频、精确、可重复的协调);(b) 3 台家用机器人协作"准备一顿晚餐"(开放任务、需常识理解"先洗菜再切菜"、需理解主人的自然语言偏好)。
-
【安全设计 + 跨节综合】 综合 §13.4(CBF 过滤)和本节,为一个"LLM 高层 + MPC 底层"的双机械臂协作系统设计完整的安全方案。要求回答:(a) LLM 幻觉出一个会导致两臂碰撞的子目标时,谁来阻止碰撞?(b) 接地步骤如何检查 LLM 子目标的合法性?(c) 为什么"安全绝不能交给 LLM"这条铁律在这个系统里如何具体落实?画出数据流,标出每一道安全检查的位置。
本章常见误解汇总¶
下表汇总本章贯穿始终、最容易绊倒初学者的认知误区。每一条都对应正文里详细论证过的本质洞察——如果某条你还觉得"不就是这样吗",建议回对应小节重读。
| 误解 | 正确理解 | 对应小节 |
|---|---|---|
| 把碰撞惩罚调到无穷大就能让 MARL 安全 | 奖励是期望意义的软目标,碰撞是它优化的一个"项";安全必须是优化的"约束"(逐状态硬约束或期望约束),这是数学层次的不同,不是调参能解决的 | §13.1 |
| 纯 MPC 更安全,所以应尽量多用 MPC | 安全和决策质量是正交维度。MPC 在"有模型执行"上安全,但在"难建模协调决策"上毫无优势——它只是把"学策略"换成"人脑手工设计代价",而人脑做不好 | §13.1 |
| 混合就是"先跑 MARL 再跑 MPC"的串联 | 混合的核心是"沿正确维度切分 + 设计语义清晰的窄接口",难点 90% 在接口设计。简单串联会导致语义不对齐、时间尺度错配 | §13.1, §13.3 |
| 让相邻层频率接近能提高响应速度 | 分层解耦依赖时间尺度分离(内环比外环快 5-10 倍)。频率太接近会让两层强耦合、产生振荡 | §13.2 |
| RL 应该直接输出底层动作(力矩/轨迹) | RL 应只出低维运动学意图,把"展开成可行控制"留给有模型的 MPC。直接出底层动作既维度爆炸又让 RL 独自承受 sim-to-real gap | §13.3 |
| 训练和部署用不同命令语义没关系 | MARL 是在某种"命令→行为"映射下学的,这个映射由 MPC 如何解释命令决定。换了解释=换了环境,策略失效。接口语义必须训练部署严格一致 | §13.3 |
| 对二阶/三阶系统用一阶 CBF | 当 \(h\) 是位置函数、\(u\) 是加速度/力时相对度≥2,\(\dot h\) 不含 \(u\),一阶 CBF 形同虚设。必须用 HOCBF | §13.4 |
| CBF-QP infeasible 时退回名义控制 | infeasible 恰恰发生在最危险时刻,退回名义控制=在最该保护时撤掉保护。应降级到保守安全动作(急停/最大减速) | §13.4 |
| 有了安全过滤就让上层完全不管安全 | 安全过滤保证"不越界"但不保证"行为优雅"。上层完全不管安全会让过滤器满负荷工作、系统在安全边缘横跳。上层仍需温和的安全意识 | §13.4 |
| CBF 保证安全就等于保证任务能完成 | CBF 保证安全(前向不变性)但不保证活性(liveness)。安全和活性是独立性质,CBF 只管前者,可能死锁,需上层决策打破对称 | §13.4 |
| 残差策略随便初始化就行 | 残差必须初始接近零(最后一层权重≈0),系统才从"纯基线行为"出发。随机初始化第一步就破坏基线,退化成带偏置的从零训练 | §13.5 |
| 残差可以无界 | 残差 RL 的安全性来自"不偏离可信基线太远",必须用 tanh×ρ 限幅。不限幅则退化成不安全的纯 RL | §13.5 |
| 基线控制器也可以一起训练 | 基线的价值在于"可信、固定、有保证",是残差 RL 的安全锚点。让它可训练=锚点漂移=安全论证失效。基线必须冻结 | §13.5 |
| Safe MARL 的期望安全=硬安全保证 | 期望约束 \(\mathbb{E}[\text{cost}]\le\delta\) 只保证平均安全,单条轨迹仍可能违反。安全关键场景必须再叠 CBF 硬过滤 | §13.6 |
| 混合一定比纯方案好 | 混合的代价是工程复杂度。只有任务确实同时需要多种范式优势时混合才值得。简单任务用纯方案更好,复杂度要花在刀刃上 | §13.6 |
| LLM 强大就能让它直接控制机器人底层 | LLM 是符号/语言推理器,频率(秒级)、动力学理解、数值精度全面不适合底层控制。它只能做最高层低频符号决策,连续控制留给 MPC | §13.7 |
| LLM 的决策可信,无需安全兜底 | LLM 会幻觉且不可形式化验证。它的输出只当"建议",须做合法性接地检查 + CBF 兜底物理安全。安全永不依赖高层正确性 | §13.7 |
本章小结¶
本章把整个多机器人方向的两条技术路线——学习(MARL)与模型(MPC/CBF/MAPF)——焊接成一个可部署的混合系统,并以此收口整个方向。核心逻辑链条是:
- 为什么混合(§13.1):纯 MARL 无硬安全保证、sim-to-real gap 弥漫、黑盒难调试;纯规控写不出难建模的高层协调决策。两者各有不可在单一范式内调和的天花板——这就是"探索-保证两难"。化解之道是**解耦原理**:沿"学习/模型"维度切分,让每种范式只在自己有比较优势的地方工作,通过窄接口通信,把 sim-to-real gap **局部化**到高层决策接口上。
- 分层混合架构(§13.2):四层结构(MARL 高层 10 Hz → MPC 中层 50 Hz → WBC 底层 200-1000 Hz + CBF 横切安全层),频率阶梯由**时间尺度分离**原理决定,每层可独立降级把单点故障隔离在层内。
- RL→MPC 接口(§13.3):混合成败 90% 取决于接口设计。命令空间应满足低维、运动学抽象、可执行三原则。三种典型接口:目标速度、编队偏移、子目标。进阶接口:RL 出 MPC 尾代价(补"看不远")。
- 安全过滤(§13.4):CBF-QP 把安全做成可叠加在任何控制器上的最小修正(正交投影到安全半空间),提供逐状态硬保证(前向不变性);GCBF+ 用 GNN 参数化 CBF 扩展到上千 agent。
- 残差 RL(§13.5):在可信基线上只学修正 \(u=u_{\text{base}}+u_{\text{res}}\),样本效率高、有安全性下界(残差限幅 + 基线裕度)。多机场景里残差恰好捕捉"难建模的多体交互"。
-
Safe MARL 与选型(§13.6):CMG + Lagrangian 把安全写进训练目标(期望约束,\(\mu\) 自适应权衡),与 CBF 过滤(逐状态硬保证)互补成两道防线。三范式对比表 + 四问选型框架收口整个方向。
-
前沿延伸——LLM 高层(§13.7):高层决策器从 MARL 策略网络延伸到 LLM(RoCo 范式),底层仍是 MPC/CBF。这印证了四层架构的通用性——Level 3 是可替换插件。但无论高层多聪明,安全永远由底层硬保证,绝不交给会幻觉的 LLM。
贯穿全章的元洞察:没有银弹,只有组合。混合范式教的不是某个算法,而是"如何判断工具的比较优势、沿正确维度切分问题、设计模块接口"的系统设计方法论。从 MARL 高层到 LLM 高层的延伸进一步揭示:这个方法论的骨架是稳定的,可替换的只是每一层的具体实现——这正是一个好的系统设计该有的样子。
术语速查表¶
| 术语(中/英) | 一句话定义 |
|---|---|
| 混合范式(Hybrid Paradigm) | 把 MARL 的探索能力与传统规控的可证明保证组合在一个系统里 |
| 探索-保证两难(Exploration-Guarantee Dilemma) | RL 善探索无保证、控制有保证难探索,单一范式无法兼得 |
| 解耦原理(Decoupling Principle) | 沿特征维度切分系统,每层只处理有比较优势的子问题,窄接口通信 |
| 时间尺度分离(Time-Scale Separation) | 内环比外环快 5-10 倍,外环可把内环近似当瞬时执行器,从而解耦 |
| 分层混合(Hierarchical Hybrid) | RL 出高层命令、规控管底层执行,按抽象层次纵向切分 |
| 命令空间(Command Space) | RL 输出给底层的语义量空间,应低维、运动学抽象、可执行 |
| 安全过滤(Safety Filtering / Shielding) | 在名义控制执行前做最小修正,投影到安全集 |
| 控制屏障函数(Control Barrier Function, CBF) | 用 \(h(x)\ge 0\) 定义安全集,逐时刻约束 \(\dot h\ge-\alpha(h)\) 保证前向不变 |
| 前向不变性(Forward Invariance) | 初始在安全集内且每时刻满足 CBF 条件 ⟹ 永远在安全集内 |
| 相对度(Relative Degree) | \(h\) 对 \(u\) 求几阶导才显含 \(u\);≥2 时需高阶 CBF |
| 高阶 CBF(HOCBF) | 相对度≥2 时构造嵌套函数链逼出对 \(u\) 的约束 |
| CBF-QP | 求"最接近名义控制且满足 CBF 约束"的控制的二次规划 |
| GCBF+(Graph CBF+) | 用 GNN 参数化 CBF,可扩展到上千 agent 的分布式安全过滤 |
| 残差强化学习(Residual RL) | 在固定基线控制器上叠加 RL 学的修正 \(u=u_{\text{base}}+u_{\text{res}}\) |
| 安全性下界(Safety Lower Bound) | 残差限幅 + 基线裕度保证总控制不偏离安全边界 |
| 约束马尔可夫博弈(Constrained Markov Game, CMG) | 多智能体的约束优化:max 奖励 s.t. 期望累积代价≤阈值 |
| Lagrangian 松弛(Lagrangian Relaxation) | 用乘子 \(\mu\) 把约束吸进目标,原始-对偶交替优化 |
| 原始-对偶优化(Primal-Dual Optimization) | 交替更新策略 \(\theta\)(原始)与乘子 \(\mu\)(对偶),\(\mu\) 应更新更慢 |
知识点总表¶
| 编号 | 知识点 | 核心要点 | 对应节 | 难度 |
|---|---|---|---|---|
| 13-1 | 探索-保证两难 | 纯 MARL 无硬保证、纯规控难建模协调,单范式有天花板 | §13.1 | ⭐⭐⭐ |
| 13-2 | 解耦原理 | 沿比较优势维度切分 + 窄接口,gap 局部化 | §13.1 | ⭐⭐⭐ |
| 13-3 | 三种 sim-to-real gap 分类 | 动力学/感知/执行/多体交互,各甩给最适合的层 | §13.1 | ⭐⭐ |
| 13-4 | 四层混合架构 | MARL 10Hz → MPC 50Hz → WBC 200-1000Hz + CBF 横切 | §13.2 | ⭐⭐⭐ |
| 13-5 | 时间尺度分离 | 相邻层差一个数量级,外环把内环当瞬时执行器 | §13.2 | ⭐⭐⭐ |
| 13-6 | 分层降级 | 每层在上层失效时优雅降级,单点故障隔离在层内 | §13.2 | ⭐⭐ |
| 13-7 | 命令空间三原则 | 低维、运动学抽象、可执行 | §13.3 | ⭐⭐⭐⭐ |
| 13-8 | 三种 RL→MPC 接口 | 目标速度 / 编队偏移 / 子目标 | §13.3 | ⭐⭐⭐ |
| 13-9 | RL 出 MPC 尾代价 | RL 学 Q 函数补 MPC"看不远"的短板 | §13.3 | ⭐⭐⭐⭐ |
| 13-10 | CBF 与前向不变性 | \(\dot h\ge-\alpha(h)\) 保证安全集前向不变 | §13.4 | ⭐⭐⭐ |
| 13-11 | CBF-QP 闭式解 | \(u_{\text{safe}}=u_{\text{nom}}-\frac{\max(0,a^\top u_{\text{nom}}-b)}{\|a\|^2}a\),正交投影 | §13.4 | ⭐⭐⭐⭐ |
| 13-12 | HOCBF | 相对度≥2 时的嵌套函数链构造 | §13.4 | ⭐⭐⭐⭐ |
| 13-13 | GCBF+ | GNN 参数化 CBF,置换等变 + 邻居数不变,扩展到上千 agent | §13.4 | ⭐⭐⭐⭐ |
| 13-14 | 残差 RL 公式 | \(u=u_{\text{base}}+u_{\text{res}}^\theta\),学修正而非完整策略 | §13.5 | ⭐⭐⭐⭐ |
| 13-15 | 残差初始化与限幅 | 末层权重≈0 + tanh×ρ 限幅,保证从基线出发且有界 | §13.5 | ⭐⭐⭐ |
| 13-16 | 残差安全性下界 | 残差有界 + 基线裕度 ⟹ 全程不越界 | §13.5 | ⭐⭐⭐ |
| 13-17 | 约束马尔可夫博弈 | max 奖励 s.t. \(\mathbb{E}[\sum\gamma^t c]\le\delta\) | §13.6 | ⭐⭐⭐ |
| 13-18 | Lagrangian 原始-对偶 | \(\theta\) 升 \(A^r-\mu A^c\),\(\mu\) 升约束违反量,\(\mu\) 更新更慢 | §13.6 | ⭐⭐⭐⭐ |
| 13-19 | 两种安全语义 | 期望安全(训练内化,软)vs 逐状态硬保证(部署过滤,硬) | §13.6 | ⭐⭐⭐ |
| 13-20 | 三范式选型框架 | 沿"硬安全/难建模决策/有无基线/规模"四问决策 | §13.6 | ⭐⭐⭐ |
| 13-21 | LLM 高层(RoCo) | LLM 替换 MARL 做高层符号决策,辩证协商 + MPC 底层 | §13.7 | ⭐⭐⭐⭐ |
| 13-22 | 高层决策器的可替换性 | Level 3 是可替换插件(策略网络/LLM),底层安全机制不变 | §13.7 | ⭐⭐⭐ |
| 13-23 | 符号-几何接地(grounding) | LLM 符号子目标→MPC 几何目标的映射,新失败来源 | §13.7 | ⭐⭐⭐ |
| 13-24 | 安全永不交给高层 | 无论高层多聪明(MARL/LLM),物理安全必须由底层 CBF/MPC 硬保证 | §13.4, §13.7 | ⭐⭐⭐ |
累积项目:Mini-MultiBot 第 13 章新增模块¶
项目背景:贯穿整个多机器人方向的累积项目 Mini-MultiBot——一个在 MuJoCo 里仿真的多机器人协作平台。前面章节我们已经搭好了通信图(第 1 章)、共识(第 2 章)、任务分配与 MAPF(第 3 章,
planning/模块)、分布式 MPC(第 4-5 章,control/mpc/)、MARL 训练管线(第 10-11 章,learning/)。本章新增**混合控制器模块**hybrid/,把这些零件组装成一个完整的分层混合系统。
本章新增目录结构:
mini_multibot/
├── planning/ # 第 3 章:任务分配 + MAPF(已有)
├── control/
│ ├── mpc/ # 第 4-5 章:分布式 MPC(已有)
│ └── wbc/ # 全身控制(已有)
├── learning/ # 第 10-11 章:MARL 训练(已有)
└── hybrid/ # ★ 第 13 章新增
├── interface.py # §13.3:RL → MPC 命令接口
├── safety_filter.py # §13.4:CBF-QP / GCBF+ 安全过滤
├── residual.py # §13.5:残差控制器
├── safe_marl.py # §13.6:CMG + Lagrangian 训练包装
└── orchestrator.py # 四层架构的异步多频率调度器
本章要实现的核心模块(hybrid/orchestrator.py 的骨架):
"""Mini-MultiBot 混合控制器:四层架构的异步多频率调度器。
把第 13 章的所有模块组装成一个完整系统:
Level 3 (MARL, 10Hz) → interface → Level 2 (MPC, 50Hz)
→ safety_filter (CBF)
→ Level 1 (WBC, 200Hz)
每层跑在独立频率,用最新值采样上层输出(§13.2 时间尺度分离)。
"""
import threading
import numpy as np
from .interface import RLToMPCInterface
from .safety_filter import pairwise_cbf_filter
from .residual import ResidualController
class HybridOrchestrator:
def __init__(self, n_robots, marl_policy, mpc, wbc,
v_max, a_max, r_safe):
self.n = n_robots
self.marl = marl_policy # Level 3:MARL 策略(10 Hz)
self.mpc = mpc # Level 2:分布式 MPC(50 Hz)
self.wbc = wbc # Level 1:WBC(200 Hz)
self.interface = RLToMPCInterface(v_max, a_max, ctrl_dt=0.1)
self.r_safe = r_safe
# 层间共享的"最新值"缓冲(下层采样上层最新输出)
self._v_cmd = np.zeros((n_robots, 3))
self._u_mpc = np.zeros((n_robots, 3))
self._lock = threading.Lock()
self._running = False
def _marl_loop(self, get_obs, rate_hz=10):
"""Level 3:10 Hz 高层决策。"""
dt = 1.0 / rate_hz
while self._running:
obs = get_obs() # 各 agent 局部观测
actions = self.marl.act(obs) # 策略推理
with self._lock:
for i in range(self.n):
# §13.3:动作 → 安全可执行的参考速度
self._v_cmd[i] = self.interface.policy_action_to_vcmd(
actions[i])
_sleep(dt)
def _mpc_loop(self, get_state, rate_hz=50):
"""Level 2:50 Hz MPC + 安全过滤。"""
dt = 1.0 / rate_hz
while self._running:
state = get_state()
with self._lock:
v_cmd = self._v_cmd.copy() # 采样高层最新命令
# MPC 跟踪 v_cmd,输出名义控制(这里简化为加速度)
u_nom = self.mpc.solve(state, v_cmd)
# §13.4:CBF 安全过滤(兜底硬安全)
u_safe = pairwise_cbf_filter(
state['pos'], state['vel'], u_nom, self.r_safe)
with self._lock:
self._u_mpc = u_safe
_sleep(dt)
def _wbc_loop(self, get_state, send_torque, rate_hz=200):
"""Level 1:200 Hz 全身控制。"""
dt = 1.0 / rate_hz
while self._running:
state = get_state()
with self._lock:
u_ref = self._u_mpc.copy() # 采样中层最新参考
tau = self.wbc.compute(state, u_ref) # 力参考 → 关节力矩
send_torque(tau)
_sleep(dt)
def start(self, get_obs, get_state, send_torque):
"""启动三个独立频率的线程(§13.2:异步多频率,禁止同步串联)。"""
self._running = True
self._threads = [
threading.Thread(target=self._marl_loop, args=(get_obs,)),
threading.Thread(target=self._mpc_loop, args=(get_state,)),
threading.Thread(target=self._wbc_loop,
args=(get_state, send_torque)),
]
for t in self._threads:
t.daemon = True
t.start()
def _sleep(dt):
import time
time.sleep(dt)
项目进度更新:
| 模块 | 状态 | 对应章节 | 本章贡献 |
|---|---|---|---|
| 通信图 + 共识 | ✓ 完成 | 第 1-2 章 | — |
| 任务分配 + MAPF | ✓ 完成 | 第 3 章 | 被混合系统的高层调用 |
| 分布式 MPC | ✓ 完成 | 第 4-5 章 | 成为 Level 2 执行层 |
| MARL 训练 | ✓ 完成 | 第 10-11 章 | 成为 Level 3 决策层 |
| 混合控制器 | ★ 本章新增 | 第 13 章 | 把以上零件组装成可部署系统 |
| 综合实战 | ○ 待第 14 章 | 第 14 章 | 在真实任务上端到端验证 |
本章项目任务(建议作为大作业):补全 hybrid/ 下的四个模块(接口、安全过滤、残差、Safe MARL 训练包装),用 orchestrator.py 串起来,在 MuJoCo 里让 4 台机器人完成"协同搬运 + 动态避障",并验证:(1) CBF 过滤保证全程无碰撞;(2) 关掉某层观察分层降级是否生效;(3) 对比"纯 MARL"和"混合"在 sim-to-real 扰动注入下的鲁棒性差异。
延伸阅读¶
分类标注难度:⭐⭐ 入门可读 / ⭐⭐⭐ 需要背景 / ⭐⭐⭐⭐ 研究级。
综述与理论地图(先读这些建立全局):
- ⭐⭐⭐ Brunke, Greeff 等, Safe Learning in Robotics: From Learning-Based Control to Safe Reinforcement Learning, Annual Review of Control, Robotics, and Autonomous Systems, 2022(arXiv 2108.06266)。本章的理论地图——系统梳理安全 RL 的三条路线(安全过滤 / 约束优化 / 可达性),是理解混合范式安全维度的最权威入口。
- ⭐⭐⭐ Learning Safe Control for Multi-Robot Systems: Methods, Verification, and Open Challenges, Annual Reviews in Control, 2024(ScienceDirect S1367578824000178)。多机器人安全学习专门综述,覆盖 CBF、验证、开放问题,与本章 §13.4/§13.6 直接相关。
安全过滤一侧:
- ⭐⭐⭐⭐ Zhang, Fan 等, GCBF+: A Neural Graph Control Barrier Function Framework for Distributed Safe Multi-Agent Control, T-RO 2024(arXiv 2401.14554)。§13.4 的核心论文,GNN 参数化 CBF 扩展到上千 agent。项目主页 mit-realm.github.io/gcbfplus 有代码和视频。
- ⭐⭐⭐ Ames 等, Control Barrier Functions: Theory and Applications, ECC 2019。CBF 的权威综述,§13.4 的理论根基。
- ⭐⭐⭐ CBF-RL: Safety Filtering Reinforcement Learning in Training with Control Barrier Functions, 2025(arXiv 2510.14959)。把安全过滤从部署期推进到**训练期内化**,与 §13.6 "两道防线"的讨论互补。
- ⭐⭐⭐⭐ SHIELD: Safety on Humanoids via CBFs In Expectation on Learned Dynamics, 2025(arXiv 2505.11494)。把硬 CBF 推广到**学习动力学 + 随机系统**,前沿。
- ⭐⭐⭐ Safe Multi-Agent Reinforcement Learning through Decentralized Multiple Control Barrier Functions, 2021(arXiv 2103.12553)。MADDPG-CBF,安全 MARL 的早期范式。
分层混合一侧:
- ⭐⭐⭐ Bjelonic 等, Combining Model-Predictive Control and Predictive Reinforcement Learning for Stable Quadrupedal Robot Locomotion, 2023(arXiv 2307.07752)。§13.3 "RL 出尾代价"接口的代表作。
- ⭐⭐⭐ RL-Augmented MPC for Non-Gaited Legged and Hybrid Locomotion, 2025(arXiv 2603.10878)。高层 RL 出步态/导航命令 + 低层 MPC,§13.2/§13.3 的腿足落地。
- ⭐⭐⭐ Mandi, Jain, Song, RoCo: Dialectic Multi-Robot Collaboration with Large Language Models, ICRA 2024。混合范式向"LLM 高层"延伸——高层用 LLM 做任务分解与协商,底层 MPC 执行。
残差学习一侧:
- ⭐⭐⭐ Johannink 等, Residual Reinforcement Learning for Robot Control, ICRA 2018(arXiv 2017)。§13.5 的奠基论文,必读。
- ⭐⭐⭐ Residual MPC: Blending Reinforcement Learning with GPU-Parallelized Model Predictive Control, 2025(arXiv 2510.12717)。把残差的基线升级为 GPU 并行 MPC。
约束 RL 理论:
- ⭐⭐⭐⭐ Altman, Constrained Markov Decision Processes, 1999。CMDP 的理论原典,§13.6 的根基。
- ⭐⭐⭐ Achiam 等, Constrained Policy Optimization (CPO), ICML 2017。信赖域内保证约束满足的策略优化,Lagrangian 之外的另一条路。
开源代码库(动手必备):
- ⭐⭐⭐⭐
MIT-REALM/gcbfplus(~100★,JAX):GCBF+ 官方实现,gcbfplus/目录有 GNN-CBF 训练 + CBF-QP 部署。 - ⭐⭐⭐
PKU-MARL/HARL(~300★):HAPPO/MAPPO 等异构 MARL 算法,含 safe MARL 的 Lagrangian 实现。 - ⭐⭐⭐
osqp/osqp:本章 CBF-QP 用的 QP 求解器,C/Python 接口,嵌入式友好。 - ⭐⭐⭐
leggedrobotics/ocs2:MPC(SQP-RTI)+ WBC,本章 Level 2/Level 1 的工业级实现。
本章与后续章节的关系¶
| 后续章节 | 关系 | 本章铺垫的知识点 |
|---|---|---|
| 第 14 章(综合实战) | 直接延续 | 本章的混合架构(hybrid/ 模块)会在第 14 章被部署到一个完整的端到端项目上,做真机/高保真仿真验证。本章是"搭骨架",第 14 章是"跑起来" |
| 第 14 章 | 选型框架的应用 | §13.6 的三范式选型框架是第 14 章"为给定任务选技术栈"的决策依据 |
| 各方向专题(无人机/足式/机械臂) | 模块复用 | 本章的安全过滤(§13.4)、残差(§13.5)是方向无关的通用组件,各方向专题会针对各自动力学特化它们(如足式用 SRBD-CBF、无人机用几何控制残差) |
本章在整个多机器人方向中的位置:本章是多机器人方向的**收口章**。如果说前面各章是在"打造工具"(通信、共识、分配、规划、MPC、MARL、CBF 各是一件工具),本章就是教你"如何把工具组装成机器"——它不引入太多全新的算法,而是提供组装这些工具的**系统设计方法论**。读完本章,你应该完成从"会用单个算法"到"会设计多机器人系统"的认知跃迁。
🔧 故障排查手册¶
下面是混合系统调试中最高频的 5 类故障。每类给出"症状→可能原因→排查步骤→相关章节"的结构化排查路径。混合系统的调试难点在于**故障可能源自任何一层或层间接口**,所以排查的第一原则是"逐层隔离"——先确定故障在哪一层,再深入。
故障 1:仿真训练完美,部署真机频繁碰撞¶
| 项 | 内容 |
|---|---|
| 症状 | MARL 在仿真里协调流畅、零碰撞,部署真机后偶发甚至频繁碰撞 |
| 可能原因 | (a) 没有部署安全过滤层,纯靠 MARL 软安全;(b) 安全过滤层的 CBF 相对度搞错(二阶系统用了一阶 CBF,过滤形同虚设);(c) CBF 的 \(\alpha\) 太大,贴边才刹来不及;(d) sim-to-real gap 让 MARL 输出 OOD 危险动作而无过滤兜底 |
| 排查步骤 | 1. 确认安全过滤层是否真的在部署回路里(打印每帧是否调用、修正量是否非零);2. 检查 CBF 相对度——若控制是力/加速度且 \(h\) 是位置函数,必须 HOCBF(§13.4 陷阱 1);3. 注入一个故意冲向障碍的名义控制,验证过滤器是否拦截、何时开始减速;4. 减小 \(\alpha\) 让减速更早,观察是否改善 |
| 相关章节 | §13.1(软安全缺陷)、§13.4(CBF 相对度、HOCBF、\(\alpha\) 整定) |
故障 2:机器人整体协调但每台高频抖动¶
| 项 | 内容 |
|---|---|
| 症状 | 编队整体行为正确,但每台机器人在原地高频抖动/震荡 |
| 可能原因 | (a) 相邻层频率太接近,时间尺度分离失效(§13.2);(b) RL→MPC 命令未限幅/未平滑,命令跳变导致 MPC 输出剧烈饱和(§13.3);(c) 训练与部署的接口语义不一致,策略与 MPC 响应对不上(§13.3);(d) CBF 过滤与名义控制持续对抗(上层完全不管安全) |
| 排查步骤 | 1. 检查各层频率比是否 ≥5 倍;2. 打印 RL 输出的命令序列,看是否有跳变,确认限幅和速率限制生效;3. 核对训练时和部署时的接口代码是否**逐行一致**;4. 打印 CBF 修正量,若持续大幅修正说明上层太激进,给 MARL 加温和安全惩罚 |
| 相关章节 | §13.2(时间尺度分离)、§13.3(命令限幅/平滑、语义一致)、§13.4(陷阱 3) |
故障 3:CBF-QP 频繁求解失败(infeasible)¶
| 项 | 内容 |
|---|---|
| 症状 | 安全过滤的 QP 经常报 infeasible,系统行为突然失控或急停 |
| 可能原因 | (a) 多个 pairwise 约束在密集场景下互相冲突(往左躲A就撞B);(b) \(\alpha\)/安全半径过保守,把可行域压没了;(c) 没有 infeasible 降级逻辑,直接崩溃;(d) 缺少打破对称的上层决策导致死锁 |
| 排查步骤 | 1. 统计 infeasible 发生时的邻居数和密度,确认是否密集冲突;2. 检查是否有 infeasible 降级(应降到急停/最大减速,不是退回名义控制);3. 考虑用软约束 CBF(加松弛变量 + 大惩罚)保证 QP 始终可行;4. 检查上层是否提供"谁让谁"的协调决策打破对称(§13.4 陷阱 4) |
| 相关章节 | §13.4(多约束 QP、infeasible 降级、死锁/活性、陷阱 2/4) |
故障 4:残差 RL 训练不收敛或行为比基线还差¶
| 项 | 内容 |
|---|---|
| 症状 | 叠了残差 RL 后,训练初期就发散,或最终性能反而不如纯基线控制器 |
| 可能原因 | (a) 残差策略末层随机初始化,第一步就破坏基线(§13.5 陷阱 1);(b) 残差不限幅,偏离基线太远(§13.5 陷阱 2);(c) 基线被误加进训练,污染可信性(§13.5 陷阱 3);(d) 基线太弱,残差不"小",退化成从零训练 |
| 排查步骤 | 1. 打印训练第一步的残差幅值,应接近零——若很大则末层未零初始化;2. 确认 tanh×ρ 限幅生效,残差有界;3. 检查优化器参数列表,确认基线参数**未**被包含;4. 评估基线单独运行的性能,太差则先用控制论改进基线 |
| 相关章节 | §13.5(初始化、限幅、基线冻结、基线质量,陷阱 1/2/3) |
故障 5:Safe MARL 训练中安全代价振荡、约束时满足时违反¶
| 项 | 内容 |
|---|---|
| 症状 | CMG 训练时安全代价 \(J^{\text{cost}}\) 剧烈震荡,策略在过度保守和过度激进间横跳,不收敛 |
| 可能原因 | (a) Lagrangian 乘子 \(\mu\) 学习率太大,破坏原始-对偶的时间尺度分离(§13.6 陷阱 3);(b) 安全代价 \(c_{i,t}\) 设计不合理(量纲/尺度问题);(c) 把期望安全误当硬保证,没有运行时过滤兜底导致评估时偶发大违反 |
| 排查步骤 | 1. 把 \(\mu\) 的学习率降到策略学习率的 1/10~1/100,观察是否平滑;2. 打印 \(\mu\) 的轨迹,应缓慢单调趋稳而非震荡;3. 检查各代价分量的尺度是否可比(碰撞/翻转/限位代价量纲);4. 评估时叠加 CBF 过滤做硬兜底(§13.6 陷阱 1) |
| 相关章节 | §13.6(原始-对偶时间尺度分离、\(\mu\) 作为积分控制器、两种安全语义,陷阱 1/3) |
故障 6(前沿):LLM 高层系统执行了错误/危险的目标¶
| 项 | 内容 |
|---|---|
| 症状 | LLM 高层(RoCo 式)系统中,机器人偶尔去抓取不存在的物体、移动到危险位置或执行明显错误的动作 |
| 可能原因 | (a) LLM 幻觉出错误指令且未做合法性检查;(b) 符号→几何接地错误(感知错误把"红块"接地到了错误坐标);(c) 误把 LLM 输出当可信、未做安全兜底;(d) LLM 直接碰了不该碰的层 |
| 排查步骤 | 1. 在接地步骤打印"LLM 符号目标 → 几何目标"的映射,检查目标是否存在、是否可达(合法性检查);2. 核对感知模块对该物体的检测/位姿是否正确(接地脆弱性);3. 确认 CBF 过滤层在 LLM 系统里仍生效(物理安全兜底);4. 确认 LLM 只输出高层符号决策、未触碰底层控制(§13.7 陷阱 1) |
| 相关章节 | §13.7(幻觉、接地、安全不依赖 LLM,陷阱 1/2)、§13.4(CBF 兜底) |
API 速查表¶
本章涉及的核心 API / 函数签名汇总,供实现时回查。
RL→MPC 接口(§13.3):
# 命令接口
interface = RLToMPCInterface(v_max, a_max, ctrl_dt)
v_cmd = interface.policy_action_to_vcmd(action) # 归一化动作 → 安全可执行参考速度
cost_fn = build_mpc_cost(v_cmd, Q_v) # v_cmd → MPC 速度跟踪代价项
安全过滤(§13.4):
# pairwise HOCBF 碰撞避免过滤
u_safe = pairwise_cbf_filter(p, v, u_nom, r_safe, alpha1, alpha2)
# p:(N,2) 位置, v:(N,2) 速度, u_nom:(N,2) 名义加速度 → u_safe:(N,2)
# OSQP QP 求解(CBF-QP 后端)
import osqp
prob = osqp.OSQP()
prob.setup(P, q, A, l, u, verbose=False) # min ½xᵀPx+qᵀx s.t. l≤Ax≤u
res = prob.solve() # res.x, res.info.status_val
# CBF-QP 单约束闭式解(无需求解器)
# u_safe = u_nom - max(0, aᵀu_nom - b)/||a||² · a 其中 a=-Lgh^T, b=Lfh+α(h)
# GCBF+ GNN-CBF(§13.4,部署接口示意)
h_values = gcbf_gnn(node_features, edge_features, adj_matrix) # (N,1) 每 agent CBF 值
残差控制器(§13.5):
# 残差策略(末层须零初始化 + tanh 限幅)
policy = ResidualPolicy(obs_dim, act_dim, res_max, hidden=256)
u_res = policy(obs) # 有界残差 ∈ [-res_max, res_max]
# 残差控制器
ctrl = ResidualController(baseline_fn, policy) # baseline_fn 须冻结
u, u_base, u_res = ctrl.act(obs, state) # u = u_base + u_res(返回分解)
Safe MARL(§13.6):
# CMG Lagrangian 原始-对偶更新(伪代码签名)
theta = happo_update(theta, adv_reward - mu * adv_cost) # 策略:组合优势
mu = max(0.0, mu + eta_mu * (J_cost - delta)) # 乘子:约束违反量
# 关键:eta_mu 应比策略学习率小 1-2 个数量级(时间尺度分离)
# 混合调度器(累积项目)
orch = HybridOrchestrator(n_robots, marl_policy, mpc, wbc, v_max, a_max, r_safe)
orch.start(get_obs, get_state, send_torque) # 启动三个独立频率线程
研究实践建议¶
按"刚入门 / 做项目 / 做研究"三个层次给建议。
如果你刚入门混合范式: - 先吃透 §13.1 的"探索-保证两难"和"解耦原理"——这是整章的思想根。不理解"为什么不能用单一范式",后面的架构都是机械模仿。 - 动手第一步建议做 §13.4 练习 1(3 agent CBF 碰撞避免)——它最能让你直观感受"安全过滤如何把不安全动作拉回",且代码量小、效果可视化强。 - 不要一上来就追求全套混合。先用纯 MPC 或纯 MARL 把一个简单任务跑通,再逐步引入混合机制,每加一层都验证它解决了什么具体问题。
如果你在做混合系统项目: - 接口设计先行(§13.3)。在写任何 RL 训练或 MPC 代码之前,先冻结接口语义(命令是什么、谁怎么解释),并把接口当成环境的一部分。接口语义训练部署不一致是最高频的"仿真好真机崩"根因。 - 安全分层兜底(§13.4 + §13.6)。安全关键系统必须有 CBF 硬过滤,不能只靠 MARL 软安全或 Safe MARL 期望安全。把安全做成"两道防线":训练内化 + 部署硬过滤。 - 善用残差复用已有成果(§13.5)。如果你已经有成熟的单机控制器,优先考虑残差 RL 而非从零训——能省一个数量级的样本,且安全得多。 - 调试用"逐层隔离"。混合系统故障可能在任何层或接口,先定位层再深入(见故障排查手册的方法论)。
如果你在做混合范式研究: - 安全保证的"形式化"是最大的开放问题。GCBF+ 这类学习式 CBF 的安全保证是**概率性**的(依赖训练覆盖),如何走向 formal certification(可证明的、覆盖所有状态的安全)是当前最热的方向之一(§13.4 提到)。 - "训练期内化 vs 部署期过滤"的统一是另一前沿。CBF-RL、SHIELD(2025)在探索"让策略在训练时就内化硬约束",目标是减少甚至消除部署期过滤器——这关系到能否把硬安全做进策略本身。 - 接口的"自动设计"值得探索。本章的命令接口都是人工设计的。能否让系统**自动发现**最优的"学习/模型"切分点和接口语义?这是一个有趣的元学习问题。 - 多体交互残差的可解释性。残差 RL 在多机场景学的"多体交互修正"是黑盒,能否从中提取出可解释的交互模型(如气流耦合的物理规律)?这是连接"学习"和"建模"的有趣方向。
版本信息速查¶
| 项目 | 版本 / 说明 |
|---|---|
| 文档版本 | v1.0(2026-06) |
| 适用规范 | 教学文档编写规范 v5.0(算法工程教学类型) |
| GCBF+ | T-RO 2024,arXiv 2401.14554,代码 MIT-REALM/gcbfplus(JAX) |
| HARL(HAPPO/MAPPO) | PKU-MARL/HARL,含 safe MARL Lagrangian 实现 |
| OSQP | CBF-QP 后端,C/Python,嵌入式友好 |
| OCS2 | leggedrobotics/ocs2,MPC(SQP-RTI)+ WBC |
| 关键前置章节 | 第 1-2 章(图/共识)、第 3 章(分配/MAPF)、第 4-5 章(分布式 MPC)、第 10-11 章(MARL 全栈)、CBF 基础 |
| 后续衔接 | 第 14 章(综合实战) |
结语:混合范式不是一个算法,而是一种成熟工程师看待问题的方式——承认没有银弹,转而设计让每种范式各展所长的系统。当你下次面对一个真实多机器人任务时,希望你脑中浮现的不是"该用哪个算法",而是"该沿哪些维度切分、让谁做什么、接口怎么设计、安全谁来兜底"。这种从"算法使用者"到"系统设计者"的转变,正是本章——也是整个多机器人方向——最想留给你的东西。