跳转至

第 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/任务分配),再来读本章。本章会**大量复用**这些前置,但不重新从零教它们——它教的是"如何把它们拼起来"。

  1. (接第 10-11 章) 什么是**集中训练分散执行**(Centralized Training with Decentralized Execution, CTDE)?MAPPO 和 HAPPO 的核心区别是什么——为什么后者在异构智能体上更稳?一个训练好的 MARL 策略 \(\pi_\theta(a_i \mid o_i)\) 的输出,在真机上为什么**不能**直接当成电机力矩用? (答不出 → 回第 10 章 §MAPPO、第 11 章 §HAPPO)

  2. (接第 4-5 章) 模型预测控制(Model Predictive Control, MPC)的"滚动时域"(receding horizon)是什么意思?为什么 MPC 每个控制周期只执行优化解的**第一步**就丢掉其余、下一周期重新优化?一个 MPC 的硬约束(如关节限位、摩擦锥)和软约束(代价惩罚)在数学形式上有什么本质区别? (答不出 → 回第 4 章 §MPC 基础、第 5 章 §分布式 MPC)

  3. (接 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 基础章节)

  4. (接第 3 章) 多机路径规划(Multi-Agent Path Finding, MAPF)的顶点冲突和边冲突是什么?为什么 \(N\) 个机器人的联合状态空间搜索会随 \(N\) 指数爆炸?任务分配里"谁去做哪件事"这个离散决策,和"怎么走"这个连续控制,为什么要分成两层来解? (答不出 → 回第 3 章 §任务分配与 MAPF)

  5. (综合) 假设你已经有一个能在仿真里完美协调 8 台无人机编队穿越障碍的 MARL 策略,现在要把它部署到真机。你最担心的**三件事**分别是什么?(提示:从"训练分布 vs 真实分布"、"安全保证"、"可解释性/可调试性"三个角度想。)想不清楚没关系——这正是本章 §13.1 要回答的核心动机。

参考答案要点(先自己答,再对照):

  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)观测可能让它输出灾难性动作。

  2. 滚动时域:每个周期在长度为 \(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\),违反只是代价升高、解仍存在。

  3. 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\) "逼"出来。

  4. 顶点冲突:两机器人同一时刻占同一格;边冲突:两机器人同一时刻交换相邻格(对穿)。联合搜索爆炸是因为联合状态是各 agent 状态的笛卡尔积,分支因子随 \(N\) 指数增长。分层解(先分配后规划、或先离散后连续)是因为离散决策(组合优化)和连续控制(数值优化)有完全不同的数学结构和时间尺度——混在一起既慢又难收敛。

  5. 三件事:(1) 分布偏移——真实世界的动力学、传感器噪声、延迟不在训练分布里,策略可能输出训练时从没见过的危险动作;(2) 无安全保证——MARL 的奖励是"软"的,碰撞惩罚再大也只是降低概率,不能保证碰撞概率为零,而真机一次碰撞就是硬件损毁;(3) 不可解释/难调试——黑盒策略出问题时,你无法定位"为什么它在这一帧让 3 号机撞墙",没有可检查的中间量。这三点正是混合架构要逐一化解的。


本章目标

学完本章后,你应该能够:

  1. 论证混合范式的必然性:从"探索-保证两难"(exploration-guarantee dilemma)出发,严格说清为什么纯 MARL 和纯传统规控各自都不够,以及"分层解耦"为什么是化解这个两难的工程主轴——而不是把它当成一句口号。
  2. 设计分层混合架构:把一个多机器人任务分解到"高层决策(RL,~10 Hz)→ 中层轨迹/MPC(~50 Hz)→ 底层 WBC/PD(~200-1000 Hz)→ 安全过滤层(CBF,叠加在中层之上)"四个层次,说清每层的输入输出、时间尺度、为什么放在这一层。
  3. 实现 RL 高层 + MPC/CBF 底层的接口:讲清 RL 策略输出(编队偏移、质心目标速度、子目标)如何变成 MPC 的参考/代价,以及为什么这个接口的"语义对齐"是整个系统能不能工作的关键,并能写出最小可运行的接口代码。
  4. 推导并实现安全过滤器:从 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 碰撞避免过滤器。
  5. 掌握残差强化学习:讲清 residual RL 的核心公式 \(u = u_{\text{base}}(x) + u_{\text{res}}^{\theta}(x)\) 为什么比"从零学"样本效率高一个数量级、为什么继承了基线控制器的安全性下界,并能在一个 MPC/PD 基线上叠加一个残差策略。
  6. 公式化 Safe MARL:把混合系统的安全需求写成约束马尔可夫博弈(Constrained Markov Game, CMG),用 Lagrangian 松弛 + HAPPO 求解,理解"奖励最大化 s.t. 期望代价 ≤ 阈值"与"逐状态硬安全保证"两种安全语义的根本差异。
  7. 做出有依据的范式选型:面对一个真实多机器人问题,能沿"是否需要硬安全保证 × 是否有可靠模型 × 任务组合复杂度 × 是否上真机"四维,判断该用纯 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 会详细讲这个接口设计。

