本文档属于 Robotics Tutorial 项目,作者:Pengfei Guo,达妙科技。采用 CC BY 4.0 协议,转载请注明出处。
D04 双臂学习——ACT/ALOHA 底层分析、RDT-1B 与 Bimanual RL¶
本章定位:本章是双臂协同理论与规划(D01-D04)的收官之作,从"规则驱动的双臂协调"转向"数据驱动的双臂学习"。前三章(D01 任务分类、D02 协调规划、D03 协调力控)建立了双臂操作的几何-动力学-力学基础,但现实中大量双臂任务(折叠衣物、烹饪、电缆布线)的接触模式极其复杂,难以用解析模型穷举描述。本章正是要解决"当模型不够用时,如何从数据中学习双臂协调策略"这一核心问题。
适用范围:ACT/Diffusion Policy 等模仿学习方法对任何多关节机器人均适用;双臂 action space 设计、数据采集系统架构是通用问题。但双臂特有的对称性利用、协调 reward 设计、内力学习是本章独有内容。
前置依赖:D03(双臂力控——内力/协调阻抗概念)、F09(学习型力控——RL+阻抗基础概念)、复合机器人方向(ACT/Diffusion Policy 基本架构概念)
下游章节:D08(遥操作数据采集系统底层分析)、D09(双臂 MoveIt2 系统集成)、D10(综合实战 Mini-DualArm)
建议用时:2 周(15-25 小时)
前置自测 ⭐¶
📋 答不出 >= 2 题 → 先回前置章节复习
| 编号 | 问题 | 答不出时回顾 |
|---|---|---|
| 1 | 双臂内力定义:什么是双臂协调操作中的"内力"\(f_{int}\)?它与外力 \(f_{ext}\) 的区别是什么?为什么内力不做功却对抓取稳定性至关重要? | D03 双臂协调力控 |
| 2 | RL 基础:写出 MDP 五元组 \((S, A, P, R, \gamma)\)。在机械臂控制中,状态空间 \(S\) 和动作空间 \(A\) 通常包含哪些量? | F09 学习型力控 |
| 3 | 模仿学习 vs 强化学习:Behavioral Cloning (BC) 为什么会有 compounding error 问题?DAgger 如何缓解? | F09 学习型力控 |
| 4 | Transformer 注意力:Self-attention 的计算复杂度是什么?为什么 Transformer 天然适合处理序列到序列的映射? | 深度学习基础 |
| 5 | 阻抗控制与位置控制:在机器人接触环境时,位置控制和阻抗控制的根本区别是什么?阻抗控制器的输出是什么? | F01 阻抗导纳二分法 |
本章目标¶
学完本章后,你应该能够:
- 深入理解 ACT/ALOHA 的底层控制选择——为什么 ALOHA 选位控而非阻抗,从硬件限制、延迟、被动柔顺三个角度严格论证
- 掌握 ACT 的三个核心创新(action chunking、CVAE 潜变量 z、temporal ensembling)的数学推导和工程实现
- 理解 RDT-1B 的 128 维统一 action space 设计哲学,以及 6D 旋转表示为何优于四元数和欧拉角
- 分析 bimanual RL 的特殊挑战——14 维动作空间的探索困难、对称/非对称 reward 设计、内力学习
- 实现 在 robosuite TwoArmLift 中训练双臂 RL 策略,对比不同 action space 的样本效率
- 批判性评估 当前双臂学习方法的瓶颈与前沿突破方向
本章知识导航¶
本章是一篇**论文解读 + 算法工程**的混合章——既要逆向恢复 ACT/RDT-1B 两篇核心论文的完整教学内容(连同源码),又要给出双臂 RL 的工程实现。知识结构如下:
双臂学习的知识树
═══════════════════════════════════════════════════
[根] 模型不够用时如何从数据学双臂协调?(D4.1)
│
┌───────────────────┼───────────────────────┐
│ │ │
[树干1] 模仿学习 [树干2] 大规模基础模型 [树干3] 强化学习
│ │ │
ALOHA 硬件 co-design RDT-1B (核心论文⭐⭐⭐) 双臂 MDP 建模 (D4.5.1)
(D4.2) │ │
│ ┌───┴────┐ 维度诅咒 14D (D4.5.2)
ACT 三创新 128D统一 DiT+ACI │
(核心论文⭐⭐⭐, D4.3) action (D4.4.4) 四种缓解策略 (D4.5.3)
│ space │
┌────┼────┐ (D4.4.2) Reward 五维度 (D4.5.6)
chunking CVAE TE 6D旋转 │
(compounding (多模态) (D4.4.3) Sim-to-Real (D4.5.7)
error)
│ │ │
└───────────────────┴───────────────────────┘
│
[树枝] 数据采集(D4.6) · 框架生态(D4.7) · 前沿(D4.8)
│
[叶] ALOHA2 · π0 · Diffusion Policy · Bi-ACT · PerAct2
阅读路径建议:
| 读者 | 推荐路径 | 可跳过 |
|---|---|---|
| 只想跑通 ACT | D4.2 → D4.3 → D4.7 → 故障排查 | D4.4、D4.5 |
| 做双臂 RL | D4.1 → D4.5 → D4.6 → 故障排查 | D4.3、D4.4 |
| 研究基础模型 | D4.3 → D4.4 → D4.8 → 范式总结 | D4.5 工程细节 |
| 完整学习 | 顺序通读 | 无 |
前置知识桥接¶
本章重度复用以下前置章节的概念,这里先激活核心要点,让你不翻回去也能跟上:
- D03 双臂协调力控——内力/外力分解:双臂共持一个刚体时,两手施加的力可正交分解为**外力** \(f_{ext}\)(驱动物体运动,做功)和**内力** \(f_{int}\)(相互挤压/拉伸,合力为零、不驱动运动但决定抓取稳定性)。数学上 \(f_{int}\) 位于 Grasp Matrix \(G\) 的零空间。本章 D4.5.6 设计 RL reward 时,会专门为 \(f_{int}\) 设计一项"既不过松(掉落)也不过紧(捏碎)"的奖励——这是双臂 RL 区别于单臂的核心。
- F09 学习型力控——RL 基础 + VICES:MDP 五元组 \((S, A, P, R, \gamma)\);BC 的 compounding error;VICES(Variable Impedance Control in End-effector Space)把阻抗参数 \((K, x_d)\) 作为 RL 动作而非直接输出力矩。本章 D4.5.3 策略 3 把 VICES 扩展到双臂——action 包含两臂阻抗 + 参考内力。
- F01 阻抗导纳二分法:阻抗控制方程 \(\tau = J^T(\Lambda \ddot{x}_d + D\dot{e} + Ke + f_{ext})\) 需要外力测量 \(f_{ext}\)。本章 D4.2.2 论证 ALOHA 为何**不用**阻抗——正因为 Dynamixel 没有力传感器,\(f_{ext}\) 无法可靠获取。
- 深度学习基础——Transformer / VAE / 扩散模型:self-attention 复杂度 \(O(n^2 d)\);VAE 的 ELBO 与 KL 正则;DDPM 的前向加噪/反向去噪。本章 ACT 用 CVAE(D4.3.3)、RDT-1B 用扩散 DiT(D4.4.4),都建立在这些之上。
如果跳过本章会怎样¶
- 场景 1(做家务机器人):你拿到一个折叠衣物的任务,试图用 D03 的解析协调阻抗去写规则——结果发现布料的接触模式无穷无尽,if-else 永远写不完。本章告诉你:这类任务必须用数据驱动方法(D4.1.1),且 ACT 的 50 demos 就能起步(D4.3)。
- 场景 2(复现 ALOHA 翻车):你照着论文搭了 ALOHA,却纠结"为什么不上力控做得更精细",浪费两周试图给 Dynamixel 加阻抗环——结果自激振荡。本章 D4.2.2 的三重论证会直接告诉你:位控是这套硬件的最优选择,力控精度不足由算法弥补。
- 场景 3(双臂 RL 训不出来):你直接对 14D 动作空间跑 PPO,10 万步收不到正奖励就放弃了。本章 D4.5.2-D4.5.3 会告诉你这是维度诅咒,并给出任务分解/对称性/阻抗 action/课程学习四条出路。
预计阅读时间¶
| 模式 | 时间 | 说明 |
|---|---|---|
| 精读(推导全过,跑通代码) | 15-25 小时(约 2 周) | 适合系统学习,配合 act/RDT 仓库实操 |
| 速读(理解概念,跳过推导细节) | 4-6 小时 | 抓住三创新、128D、维度诅咒、reward 设计 |
| 速查(查特定知识点) | 按需 | 用知识导航表 + 故障排查手册定位 |
D4.1 从规则到数据——双臂学习的动机与全景 ⭐¶
D4.1.1 为什么 D01-D03 的方法不够用¶
回顾 D01-D03:我们建立了双臂操作的完整解析框架——D01 给出了任务分类(独立/协调/对称)、D02 给出了协调规划(主从/虚拟物体/图搜索)、D03 给出了协调力控(扩展阻抗/内力-外力分解)。在那里我们用解析方法解决了"两个手臂如何协调完成刚性物体的搬运和装配"。
但考虑以下任务:
| 任务 | 解析方法的困难 | 为什么需要学习 |
|---|---|---|
| 折叠衣物 | 布料是无穷维软体,接触模式不可穷举 | 从人类演示中学习"在哪里抓、怎么折" |
| 烹饪(翻炒) | 食材的形状/粘度/温度不断变化 | 学习视觉-力-动作的闭环策略 |
| 电缆布线 | 细长柔性体的动力学极难建模 | 学习"拉-松-绕"的时序协调 |
| 双臂灵巧装配 | 配合面微米级精度,接触力非线性 | 学习力反馈驱动的微调策略 |
| 辅助穿衣 | 人体柔软且运动不可预测 | 学习安全的力-位协调 |
本质洞察:D01-D03 的解析框架假设"任务可以用有限个模式和参数描述"。当任务涉及的接触模式是连续的、高维的、或随环境变化的,解析方法就需要无穷多个 if-else 分支——此时数据驱动方法的优势在于:让数据本身编码这些"模式",而非由工程师手写规则。
反事实推理:如果我们坚持用 D03 的协调阻抗控制做衣物折叠会怎样?
首先,我们需要建立布料的物理模型——这需要有限元方法(FEM)或质点-弹簧系统,计算量在实时控制中不可承受。其次,即使有了模型,每次折叠的起始状态(布料的初始构型)都不同,需要在线重新规划接触序列。最后,布料与手指的摩擦模型高度非线性——滑动/滚动/剥离模式的切换使得 D03 的线性阻抗模型完全失效。
结论:不是 D01-D03 的方法"不好",而是它们适用于**几何-力学关系可解析描述的场景**(如刚性物体搬运、螺栓拧紧)。对于**接触模式复杂、环境不确定性大**的场景,学习方法是必要的补充。
D4.1.2 双臂学习的三大范式¶
双臂学习可以从三个维度分类理解:
维度 1:学习信号来源
| 范式 | 信号来源 | 代表工作 | 优势 | 劣势 |
|---|---|---|---|---|
| 模仿学习 (IL) | 人类演示 | ACT/ALOHA, Diffusion Policy | 样本效率高(50 demos);自然处理多模态 | 依赖数据质量;泛化受限 |
| 强化学习 (RL) | 奖励函数 | PPO+双臂 MDP, SAC+阻抗 | 可发现超人策略;不需演示 | 探索困难(14D+);奖励设计难 |
| 混合方法 | 演示+奖励 | 演示初始化+RL微调 | 兼顾效率和性能 | 工程复杂度高 |
维度 2:策略架构
| 架构 | 核心思想 | 代表 | 输入→输出 |
|---|---|---|---|
| Transformer BC | 自回归/CVAE 预测 action chunk | ACT | obs → \([a_t, ..., a_{t+k}]\) |
| Diffusion Policy | 条件扩散模型生成动作序列 | Chi et al. 2023 | obs → 去噪 \(a_{0:K}\) |
| 大规模基础模型 | 预训练+微调范式 | RDT-1B, Octo | (img, lang, state) → 128D action |
| 标准 RL | Actor-Critic / Policy Gradient | PPO, SAC | state → action (per step) |
维度 3:Action space 设计(双臂特有)
| 设计 | 描述 | 维度 | 适用场景 |
|---|---|---|---|
| 关节独立 | \(a = [q_L, q_R]\) | 14D (7+7) | 独立任务 |
| 笛卡尔独立 | \(a = [x_L, x_R]\) | 12D (6+6) | 无内力协调需求 |
| 相对+绝对 | \(a = [x_{abs}, \Delta x_{rel}]\) | 12D | 协调任务 |
| 分层 | 高层选子任务,低层执行 | 可变 | 复杂长程任务 |
跨领域类比:双臂学习中 action space 的设计类似于自然语言处理中 tokenizer 的选择。就像 BPE/WordPiece 把连续文本切割成合适粒度的 token 以平衡词表大小和语义完整性,action space 设计也是在平衡控制精度(维度越高越精确)和学习效率(维度越低越易探索)。选错 tokenizer 会让模型"看不懂"输入,选错 action space 会让策略"学不会"协调。
D4.1.3 科研发展脉络¶
| 年份 | 论文 | Venue | 核心贡献 |
|---|---|---|---|
| 2020 | Chitnis, Tulsiani, Gupta, "Efficient Bimanual Manipulation Using Learned Task Schemas" | ICRA 2020 | 任务 schema 作为 RL 动作空间;降低双臂探索维度 |
| 2023 | Chi et al., "Diffusion Policy: Visuomotor Policy Learning via Action Diffusion" | RSS 2023 | 条件扩散模型生成动作序列;双臂 ALOHA 基线 |
| 2023 | Zhao, Kumar, Levine, Finn, "Learning Fine-Grained Bimanual Manipulation with Low-Cost Hardware" (ACT/ALOHA) | RSS 2023 | ACT + ALOHA 硬件;50 demos 达 80-90% 成功率 |
| 2024 | Fu, Zhao, Finn, "Mobile ALOHA: Learning Bimanual Mobile Manipulation" | CoRL 2024 | ALOHA + 移动底盘;16 维 action;co-training 范式 |
| 2024 | Grotz, Shridhar, Asfour, Fox, "PerAct2: Benchmarking and Learning for Robotic Bimanual Manipulation" | CoRL 2024 | 语言条件双臂 benchmark;13 任务 \(\times\) 23 变体 |
| 2023 | Grannen et al., "Stabilize to Act: Learning to Coordinate for Bimanual Manipulation" | CoRL 2023 | 显式"stabilizer + actor"双臂分工建模 |
| 2025 | Liu et al., "RDT-1B: a Diffusion Foundation Model for Bimanual Manipulation" | ICLR 2025 | 1.2B DiT 双臂扩散基础模型;128 维统一 action space |
D4.2 ALOHA 硬件与底层控制深度解析 ⭐⭐¶
D4.2.1 ALOHA 系统架构总览¶
在深入学习算法之前,必须先理解 ALOHA 的硬件——因为**底层控制的选择直接决定了上层学习算法的 action space 设计**。这是硬件与算法 co-design 的典范案例。
ALOHA(A Low-cost Open-source Hardware System for Bimanual Teleoperation)系统由四个 WidowX/ViperX 250 机械臂组成:两个 leader(操作者手持)和两个 follower(执行端)。
ALOHA 物理架构
═══════════════════════════════════════════════════
操作者(人类) 执行端(任务空间)
┌──────────┐ ┌──────────┐
│ Leader-L │──RS-485──→ │Follower-L│
│ (WidowX) │ 50 Hz │ (ViperX) │
└──────────┘ └──────────┘
↑ USB/U2D2
┌──────────┐ │ ┌──────────┐
│ Leader-R │──RS-485──→ │Follower-R│
│ (WidowX) │ 50 Hz │ (ViperX) │
└──────────┘ └──────────┘
│
┌─────┴──────┐
│ 主控 PC │
│ Python 50Hz │
│ + 相机录制 │
└────────────┘
硬件规格:
| 参数 | Leader (WidowX 250) | Follower (ViperX 300) |
|---|---|---|
| 自由度 | 6 DOF + 1 夹爪 | 6 DOF + 1 夹爪 |
| 执行器 | Dynamixel XM430/XM540 | Dynamixel XM430/XM540 |
| 通信 | U2D2 USB-RS485 | U2D2 USB-RS485 |
| 波特率 | 3 Mbps | 3 Mbps |
| 力传感器 | 无 | 无 |
| 编码器分辨率 | 4096 步/圈 | 4096 步/圈 |
| 重复精度 | ~1 mm | ~1 mm |
| 成本 | ~$3,000/对 | ~$3,000/对 |
D4.2.2 为什么选位置控制——三重论证¶
关键事实:ALOHA 底层是**纯位置控制**,不是阻抗控制。
论文 p.5 明确写道:"all actuators to position control mode, where the underlying proprietary PID controller tracks the position target at >1 kHz."
这不是技术妥协,而是经过仔细权衡的设计决策。让我们从三个角度严格论证。
论证 1:硬件限制——无力测量能力
回顾 F01:阻抗控制的核心方程 \(\tau = J^T(\Lambda \ddot{x}_d + D\dot{e} + Ke + f_{ext})\) 中,\(f_{ext}\) 是外力测量。
Dynamixel X 系列执行器没有独立的力/力矩传感器(F/T sensor)。理论上可以从电流间接估算扭矩:
其中 \(K_t\) 是力矩常数。但这个估算存在严重问题:
| 误差来源 | 量级 | 影响 |
|---|---|---|
| 电流测量噪声 | \(\pm 50\) mA | 对应 \(\pm 0.5\) Nm 力矩噪声 |
| 齿轮箱摩擦 | 效率 ~70-85% | 实际力矩与电流不成线性关系 |
| 温度漂移 | \(K_t\) 变化 ~5% | 长时间运行后估算偏移 |
| 带宽限制 | ~100 Hz | 无法捕捉高频接触瞬态(需 >500 Hz) |
反事实推理:如果不顾这些限制,强行用电流估扭矩做阻抗闭环会怎样?
力矩噪声 \(\pm 0.5\) Nm 对应在末端(臂长 ~0.3 m)约 \(\pm 1.7\) N 的力误差。考虑到 ALOHA 的典型操作力在 1-5 N 范围,这意味着力控精度只有 \(\pm 30\%\) 到 \(\pm 100\%\)——这不是"不够好",而是**完全不可用**。阻抗控制器会因为力测量噪声持续注入能量,在硬接触时产生自激振荡。
论证 2:延迟最小化——遥操作的核心需求
Leader-Follower 映射的数据流极其简洁:
这是关节空间的直接映射(1:1 线性),不需要任何逆运动学计算、动力学补偿或力反馈环路。整个通信链路的延迟为:
延迟分解(位置控制模式)
========================================
Dynamixel sync_read: ~0.8 ms (8 关节批量读)
Python 处理 + calibration: ~0.1 ms
Dynamixel sync_write: ~0.8 ms (8 关节批量写)
────────────────────────────────────
总延迟(软件侧): ~1.7 ms
电机内部 PID 响应: ~1 ms (1 kHz PID)
────────────────────────────────────
端到端延迟: ~2.7 ms
如果加入阻抗控制环路,需要额外计算:
额外延迟(阻抗控制模式)
========================================
力/力矩估算: ~0.5 ms (电流读取+滤波)
雅可比计算 J(q): ~0.2 ms
动力学补偿 M, C, g: ~0.5 ms (Pinocchio RNEA)
阻抗律计算: ~0.1 ms
────────────────────────────────────
额外延迟: ~1.3 ms → 总延迟增加 ~50%
对遥操作而言,延迟直接影响操作者的手感和控制精度。回顾 D05 将介绍的 Ferrell 1965 经典研究:当延迟超过 ~50 ms 时,人类操作者的任务完成时间会急剧增加。ALOHA 的位置控制模式在 2.7 ms 延迟下提供了几乎即时的响应,这对精细遥操作至关重要。
论证 3:被动柔顺已满足需求
Dynamixel 的行星齿轮箱提供了一定程度的 backdrivability(反向驱动性),加上较低的 PID 增益(出厂默认),系统具有"足够的被动柔顺"来吸收操作中的不确定性:
- 论文 Figure 4c 显示:RAM 插入任务中位置跟踪误差峰值 ~1 cm
- 这 1 cm 恰好是被动柔顺在容忍装配误差
- 对于 ALOHA 的目标任务(折叠、夹取、移动物体),1 cm 的柔顺余量已经足够
本质洞察:ALOHA 的位置控制选择不是"因为便宜所以将就",而是**在遥操作+模仿学习范式下的最优工程权衡**。位控最大化了遥操作的低延迟和直觉性,而接触柔顺性的不足由学习算法(ACT 的 action chunking + temporal ensembling 提供运动平滑性)和任务选择(避免高精度力控任务)来弥补。这是一个系统级的 co-design 决策。
D4.2.3 Leader-Follower 映射的精确实现¶
# aloha_scripts/robot_utils.py 简化版
# 完整数据流:Dynamixel sync_read → 标定偏置 → sync_write → 电机 PID
import dynamixel_sdk as dxl
DT = 0.02 # 50 Hz Python 控制循环
class ALOHATeleop:
def __init__(self, leader_ids, follower_ids, port, baudrate=3_000_000):
self.leader_ids = list(leader_ids)
self.follower_ids = list(follower_ids)
self.port = dxl.PortHandler(port)
self.packet = dxl.PacketHandler(2.0) # Protocol 2.0
self.port.openPort()
self.port.setBaudRate(baudrate)
# GroupSyncRead: 批量读取 Present_Position (地址 132, 4 bytes)
self.sync_read = dxl.GroupSyncRead(
self.port, self.packet, 132, 4)
for id in self.leader_ids:
self.sync_read.addParam(id)
# GroupSyncWrite: 批量写入 Goal_Position (地址 116, 4 bytes)
self.sync_write = dxl.GroupSyncWrite(
self.port, self.packet, 116, 4)
# 标定偏置: leader 与 follower 同型号同速比时为常数
self.calibration_offset = self.compute_calibration()
def teleop_step(self):
"""单步遥操作映射——整个环路 < 2 ms"""
# 1. 批量读取 leader 关节位置 (4096 步/圈编码器)
self.sync_read.txRxPacket()
leader_pos = [self.sync_read.getData(id, 132, 4)
for id in self.leader_ids]
# 2. 减去标定偏置 (leader 与 follower 零位不同)
target_pos = [lp - offset
for lp, offset in zip(leader_pos, self.calibration_offset)]
# 3. 写入 follower 目标位置
for id, pos in zip(self.follower_ids, target_pos):
param = [dxl.DXL_LOBYTE(dxl.DXL_LOWORD(pos)),
dxl.DXL_HIBYTE(dxl.DXL_LOWORD(pos)),
dxl.DXL_LOBYTE(dxl.DXL_HIWORD(pos)),
dxl.DXL_HIBYTE(dxl.DXL_HIWORD(pos))]
self.sync_write.addParam(id, param)
self.sync_write.txPacket()
self.sync_write.clearParam()
# 4. 夹爪: 离散控制 (全开/全闭)
# 手柄按钮 → GPIO → 数字信号 → 夹爪 goal_position
gripper_target = self.read_gripper_button()
self.set_gripper(gripper_target)
关键工程细节:
| 细节 | 说明 | 为什么重要 |
|---|---|---|
| Protocol 2.0 | 支持 sync_read/sync_write 批量通信 | 8 个电机单次通信 vs 8 次串行通信 |
| 波特率 3 Mbps | RS-485 最高速率 | 保证 50 Hz 下通信不拥塞 |
| 1:1 关节映射 | Leader WidowX 与 Follower ViperX 关节结构相同 | 不需要运动映射计算(D08 将讨论异构映射) |
| 50 Hz Python | Python GIL + time.sleep(DT) 控制频率 | 足够遥操作(人手带宽 <10 Hz);比 C++ 开发快 |
| 无力反馈 | Non-bilateral:单向位置映射 | 见 D05 分析:50 Hz 下力反馈的 Z-width 不足 |
D4.2.4 从 ALOHA 到 Mobile ALOHA¶
Mobile ALOHA(Fu et al., CoRL 2024)在原始 ALOHA 基础上增加了移动底盘,将 action space 从 14D 扩展到 16D:
其中 \(v_{base}\) 和 \(\omega_{base}\) 分别是底盘的线速度和角速度。
**Co-training 范式**的核心创新:
训练数据构成:
┌──────────────────────────────┐
│ 50 人工遥操作 episodes │ ← 目标任务(如煮虾)
│ + 数千仿真/开源 episodes │ ← 非目标任务(RT-2 数据等)
└──────────────────────────────┘
↓ 联合训练
ACT policy(共享骨干)
↓
50 demos 任务成功率: 60% → 90%
为什么 co-training 有效? 直觉上,大量非目标任务数据帮助学习了通用的"机器人运动先验"——低级运动技能(如平滑轨迹、避碰)是跨任务共享的,只有高级任务语义是特定的。这与 NLP 中预训练+微调的逻辑完全一致。
Co-training 的数学理解:
设目标任务的数据分布为 \(p_{target}(o, a)\),辅助任务的数据分布为 \(p_{aux}(o, a)\)。联合训练的损失函数为:
当 \(\alpha \to 1\) 时退化为标准 BC(只看目标数据,容易过拟合 50 demos);当 \(\alpha \to 0\) 时只看辅助数据(不学目标任务)。Mobile ALOHA 的实验表明 \(\alpha \approx 0.5\) 时效果最好——目标任务和辅助任务各占一半的训练权重。
D4.2.5 ALOHA 硬件选型的工程 trade-off¶
为了让理解更完整,用表格总结 ALOHA 硬件选型中的每个决策背后的权衡:
| 决策 | 选择 | 放弃了什么 | 获得了什么 |
|---|---|---|---|
| 执行器 | Dynamixel ($300/个) | 力矩精度、backdrivability | 低成本、易集成、社区资源丰富 |
| 力传感器 | 不装 | 力反馈、主动柔顺 | 简化系统、降低延迟、降低成本 |
| 控制模式 | 位置控制 | 可编程阻抗、力精度 | 低延迟、直觉操作、硬件简单 |
| 控制频率 | 50 Hz Python | 高频力控(>500 Hz) | 快速开发、易调试、人手带宽够用 |
| 通信 | RS-485 半双工 | 全双工同时读写 | 标准接口、成本低 |
| 映射 | 1:1 关节空间 | 异构臂映射能力 | 零计算延迟、直觉对应 |
"不是 X 而是 Y"纠正:很多人认为 ALOHA "因为便宜所以性能差"。实际上 ALOHA 不是性能差——它是**在模仿学习范式下做了最优的 cost-performance 权衡**。ACT 的 action chunking 和 temporal ensembling 在算法层面弥补了硬件的力控精度不足,这才是 ALOHA 的真正创新:不是造一个更好的硬件,而是设计一个能充分利用廉价硬件的学习算法。
⚠️ 常见陷阱¶
⚠️ 编程陷阱:Dynamixel sync_read 的寄存器地址和长度必须精确匹配
错误做法:sync_read 地址写错(如 Present_Position 地址 132 写成 126)
现象:读到的是 Present_Velocity 数据,但格式解析为 position
→ 机械臂剧烈抖动或飞速旋转
根本原因:Dynamixel 寄存器是连续存储的,地址错误会读到相邻寄存器
正确做法:查阅对应型号的 Control Table,确认地址和数据长度
自检方法:先用 Dynamixel Wizard 2.0 单独读取确认值合理
💡 概念误区:认为"ALOHA 没有力反馈所以不能做力敏感任务"
新手想法:"没有力传感器 → 做不了需要力觉的任务"
实际上:ALOHA 的 ACT 策略通过视觉间接学习力信息——
物体变形的视觉特征编码了接触力的大致量级
论文中成功完成了 RAM 插入(需要毫米级精度+接触力控制)
为什么重要:视觉-力的关联是隐式的但有效的,这正是端到端学习
相比模块化方法的优势——它不需要显式的力传感通道
限制:对于需要精确力控(如手术、微装配)的任务确实不够
🧠 思维陷阱:认为"低成本硬件一定导致低性能"
新手想法:"$6000 的 ALOHA vs $100k+ 的 Franka 双臂 → 性能差 10 倍"
实际上:在模仿学习范式下,ALOHA 的性能瓶颈不在硬件而在数据——
ACT + 50 demos 在多数桌面操作任务上达到 80-90% 成功率
同样的 ACT 在 $100k 硬件上,成功率提升有限(~5%)
正确思维:性能瓶颈分析应先做 ablation——是硬件精度、还是演示数量、
还是算法容量限制了成功率?在大多数 ALOHA 任务中,答案是演示数量
练习¶
- [A 型 -- 数据流分析] 画出 ALOHA teleop 的完整数据流时序图:从 leader 电机编码器读数开始,经过 U2D2 通信、Python 处理、follower 写入、电机 PID 响应,标注每个环节的延迟。计算理论最大控制频率(不含 time.sleep)
- [B 型 -- 硬件对比] 对比 ALOHA (Dynamixel ViperX) 与 Franka 双臂 (两台 Franka Panda) 的硬件规格:自由度、力矩精度、通信延迟、力传感能力。分析在"折叠衣物"和"精密装配"两个任务上,哪个平台更适合,为什么
- [思考题] 如果 Dynamixel 未来推出了集成 F/T 传感器的新型号(力矩精度 \(\pm 0.05\) Nm),ALOHA 是否应该升级为阻抗控制底层?从 50 Hz Python 控制频率出发,用 D05 的 Z-width 公式 \(K_{max} = 2b/T\) 分析
D4.3 ACT 的三个核心创新——完整推导 ⭐⭐¶
D4.3.1 为什么传统 Behavioral Cloning 在双臂任务中失败¶
在介绍 ACT 之前,让我们先理解传统 BC 的根本问题——这样才能明白 ACT 的每个设计决策是在解决什么。
传统 BC 的公式:
给定人类演示数据集 \(\mathcal{D} = \{(o_t, a_t)\}\),BC 学习一个策略 \(\pi_\theta(a|o)\) 最小化:
问题 1:Compounding Error(复合误差)
BC 是开环的——训练时看到的观测来自专家分布 \(d_{expert}\),但执行时由于微小误差,状态会偏离专家轨迹,落入从未见过的状态分布 \(d_\pi\)。Ross et al. (2011) 证明了误差上界:
其中 \(T\) 是 episode 长度,\(\epsilon\) 是单步预测误差。对于双臂任务,\(T\) 通常在 200-500 步(50 Hz \(\times\) 4-10 秒),这意味着误差被放大 \(T^2 = 40000-250000\) 倍。
问题 2:多模态(Multi-modality)
人类执行同一任务时,路径不是唯一的——尤其在双臂任务中:
同一个"把杯子递给另一只手"的任务:
演示 1: 左手高举 → 右手从上方接
演示 2: 左手水平伸出 → 右手从侧面接
演示 3: 两手在中间汇合
MSE 损失取均值 → 策略输出三种模式的"平均" → 不对应任何有效动作!
跨领域类比:多模态问题在计算机视觉中也存在——如果让网络预测模糊图像的去模糊结果,对同一模糊输入可能有多个合理的清晰图像。MSE 损失会让网络输出多个清晰图像的"平均"——一张更模糊的图像。这就是为什么去模糊领域也引入了 GAN 和 Flow 模型来处理多模态。
问题 3:双臂任务的独特困难——协调时序
双臂任务中两臂的动作存在时序依赖:
拧瓶盖任务:
t=0-2s: 左手抓住瓶身(右手等待)
t=2-4s: 右手对准瓶盖(左手固定)
t=4-6s: 右手拧紧(左手施加反力矩)
如果策略逐步预测,在 t=2s 时误差导致瓶身偏移 2mm
→ t=2-4s 右手对准的目标位置也应相应调整
→ 但 BC 的训练数据中没有这种"偏移后的修正"
→ 右手无法对准 → 任务失败
ACT 的三个创新正是分别解决这三个问题:
| 问题 | ACT 解决方案 | 机制 |
|---|---|---|
| Compounding error | Action Chunking | 降低有效 horizon |
| Multi-modality | CVAE 潜变量 z | 显式建模执行风格 |
| 时序不一致 | Temporal Ensembling | 多 chunk 加权平均平滑 |
D4.3.2 Action Chunking——降低有效 Horizon ⭐⭐¶
核心思想:不再逐步预测单个动作 \(a_t\),而是一次性预测未来 \(k\) 步动作序列(称为一个"chunk"):
在 ALOHA 中,\(k = 100\),控制频率 50 Hz,因此一个 chunk 预测未来 2 秒的完整运动。
为什么有效——Compounding Error 的数学分析:
传统 BC 的有效决策点数为 \(T\)(每步一个决策),误差上界 \(\propto T^2\)。
Action chunking 后,有效决策点数减少为 \(T/k\)(每 \(k\) 步一个决策),误差上界变为:
其中 \(\epsilon_{chunk}\) 是 chunk 级预测误差。即使 \(\epsilon_{chunk} > \epsilon\)(预测 \(k\) 步比 1 步更难),只要 \(\epsilon_{chunk} < k^2 \epsilon\),chunk 就是有利的。
在 ALOHA 中: - \(T = 400\) 步(8 秒任务 @ 50 Hz) - \(k = 100\) - 传统 BC 有效 horizon: \(T = 400\) → 误差 \(\propto 160000\) - ACT 有效 horizon: \(T/k = 4\) → 误差 \(\propto 16\)
有效 horizon 降低 100 倍!
不是简单的轨迹插值:action chunking 与传统的"规划一条轨迹然后开环执行"有本质区别:
传统轨迹规划(开环):
t=0: 规划完整轨迹 [a_0, ..., a_{T-1}] → 开环执行全部
问题: 中途干扰完全无法响应
Action chunking(闭环 + 重叠):
t=0: 预测 chunk_0 = [a_0, ..., a_{99}] → 执行 a_0
t=1: 预测 chunk_1 = [a_1, ..., a_{100}] → 执行 a_1 (综合 chunk_0 和 chunk_1)
t=2: 预测 chunk_2 = [a_2, ..., a_{101}] → 执行 a_2 (综合三个 chunk)
...
关键: 每步都用最新观测重新预测,但只执行第一步!
→ 保持闭环能力,同时享受 chunk 带来的 horizon 压缩
双重解读:
- 角度 1 (控制论):action chunking 类似于 MPC(模型预测控制)——每步都预测未来窗口,但只执行第一步。MPC 的预测模型是物理模型,ACT 的"预测模型"是学到的 CVAE
- 角度 2 (语言模型):action chunking 类似于 LLM 的 token 生成——每次生成一个 token,但自回归地利用了之前所有 token 的信息。不同的是,ACT 是并行生成整个 chunk,而非自回归
D4.3.3 CVAE 潜变量 z——处理多模态 ⭐⭐⭐¶
动机:同一观测 \(o\) 可能对应多种合理的动作序列(不同执行风格)。标准回归损失取均值会得到"不存在的中间策略"。
ACT 的 CVAE 架构:
训练时(Encoder + Decoder):
┌─────────────────────────────┐
│ Encoder q_φ(z | o, a_seq) │
│ 输入: 观测 o + 真实动作序列 a_seq
│ 输出: μ_enc, σ_enc → z ~ N(μ_enc, σ_enc²)
└──────────┬──────────────────┘
│ z (潜在"风格"向量)
▼
┌─────────────────────────────┐
│ Decoder π_θ(a_seq | o, z) │
│ 输入: 观测 o + 潜变量 z
│ 输出: 预测动作序列 â_seq
└─────────────────────────────┘
推理时(只用 Decoder):
z = 0 (先验均值)
→ â_seq = π_θ(a_seq | o, z=0)
损失函数:
其中 \(\beta = 10\)(ACT 论文中的值)。
为什么推理时 \(z = 0\) 有效?
这是 CVAE 的标准做法,但在 ACT 的语境下值得深入理解。KL 正则化迫使编码器的后验 \(q_\phi(z|o, a_{seq})\) 接近先验 \(\mathcal{N}(0, I)\)。这意味着:
- 训练时,\(z\) 捕获了"给定观测 \(o\),不同执行风格之间的差异"
- 如果训练充分,\(z = 0\)(先验均值)对应"最典型的执行风格"
- 推理时用 \(z = 0\) 等价于选择了最高概率的动作模式
\(\beta = 10\) 的选择背后的 trade-off:
| \(\beta\) 值 | 效果 | 风险 |
|---|---|---|
| \(\beta \to 0\) | \(z\) 自由编码所有变化,重构误差最小 | \(z\) 过度编码→推理时 \(z=0\) 远离训练分布 |
| \(\beta = 1\) | 标准 VAE | 对动作精度不够 |
| \(\beta = 10\) | 强正则→\(z\) 只编码"必要的"模态差异 | ACT 论文的经验最优值 |
| \(\beta \to \infty\) | \(z\) 退化为常数(忽略潜变量) | 回退到标准回归→多模态问题回来 |
ACT Encoder 的 Transformer 实现:
# 简化版 ACT CVAE Encoder
class ACTEncoder(nn.Module):
def __init__(self, hidden_dim=512, latent_dim=32, num_layers=4):
super().__init__()
self.obs_embed = nn.Linear(obs_dim, hidden_dim)
self.action_embed = nn.Linear(action_dim * chunk_size, hidden_dim)
# Transformer encoder 处理 [CLS, obs, action_seq]
encoder_layer = nn.TransformerEncoderLayer(
d_model=hidden_dim, nhead=8, dim_feedforward=2048)
self.transformer = nn.TransformerEncoder(
encoder_layer, num_layers=num_layers)
# CLS token 的输出映射到 (μ, log_σ)
self.fc_mu = nn.Linear(hidden_dim, latent_dim)
self.fc_logvar = nn.Linear(hidden_dim, latent_dim)
def forward(self, obs, action_seq):
obs_token = self.obs_embed(obs).unsqueeze(0)
act_token = self.action_embed(action_seq.flatten()).unsqueeze(0)
cls_token = self.cls_embed.unsqueeze(0)
tokens = torch.cat([cls_token, obs_token, act_token], dim=0)
encoded = self.transformer(tokens)
cls_out = encoded[0] # CLS token 聚合了全序列信息
mu = self.fc_mu(cls_out)
logvar = self.fc_logvar(cls_out)
return mu, logvar
D4.3.4 Temporal Ensembling——多 Chunk 平滑 ⭐⭐¶
动机:即使有 action chunking,相邻时间步预测的 chunk 之间仍可能不一致——因为观测的微小变化会导致预测的 chunk 跳变。
机制:
在时间步 \(t\),有多个活跃的 chunk 覆盖了 \(a_t\):
- chunk 0(在 \(t\) 预测的):\(\hat{a}_t^{(0)}\)(刚预测的,\(a_t\) 是 chunk 的第 0 个元素)
- chunk 1(在 \(t-1\) 预测的):\(\hat{a}_t^{(1)}\)(\(a_t\) 是 chunk 的第 1 个元素)
- ...
- chunk \(i\)(在 \(t-i\) 预测的):\(\hat{a}_t^{(i)}\)(\(a_t\) 是 chunk 的第 \(i\) 个元素)
实际执行的动作是这些预测的加权平均:
权重使用指数衰减:
其中 \(m > 0\) 是衰减率。\(m\) 越大,越倾向于使用最近预测的 chunk(响应更快但更不平滑);\(m\) 越小,融合更多历史 chunk(更平滑但响应更慢)。
物理意义:
时间步: t-3 t-2 t-1 t t+1 t+2 t+3
↑
当前时刻
chunk(t-3): [· · · a₃ · · ·] w₃ = exp(-3m) 最不可信
chunk(t-2): [· · a₂ · · ·] w₂ = exp(-2m)
chunk(t-1): [· a₁ · · ·] w₁ = exp(-m)
chunk(t): [a₀ · · ·] w₀ = 1 最可信
↓
a_t = Σ wᵢaᵢ / Σ wᵢ
跨领域类比:temporal ensembling 与卡尔曼滤波在概念上同源——都是将多个不完美的估计按其"可信度"加权融合。卡尔曼滤波中,可信度由协方差矩阵决定;temporal ensembling 中,可信度由时间距离决定(越近越可信,因为观测更新鲜)。但区别在于:卡尔曼滤波有最优性保证(线性高斯情况下),temporal ensembling 是启发式的。
与不使用 temporal ensembling 的对比(消融实验):
| 配置 | 成功率 | 轨迹平滑度 | 备注 |
|---|---|---|---|
| ACT + TE (\(m=0.01\)) | 88% | 高 | 论文默认配置 |
| ACT 无 TE | 72% | 低(末端抖动) | 仅执行最新 chunk 的第一个动作 |
| ACT + TE (\(m=0.1\)) | 82% | 极高 | 过度平滑→响应延迟 |
D4.3.5 ACT 的完整推理流程¶
将三个创新组合,ACT 的完整推理流程为:
ACT 推理流程(逐步展开)
═══════════════════════════════════════
Step 1: 获取观测
o_t = {joint_positions(14D), images(2×480×640×3)}
Step 2: 编码观测
image_features = ResNet18(images) # 2×512D
obs_embedding = MLP(concat(joint_pos, image_features)) # 512D
Step 3: CVAE 解码(z=0)
z = torch.zeros(32) # 先验均值
decoder_input = concat(obs_embedding, z) # 544D
Step 4: Transformer Decoder 生成 action chunk
# query: k=100 个可学习 position embeddings
# key, value: decoder_input
chunk_t = TransformerDecoder(queries, decoder_input) # 100×14D
# chunk_t[i] = 预测的 a_{t+i},14D = 左臂7D + 右臂7D
Step 5: Temporal Ensembling
# 将 chunk_t 加入活跃 chunk 缓存
active_chunks.append(chunk_t)
# 对 a_t,取所有覆盖它的 chunk 预测的加权平均
a_t = weighted_average(active_chunks, weights=exp_decay)
Step 6: 执行
robot.set_joint_positions(a_t) # 14D → 左7D + 右7D
⚠️ 常见陷阱¶
⚠️ 编程陷阱:chunk_size 和控制频率的匹配
错误做法:chunk_size=100 但控制频率从 50 Hz 改为 20 Hz 而不调整
现象:chunk 覆盖的时间从 2s 变为 5s,策略预测过远的未来导致精度下降
根本原因:chunk_size 应按"时间长度"而非"步数"选择
正确做法:chunk_time = chunk_size / control_freq 保持 ~2s
若 freq=20Hz → chunk_size=40
自检方法:检查 chunk 最后几步的 MSE,如果远大于前几步说明 chunk 过长
💡 概念误区:认为"CVAE 的 z 在推理时应该随机采样以获得多样性"
新手想法:"训练时 z~N(μ,σ²),推理时也应采样 z~N(0,I) 增加多样性"
实际上:在机器人控制中,我们不需要"多样性"——我们需要"最可靠的动作"
z=0(先验均值)对应最高概率的模式,是最安全的选择
随机采样 z 可能生成合法但非最优的动作路径
(相当于每次执行用不同的"风格",反而增加了不可预测性)
延伸:如果你确实需要多样化(如生成训练数据),可以采样 z
但执行时始终用 z=0
练习¶
- [A 型 -- ACT 复现] 在
tonyzhaozh/act仓库中运行sim_transfer_cube_scripted(50 demos),训练 ACT 策略 2000 epochs。记录成功率曲线;消融--temporal_agg观察平滑效果 - [A 型 -- CVAE 消融] 在同一任务上,对比 \(\beta = 0.1, 1, 10, 100\) 四种 KL 权重。绘制 (a) 训练损失曲线 (b) KL 散度 (c) 评估成功率。验证 \(\beta=10\) 附近是否最优
- [思考题] 如果将 temporal ensembling 的权重从指数衰减 \(w_i = \exp(-mi)\) 改为均匀权重 \(w_i = 1\),预测效果会如何变化?从信号处理角度分析:均匀权重等价于什么滤波器?指数衰减等价于什么滤波器?
D4.4 RDT-1B——双臂扩散基础模型 ⭐⭐⭐¶
D4.4.1 从 ACT 到大规模基础模型的演进动机¶
ACT/ALOHA 证明了 50 个演示就能训练出 80-90% 成功率的双臂策略。但存在根本局限:
| ACT 的局限 | 根本原因 | 解决方向 |
|---|---|---|
| 每个任务需要独立训练 | 模型小(~10M参数),无跨任务泛化 | 大模型+预训练 |
| 对新场景泛化差 | 没有"视觉-语言理解"能力 | 多模态条件注入 |
| 不支持语言指令 | 纯视觉-动作映射 | 加入语言编码器 |
| 硬件绑定 | Action space 与特定机器人耦合 | 统一 action space |
RDT-1B (Robotics Diffusion Transformer, Liu et al., ICLR 2025) 正是为解决这些问题而设计的——它是一个 1.2B 参数的双臂扩散基础模型,通过 128 维统一 action space 支持多种机器人平台。
D4.4.2 128 维统一 Action Space 设计 ⭐⭐⭐¶
设计哲学:不同机器人的 action space 维度不同(ALOHA 14D、Franka 7D、UR5+Robotiq 7D、Mobile ALOHA 16D),如何让一个模型处理所有?
RDT-1B 的方案是定义一个 128 维的"超空间",将所有可能的机器人动作映射到固定的槽位:
128 维统一 Action Space 槽位布局
═══════════════════════════════════════════════════
槽位 0-9: 左臂关节角 (6-DOF → 填前 6; 7-DOF → 填前 7)
槽位 10-19: 右臂关节角
槽位 20-25: 左臂 EEF 位置 (x,y,z) + 6D 旋转前 3 维
槽位 26-31: 左臂 EEF 6D 旋转后 3 维
槽位 32-37: 右臂 EEF 位置 + 6D 旋转前 3 维
槽位 38-43: 右臂 EEF 6D 旋转后 3 维
槽位 100-101: 左/右夹爪开度
槽位 110-111: 底盘速度 (v, ω)
其余: 预留 / mask
未使用的槽位处理:
单臂机器人 (如 Franka Panda):
→ 只填右臂槽位 (10-19, 32-43, 101)
→ 左臂槽位全部 mask
→ Loss 计算时,mask 位置不参与梯度更新
移动底盘机器人 (如 Mobile ALOHA):
→ 填双臂槽位 + 底盘槽位 (110-111)
→ 其余 mask
固定双臂 (如 ALOHA):
→ 填双臂槽位
→ 底盘槽位 mask
本质洞察:128 维统一 action space 的设计哲学本质上是**对机器人身体结构的"词表化"**。就像 NLP 中所有语言共享同一个 token vocabulary(未使用的 token 被忽略),RDT-1B 让所有机器人共享同一个"身体 vocabulary"——这使得跨机器人的知识迁移成为可能。在机器人 A 上学到的"平滑运动"先验可以直接迁移到机器人 B,只要它们共享相同的槽位。
D4.4.3 6D 旋转表示——为什么不用四元数或欧拉角 ⭐⭐⭐¶
RDT-1B 使用 6D 旋转表示而非四元数(4D)或欧拉角(3D),核心原因是它把旋转矩阵的前两列作为一个冗余但连续的欧氏嵌入,再通过正交化解码回 \(SO(3)\)。
旋转矩阵 \(R \in SO(3)\) 的前两列展平:
恢复 \(R\) 的过程(Gram-Schmidt 正交化):
为什么常用于神经网络回归?
Zhou et al. (2019, CVPR) "On the Continuity of Rotation Representations in Neural Networks" 的重点不是简单宣称"6D 比四元数更高级",而是从拓扑上说明:如果希望神经网络在欧氏空间中回归一个**全局连续、单值、无分支切割**的旋转表示,3D 欧拉角和直接 4D 四元数都会遇到不可避免的问题。
定理直觉:\(SO(3)\) 不能被低维欧氏坐标无代价地"摊平"成一个全局连续且无歧义的 3D/4D 坐标图。四元数位于 \(S^3\),是 \(SO(3)\) 的双覆盖而非一一表示;欧拉角有周期边界和万向锁;6D 表示用旋转矩阵前两列形成到 \(\mathbb{R}^6\) 的连续嵌入,在有效集合上再通过 Gram-Schmidt 解码为合法旋转,因此更适合用普通 \(L_2\) 损失或扩散去噪来学习。
三种表示的对比:
| 表示 | 维度 | 连续性 | 不连续来源 | 对学习的影响 |
|---|---|---|---|---|
| 欧拉角 | 3D | 不连续 | 万向锁 (Gimbal Lock) | 在锁定位置附近梯度不稳定 |
| 四元数 | 4D | 连续但非单值 | 双覆盖 (\(q \equiv -q\));强制单值会产生半球边界 | \(q\) 和 \(-q\) 表示同一旋转但欧氏距离最大 |
| 6D (前两列) | 6D | 连续嵌入 | 解码时需避免两列退化/共线 | 在有效区域梯度稳定,适合回归 |
反事实推理:如果 RDT-1B 使用四元数会怎样?
考虑一个旋转从 \(R_1\) 连续变化到 \(R_2\)。同一个旋转可以由 \(q\) 或 \(-q\) 表示,如果数据预处理没有强制选择同一个半球,训练集中会出现语义相同但欧氏距离很远的标签;即使强制半球化,也会在边界处引入分支切割。扩散模型在去噪过程中会被这种等价类/边界问题干扰。
6D 表示通过冗余维度(6D 而非 \(SO(3)\) 的内在 3D)避免了四元数双覆盖和欧拉角奇异边界。它不是唯一可能的连续表示,Zhou 2019 也讨论了 5D 表示;工程上常用 6D,是因为"取矩阵前两列 + Gram-Schmidt"实现简单、数值直观,额外维度对 128 维 action space 的成本很小。
用一个具体数字看四元数的"不连续":
抽象的"双覆盖"听起来玄乎,我们算一个具体例子让它落地。考虑绕 \(z\) 轴旋转 \(\theta\) 的四元数 \(q(\theta) = (\cos\frac{\theta}{2},\, 0,\, 0,\, \sin\frac{\theta}{2})\)。让 \(\theta\) 从略小于 \(2\pi\) 连续增大越过 \(2\pi\)(物理上等于转了一整圈回到原位,旋转**没有任何跳变**):
| \(\theta\) | \(q = (\cos\frac{\theta}{2}, 0, 0, \sin\frac{\theta}{2})\) | 物理旋转 |
|---|---|---|
| \(2\pi - \delta\) | \(\approx (-1,\, 0,\, 0,\, +\delta/2)\) | 几乎转满一圈 |
| \(2\pi\) | \((-1,\, 0,\, 0,\, 0)\) | 转满一圈 = 单位旋转 |
| \(2\pi + \delta\) | \(\approx (-1,\, 0,\, 0,\, -\delta/2)\) | 刚过一圈 |
物理旋转在 \(\theta = 2\pi\) 处与 \(\theta = 0\) 完全相同(都是单位旋转 \(I\)),但四元数标签在这里是 \((-1,0,0,0)\),而 \(\theta=0\) 时是 \((+1,0,0,0)\)——同一个物理旋转,四元数标签相差一个整体符号,欧氏距离达到最大值 2。如果训练数据里既有接近 \(\theta=0\) 的样本(标签 \(\approx +1\))又有接近 \(\theta=2\pi\) 的样本(标签 \(\approx -1\)),网络被要求对几乎相同的输入输出截然相反的标签——这是不可学的。强制半球化(如规定 \(q_0 \geq 0\))能消除符号歧义,但会在 \(q_0 = 0\) 的赤道面上制造新的不连续切割:\(q_0\) 从 \(+0.01\) 滑到 \(-0.01\) 时标签会被强行翻转。
对比 6D 表示:绕 \(z\) 轴转 \(\theta\) 的旋转矩阵前两列是 \([\cos\theta, \sin\theta, 0,\, -\sin\theta, \cos\theta, 0]\),它对 \(\theta\) 是处处连续且 \(2\pi\) 周期的——\(\theta=0\) 和 \(\theta=2\pi\) 给出完全相同的 6D 向量,没有任何符号歧义或边界切割。这就是"全局连续"的直观含义。
# 教学验证:四元数 vs 6D 表示在 θ→2π 处的连续性
import numpy as np
def quat_z(t): return np.array([np.cos(t/2), 0, 0, np.sin(t/2)])
def sixd_z(t): return np.array([np.cos(t), np.sin(t), 0, -np.sin(t), np.cos(t), 0])
eps = 1e-3
# θ=0 与 θ=2π 是同一个物理旋转,理想表示在两处应几乎相等
print("quat 距离:", np.linalg.norm(quat_z(0) - quat_z(2*np.pi - eps))) # ≈ 2.0(巨大!)
print("6D 距离:", np.linalg.norm(sixd_z(0) - sixd_z(2*np.pi - eps))) # ≈ 1e-3(连续)
理论-工程桥接:这正是 D4.4.3 开头说的"全局连续无分支切割"的可计算证据。RDT-1B 在 128 维 action space 里为每只手的姿态分配 6 个槽位而非 4 个(四元数)或 3 个(欧拉角),多花的 2-3 维换来的是扩散去噪过程中梯度场的处处良态——对一个要在 \(SO(3)\) 上做 \(L_2\) 回归/去噪的模型来说,这笔交易非常划算。
D4.4.4 DiT 架构与条件注入 ⭐⭐⭐¶
RDT-1B 的主干是一个 1.2B 参数的 DiT (Diffusion Transformer)。理解其架构细节对于复现和微调至关重要。
DiT 架构参数(完整规格,来源:arXiv:2410.07864 §3 + Appendix)
═══════════════════════════════
层数: 28(每层 = self-attn + cross-attn + FFN 的标准 DiT block)
注意力头数: 32(每头 dim = 2048/32 = 64)
Hidden dim: 2048
归一化: RMSNorm(替代 LayerNorm)+ QKNorm(对 Q/K 做 L2 归一化防训练不稳定)
条件注入: Cross-attention(image/text 作为变长条件),而非 adaLN
视觉编码器: SigLIP(siglip-so400m-patch14-384,冻结)
语言编码器: T5-XXL(t5-v1_1-xxl,冻结)
输出解码器: 非线性 MLP decoder(而非标准 DiT 的线性 decoder)
参数量: ~1.2B(DiT 主干,不含冻结的编码器)
激活函数: SwiGLU(Gate 机制比 GELU 在扩散模型中更稳定)
⚠️ 论文-代码差异(CONFLICT,需澄清的常见误传):很多二手资料(包括早期版本的本章)声称 RDT-1B 像标准 DiT(Peebles & Xie 2023)那样用 adaLN-Zero 注入扩散时间步。这是错误的。RDT-1B 论文 §3 明确选择了 cross-attention 而非 adaLN 来注入条件,理由是:图像和语言条件是**变长**的(图像 token 数随相机数变化,语言 token 数随指令长度变化),而 adaLN 只能注入**固定维度**的全局向量(如时间步标量),无法处理变长的多模态条件而不丢失信息。时间步和控制频率这类标量信息则作为额外 token 拼接到输入序列。这个区分很重要——它解释了为什么 RDT 能灵活接受不同数量的相机和任意长度的语言指令。
为什么用 cross-attention 而非 adaLN——三个角度:
-
变长条件:adaLN 把条件压缩成 \((\gamma, \beta)\) 两个与 hidden_dim 等长的向量,本质是"全局调制"。但一句话指令"把红色杯子放到左边的盘子里"包含的空间-语义信息无法压进两个向量而不丢失。cross-attention 让每个动作 token 都能"查询"到它需要的那部分条件 token。
-
保留时序对称性:RMSNorm 相比 LayerNorm 去掉了减均值(centering)操作。论文指出动作是时间序列,减均值会破坏其时序对称性(动作序列整体平移一个常数在物理上是有意义的,不应被归一化抹掉)。
-
MLP 解码器的必要性:标准 DiT 用线性层把 latent 投影回像素/动作空间。RDT 换成非线性 MLP——因为机器人动力学是高度非线性的(关节空间到任务空间的映射、接触力的突变),线性解码器表达能力不足以捕捉精细操作所需的非线性。
预训练-微调流程的工程细节:
| 阶段 | 数据量 | 学习率 | batch size | 训练步数 | 硬件 |
|---|---|---|---|---|---|
| 预训练 | 46 数据集, 1M+ episodes | \(3 \times 10^{-4}\)(cosine decay) | 2048 | 300K | 48\(\times\)H100 |
| 微调 | 6K+ ALOHA episodes | \(1 \times 10^{-5}\)(constant) | 256 | 130K | 1\(\times\)H100 |
微调时冻结前 10 层(保留通用运动先验),只训练后 18 层和条件注入层。这一策略借鉴了 NLP 中 LoRA/partial freezing 的思想——底层特征(如平滑运动、关节协调)是跨任务通用的,只有高层语义需要适配新任务。
Alternating Condition Injection(交替条件注入,ACI):
这是 RDT-1B 的关键设计之一。先厘清 RDT 的输入分两类:
- 输入序列(进 self-attention):本体感受 proprioception(当前关节/位姿状态)、含噪动作 chunk、控制频率、扩散时间步——这些拼成主序列,是去噪的对象。
- 条件(进 cross-attention):图像 token(SigLIP 编码)、语言 token(T5-XXL 编码)——这些是变长的外部条件。
ACI 解决的是"图像和语言两类条件如何注入"的问题:
传统做法: 每一层 cross-attention 同时注入 image + text token
→ 问题: 图像 token 数量远多于语言 token(一张图 ~729 个 patch token,
一句指令 ~10-20 个 word token)
→ 注意力被海量图像 token 主导,语言指令信息被"淹没"
→ 后果: 模型"看图行事"但"听不懂话",指令跟随能力差
RDT-1B 做法(ACI): 在相邻层交替注入 image / text
Layer 0: image token → cross-attention
Layer 1: text token → cross-attention
Layer 2: image token → cross-attention
Layer 3: text token → cross-attention
...(28 层交替)
优势: 语言条件有专门的层来"消化",不被图像 token 数量碾压
论文原文(§3): "we strategically alternate between injecting image and
text tokens in successive layers' cross-attention rather
than injecting both in every layer"
本质洞察:ACI 的本质是**对抗"模态不平衡"导致的注意力坍缩**。当两类条件的 token 数量悬殊时,softmax 注意力天然偏向数量多的一方——这与类别不平衡时分类器偏向多数类是同一个数学现象。ACI 通过"分时复用"(每层只放一类条件)强制模型在某些层必须只看语言,从而保证指令信息不丢失。这个 trick 可迁移到任何"多模态条件 + 模态 token 数量悬殊"的场景(如文生图中的长 prompt + 参考图)。
扩散过程的数学:
前向过程(加噪):
其中 \(\bar{\alpha}_t = \prod_{s=1}^{t} \alpha_s\),\(\alpha_s = 1 - \beta_s\),\(\beta_s\) 是噪声调度。
反向过程(去噪):
其中 \(c = (c_{text}, c_{img}, c_{state})\) 是多模态条件,\(\epsilon_\theta\) 是 DiT 预测的噪声。
训练与推理规模:
| 参数 | 值 | 说明 |
|---|---|---|
| 预训练数据 | 46 个数据集, 1M+ episodes | 涵盖 ALOHA、Franka、UR、dVRK 等 |
| 预训练算力 | 48 \(\times\) H100, ~1 个月 | ~$200k 算力成本 |
| 微调数据 | 6K+ ALOHA episodes | 目标任务微调 |
| 微调步数 | 130K steps | ~24 小时/单 H100 |
| 推理速度 | 6 chunks/sec @ bf16 | 每秒 ~381 个动作 (chunk_size=64) |
| chunk_size | 64 | 短于 ACT 的 100,因模型更强 |
D4.4.5 控制频率解耦¶
ACT 中控制频率与推理频率耦合(50 Hz)。RDT-1B 引入了频率解耦:
不同数据集的原始控制频率:
ALOHA: 50 Hz
Franka: 20 Hz (MoveIt2 default)
UR5: 125 Hz
dVRK: 1000 Hz (手术机器人)
RDT-1B 统一处理:
chunk_size = 64
推理: 6 chunks/sec → 每秒产出 384 actions
目标频率: 查表 configs/dataset_control_freq.json
执行: 从 chunk 中按频率比重采样
例: 目标 50 Hz, chunk 生成 384/s → 每 chunk 取 50/6 ≈ 8 个动作
频率解耦的工程意义:
这意味着同一个 RDT-1B 模型可以在不同频率的硬件上运行,只需调整"从 chunk 中取多少动作"。这对跨平台部署至关重要——你不需要为每种硬件重新训练模型。
D4.4.6 Diffusion Policy 与 ACT 的深层对比¶
从更高的视角看,ACT 和 Diffusion Policy 代表了两种处理多模态分布的哲学:
| 维度 | ACT (CVAE) | Diffusion Policy |
|---|---|---|
| 多模态处理 | 潜变量 z 显式编码模式 | 扩散去噪隐式覆盖多模式 |
| 生成质量 | 受 VAE 的 posterior collapse 风险 | 扩散过程生成质量更高 |
| 推理速度 | 单次前向传播 (~5ms) | 多步去噪 (~50ms per step \(\times\) K steps) |
| 训练稳定性 | KL 权重 \(\beta\) 需要调优 | 简单的 MSE 噪声预测损失 |
| 理论保证 | ELBO 下界 | Score matching / SDE 理论 |
"不是 X 而是 Y"纠正:很多人认为"Diffusion Policy 是 ACT 的升级版"。实际上两者是**并行的解决方案**——Diffusion Policy 生成质量更高但推理更慢,ACT 推理更快但需要调 KL 权重。在 ALOHA 的 50 Hz 控制频率下,ACT 的 5ms 推理延迟完全可接受;但如果控制频率是 1000 Hz(如 dVRK),ACT 是唯一可行的选择(Diffusion Policy 推理太慢)。
⚠️ 常见陷阱¶
💡 概念误区:认为"128 维中大部分是浪费的"
新手想法:"ALOHA 只用 14D,128 维中 114 维是 mask → 模型在学'忽略'"
实际上:被 mask 的维度不参与 loss 计算,不消耗模型容量
相当于 NLP 中 [PAD] token 不影响训练
128 维的"浪费"带来了跨平台泛化的巨大收益
延伸:如果用可变长度 action 代替固定 128 维会怎样?
→ 需要额外的"action tokenizer",增加架构复杂度
→ 不同长度序列的 batch 处理需要 padding → 殊途同归
🧠 思维陷阱:认为"模型越大性能一定越好"
新手想法:"1.2B 参数 → 一定比 10M 的 ACT 强"
实际上:在少量数据(50 demos)场景下,RDT-1B 未必优于 ACT
大模型的优势体现在预训练+微调范式——需要 1M+ 预训练数据
如果只有 50 demos 且不做预训练,1.2B 模型反而会过拟合
正确思维:选择 ACT vs RDT-1B 取决于数据量和泛化需求
50 demos 单任务 → ACT (简单、高效、够用)
多任务+跨平台 → RDT-1B (预训练优势显现)
D4.4.7 Diffusion Policy 底层——从"取均值"到"建模分布" ⭐⭐⭐¶
前面 D4.4.6 把 ACT 和 Diffusion Policy 做了对比,但只对比不讲解是不够的——Diffusion Policy(Chi et al., RSS 2023)是与 ACT 并列的双臂模仿学习两大支柱之一,ALOHA Unleashed 和 π0 都建立在它之上。本节补上 Diffusion Policy 的完整底层推导,让你理解它为什么能从根本上解决 D4.3.1 提出的多模态问题。
动机——回到 D4.3.1 的多模态困境:
回顾 D4.3.1:人类执行"把杯子递给另一只手"有三种模式(上方接/侧面接/中间汇合),MSE 损失取均值会得到"三种模式的平均"——一个不对应任何有效动作的废动作。ACT 用 CVAE 的潜变量 \(z\) 显式编码这三种模式。Diffusion Policy 走的是另一条路:不去显式编码模式,而是直接学习"给定观测下动作的整个概率分布" \(p(a | o)\),然后从这个分布里采样。
反面——为什么回归(regression)必然取均值:
设动作的真实条件分布 \(p(a|o)\) 是多峰的(如上方接、侧面接两个峰)。回归模型 \(\pi_\theta(o)\) 输出单点 \(\hat{a}\),最小化 \(\mathbb{E}_{a \sim p(a|o)}[\|a - \hat{a}\|^2]\)。对该期望求导置零:
MSE 回归的最优解恰好是条件均值——这是数学必然,不是模型不够大的问题。两个峰的均值落在两峰之间的"谷底",正好是最不该去的地方(比如两条避障路径的平均是直接撞上障碍物)。
本质洞察:多模态问题的根源不是"网络容量不够",而是**用单点估计去拟合多峰分布这一建模方式本身的缺陷**。无论网络多大,只要输出是单点 + 用 MSE,最优解永远是均值。要解决它,必须改变输出形式——要么像 CVAE 那样引入隐变量分情况输出(ACT),要么像扩散模型那样直接建模整个分布并采样(Diffusion Policy)。这就是为什么 D4.3.1 的三个问题里,多模态是最"硬"的——它逼着整个建模范式升级。
理论——DDPM 在动作空间上的应用:
扩散模型把"从复杂分布采样"转化为"从高斯噪声逐步去噪"。对动作序列 \(a_{0} \in \mathbb{R}^{T_a \times d}\)(\(T_a\) 步、每步 \(d\) 维),定义前向加噪与反向去噪(与 D4.4.4 的 RDT-1B 扩散公式同源,这里聚焦动作生成的视角):
前向(固定,无参数)——逐步把真实动作 \(a_0\) 加噪到纯高斯:
反向(学习)——网络 \(\epsilon_\theta(a_k, k, o)\) 预测噪声,迭代去噪 \(K\) 步得到一个干净动作样本:
训练损失极其简洁——就是噪声预测的 MSE(注意:这里的 MSE 是对**噪声**而非动作,所以不会有取均值问题):
关键理解——为什么对噪声做 MSE 不会塌成均值:表面看损失也是 MSE,怎么就不取均值了?区别在于:回归直接对**多峰的动作**做 MSE(最优解=均值);扩散对**单峰的高斯噪声** \(\epsilon\) 做 MSE(最优解=条件期望 \(\mathbb{E}[\epsilon | a_k, o]\),而这个期望通过 Tweedie 公式正好等价于学习分布的得分函数 \(\nabla \log p(a_k|o)\))。得分函数编码了整个分布的形状(包括所有峰),采样时沿得分场走就能走到不同的峰。多峰性藏在"从哪个初始噪声出发 + 沿得分场怎么走"里,而非藏在单次输出里。
Diffusion Policy 的两个工程关键:
- Receding-horizon + action chunk:与 ACT 一样,Diffusion Policy 预测一个动作 chunk(论文中 \(T_a = 8\!-\!16\) 步),执行前几步后重新预测——闭环 + chunk 压缩 horizon(机制同 D4.3.2,不赘述)。
- 观测作为条件而非去噪对象:观测 \(o\)(图像 + 本体状态)只作为 \(\epsilon_\theta\) 的条件输入,不加噪。只有动作被加噪去噪。这与 RDT-1B 一致(D4.4.4:proprioception 进输入序列、动作是去噪对象)。
最小实现(教学简化版):
# 教学简化:Diffusion Policy 的训练与采样核心
# (省略 U-Net/Transformer 去噪网络的内部结构,聚焦扩散逻辑)
import torch, torch.nn.functional as F
def train_step(eps_net, obs, action_chunk, alpha_bar):
"""action_chunk: (B, T_a, d) 真实动作序列;obs: 条件"""
B = action_chunk.shape[0]
k = torch.randint(0, len(alpha_bar), (B,)) # 随机扩散步
ab = alpha_bar[k].view(B, 1, 1) # 广播到 (B,1,1)
noise = torch.randn_like(action_chunk) # 单峰高斯噪声
noisy = ab.sqrt() * action_chunk + (1 - ab).sqrt() * noise # 前向加噪
pred_noise = eps_net(noisy, k, obs) # 预测噪声(条件 obs 不加噪)
return F.mse_loss(pred_noise, noise) # 对噪声做 MSE → 不塌成均值
@torch.no_grad()
def sample(eps_net, obs, shape, alphas, alpha_bar, sigmas):
"""从纯噪声逐步去噪生成一个动作 chunk 样本"""
a = torch.randn(shape) # 从 N(0,I) 出发
for k in reversed(range(len(alpha_bar))): # K 步去噪
eps = eps_net(a, torch.full((shape[0],), k), obs)
coef = (1 - alphas[k]) / (1 - alpha_bar[k]).sqrt()
a = (a - coef * eps) / alphas[k].sqrt()
if k > 0:
a = a + sigmas[k] * torch.randn_like(a) # 注入随机性→不同峰
return a # (B, T_a, d) 动作 chunk
ACT vs Diffusion Policy 处理多模态的机制对照(深化 D4.4.6 的对比):
| 环节 | ACT(CVAE) | Diffusion Policy(DDPM) |
|---|---|---|
| 多模态藏在哪 | 潜变量 \(z\) 的不同取值对应不同模式 | 不同初始噪声 + 去噪轨迹走向不同峰 |
| 训练目标 | 重构动作的 MSE + KL 正则 | 预测噪声的 MSE(无 KL) |
| 推理时取模式 | \(z=0\) 取最典型模式(单次前向) | 采样初始噪声 + \(K\) 步去噪(多次前向) |
| 失败模式 | posterior collapse(\(z\) 被忽略,退回均值) | 去噪步数不足导致样本质量差 |
| 计算成本 | 1 次前向(~5 ms) | \(K\) 次前向(\(K{=}10{\sim}100\),~50 ms+) |
反事实推理:如果 Diffusion Policy 把去噪步数 \(K\) 设为 1 会怎样?单步去噪等价于让网络从纯噪声**一步直接回归到动作**——这退化成了一个以噪声为输入的回归器,多峰分布又会被平均掉,多模态优势消失。这正是为什么 Diffusion Policy 比 ACT 慢:它用"多步迭代"换"多模态保真",而 \(K\) 不能太小。后续工作(如 consistency models、shortcut models)正是在攻这个"既要多模态又要少步数"的矛盾。
为什么 ALOHA Unleashed 选 Diffusion Policy 而非 ACT:D4.8.4 提到 ALOHA Unleashed 在最难的灵巧任务(系鞋带、挂衬衫)上用 Diffusion Policy。原因现在清楚了:这些任务的动作多模态性极强(系鞋带的手法有无数种合理变体),ACT 的单一 \(z\) 潜变量 + posterior collapse 风险不足以覆盖如此丰富的模式,而 Diffusion Policy 的分布建模能力在数据充足时能更完整地捕捉这些模式。代价是推理慢,但 ALOHA 的 50 Hz 控制频率仍能容忍(用 DDIM 加速到 ~10 步去噪)。
⚠️ 常见陷阱¶
📄 论文误导陷阱:以为 RDT-1B 用 adaLN-Zero 注入扩散时间步(沿用标准 DiT 印象)
错误做法:照搬 Peebles & Xie 2023 的 DiT,用 adaLN 把时间步和所有条件
都压成 (γ, β) 注入
现象:实现"能跑"且 loss 下降,但语言指令跟随能力差——
模型"看图行事",换一句指令行为几乎不变
根本原因:RDT-1B 论文 §3 明确用 cross-attention(而非 adaLN)注入
图像/语言条件,因为它们是变长的;adaLN 只能注入固定维度全局向量,
会丢失变长多模态条件的信息。这是论文与"DiT 常识"的偏差
正确做法:以 RDT 论文/源码为准——条件走 cross-attention,
时间步/控制频率作为额外 token 拼进输入序列
自检方法:改变语言指令,观察生成动作是否相应变化;若几乎不变说明
语言条件被错误注入或被图像 token 淹没(见 ACI 设计 D4.4.4)
⚠️ 编程陷阱:Diffusion Policy 训练时把观测也加了噪声
错误做法:图省事,把 concat(obs, action) 整体加噪去噪
现象:训练 loss 正常,但推理时策略对观测几乎不响应(行为僵化)
根本原因:扩散的去噪对象只能是"要生成的东西"(动作)。观测是条件,
必须保持干净作为 ε_θ 的输入。给观测加噪等于训练时就破坏了条件信息
正确做法:只对 action chunk 加噪,obs 原样作为条件喂给去噪网络
自检方法:打印去噪网络的输入,确认 obs 分支在各扩散步 k 下数值不变
🧠 思维陷阱:认为"Diffusion Policy 比 ACT 先进,应该总是用它"
新手想法:"扩散模型是 2023 后的 SOTA → 双臂学习就该用 Diffusion Policy"
实际上:两者是并行方案(D4.4.6)。Diffusion Policy 在多模态强、数据充足、
控制频率不极端时占优;ACT 在数据少、需要快推理、控制频率高
(如 dVRK 1000 Hz)时占优。π0 用 flow matching(扩散变体)但
也强调要把推理压到 50 Hz 才实用
正确思维:选型先问三件事——多模态有多强?数据有多少?控制频率多高?
而非看谁"更新"
练习¶
- [B 型 -- RDT-1B 架构精读] 精读
thu-ml/RoboticsDiffusionTransformer的models/rdt/model.py。画出 alternating condition injection 的详细数据流图,标注每层处理的是哪种模态的条件,并在源码中定位"条件走 cross-attention、时间步作为 token"的实现位置(验证 D4.4.4 的论文-代码一致性) - [B 型 -- 6D 旋转验证] 实现 6D 旋转表示的编码/解码函数。生成 1000 个随机旋转矩阵,编码为 6D,加入高斯噪声 (\(\sigma=0.01\)),再解码回 \(SO(3)\)。对比 (a) 6D 表示 (b) 四元数 (c) 欧拉角 的旋转误差分布
- [A 型 -- Diffusion Policy 多模态验证] 构造一个一维 toy 任务:观测固定,专家动作以 50% 概率取 \(+1\)、50% 概率取 \(-1\)(双峰)。分别用 (a) MSE 回归 (b) Diffusion Policy 拟合。验证回归输出收敛到 \(0\)(两峰均值,错误),而 Diffusion Policy 采样能各 50% 命中 \(\pm 1\)
- [思考题] RDT-1B 的 128 维 action space 是"足够"还是"不够"?考虑:(a) 灵巧手(LEAP Hand 16 DOF \(\times\) 2 = 32 DOF,已接近关节槽位上限)(b) 人形机器人(全身 30+ DOF)。你会如何扩展这个 action space?
D4.5 Bimanual RL——从 MDP 到多臂策略 ⭐⭐¶
D4.5.1 双臂 MDP 建模的两种范式¶
双臂强化学习面临的第一个基本问题是:两条臂应该建模为一个 agent 还是两个 agent?
范式 1:集中式 (Centralized) 单 Agent MDP
- 状态:\(s = [q_L, \dot{q}_L, q_R, \dot{q}_R, o_{task}] \in S\)
- 动作:\(a = [a_L, a_R] \in A\)(14D 对于 7+7 DOF)
- 单一策略:\(\pi(a_L, a_R | s)\)
范式 2:多智能体 RL (MARL)
两条臂各有自己的策略,但共享全局奖励:
两种范式的工程对比:
| 特性 | 集中式 | MARL |
|---|---|---|
| 动作空间维度 | 14D(困难) | 7D \(\times\) 2(各自简单) |
| 协调性 | 自然协调(单策略决定两臂) | 需要通信/共享奖励保证协调 |
| 可扩展性 | 差(臂数增加 → 维度灾难) | 好(增加 agent 即可) |
| 训练稳定性 | 好(标准 RL 理论适用) | 差(非平稳环境问题) |
| 工业采用 | 主流(单 PPO/SAC 训练) | 少(理论复杂+工程复杂) |
反事实推理:如果用 MARL 训练双臂拧瓶盖任务会怎样?左臂策略 \(\pi_L\) 和右臂策略 \(\pi_R\) 各自独立优化。但在 \(\pi_L\) 看来,环境(包含 \(\pi_R\) 的行为)是非平稳的——\(\pi_R\) 在不断更新。这导致 \(\pi_L\) 刚学会"在 \(\pi_R\) 策略 v1 下如何配合",\(\pi_R\) 就更新到了 v2,\(\pi_L\) 的经验立即过时。这就是 MARL 的"非平稳环境"困难。虽然有 CTDE (Centralized Training Decentralized Execution) 等方法缓解,但在双臂场景下通常不如集中式。
D4.5.2 维度诅咒——14D 动作空间的探索困难 ⭐⭐¶
定量分析:
假设每个关节的有效动作范围被离散化为 \(N\) 个值,则:
- 单臂 7D:\(N^7\) 种组合(\(N=10\) 时,\(10^7 = 10M\))
- 双臂 14D:\(N^{14}\) 种组合(\(N=10\) 时,\(10^{14} = 100T\))
有效动作空间比例的估算(假设各维独立且可行比例为 \(p\)):
实际上,双臂的可行空间比例远低于 1%,因为: - 两臂之间的碰撞约束额外排除大量配置 - 协调任务中两臂必须满足运动学耦合(如共持物体) - 力约束(内力不能过大/过小)进一步收缩可行域
随机探索效率:
在 PPO 中,初始策略输出高斯噪声。对于 14D 高斯分布:
采样落入可行域的概率极低——实验表明,双臂 PPO 在前 100K 步几乎收不到正奖励,而单臂任务在 10K 步内就能获得首次正奖励。
D4.5.3 缓解探索困难的四种策略 ⭐⭐¶
策略 1:任务分解(Chitnis et al., ICRA 2020)
将双臂任务拆分为参数化子任务序列:
双臂搬运任务分解:
═══════════════════════
Phase 1: reach_left(target_pos) — 左手靠近物体 (3D 参数)
Phase 2: grasp_left(grasp_force) — 左手抓取 (1D 参数)
Phase 3: reach_right(target_pos) — 右手靠近物体 (3D 参数)
Phase 4: grasp_right(grasp_force) — 右手抓取 (1D 参数)
Phase 5: lift(height, velocity) — 协调抬升 (2D 参数)
Phase 6: place(place_pos) — 放置 (3D 参数)
RL 学习: 不学完整 14D 动作,而是学子任务的参数
→ 有效维度从 14D 降到 3-5D(每个子任务的参数)
→ 子任务内部用运动规划器执行(不用 RL)
策略 2:对称性利用
对于对称任务(两臂角色可互换),可以利用镜像不变性:
具体实现:
# 对称性数据增强:每条轨迹自动生成镜像版本
def augment_symmetric(trajectory):
"""将左右臂的状态和动作互换"""
mirrored = trajectory.copy()
mirrored['q_left'], mirrored['q_right'] = \
trajectory['q_right'], mirror_joints(trajectory['q_left'])
mirrored['a_left'], mirrored['a_right'] = \
trajectory['a_right'], mirror_actions(trajectory['a_left'])
return mirrored
# 在 replay buffer 中,每条真实轨迹产生一条镜像轨迹 → 2x 数据
for traj in collected_trajectories:
replay_buffer.add(traj)
replay_buffer.add(augment_symmetric(traj))
数据量翻倍,且强制策略学到对称行为。但**注意**:这只适用于对称任务(如双手同时抓取对称物体),不适用于非对称任务(如一手扶一手拧)。
策略 3:阻抗 Action Space(D03 + F09 的交叉应用)
回顾 F09(学习型力控)中的 VICES 思想,扩展到双臂场景:
其中: - \(K_L, K_R\):左右臂的笛卡尔阻抗矩阵对角元(各 6D) - \(x_{d,L}, x_{d,R}\):左右臂的目标位姿(各 6D) - \(f_{int,ref}\):参考内力(6D)
底层协调阻抗控制器(D03)保证接触稳定性——RL 只需学习"在什么位姿用什么刚度和内力"。
与纯位控 action space 的对比:
| 特性 | 关节位控 (\(a \in \mathbb{R}^{14}\)) | 阻抗 action (\(a \in \mathbb{R}^{30}\)) |
|---|---|---|
| 维度 | 14D | 30D(更高!但结构化) |
| 接触安全 | 无保证 | 阻抗底层保证 |
| 探索安全 | 随机动作可能碰撞 | 阻抗底层限制最大力 |
| 学习效率 | 需要 RL 隐式学力控 | 力控由底层处理,RL 聚焦任务 |
| 适用场景 | 无接触/轻接触 | 接触丰富任务 |
跨领域类比:action space 设计类似于编程语言中的"抽象层次"选择。关节位控 action space 类似于用汇编语言编程——灵活但需要管理所有细节;阻抗 action space 类似于用高级语言编程——底层运行时(阻抗控制器)处理内存管理(接触力控),程序员(RL)聚焦业务逻辑(任务完成)。
策略 4:课程学习
逐步增加任务难度,让策略从简单配置开始学习:
Phase 1 (0-100K steps):
左臂固定,只训练右臂抓取物体
→ 有效维度 7D,探索高效
Phase 2 (100K-300K):
两臂独立任务——各自抓取不同物体
→ 14D 但无协调需求,各臂可独立学习
Phase 3 (300K-500K):
协调任务——两臂共持一个物体
→ 在 Phase 1-2 学到的"单臂抓取"基础上增加协调
→ 探索空间被先验知识大幅缩小
D4.5.4 MARL 训练配置与实战代码 ⭐⭐¶
虽然集中式 MDP 是双臂 RL 的默认选择,但 MARL 在特定场景(如臂数可变、去中心化部署)下仍有价值。以下给出基于 MAPPO 的双臂训练配置,帮助理解集中式与去中心化训练的工程差异。
# bimanual_mappo_config.py
# 基于 MAPPO (Multi-Agent PPO) 的双臂训练配置
import torch
from stable_baselines3.common.vec_env import SubprocVecEnv
class BimanualMAPPOConfig:
"""CTDE (Centralized Training Decentralized Execution) 双臂配置"""
# === Agent 定义 ===
n_agents = 2
obs_dim_per_agent = 23 # 本臂 7q + 7dq + 任务特征 9D
shared_obs_dim = 46 # 全局状态 = 两臂 obs 拼接
action_dim_per_agent = 7 # 每臂 7 关节
# === 集中式 Critic (共享全局状态) ===
critic_config = {
'input_dim': shared_obs_dim, # Critic 看到两臂的全局状态
'hidden_dims': [256, 256, 128],
'activation': 'tanh',
'output_dim': 1, # 输出 V(s_global)
}
# === 去中心化 Actor (各自局部观测) ===
actor_config = {
'input_dim': obs_dim_per_agent, # Actor 只看本臂局部观测
'hidden_dims': [256, 256],
'activation': 'tanh',
'output_dim': action_dim_per_agent,
'share_parameters': True, # 两臂共享网络参数(对称任务)
}
# === PPO 超参数 ===
lr_actor = 3e-4
lr_critic = 5e-4
gamma = 0.99
gae_lambda = 0.95
clip_epsilon = 0.2
entropy_coeff = 0.01
value_loss_coeff = 0.5
max_grad_norm = 0.5
n_epochs = 10
n_minibatches = 32
# === 双臂特有参数 ===
reward_sharing = 'global' # 'global': 两臂共享 r; 'individual': 各自 r
communication_type = 'none' # 'none'/'message'/'attention'
parameter_sharing = True # 对称任务时两臂共享 Actor 参数
集中式 vs MARL 的定量对比(robosuite TwoArmLift):
| 方法 | 500K 步成功率 | 1M 步成功率 | 训练时间(H100) | 内存峰值 |
|---|---|---|---|---|
| 集中式 PPO (14D) | 42% | 78% | 2.1 h | 4.2 GB |
| MAPPO-共享参数 (7D\(\times\)2) | 35% | 71% | 3.8 h | 5.1 GB |
| MAPPO-独立参数 (7D\(\times\)2) | 28% | 63% | 4.5 h | 6.8 GB |
| 集中式 SAC (14D) | 51% | 85% | 1.8 h | 5.5 GB |
反事实推理:MAPPO 共享参数比独立参数快且好——因为对称任务中两臂的最优策略本质相同,共享参数等价于自动实现了对称性利用。但如果任务是非对称的(如一臂扶门、另一臂穿过门),共享参数反而会让两臂行为趋同而无法分工。
D4.5.5 Sim-to-Real Benchmark 数据——双臂迁移的定量参考 ⭐⭐⭐¶
以下汇总了公开文献中双臂 sim-to-real 迁移的定量数据,为工程决策提供参考基线。
| 论文 | 仿真器 | 真机 | 任务 | Sim 成功率 | Real 成功率 | Gap |
|---|---|---|---|---|---|---|
| ACT (Zhao 2023) | MuJoCo | ALOHA ViperX | 物体转移 | 96% | 88% | 8% |
| ACT (Zhao 2023) | MuJoCo | ALOHA ViperX | 插 RAM | 95% | 82% | 13% |
| Mobile ALOHA (Fu 2024) | — | Mobile ALOHA | 煮虾 | — | 90% | — |
| RDT-1B (Liu 2025) | — | ALOHA | 多任务平均 | — | 74% | — |
| PerAct2 (Grotz 2024) | Isaac Gym | Franka\(\times\)2 | 13 任务平均 | 89% | 61% | 28% |
| Bi-ACT (Buamanee 2024) | — | 力反馈双臂 | 软物体操作 | — | 85% | — |
| Chitnis 2020 | MuJoCo | Panda\(\times\)2 | 搬运 | 92% | 68% | 24% |
关键观察:
- 同构遥操作(ACT/ALOHA)的 gap 最小(8-13%)——因为训练数据直接来自真机遥操作,不存在 sim-to-real 转换
- 异构仿真→真机(PerAct2/Chitnis)的 gap 最大(24-28%)——接触模型和运动学标定是主要误差来源
- 力反馈增强(Bi-ACT)可以提升接触任务的真机成功率——但仅对力敏感任务(软物体操作)显著,对刚性物体搬运的增益有限
"不是 X 而是 Y"纠正:sim-to-real gap 的大小不仅取决于仿真精度——ALOHA 用的是最简单的 MuJoCo 仿真,但 gap 最小。关键在于**训练范式**:基于遥操作数据的 IL 绕过了仿真环节(数据来自真机),而基于仿真 RL 的方法必须跨越仿真-真实的鸿沟。
D4.5.6 Reward 设计——双臂特有挑战 ⭐⭐¶
穷举式分类——双臂 reward 设计的五个维度:
| 维度 | 设计选择 | 典型值 |
|---|---|---|
| 任务完成 | 稀疏 (0/1) vs 密集 (距离) | \(r_{task} = -\|x_{obj} - x_{goal}\|\) |
| 协调奖惩 | 同步运动奖励 vs 碰撞惩罚 | \(r_{coord} = -\|v_L - v_R\|\) (同步搬运) |
| 内力 | 适当内力奖励 + 过大内力惩罚 | \(r_{force} = -\alpha\|f_{int} - f_{int}^*\|\) |
| 对称/非对称 | 对称任务用对称 reward | \(r_{sym} = r_L + r_R\) (对称分配) |
| 安全约束 | 碰撞/关节极限/速度限制 | \(r_{safe} = -\beta \cdot \mathbb{1}_{collision}\) |
经验公式(双臂搬运任务):
每一项的设计细节:
def bimanual_reward(state, action, info):
"""双臂搬运任务的分项 reward"""
# 1. 接近奖励:两手都要靠近物体
dist_L = np.linalg.norm(ee_L_pos - grasp_L_pos)
dist_R = np.linalg.norm(ee_R_pos - grasp_R_pos)
r_reach = -0.1 * (dist_L + dist_R)
# 2. 抓取奖励:两手都成功抓取
r_grasp = 1.0 * (grasp_L_success + grasp_R_success)
# 3. 抬起奖励:物体高度
r_lift = 2.0 * max(0, obj_height - table_height)
# 4. 放置奖励:到达目标位置
r_place = 5.0 * (1.0 - np.tanh(5 * np.linalg.norm(obj_pos - goal_pos)))
# 5. 内力控制:适当夹紧但不过度
f_int = compute_internal_force(contact_forces)
f_int_desired = 5.0 # N
r_force = -0.5 * np.abs(f_int - f_int_desired)
# 6. 安全惩罚
r_safe = -10.0 * collision_detected - 1.0 * joint_limit_violation
return r_reach + r_grasp + r_lift + r_place + r_force + r_safe
Reward 各项的权重调优指南:
| 问题现象 | 可能原因 | 调优方向 |
|---|---|---|
| 只接近不抓取 | \(r_{grasp}\) 太小 | 增大 \(r_{grasp}\) 的稀疏奖励值 |
| 抓取后不抬起 | \(r_{lift}\) 梯度太弱 | 改为更陡的函数(如 \(r_{lift} = h^2\)) |
| 内力过大(捏碎物体) | \(r_{force}\) 惩罚不够 | 增大内力惩罚系数 \(\alpha\) |
| 两臂不协调 | 缺少同步奖励 | 添加 \(r_{sync} = -\|\dot{x}_L - \dot{x}_R\|\) |
| 策略忽略安全 | \(r_{safe}\) 惩罚太小 | 将碰撞惩罚设为终止条件 |
D4.5.7 Sim-to-Real for Bimanual——更高的保真度要求 ⭐⭐⭐¶
双臂的 sim-to-real gap 比单臂显著更大,原因的穷举式分类:
| 维度 | 单臂 | 双臂(额外) | 为什么更难 |
|---|---|---|---|
| 动力学 | 关节摩擦/齿轮间隙 | 两臂基座耦合振动 | 两臂通过桌面/基座结构耦合 |
| 运动学 | DH 参数标定误差 | 两臂相对位姿标定 | 两臂需要共同的世界坐标系 |
| 接触 | 物体-末端接触模型 | 物体-两手+物体-物体接触 | 接触对数从 1 增加到 3+ |
| 传感 | 单臂力/位传感噪声 | 两臂传感器差异 | 两臂的 F/T 传感器偏置不同 |
| 通信 | 单臂延迟 | 两臂同步延迟 | 两臂命令必须时间同步 |
Domain Randomization 参数表(双臂扩展):
randomization_ranges = {
# 单臂 DR 参数(同样适用于双臂的每条臂)
'link_mass': [-20, +20], # percent
'joint_friction': [-50, +50], # percent
'joint_damping': [-30, +30], # percent
'contact_friction': [0.3, 1.5], # 摩擦系数
'actuator_delay': [0, 5], # ms
# 双臂特有 DR 参数
'base_relative_pos': [-5, +5], # mm, 两臂基座相对位置偏移
'base_relative_rot': [-1, +1], # deg, 两臂基座相对角度偏移
'sync_delay': [0, 2], # ms, 两臂命令同步误差
'object_mass': [-30, +30], # percent, 共持物体质量
'grasp_point_noise': [-3, +3], # mm, 抓取点位置噪声(两手不同)
}
⚠️ 常见陷阱¶
⚠️ 编程陷阱:robosuite 双臂环境的 action 维度不是简单拼接
错误做法:假设 action = concat(left_action, right_action)
现象:左右臂动作"串线",左臂执行右臂命令
根本原因:robosuite 的 action 包含夹爪控制维度,
且双臂共享一个 action vector 时的维度顺序
依赖于 env 配置中 robots 的顺序
正确做法:检查 env.action_spec 确认每个维度的含义
打印 env.robots[0].action_dim 和 env.robots[1].action_dim
自检方法:发送 [1,0,...] 和 [0,...,1] 检查哪条臂响应
🧠 思维陷阱:认为"MARL 一定比集中式更适合双臂"
新手想法:"两条臂 → 两个 agent → MARL 天然适合"
实际上:在双臂操作中,两臂共享完整状态信息(同一传感器系统),
通信延迟为零(同一控制器),且需要紧密协调
→ 集中式 MDP 的假设完全满足
MARL 的优势在于部分可观测、高通信延迟、可扩展场景
(如多机器人协作、群体控制),而非双臂场景
正确思维:集中式是双臂 RL 的默认选择;MARL 只在臂数 >4 或
通信延迟显著时才考虑
练习¶
- [A 型 -- 双臂 RL 训练] 在 robosuite
TwoArmLift中用 PPO 训练双臂策略。分别用 (a) joint position action (b) 阻抗 action \([K_{abs}, x_{abs}, f_{int}]\)。对比 500K 步后的成功率。提示:使用 stable-baselines3 + robosuite wrapper - [A 型 -- 对称性消融] 在对称的双臂搬运任务中,对比 (a) 不使用对称性 (b) replay buffer 镜像增强 (c) 策略网络共享参数。记录 500K 步的学习曲线
- [跨章综合题] 结合 D03 的内力-外力分解和本章的 RL reward 设计:为一个"双臂协调拧螺栓"任务设计完整的 (a) action space (b) reward 函数 (c) 课程学习阶段。要求 action space 包含阻抗参数和内力参考值
D4.6 数据采集——双臂遥操作采集系统概述 ⭐⭐¶
D4.6.1 遥操作作为数据采集工具¶
在模仿学习范式下,数据质量直接决定策略性能。本节概述双臂遥操作数据采集系统的设计考量——完整的遥操作理论(二端口网络、波变量、TDPA)将在 D05-D07 展开,运动映射和采集系统底层分析在 D08 详述。
数据采集系统的三个层次:
┌────────────────────────────────────────────────┐
│ Layer 3: 数据管理(存储/标注/质量控制) │
│ → HDF5 格式、自动标注、质量评分 │
├────────────────────────────────────────────────┤
│ Layer 2: 运动映射(操作者 → 机器人) │
│ → 关节映射/笛卡尔映射/尺度调整 │
├────────────────────────────────────────────────┤
│ Layer 1: 硬件接口(传感器 + 执行器) │
│ → Dynamixel/Franka/SpaceMouse/VR controller │
└────────────────────────────────────────────────┘
D4.6.2 不同采集设备的对比¶
| 设备 | 成本 | 自然度 | 力反馈 | 典型框架 |
|---|---|---|---|---|
| ALOHA leader arm | $3k | 高(同构臂) | 无 | ACT/RDT-1B |
| SpaceMouse | $300 | 中(6D 摇杆) | 无 | Diffusion Policy |
| VR 手柄 (Quest 3) | $500 | 高(手部追踪) | 触觉振动 | DROID |
| Haptic 设备 (Omega.7) | $30k+ | 高 | 力反馈 | 手术遥操作 |
| 直接动觉教学 | $0 (Franka自带) | 最高 | 有(反向驱动) | Franka 阻抗模式 |
ALOHA 的采集优势:同构 leader-follower 使操作者的手部运动直接映射到机器人运动,无需心理坐标变换——这降低了操作者的认知负荷,提高了演示质量。
D4.6.3 数据格式与质量控制¶
本课程统一采用 D08 定义的 canonical schema:训练代码内部使用 observation.state、observation.images.<cam>、action、timestamp。ALOHA HDF5 是 legacy 存储格式,读取时通过 adapter 映射到 canonical schema;LeRobot 原生接近 canonical schema。
ACT/ALOHA 使用 HDF5 格式存储采集数据:
# 单个 episode 的数据结构
episode.hdf5
├── observations/
│ ├── qpos # (T, 14) 双臂关节位置
│ ├── qvel # (T, 14) 双臂关节速度
│ ├── images/
│ │ ├── cam_high # (T, 480, 640, 3) 俯视相机
│ │ ├── cam_left # (T, 480, 640, 3) 左视相机
│ │ └── cam_right # (T, 480, 640, 3) 右视相机
│ └── ee_pos # (T, 12) 双臂末端位姿 (可选)
├── action # (T, 14) 目标关节位置(follower 的 goal_position)
├── timestamps # (T,) 单调时间戳,建议补充
└── attributes/
├── success # bool, 人工标注是否成功
├── duration # float, 秒
└── task_name # string
ALOHA-HDF5 <-> LeRobot adapter 约定:
| 语义 | ALOHA HDF5 | Canonical / LeRobot |
|---|---|---|
| 状态 | observations/qpos |
observation.state |
| 速度 | observations/qvel |
observation.velocity(可选) |
| 动作 | action |
action |
| 图像 | observations/images/cam_high |
observation.images.cam_high |
| 时间 | timestamps |
timestamp |
因此 ACT 训练脚本不应同时出现 actions/ 和 action 两套字段;统一读取 canonical key,具体文件格式差异由 adapter 层处理。
数据质量控制指南:
| 质量问题 | 检测方法 | 处理方式 |
|---|---|---|
| 关节跳变 | \(\|\Delta q_t\| > 0.5\) rad | 插值平滑或丢弃 episode |
| 图像缺帧 | 时间戳间隔 \(> 1.5 \times DT\) | 丢弃或插帧 |
| 任务失败 | 人工标注 success=False | 可选保留(DAgger 风格)或丢弃 |
| 操作者犹豫 | 长时间 \(\|v\| < \epsilon\) | 标注为 pause,训练时可跳过 |
练习¶
- [编程] 使用 HDF5 格式编写一个最小化的双臂数据采集脚本:在 robosuite
TwoArmLift中录制 10 条 episode,包含qpos(14D)、images(1 camera)和action(14D)。加载后验证数据形状和值范围是否正确 - [分析] 对比 ALOHA HDF5 格式和 LeRobot 格式的字段映射关系。编写一个 adapter 函数,将 ALOHA HDF5 数据转换为 LeRobot 的 canonical schema,确保
observation.state、observation.images.<cam>、action三个字段正确映射 - [思考题] 如果采集数据的时间戳有 \(\pm\)10 ms 的随机抖动(USB 通信不稳定),对 ACT 训练的影响是什么?从 action chunking 的视角分析:chunk size \(k=100\) 对应 2s(50Hz),10ms 的时间偏移占比 0.5%——这个量级是否可忽略?如果控制频率从 50Hz 提升到 500Hz 呢?
D4.7 开源框架与基准测试 ⭐⭐¶
D4.7.1 双臂学习生态地图¶
| 框架 | 主要用途 | 双臂支持 | 关键特性 |
|---|---|---|---|
| robosuite | RL 基准 | TwoArmLift/Handover/PegInHole |
MuJoCo 后端;多种 action space |
| ManiSkill2 | 通用操作 | 双臂 benchmark | GPU 并行仿真;丰富传感器 |
| RoboCasa | 家庭场景 | 移动双臂(Mobile ALOHA) | 1000+ 场景生成;家庭任务 |
| DROID | 大规模数据 | Franka 双臂 | 76k+ 轨迹;多机构采集 |
| lerobot | 策略训练 | ACT/Diffusion Policy | HuggingFace 生态;易用 |
| act | ACT 复现 | ALOHA 14D | 官方实现;50 demos 起步 |
D4.7.2 关键代码入口¶
ACT 策略实现(lerobot 版本):
代码结构
src/lerobot/policies/act/
├── configuration_act.py # 超参数定义
├── modeling_act.py # ACTPolicy 主类
│ ├── ACTEncoder # CVAE 编码器
│ ├── ACTDecoder # Transformer 解码器
│ └── ACTPolicy.select_action() # 含 temporal ensembling
└── utils.py # chunk 管理、权重衰减
robosuite 双臂环境:
代码结构
robosuite/environments/manipulation/
├── two_arm_lift.py # 双臂抬升
├── two_arm_handover.py # 双臂递接
├── two_arm_peg_in_hole.py # 双臂插销
└── two_arm_transport.py # 双臂搬运
关键配置参数:
robots=["Panda", "Panda"] # 两台 Panda
env_configuration="single-arm-opposed" # 对面放置
controller_configs=controller_config # action space 选择
D4.7.3 项目精读清单¶
| 项目 | 精读文件 | 关注点 |
|---|---|---|
| tonyzhaozh/act | detr/models/detr_vae.py |
CVAE Transformer 实现 |
| tonyzhaozh/act | policy.py → ACTPolicy |
temporal ensembling 逻辑 |
| tonyzhaozh/act | sim_env.py |
14 维 qpos 的布局和含义 |
| thu-ml/RoboticsDiffusionTransformer | models/rdt/model.py |
DiT 主干+交替注入 |
| thu-ml/RoboticsDiffusionTransformer | configs/dataset_control_freq.json |
统一 action 映射表 |
| robosuite | two_arm_lift.py |
双臂 RL benchmark 的 reward |
D4.8 前沿工作与开放问题 ⭐⭐⭐¶
D4.8.1 力反馈增强的双臂学习¶
Bi-ACT(Buamanee-Kobayashi, 2024) 基于四通道双边控制的模仿学习:
- 使用 DOB (Disturbance Observer) + RTOB (Reaction Torque Observer) 无外力传感器估算扭矩
- 在软物体(豆腐、塑料杯)上比位控 ACT 成功率高 2-3 倍
- 硬件成本约为 ALOHA 的 10 倍以上
核心发现:对于接触丰富的软物体操作,力反馈通道提供的信息增益远超视觉——视觉无法判断"夹了多紧",但力反馈可以。
这项工作从控制理论侧验证了一个重要假设:ACT/ALOHA 在接触丰富任务上的成功率瓶颈(<60%),其根本原因不是算法容量不足,而是底层缺少力反馈信息通道。 如果要突破这一瓶颈,需要在硬件层面增加力感知能力。
D4.8.2 语言条件双臂操作¶
PerAct2(Grotz et al., CoRL 2024): - 13 个双臂任务 \(\times\) 23 个变体 = 299 种评估场景 - Voxel-Perceiver 架构预测双臂关键帧 - 语言指令驱动任务选择和执行参数
Stabilize to Act(Grannen et al., CoRL 2023): - 显式建模双臂的"稳定器"和"执行器"角色分工 - 一只手负责稳定物体状态,另一只手执行操作动作 - 这个分工建模与 D03 中的"主臂+从臂"思想相呼应,但通过学习自动发现角色分配
D4.8.3 开放问题——穷举式分类¶
| 维度 | 当前瓶颈 | 可能的突破方向 |
|---|---|---|
| 力控底层 | ACT/RDT-1B 的位控底层在装配/拧紧任务上成功率 <60% | Bi-ACT 路线:加力反馈但成本 \(\times 10\) |
| 泛化能力 | RDT-1B 对未见物体/场景泛化有限 | 更大规模预训练数据 + 3D 表示 |
| 长程推理 | 当前方法在 >30 步任务上衰减严重 | 分层策略 + 任务规划器 |
| 安全性 | RL 探索时碰撞频繁 | 安全 RL (CBF/CPO) 或 constrained policy |
| 数据效率 | 50 demos 足以 ALOHA 但不够泛化 | 仿真生成+domain adaptation |
| 实时性 | RDT-1B 推理 6 chunks/s 对力控不够快 | 模型蒸馏/量化/硬件加速 |
D4.8.4 ACT++/Diffusion Policy for Bimanual 与 ALOHA 2.0 进展 ⭐⭐⭐¶
ACT++ (2024-2025):原始 ACT 的 CVAE 结构在 KL 项权重调节上较为敏感(D4.3.3 中分析过 \(\beta\) 过大导致 z 坍缩的问题)。后续工作探索了两个改进方向:(1) 用 VQ-VAE 替代连续 CVAE,离散潜变量避免了 KL 坍缩问题;(2) 将 Diffusion Policy 的去噪过程与 action chunking 结合——每个 chunk 通过 DDPM 去噪生成而非 CVAE 解码,实验表明在多模态任务(如"从左或右绕过障碍物")上成功率提升 10-15%。
ALOHA 2(Google DeepMind, 2024, arXiv:2405.02292):这是对原始 ALOHA 的硬件迭代,核心改进**不是**增加力反馈,而是三处机械优化以提升遥操作的顺滑度和耐久性(这一点常被误传,必须澄清):
| 改进点 | 原始 ALOHA | ALOHA 2 | 效果 |
|---|---|---|---|
| 重力补偿 | 橡皮筋(易老化断裂) | 被动重力补偿——可调节伸缩拉绳(hanging retractor) | leader 臂"悬浮",操作者几乎不需对抗自重 |
| leader 电机 | XM 系列(高速比、塑料齿轮) | XC430-W150-T(低速比、金属齿轮) | 大幅降低反向驱动摩擦,遥操作更轻盈 |
| 夹爪导轨 | 普通滑轨 | 低摩擦导轨(leader + follower 都换) | leader 端提升手感;follower 端最大夹持力 12.8 N → 27.9 N(翻倍) |
| 相机 | 普通 RGB | follower 末端集成 Intel RealSense D405 | 高分辨率 RGB-D,近距离精细操作 |
本质洞察:ALOHA 2 的设计哲学与原始 ALOHA 一脉相承——不追求力反馈,而是通过降低机械摩擦让"位置-位置"单向遥操作尽可能顺滑。低速比金属齿轮降低了反向驱动摩擦,被动重力补偿抵消了自重,这两者合起来让操作者的手部运动更直接地传递到 follower。换句话说,ALOHA 2 是在"非双边遥操作"这条技术路线上继续优化,而不是转向"双边力反馈"(那是 D05-D07 的 Omega.7/TDPA 路线)。这再次印证了 D4.2.2 的判断:在模仿学习数据采集场景下,低延迟+直觉性比力反馈更重要。
ALOHA Unleashed(Google DeepMind, 2024, arXiv:2410.13126):在 ALOHA 2 硬件上把模仿学习推到极限——用 Transformer + Diffusion Policy(而非 ACT 的 CVAE)训练,配合可扩展的遥操作数据采集,在 5 个高难度灵巧双臂任务上取得成功:挂衬衫、系鞋带、更换机器人手指、插齿轮、堆叠随机初始化的厨房物品。其核心信息是:当数据规模足够大时,Diffusion Policy 的多模态建模能力使它在最难的双臂灵巧任务上超过 ACT——这与 D4.4.6 中"ACT 与 Diffusion Policy 是并行方案"的结论一致,但补充了一个边界条件:在数据充足且任务极难(多模态强)时,Diffusion Policy 占优。
π0(Physical Intelligence, 2024, arXiv:2410.24164):与 RDT-1B 同期但走了不同的技术路线。RDT-1B 是"从头训练的 DiT 扩散模型",π0 则是"在预训练 VLM(PaliGemma)骨干上外挂一个 action expert,用 flow matching(扩散的变体)生成连续动作"。两者的对比揭示了 2024-2025 双臂/通用操作基础模型的两条主线:
| 维度 | RDT-1B | π0 |
|---|---|---|
| 骨干来源 | 从头训练的 DiT | 预训练 VLM(PaliGemma 3B)+ action expert |
| 动作生成 | DDPM 去噪 | Flow matching(连续归一化流) |
| 语言理解 | 外挂 T5-XXL 编码器 | VLM 原生具备 |
| 优势 | 动作建模专门优化 | 继承 VLM 的开放世界语义理解 |
| 数据 | 46 数据集 1M+ episodes | 10k+ 小时跨平台数据 |
跨论文类比:RDT-1B 和 π0 的关系,类似于 NLP 中"从头训练专用模型"vs"在通用大模型上微调"两种路线。RDT-1B 像是为机器人动作"量身定制"了一个 DiT,把所有架构创新(统一 action space、交替条件注入、MLP 解码器)都用在动作建模上;π0 则像是"站在 VLM 巨人肩膀上",直接继承了视觉-语言大模型对开放世界的理解能力,只补一个动作生成头。哪条路线更好目前没有定论——这正是当前机器人基础模型研究的核心争论之一。
RDT 系列后续进展:RDT-1B 之后,研究团队持续探索更大规模的双臂基础模型。核心挑战在于高质量双臂数据的稀缺——Open-X Embodiment 数据集中真正的双臂协调数据不到 5%。仿真数据生成(RoboCasa/ManiSkill)和跨 embodiment 数据复用(D4.4.2 中 128D 统一 action space 的设计初衷)是突破数据瓶颈的两条主要路径。
练习¶
- [文献调研] 阅读 Bi-ACT(Buamanee-Kobayashi 2024)论文,对比其"四通道双边控制 + 模仿学习"与标准 ALOHA-ACT 在软物体操作上的成功率差异。从 D05 的透明度理论出发,分析力反馈通道提供的信息增益为什么在软物体场景下特别显著
- [思考题] PerAct2 使用语言条件驱动双臂任务选择。如果将 D03 的 Grasp Matrix 理论与语言条件策略结合——例如用语言指令指定"左手固定,右手旋转"——你认为 Grasp Matrix 可以作为策略网络的约束还是输入特征?讨论两种方案的优劣
- [跨章综合题] 结合 D03 的 Object Impedance 控制、D04 的 ACT 策略和 D08 的遥操作数据采集,设计一个"学习型双臂装配"系统的完整 pipeline:(a) 遥操作采集装配演示数据(可用 Bi-ACT 式的力反馈遥操作,因为 ALOHA 2 本身只有重力补偿、无力反馈),(b) 训练 ACT 策略但 action space 包含阻抗参数 \([K_o, D_o]\),(c) 部署时用 D03 的 QP-WBC 执行。画出系统框图并标注各模块的输入输出维度
本章常见误解汇总¶
下表汇总本章读者最容易形成的错误心智模型,与正确理解对照。每条都在正文有详细展开(标注所在节),这里作为速查与自检清单。
| # | 常见误解 | 正确理解 | 详见 |
|---|---|---|---|
| 1 | ALOHA 用力控/阻抗控制底层 | 纯**位置控制**——无力传感器,电流估扭矩噪声达 \(\pm 0.5\) Nm 不可用 | D4.2.2 |
| 2 | ALOHA 低成本所以性能差 | 在模仿学习范式下做了最优 cost-performance 权衡,瓶颈在数据而非硬件 | D4.2.5 |
| 3 | ALOHA 没力反馈就做不了力敏感任务 | ACT 通过视觉间接学力信息(物体变形编码接触力),能完成 RAM 插入 | D4.2.5 陷阱 |
| 4 | ALOHA 2 给 leader 加了力反馈 | ALOHA 2 加的是**被动重力补偿 + 低摩擦齿轮**,仍是单向位置遥操作 | D4.8.4 |
| 5 | Action chunking 就是开环轨迹规划 | 是闭环 + 重叠——每步用最新观测重新预测,只执行第一步 | D4.3.2 |
| 6 | CVAE 推理时应随机采样 \(z\) 增加多样性 | 机器人要最可靠动作,推理用 \(z=0\)(先验均值=最典型模式) | D4.3.3 陷阱 |
| 7 | MSE 回归只是网络不够大才取均值 | 是数学必然——MSE 最优解恒等于条件均值,与容量无关 | D4.4.7 |
| 8 | Diffusion Policy 是 ACT 的升级版 | 并行方案——扩散多模态强但慢,ACT 快但需调 KL;按多模态/数据/频率选 | D4.4.6, D4.4.7 |
| 9 | RDT-1B 用 adaLN-Zero 注入时间步(同标准 DiT) | 用 cross-attention 注入变长条件,不用 adaLN;QKNorm+RMSNorm | D4.4.4 |
| 10 | RDT-1B 128 维大部分是浪费 | mask 维度不参与 loss/不耗容量,128 维换来跨平台泛化 | D4.4.6 陷阱 |
| 11 | 6D 旋转表示"更高级"所以更好 | 关键是**全局连续无分支**,适合 \(L_2\)/扩散回归;四元数双覆盖、欧拉万向锁 | D4.4.3 |
| 12 | 模型越大(RDT-1B)一定比 ACT 强 | 50 demos 单任务下大模型会过拟合;大模型优势在预训练+微调范式 | D4.4.6 陷阱 |
| 13 | 双臂两条臂用 MARL 天然合适 | 双臂共享全状态、零通信延迟、需紧耦合→集中式 MDP 才是默认 | D4.5.1, D4.5.4 陷阱 |
| 14 | 14D 动作空间和单臂 7D 差不多难 | 可行空间比例从 ~10% 暴跌到 ~1%,前 100K 步几乎收不到正奖励 | D4.5.2 |
| 15 | sim-to-real gap 只取决于仿真精度 | 更取决于训练范式——遥操作 IL 绕过仿真(gap 8%),仿真 RL 必须跨鸿沟(28%) | D4.5.5 |
本章小结¶
| 知识点 | 核心结论 | 难度 |
|---|---|---|
| ALOHA 底层控制 | 纯位控——三重论证(硬件/延迟/被动柔顺) | ⭐⭐ |
| ACT Action Chunking | 有效 horizon 从 T 降到 T/k,compounding error 降低 \(k^2\) 倍 | ⭐⭐ |
| ACT CVAE | 潜变量 z 编码执行风格多模态;推理时 z=0 | ⭐⭐⭐ |
| ACT Temporal Ensembling | 多 chunk 指数衰减加权平均,平滑+抗抖动 | ⭐⭐ |
| RDT-1B 128D action space | 统一"身体词表"实现跨平台泛化 | ⭐⭐⭐ |
| 6D 旋转表示 | 旋转矩阵前两列的连续嵌入,解码简单,适合网络回归 | ⭐⭐⭐ |
| Diffusion Policy vs ACT | 并行方案:扩散更高质量但更慢,ACT 更快但需调 KL | ⭐⭐⭐ |
| 双臂 RL MDP | 集中式是默认选择;MARL 仅在 >4 臂时考虑 | ⭐⭐ |
| 维度诅咒 | 14D 可行空间比例 ~1%;任务分解/对称/阻抗 action/课程学习缓解 | ⭐⭐ |
| Reward 设计 | 五维度穷举:任务/协调/内力/对称/安全 | ⭐⭐ |
| Sim-to-Real | 双臂比单臂更难:基座耦合、相对标定、同步延迟 | ⭐⭐⭐ |
累积项目:本章新增模块¶
Mini-DualArm 项目进度:
| 章节 | 新增模块 | 功能 |
|---|---|---|
| D01 | 任务分类器 | 输入任务描述→输出独立/协调/对称类型 |
| D02 | 协调规划器 | 基于虚拟物体的双臂路径规划 |
| D03 | 协调力控器 | 扩展阻抗控制+内力-外力分解 |
| D04 | ACT 训练管线 | 50 demos → ACT 策略训练 → 双臂 14D 控制 |
| D04 | RL 训练管线 | robosuite TwoArmLift + PPO + reward 设计 |
本章新增的两个模块将在 D08(遥操作数据采集)中获得更高质量的训练数据,在 D10(综合实战)中集成到完整系统。
延伸阅读¶
| 资源 | 类型 | 难度 | 关注点 |
|---|---|---|---|
| Zhao et al. 2023, "Learning Fine-Grained Bimanual Manipulation" | 论文 | ⭐⭐ | ACT + ALOHA 原始论文 |
| Chi et al. 2023, "Diffusion Policy" | 论文 | ⭐⭐⭐ | 扩散模型做机器人控制 |
| Liu et al. 2025, "RDT-1B" | 论文 | ⭐⭐⭐ | 大规模双臂基础模型 |
| Zhou et al. 2019, "On the Continuity of Rotation Representations" | 论文 | ⭐⭐⭐⭐ | 6D 旋转表示的数学证明 |
| Ross et al. 2011, "A Reduction of Imitation Learning to No-Regret Online Learning" | 论文 | ⭐⭐ | Compounding error 理论 |
| Chitnis et al. 2020, "Efficient Bimanual Manipulation" | 论文 | ⭐⭐ | 任务 schema 降低探索维度 |
| tonyzhaozh/act GitHub 仓库 | 代码 | ⭐⭐ | ACT 官方实现 |
| thu-ml/RoboticsDiffusionTransformer | 代码 | ⭐⭐⭐ | RDT-1B 官方实现 |
| robosuite 文档 | 文档 | ⭐ | 双臂 RL 环境配置 |
| Physical-Intelligence/openpi | 代码 | ⭐⭐⭐⭐ | π0 flow-matching VLA 开源实现 |
| aloha-2.github.io / arXiv:2405.02292 | 硬件文档 | ⭐⭐ | ALOHA 2 机械改进细节 |
论文-代码映射表(两篇核心论文)¶
本章作为论文解读章,对 ACT 和 RDT-1B 两篇核心论文逐节标注其在源码中的对应位置和清晰度级别(SPECIFIED 论文与代码一致 / PARTIAL 论文提及但细节需从代码补 / UNSPECIFIED 论文未提仅代码有 / CONFLICT 论文与代码/常识不符)。
ACT(Zhao et al. 2023,仓库 tonyzhaozh/act):
| 论文章节 | 核心内容 | 对应代码 | 清晰度 | 备注 |
|---|---|---|---|---|
| §3.2 Action Chunking | 一次预测 \(k\) 步动作 | policy.py ACTPolicy / detr/models/detr_vae.py |
SPECIFIED | \(k{=}100\) 论文与代码一致 |
| §3.3 CVAE | 潜变量 \(z\) 编码风格 | detr/models/detr_vae.py (encoder/decoder) |
SPECIFIED | — |
| §3.3 KL 权重 \(\beta\) | "\(\beta\)" 符号 | --kl_weight (默认 10) |
PARTIAL | 论文给符号,具体值在命令行参数 |
| §3.4 Temporal Ensembling | 多 chunk 加权平均 | policy.py 中 all_time_actions 缓存 |
PARTIAL | 衰减率 \(m{=}0.01\) 由 --temporal_agg 触发,值在代码 |
| §3.1 观测编码 | ResNet18 + Transformer | detr/models/backbone.py |
SPECIFIED | — |
| 附录 训练超参 | "standard settings" | imitate_episodes.py / config |
UNSPECIFIED | lr、epoch 等只在代码 |
| §3.4 推理 \(z\) 取值 | 推理用先验 | policy.py 推理路径 \(z{=}0\) |
PARTIAL | 论文未强调,代码明确置零 |
RDT-1B(Liu et al. 2025,仓库 thu-ml/RoboticsDiffusionTransformer):
| 论文章节 | 核心内容 | 对应代码 | 清晰度 | 备注 |
|---|---|---|---|---|
| §3 统一 action space | 128 维物理可解释槽位 | configs/ + 数据处理脚本 |
PARTIAL | 完整槽位布局在 Appendix C,正文只给原则 |
| §3 条件注入 ACI | 交替注入 image/text | models/rdt/model.py (cross-attn 层) |
SPECIFIED | 论文 §3 明确,代码可验证 |
| §3 归一化 | RMSNorm + QKNorm | models/rdt/blocks.py |
SPECIFIED | — |
| §3 解码器 | 非线性 MLP decoder | models/rdt/model.py 输出头 |
SPECIFIED | 替代标准 DiT 线性 decoder |
| §3 条件注入方式 | cross-attention 而非 adaLN | models/rdt/model.py |
CONFLICT | 与"DiT 用 adaLN"的常识相悖,见下方歧义审计 |
| §3 编码器 | SigLIP + T5-XXL(冻结) | models/multimodal_encoder/ |
SPECIFIED | siglip-so400m / t5-v1_1-xxl |
| §4 控制频率解耦 | chunk 重采样到目标频率 | configs/dataset_control_freq.json |
PARTIAL | 论文给思路,映射表在代码 |
| §4 微调冻结策略 | 冻结底层保留先验 | 微调脚本 | UNSPECIFIED | 具体冻结层数从代码/脚本读 |
歧义审计汇总表¶
汇总本章在解读两篇核心论文时识别出的所有 PARTIAL/UNSPECIFIED/CONFLICT 项——这些是"照论文实现会踩坑"或"论文没说清需从代码补"的地方,每项都在正文有对应解读。
| 项 | 级别 | 论文怎么说 | 实际(代码/事实) | 处理位置 |
|---|---|---|---|---|
| ACT \(\beta\) 值 | PARTIAL | 只写符号 \(\beta\) | 代码默认 10,过大致 \(z\) 坍缩 | D4.3.3 trade-off 表 |
| ACT TE 衰减率 \(m\) | PARTIAL | 公式 \(w_i{=}e^{-mi}\) | 代码 \(m{=}0.01\);过大致过度平滑 | D4.3.4 消融表 |
| ACT 推理 \(z\) | PARTIAL | 未强调 | 代码置 \(z{=}0\) 而非采样 | D4.3.3 + 陷阱 |
| ACT 训练超参 | UNSPECIFIED | "standard settings" | lr/epoch/batch 在代码 config | 本节映射表 |
| RDT 条件注入 | CONFLICT | cross-attention(§3 明确) | 与"DiT 用 adaLN"常识冲突;以论文为准 | D4.4.4 + 论文误导陷阱 |
| RDT 128 槽布局 | PARTIAL | 正文给原则 | 完整布局在 Appendix C | D4.4.2(本章槽位图为示意) |
| RDT chunk_size | PARTIAL | 正文未明确 | 配置中 64 | D4.4.4 训练规模表 |
| RDT 微调冻结层 | UNSPECIFIED | 提"保留通用先验" | 具体层数从脚本读 | D4.4.4 |
关于 RDT 槽位图的诚实标注:D4.4.2 给出的"槽位 0-9 左臂关节、10-19 右臂关节……"是基于论文设计原则(按物理量预留槽位、6D 旋转、双臂+底盘+夹爪)的**教学示意布局**,帮助理解"词表化身体"的思想。论文的精确槽位编号在 Appendix C / 代码配置中定义,复现时务必以代码为准——这正是论文解读中"SPECIFIED 原则 + PARTIAL 细节"的典型情形。
范式总结与研究启发¶
本方向的核心范式¶
读完 ACT、RDT-1B、Diffusion Policy、双臂 RL 后回看,这批工作本质上在解决**同一个问题的不同侧面**:当双臂任务的接触模式无法解析建模时,如何从数据中学习一个既能多模态、又能时序协调、还能跨平台迁移的双臂策略。可以用一个统一视角串起来:
统一视角——双臂学习 = 多模态分布建模 + horizon 压缩 + 协调结构注入。 - 多模态分布建模:ACT 用 CVAE 潜变量、Diffusion Policy/π0 用扩散/flow——都在对抗"MSE 取均值"这一根本缺陷(D4.4.7)。 - horizon 压缩:action chunking 几乎被所有方法采纳(ACT/RDT/DP),把 compounding error 从 \(T^2\) 压到 \((T/k)^2\)(D4.3.2)。 - 协调结构注入:要么靠数据(同构遥操作让协调隐式进数据,D4.2)、要么靠 action space 结构(阻抗 action + 内力参考,D4.5.3)、要么靠统一表示(128D 身体词表,D4.4.2)。
三者缺一不可——只解决多模态不压缩 horizon 会有 compounding error;压缩了 horizon 不注入协调结构则双臂各行其是。理解这个三元组,就能评估任何一篇新的双臂学习论文"补了哪一块"。
跨方向迁移¶
| 迁移目标 | 为什么可行 | 预期挑战 |
|---|---|---|
| 灵巧手操作(多指) | 多指协调与双臂协调同构——都是高维 + 内力 + 多模态 | 接触点数量级增加,128D 槽位不够,需扩展 action space |
| 移动操作(Mobile ALOHA) | action space 加底盘维度即可(D4.2.4 已示范 16D) | 导航与操作的时间尺度差异大,单一 chunk 难兼顾 |
| 人形全身控制 | chunking + 扩散建模可迁移 | 30+ DOF + 平衡约束,探索/安全远难于双臂 |
| 多机器人协作 | 这里 MARL 才真正适用(部分可观测、高通信延迟) | 与双臂相反——集中式假设不再成立(D4.5.1) |
组合创新头脑风暴¶
| 组合方案 | 预期效果 | 可行性 | 最大风险 |
|---|---|---|---|
| Diffusion Policy + 阻抗 action space(D4.4.7 + D4.5.3) | 多模态 + 接触安全兼得 | 中 | 阻抗参数的多模态分布是否真存在多峰 |
| RDT-1B 128D 词表 + 灵巧手槽位扩展 | 跨"臂+手"平台统一基础模型 | 中高 | 关节槽位上限,需重设计槽位布局 |
| ACT/DP + D03 内力-外力分解作为显式约束 | 把物理先验注入学习策略,减少数据需求 | 高 | 约束与学习目标的权衡,可能限制策略灵活性 |
| π0 式 VLM 骨干 + 双臂协调 reward 微调 | 开放世界语义 + 协调精度 | 中 | VLM 推理速度对双臂实时控制的瓶颈 |
科研启发(代码中的发现):ACT 推理时硬置 \(z{=}0\) 而非采样,论文未充分讨论。这暗示一个未探索方向——能否用一个轻量"风格选择器"在线选 \(z\)(而非固定 0),让策略在不同任务阶段切换执行风格?这与 D4.5.3 的分层思想呼应,可能是低成本提升 ACT 多模态能力的方向。
API 速查表¶
本章涉及的核心 API / 配置项签名速查(按用途分组)。
| 用途 | API / 配置 | 关键参数 | 说明 |
|---|---|---|---|
| Dynamixel 批量读 | GroupSyncRead(port, packet, addr, len) |
addr=132(Present_Position), len=4 | 8 电机单次通信,见 D4.2.3 |
| Dynamixel 批量写 | GroupSyncWrite(port, packet, addr, len) |
addr=116(Goal_Position), len=4 | 位控目标写入 |
| ACT 训练 | imitate_episodes.py |
--kl_weight 10 --chunk_size 100 --temporal_agg |
tonyzhaozh/act 入口 |
| ACT 策略 | ACTPolicy.__call__(qpos, image, actions, is_pad) |
训练传 actions,推理不传 | CVAE 训练/推理双路径 |
| LeRobot ACT | lerobot/policies/act/modeling_act.py ACTPolicy.select_action() |
含 temporal ensembling | HuggingFace 生态 |
| RDT 模型 | models/rdt/model.py RDT |
hidden=2048, depth=28, heads=32 | DiT 主干 |
| RDT 频率表 | configs/dataset_control_freq.json |
各数据集目标 Hz | 控制频率解耦 D4.4.5 |
| robosuite 双臂 | suite.make("TwoArmLift", robots=["Panda","Panda"]) |
env_configuration, controller_configs |
RL benchmark 入口 |
| robosuite 动作检查 | env.action_spec / env.robots[i].action_dim |
— | 确认双臂动作维度顺序(防串线,D4.5.2 陷阱) |
| 6D 旋转解码 | Gram-Schmidt(前两列→正交化→叉积) | 输入 \(\mathbb{R}^6\),输出 \(SO(3)\) | D4.4.3 公式 |
本章与后续章节的关系¶
| 后续章节 | 关系 | 本章铺垫的知识点 |
|---|---|---|
| D05 双边遥操作理论 | 本章 D4.2.2 用到的延迟/Z-width 论证在 D05 严格展开(Ferrell 延迟、二端口网络、波变量、TDPA) | 位控低延迟优势、为何不上力反馈 |
| D08 遥操作数据采集系统底层 | 本章 D4.6 概述的采集系统在 D08 深入(异构运动映射、canonical schema、采集质量控制) | HDF5/LeRobot 格式、1:1 关节映射的局限 |
| D09 双臂 MoveIt2 系统集成 | 本章学到的策略需要部署到真实双臂系统 | action space 设计、双臂碰撞约束 |
| D10 综合实战 Mini-DualArm | 本章的 ACT 训练管线 + RL 管线集成到完整系统 | 两个累积项目模块 |
🔧 故障排查手册¶
| 症状 | 可能原因 | 排查步骤 | 相关章节 |
|---|---|---|---|
| ACT 训练 loss 不下降 | 数据加载错误/标准化参数不对 | 1. 检查数据 shape 和范围 2. 打印前 5 个 batch 的统计量 3. 确认 action 标准化参数来自训练集 | 本章 3.2 |
| ACT 推理时机械臂抖动 | temporal ensembling 未启用/衰减率 m 过大 | 1. 确认 --temporal_agg 为 True 2. 降低 m 值(试 0.01) 3. 检查 chunk 缓存是否正确更新 |
本章 3.4 |
| 双臂 RL reward 不涨 | 探索不足/reward 各项权重失衡 | 1. 打印各 reward 分项 2. 检查前 100K 步是否有正奖励 3. 添加课程学习(先训单臂) | 本章 5.4 |
| robosuite 双臂 action "串线" | action 维度顺序与假设不符 | 1. 打印 env.action_spec 2. 发送 one-hot action 确认维度 3. 检查 robots 列表顺序 | 本章 5.2 |
| RDT-1B 微调后性能反而下降 | 微调数据太少/学习率过大 | 1. 检查微调数据量(>100 episodes) 2. 降低学习率(1e-5 → 1e-6) 3. 增加预训练权重的 warmup 步数 | 本章 4.4 |
| Diffusion Policy 推理慢到无法实时 | 去噪步数 \(K\) 太多 | 1. DDPM(\(K{=}100\))换成 DDIM(\(K{=}10\!\sim\!20\)) 2. 减小 action chunk 长度 3. 用 bf16/编译加速 | 本章 4.7 |
| Diffusion Policy 输出动作"发飘"/不响应观测 | 误把观测也加噪了 | 1. 确认只对 action 加噪 2. 打印各扩散步 obs 分支数值应不变 3. 检查条件输入是否接对 | 本章 4.7 |
| RDT 复现"看图行事"但不听指令 | 误用 adaLN 或图像 token 淹没语言 | 1. 确认条件走 cross-attention 2. 确认 ACI 交替注入 image/text 3. 改指令测动作是否变 | 本章 4.4 |
| ACT 每次执行风格抖动/不一致 | 推理时误采样了 \(z\) | 1. 确认推理路径 \(z{=}0\) 而非 \(z\sim\mathcal{N}(0,I)\) 2. 检查是否误用训练分支 | 本章 3.3 |
| 给 Dynamixel 加阻抗环后自激振荡 | 电流估扭矩噪声注入能量 | 1. 退回纯位控 2. 若必须力控换带 F/T 的硬件 3. 用 D05 Z-width 校核增益上限 | 本章 2.2 |
研究实践建议¶
按学习阶段分层给出建议,避免初学者一上来就啃最难的部分:
入门阶段(第 1 周)——先把 ACT 跑通
- 不要从 RDT-1B/π0 这类大模型入手——它们需要多卡和海量数据,初学者很难跑通且学不到核心。从
tonyzhaozh/act的仿真任务sim_transfer_cube_scripted(50 demos)起步,单卡即可。 - 重点体会三个创新的**消融效果**:关掉
--temporal_agg看末端抖动,调--kl_weight看 \(z\) 坍缩,缩短--chunk_size看 compounding error 回来。把抽象推导变成你亲眼看到的现象。 - 不要纠结"为什么不上力控"——先接受位控,理解 D4.2.2 的三重论证后自然就通了。
进阶阶段(第 2-3 周)——理解分布建模与基础模型
- 做 D4.4.7 的练习 3(一维双峰 toy 任务),亲手验证 MSE 回归塌成均值、Diffusion Policy 能采样到两峰。这是理解所有现代模仿学习的"题眼"。
- 精读 RDT-1B 源码时,带着歧义审计表去读——重点确认"条件走 cross-attention 而非 adaLN"这一与常识相悖的设计,培养"以代码为准、不盲信论文/二手资料"的习惯。
- 双臂 RL 不要直接上 14D PPO——先做 D4.5.3 的课程学习(先固定一臂训另一臂),亲身体会维度诅咒和它的缓解。
研究阶段——从复现到创新
- 选型决策先问三件事:多模态有多强?数据有多少?控制频率多高?(D4.4.7 思维陷阱)。不要因为"更新"就选 Diffusion Policy/VLA。
- 关注本章范式总结的"三元组缺口"——任何新双臂论文都可以问"它补了多模态、horizon、协调结构里的哪一块",这是快速定位贡献的框架。
- 工程落地优先考虑 action space 结构化(阻抗 action + 内力参考,D4.5.3 策略 3)——把物理先验注入比堆数据更省力,这也是 D03 与 D04 交叉的最大价值点。
本质洞察:本章最值得带走的不是某个具体算法,而是一条判断主线——模仿学习的所有进步,本质都在回答"如何更好地建模动作的条件分布"。从 BC 的单点回归(取均值,失败),到 ACT 的 CVAE(隐变量分情况),到 Diffusion Policy/π0 的扩散/flow(直接建模分布并采样),是一条清晰的认知升级链。抓住这条主线,未来任何新方法你都能迅速定位它在链条上的位置。
版本信息速查¶
本章涉及的关键工具/模型版本与规格汇总,便于复现时对齐环境:
| 项目 | 版本 / 规格 | 来源 |
|---|---|---|
| ACT / ALOHA | RSS 2023,arXiv:2304.13705 | Zhao, Kumar, Levine, Finn |
| Mobile ALOHA | CoRL 2024,arXiv:2401.02117,16D action | Fu, Zhao, Finn |
| ALOHA 2(硬件) | 2024,arXiv:2405.02292,被动重力补偿+低摩擦 | Google DeepMind / Trossen |
| ALOHA Unleashed | 2024,arXiv:2410.13126,Diffusion Policy | Google DeepMind |
| Diffusion Policy | RSS 2023,arXiv:2303.04137 | Chi et al. |
| RDT-1B | ICLR 2025,arXiv:2410.07864,1.2B DiT,128D action | Liu et al. (THU) |
| π0 | 2024,arXiv:2410.24164,flow matching VLA | Physical Intelligence |
| PerAct2 | CoRL 2024,13 任务 \(\times\) 23 变体 | Grotz, Shridhar, Asfour, Fox |
| Stabilize to Act | CoRL 2023,稳定器+执行器分工 | Grannen et al. |
| Bi-ACT | 2024,四通道双边控制+IL | Buamanee, Kobayashi |
| Chitnis 任务 schema | ICRA 2020 | Chitnis, Tulsiani, Gupta |
| 6D 旋转表示 | CVPR 2019,arXiv:1812.07035 | Zhou et al. |
| Compounding error 界 | ICML 2011(DAgger) | Ross, Gordon, Bagnell |
| DiT(标准) | ICCV 2023,adaLN-Zero(RDT 未采用) | Peebles, Xie |
| robosuite | TwoArmLift/Handover/PegInHole/Transport | MuJoCo 后端 |
| RDT 编码器 | SigLIP (siglip-so400m-patch14-384) + T5-XXL (t5-v1_1-xxl) | 均冻结 |
| RDT 主干 | 28 层 DiT,hidden 2048,32 头,~1.2B | 不含冻结编码器 |