练习

  1. 【概念辨析】 用你自己的话向一个只懂纯 MARL 的同学解释:"为什么把碰撞惩罚调到无穷大也不能让 MARL 真正安全?" 要求:(a) 从"优化目标项 vs 优化约束"的角度论证;(b) 举一个具体的反例情境,说明策略可能为了更大奖励而"赌"一次小概率碰撞;(c) 说明 CBF 安全约束在数学形式上和"无穷大惩罚"的本质区别(提示:一个是软的、在期望意义上,一个是硬的、逐状态)。

  2. 【设计分析】 回到本节开头"8 台异构机器人仓库搬运"的任务。请你把这个任务里的所有子问题**显式列出**,并为每个子问题判断它应该交给 MARL 还是传统规控,并说明你的判断依据(沿"时间尺度/抽象层次/建模难度/决策类型/空间结构"五个维度分析)。至少列出 6 个子问题。这道题没有唯一答案,重点是练习"解耦维度"的思维。

  3. 【反事实推理】 本节论证了"分层混合把 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"。从前者到后者,需要逐层翻译:

  1. "向左偏移 0.5 米" → 一条**平滑可行的目标轨迹**(什么速度过去、什么时候到);
  2. 目标轨迹 → 一串**满足动力学和约束的控制参考**(在摩擦锥、推力上限内);
  3. 控制参考 → 具体的**关节力矩 / 电机指令**;
  4. 在第 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)通信,每层按自己的频率运行,下层采样上层的"最新可用值"。这才是时间尺度分离在软件上的正确落地。

练习

  1. 【架构设计】 给定一个"3 台 Go2 四足机器人协同搬运一根长杆"的任务,请你画出完整的四层架构图,并为每一层明确写出:(a) 输入是什么;(b) 输出是什么(具体物理量);(c) 运行频率;(d) 用什么方法。特别地,思考"协同搬运一根刚性长杆"这个任务的高层决策(Level 3)具体要输出什么命令——是各自的目标位置,还是相对于长杆的抓持点偏移?为什么后者可能更好?

  2. 【降级设计】 为练习 1 的系统设计完整的"分层降级"逻辑:分别说明当 (a) MARL 推理超时、(b) MPC 求解 infeasible、(c) 某台机器人通信中断 这三种故障发生时,每一层应该如何优雅降级以保证物理安全。要求降级逻辑能保证"长杆不被摔落、机器人不相撞"。这道题练习"分层降级把单点故障隔离在层内"的设计思维。

  3. 【时间尺度分析】 假设你的 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 的尾代价

\[ \min_{u_0,\dots,u_{H-1}} \ \sum_{k=0}^{H-1} \ell(x_k, u_k) + \underbrace{Q_\theta(x_H, u_H)}_{\text{RL 学的尾代价}}, \quad \text{s.t. 动力学 + 约束} \]

这样 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 在任何命令下都有解(输出"尽力接近"的可行控制)。硬约束只留给真正不可违反的物理约束(摩擦锥、关节限位)。

练习

  1. 【接口实现】 基于本节的 RLToMPCInterface,实现一个"编队偏移接口"FormationOffsetInterface:MARL 为每个 agent 输出归一化偏移动作,接口把它翻译成相对编队中心的偏移 \(\Delta p_i\),并保证 (a) 偏移幅值不超过 max_offset(避免编队散架),(b) 任意两个 agent 的目标位置间距不小于 min_sep(避免目标本身就冲突)。给出可运行代码框架,并说明 (b) 这个约束为什么应该在接口层做、而不是留给下游 CBF。

  2. 【接口调试】 给你一个有 bug 的混合系统现象描述:"仿真里训练好的 8 机编队策略,部署到真机后整体能协调,但每台机器人都在高频抖动。" 请你列出**至少三个**可能的接口层根因(从本节讲的失败模式和陷阱里找),并为每个根因给出一个具体的排查方法和修复方案。这道题练习"从现象反推接口 bug"的调试能力。

  3. 【设计扩展】 本节讲了"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 跨章桥接)。考虑一个**控制仿射系统**:

\[ \dot x = f(x) + g(x)\,u \]

其中 \(f(x)\) 是漂移项(drift,不受控制影响的自然演化),\(g(x)\) 是输入项(控制如何影响状态)。定义**安全集**为某个函数 \(h(x)\) 的超水平集:

\[ \mathcal{C} = \{x : h(x) \ge 0\}, \quad \partial\mathcal{C} = \{x : h(x) = 0\}, \quad \text{Int}(\mathcal{C}) = \{x : h(x) > 0\} \]

直觉上,\(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\) 满足

\[ \boxed{\ \dot h(x,u) = \underbrace{L_f h(x)}_{\frac{\partial h}{\partial x}f(x)} + \underbrace{L_g h(x)}_{\frac{\partial h}{\partial x}g(x)}\,u \ \ge\ -\alpha(h(x))\ } \]

这里 \(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):

\[ x(0) \in \mathcal{C} \ \text{且每时刻满足 CBF 不等式} \ \Longrightarrow\ x(t)\in\mathcal{C}\ \ \forall t \ge 0 \]

本质洞察: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):

\[ \boxed{\ \begin{aligned} u_{\text{safe}} = \arg\min_{u} \ & \tfrac{1}{2}\|u - u_{\text{nom}}\|^2 \\ \text{s.t.}\ & L_f h(x) + L_g h(x)\,u \ge -\alpha(h(x)) \end{aligned}\ } \]

目标函数 \(\|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)\))。问题变成:

\[ \min_u \tfrac12\|u-u_{\text{nom}}\|^2 \quad \text{s.t.}\quad a^\top u \le b \]

情况一:\(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 条件:

\[ \frac{\partial\mathcal{L}}{\partial u} = (u - u_{\text{nom}}) + \lambda a = 0 \ \Rightarrow\ u = u_{\text{nom}} - \lambda a \]

代入激活约束 \(a^\top u = b\)

\[ a^\top(u_{\text{nom}} - \lambda a) = b \ \Rightarrow\ \lambda = \frac{a^\top u_{\text{nom}} - b}{a^\top a} = \frac{a^\top u_{\text{nom}} - b}{\|a\|^2} \]

于是闭式解为(合并两种情况):

\[ \boxed{\ u_{\text{safe}} = u_{\text{nom}} - \frac{\max\big(0,\ a^\top u_{\text{nom}} - b\big)}{\|a\|^2}\,a\ } \]

其中 \(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 变成多约束:

\[ \min_u \tfrac12\|u - u_{\text{nom}}\|^2 \quad \text{s.t.}\quad A u \le b \quad (A = [a_1^\top; a_2^\top; \dots], \ b=[b_1;b_2;\dots]) \]

多约束 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 的安全值"参数化为其局部邻居图的函数:

\[ h_\theta = \text{GNN}_\theta(\text{node features}, \text{edge features}, \text{graph topology}) \]

为什么 GNN 是天作之合?因为多智能体安全问题有两个结构性质,恰好是 GNN 的强项:

性质 含义 GNN 为何匹配
置换等变性 agent 的安全不依赖它们的编号顺序 GNN 的消息传递天然置换等变
邻居数不变性 同一个 CBF 要能处理"3 个邻居"和"30 个邻居" GNN 的聚合(aggregation)对邻居数不敏感
局部性 agent 的安全只依赖近邻 GNN 的有限跳消息传递 = 局部感受野

GCBF+ 的训练损失同时优化"CBF 的有效性"(违反时惩罚)和"CBF 条件的满足":

\[ \mathcal{L}_{\text{GCBF+}} = \underbrace{\sum \max(0, -h_\theta + \epsilon)\big|_{\text{safe states}}}_{\text{安全态应有 } h>0} + \underbrace{\sum \max(0, h_\theta + \epsilon)\big|_{\text{unsafe states}}}_{\text{危险态应有 } h<0} + \underbrace{\sum \max(0, -\dot h_\theta - \alpha(h_\theta))}_{\text{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 设计中引入旋转分量/优先级打破对称。

练习

  1. 【实现题】 基于本节的 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 在中心相撞。

  2. 【调试挑战】 给你一段有 bug 的 HOCBF 代码,现象是"agent 总是冲到离障碍极近(几乎贴上)才急刹,偶尔来不及就撞了"。已知代码逻辑结构正确。请你判断最可能的 bug 在哪(提示:从本节陷阱 3 关于 \(\alpha\) 的讨论想),并说明 \(\alpha_1, \alpha_2\) 应该往哪个方向调、调整背后的物理含义是什么(\(\alpha\) 如何控制"多早开始减速")。

  3. 【设计扩展 + 跨章综合】 综合本章 §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 的核心公式简洁到只有一行:

\[ \boxed{\ u = u_{\text{base}}(x) + u_{\text{res}}^\theta(x)\ } \]

其中 \(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 之外用控制论方法单独改进,改完再冻结。

练习

  1. 【实现题】 实现一个完整的残差 RL 训练循环(可用 SAC 或 PPO),任务是"2D 点质量精确到达目标",基线是一个**故意调得偏弱**的 PD 控制器(增益偏低,会有稳态误差和缓慢响应)。验证:(a) 训练初期(残差≈0)系统行为就是 PD 基线行为;(b) 训练后残差学会补偿 PD 的稳态误差和响应迟缓;(c) 画出"基线贡献 \(u_{\text{base}}\)"和"残差贡献 \(u_{\text{res}}\)"随训练进程的幅值变化,观察残差如何从零增长到补足基线的不足。

  2. 【对比实验】 用同一个任务和同一个 RL 算法,对比"从零训练"(基线恒为零)vs "残差 RL"(PD 基线)的样本效率:画出两者的"奖励 vs 训练步数"曲线。然后做一个关键的消融——把残差 RL 的基线从"还不错的 PD"换成"很差的 PD"(增益极低),观察残差 RL 的优势如何随基线质量下降而消失。这道题让你亲手验证本节的本质洞察:"残差 RL 的优势依赖基线质量"。

  3. 【设计扩展 + 跨章综合】 综合本章 §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\) 最大化期望累积折扣奖励:

\[ \text{标准 MARL:}\quad \max_{\theta_i} \ J_i^{\text{reward}}(\theta) = \mathbb{E}\left[\sum_{t=0}^\infty \gamma^t r_{i,t}\right] \]

CMG 在此基础上加一个**安全约束**——每个 agent 的期望累积安全代价不超过阈值 \(\delta\)

\[ \boxed{\ \begin{aligned} \text{CMG:}\quad \max_{\theta_i} \ & J_i^{\text{reward}}(\theta) = \mathbb{E}\Big[\textstyle\sum_t \gamma^t r_{i,t}\Big] \\ \text{s.t.}\ & J_i^{\text{cost}}(\theta) = \mathbb{E}\Big[\textstyle\sum_t \gamma^t c_{i,t}\Big] \le \delta \end{aligned}\ } \]

其中安全代价 \(c_{i,t}\) 是可分解的(这是工程上的关键设计):

\[ c_{i,t} = c_{i,t}^{\text{collision}} + c_{i,t}^{\text{flip}} + c_{i,t}^{\text{joint-limit}} + \dots \]

为什么用约束而非惩罚? 约束 \(J^{\text{cost}}\le\delta\) 直接表达了"我能容忍多少不安全"(\(\delta\) 有清晰的物理含义——比如"期望碰撞代价不超过 0.01"),而惩罚权重 \(\lambda\) 没有这种直接含义。\(\delta\) 是可解释、可设定的;\(\lambda\) 是需要试凑的。

Lagrangian 松弛求解:把约束用乘子 \(\mu \ge 0\) 吸进目标,构造 Lagrangian:

\[ \mathcal{L}(\theta, \mu) = J^{\text{reward}}(\theta) - \mu\big(J^{\text{cost}}(\theta) - \delta\big) \]

这变成一个 min-max(鞍点)问题\(\max_\theta \min_{\mu\ge 0} \mathcal{L}\)。用**原始-对偶(primal-dual)**交替优化求解:

\[ \boxed{\ \begin{aligned} \theta &\leftarrow \theta + \eta_\theta\,\nabla_\theta\big[A^{\text{reward}} - \mu\,A^{\text{cost}}\big] \quad &&\text{(策略更新:HAPPO step)}\\ \mu &\leftarrow \max\!\big(0,\ \mu + \eta_\mu\,(J^{\text{cost}} - \delta)\big) \quad &&\text{(乘子更新:约束违反则增大)} \end{aligned}\ } \]

逐行理解这个更新(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\) 作为积分控制器的洞察一脉相承)——慢变量调节快变量的边界条件。

练习

  1. 【推导题】 从 CMG 的约束优化问题出发,自己完整推导一遍 Lagrangian 原始-对偶更新公式。然后回答:(a) 为什么 \(\mu\) 的更新方向是 \(J^{\text{cost}}-\delta\)(而不是 \(\delta - J^{\text{cost}}\))?(b) 为什么要 \(\max(0,\cdot)\)?(c) 把 \(\mu\) 的更新和"积分控制器"类比——它积分的是什么量、调节的是什么、稳态(收敛)时 \(\mu\) 和约束的关系是什么?

  2. 【选型实战】 给定下面三个真实任务,分别用本节的"选型决策框架"判断该用哪种(组合)范式,并完整说明你沿四个问题的判断过程:(a) 1000 架无人机的灯光秀编队(密集、需绝对不撞、队形复杂);(b) 单台机械臂在已知工件上的精密装配(模型准确、有成熟阻抗控制器、只差精细力控);(c) 5 台异构机器人在未知灾后环境的协同搜救(难建模决策多、动态障碍、需安全)。

  3. 【综合设计 + 全章串联】 这是本章的压轴综合题。请你为"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 的正确性。

练习

  1. 【架构分析】 把 RoCo 的三层架构对齐到本章 §13.2 的四层架构上:RoCo 的哪几层对应四层架构的 Level 3?控制层对应哪一层?RoCo 缺少了四层架构的哪一层(提示:想想底层执行频率),如果要把 RoCo 部署到真实的力控机器人上,你需要补上什么?

  2. 【对比辨析】 针对下面两个任务,分别判断该用 MARL 高层还是 LLM 高层,并沿本节对比表的维度说明理由:(a) 50 架无人机表演密集队形变换(需要高频、精确、可重复的协调);(b) 3 台家用机器人协作"准备一顿晚餐"(开放任务、需常识理解"先洗菜再切菜"、需理解主人的自然语言偏好)。

  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)——焊接成一个可部署的混合系统,并以此收口整个方向。核心逻辑链条是:

  1. 为什么混合(§13.1):纯 MARL 无硬安全保证、sim-to-real gap 弥漫、黑盒难调试;纯规控写不出难建模的高层协调决策。两者各有不可在单一范式内调和的天花板——这就是"探索-保证两难"。化解之道是**解耦原理**:沿"学习/模型"维度切分,让每种范式只在自己有比较优势的地方工作,通过窄接口通信,把 sim-to-real gap **局部化**到高层决策接口上。
  2. 分层混合架构(§13.2):四层结构(MARL 高层 10 Hz → MPC 中层 50 Hz → WBC 底层 200-1000 Hz + CBF 横切安全层),频率阶梯由**时间尺度分离**原理决定,每层可独立降级把单点故障隔离在层内。
  3. RL→MPC 接口(§13.3):混合成败 90% 取决于接口设计。命令空间应满足低维、运动学抽象、可执行三原则。三种典型接口:目标速度、编队偏移、子目标。进阶接口:RL 出 MPC 尾代价(补"看不远")。
  4. 安全过滤(§13.4):CBF-QP 把安全做成可叠加在任何控制器上的最小修正(正交投影到安全半空间),提供逐状态硬保证(前向不变性);GCBF+ 用 GNN 参数化 CBF 扩展到上千 agent。
  5. 残差 RL(§13.5):在可信基线上只学修正 \(u=u_{\text{base}}+u_{\text{res}}\),样本效率高、有安全性下界(残差限幅 + 基线裕度)。多机场景里残差恰好捕捉"难建模的多体交互"。
  6. Safe MARL 与选型(§13.6):CMG + Lagrangian 把安全写进训练目标(期望约束,\(\mu\) 自适应权衡),与 CBF 过滤(逐状态硬保证)互补成两道防线。三范式对比表 + 四问选型框架收口整个方向。

  7. 前沿延伸——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 章(综合实战)

结语:混合范式不是一个算法,而是一种成熟工程师看待问题的方式——承认没有银弹,转而设计让每种范式各展所长的系统。当你下次面对一个真实多机器人任务时,希望你脑中浮现的不是"该用哪个算法",而是"该沿哪些维度切分、让谁做什么、接口怎么设计、安全谁来兜底"。这种从"算法使用者"到"系统设计者"的转变,正是本章——也是整个多机器人方向——最想留给你的东西。