跳转至

本文档属于 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 阻抗导纳二分法

本章目标

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

  1. 深入理解 ACT/ALOHA 的底层控制选择——为什么 ALOHA 选位控而非阻抗,从硬件限制、延迟、被动柔顺三个角度严格论证
  2. 掌握 ACT 的三个核心创新(action chunking、CVAE 潜变量 z、temporal ensembling)的数学推导和工程实现
  3. 理解 RDT-1B 的 128 维统一 action space 设计哲学,以及 6D 旋转表示为何优于四元数和欧拉角
  4. 分析 bimanual RL 的特殊挑战——14 维动作空间的探索困难、对称/非对称 reward 设计、内力学习
  5. 实现 在 robosuite TwoArmLift 中训练双臂 RL 策略,对比不同 action space 的样本效率
  6. 批判性评估 当前双臂学习方法的瓶颈与前沿突破方向

本章知识导航

本章是一篇**论文解读 + 算法工程**的混合章——既要逆向恢复 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)。理论上可以从电流间接估算扭矩:

\[\hat{\tau}_{motor} = K_t \cdot i_{measured}\]

其中 \(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 映射的数据流极其简洁:

leader.present_position  →  follower.goal_position

这是关节空间的直接映射(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:

\[a = [q_{L,1}, ..., q_{L,7}, q_{R,1}, ..., q_{R,7}, v_{base}, \omega_{base}] \in \mathbb{R}^{16}\]

其中 \(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)\)。联合训练的损失函数为:

\[\mathcal{L}_{co-train} = \alpha \cdot \mathbb{E}_{p_{target}} [\|a - \pi_\theta(o)\|^2] + (1-\alpha) \cdot \mathbb{E}_{p_{aux}} [\|a - \pi_\theta(o)\|^2]\]

\(\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 任务中,答案是演示数量

练习

  1. [A 型 -- 数据流分析] 画出 ALOHA teleop 的完整数据流时序图:从 leader 电机编码器读数开始,经过 U2D2 通信、Python 处理、follower 写入、电机 PID 响应,标注每个环节的延迟。计算理论最大控制频率(不含 time.sleep)
  2. [B 型 -- 硬件对比] 对比 ALOHA (Dynamixel ViperX) 与 Franka 双臂 (两台 Franka Panda) 的硬件规格:自由度、力矩精度、通信延迟、力传感能力。分析在"折叠衣物"和"精密装配"两个任务上,哪个平台更适合,为什么
  3. [思考题] 如果 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)\) 最小化:

\[\mathcal{L}_{BC} = \mathbb{E}_{(o,a) \sim \mathcal{D}} \left[ \|a - \pi_\theta(o)\|^2 \right]\]

问题 1:Compounding Error(复合误差)

BC 是开环的——训练时看到的观测来自专家分布 \(d_{expert}\),但执行时由于微小误差,状态会偏离专家轨迹,落入从未见过的状态分布 \(d_\pi\)。Ross et al. (2011) 证明了误差上界:

\[J(\pi) - J(\pi^*) \leq T^2 \epsilon\]

其中 \(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"):

\[\pi_\theta(o_t) = [a_t, a_{t+1}, ..., a_{t+k-1}]\]

在 ALOHA 中,\(k = 100\),控制频率 50 Hz,因此一个 chunk 预测未来 2 秒的完整运动。

为什么有效——Compounding Error 的数学分析

传统 BC 的有效决策点数为 \(T\)(每步一个决策),误差上界 \(\propto T^2\)

Action chunking 后,有效决策点数减少为 \(T/k\)(每 \(k\) 步一个决策),误差上界变为:

\[J(\pi) - J(\pi^*) \leq \left(\frac{T}{k}\right)^2 \epsilon_{chunk}\]

其中 \(\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)

损失函数

\[\mathcal{L} = \underbrace{\|a_{seq} - \hat{a}_{seq}\|^2}_{\text{重构损失}} + \beta \cdot \underbrace{D_{KL}(q_\phi(z|o, a_{seq}) \| \mathcal{N}(0, I))}_{\text{KL 散度正则}}\]

其中 \(\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\) 个元素)

实际执行的动作是这些预测的加权平均:

\[a_t = \frac{\sum_{i=0}^{k-1} w_i \cdot \hat{a}_t^{(i)}}{\sum_{i=0}^{k-1} w_i}\]

权重使用指数衰减:

\[w_i = \exp(-m \cdot 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

练习

  1. [A 型 -- ACT 复现]tonyzhaozh/act 仓库中运行 sim_transfer_cube_scripted(50 demos),训练 ACT 策略 2000 epochs。记录成功率曲线;消融 --temporal_agg 观察平滑效果
  2. [A 型 -- CVAE 消融] 在同一任务上,对比 \(\beta = 0.1, 1, 10, 100\) 四种 KL 权重。绘制 (a) 训练损失曲线 (b) KL 散度 (c) 评估成功率。验证 \(\beta=10\) 附近是否最优
  3. [思考题] 如果将 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 = [\mathbf{r}_1; \mathbf{r}_2] = [R_{11}, R_{21}, R_{31}, R_{12}, R_{22}, R_{32}] \in \mathbb{R}^6\]

恢复 \(R\) 的过程(Gram-Schmidt 正交化)

\[\mathbf{r}_1' = \text{normalize}(\mathbf{r}_1)$$ $$\mathbf{r}_2' = \text{normalize}(\mathbf{r}_2 - (\mathbf{r}_2 \cdot \mathbf{r}_1')\mathbf{r}_1')$$ $$\mathbf{r}_3' = \mathbf{r}_1' \times \mathbf{r}_2'$$ $$R = [\mathbf{r}_1', \mathbf{r}_2', \mathbf{r}_3']\]

为什么常用于神经网络回归?

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——三个角度

  1. 变长条件:adaLN 把条件压缩成 \((\gamma, \beta)\) 两个与 hidden_dim 等长的向量,本质是"全局调制"。但一句话指令"把红色杯子放到左边的盘子里"包含的空间-语义信息无法压进两个向量而不丢失。cross-attention 让每个动作 token 都能"查询"到它需要的那部分条件 token。

  2. 保留时序对称性:RMSNorm 相比 LayerNorm 去掉了减均值(centering)操作。论文指出动作是时间序列,减均值会破坏其时序对称性(动作序列整体平移一个常数在物理上是有意义的,不应被归一化抹掉)。

  3. 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 + 参考图)。

扩散过程的数学

前向过程(加噪):

\[a^{(t)} = \sqrt{\bar{\alpha}_t} a^{(0)} + \sqrt{1 - \bar{\alpha}_t} \epsilon, \quad \epsilon \sim \mathcal{N}(0, I)\]

其中 \(\bar{\alpha}_t = \prod_{s=1}^{t} \alpha_s\)\(\alpha_s = 1 - \beta_s\)\(\beta_s\) 是噪声调度。

反向过程(去噪):

\[a^{(t-1)} = \frac{1}{\sqrt{\alpha_t}}\left(a^{(t)} - \frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}}\epsilon_\theta(a^{(t)}, t, c)\right) + \sigma_t z\]

其中 \(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]\)。对该期望求导置零:

\[\frac{\partial}{\partial \hat{a}} \mathbb{E}[\|a - \hat{a}\|^2] = -2\mathbb{E}[a - \hat{a}] = 0 \implies \hat{a} = \mathbb{E}_{a \sim p(a|o)}[a]\]

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\) 加噪到纯高斯:

\[a_k = \sqrt{\bar{\alpha}_k}\, a_0 + \sqrt{1 - \bar{\alpha}_k}\, \epsilon, \quad \epsilon \sim \mathcal{N}(0, I)\]

反向(学习)——网络 \(\epsilon_\theta(a_k, k, o)\) 预测噪声,迭代去噪 \(K\) 步得到一个干净动作样本:

\[a_{k-1} = \frac{1}{\sqrt{\alpha_k}}\left(a_k - \frac{1-\alpha_k}{\sqrt{1-\bar{\alpha}_k}}\epsilon_\theta(a_k, k, o)\right) + \sigma_k z, \quad z \sim \mathcal{N}(0, I)\]

训练损失极其简洁——就是噪声预测的 MSE(注意:这里的 MSE 是对**噪声**而非动作,所以不会有取均值问题):

\[\mathcal{L}_{DP} = \mathbb{E}_{a_0, \epsilon, k}\left[\|\epsilon - \epsilon_\theta(\sqrt{\bar{\alpha}_k} a_0 + \sqrt{1-\bar{\alpha}_k}\epsilon,\, k,\, o)\|^2\right]\]

关键理解——为什么对噪声做 MSE 不会塌成均值:表面看损失也是 MSE,怎么就不取均值了?区别在于:回归直接对**多峰的动作**做 MSE(最优解=均值);扩散对**单峰的高斯噪声** \(\epsilon\) 做 MSE(最优解=条件期望 \(\mathbb{E}[\epsilon | a_k, o]\),而这个期望通过 Tweedie 公式正好等价于学习分布的得分函数 \(\nabla \log p(a_k|o)\))。得分函数编码了整个分布的形状(包括所有峰),采样时沿得分场走就能走到不同的峰。多峰性藏在"从哪个初始噪声出发 + 沿得分场怎么走"里,而非藏在单次输出里。

Diffusion Policy 的两个工程关键

  1. Receding-horizon + action chunk:与 ACT 一样,Diffusion Policy 预测一个动作 chunk(论文中 \(T_a = 8\!-\!16\) 步),执行前几步后重新预测——闭环 + chunk 压缩 horizon(机制同 D4.3.2,不赘述)。
  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 才实用
   正确思维:选型先问三件事——多模态有多强?数据有多少?控制频率多高?
            而非看谁"更新"

练习

  1. [B 型 -- RDT-1B 架构精读] 精读 thu-ml/RoboticsDiffusionTransformermodels/rdt/model.py。画出 alternating condition injection 的详细数据流图,标注每层处理的是哪种模态的条件,并在源码中定位"条件走 cross-attention、时间步作为 token"的实现位置(验证 D4.4.4 的论文-代码一致性)
  2. [B 型 -- 6D 旋转验证] 实现 6D 旋转表示的编码/解码函数。生成 1000 个随机旋转矩阵,编码为 6D,加入高斯噪声 (\(\sigma=0.01\)),再解码回 \(SO(3)\)。对比 (a) 6D 表示 (b) 四元数 (c) 欧拉角 的旋转误差分布
  3. [A 型 -- Diffusion Policy 多模态验证] 构造一个一维 toy 任务:观测固定,专家动作以 50% 概率取 \(+1\)、50% 概率取 \(-1\)(双峰)。分别用 (a) MSE 回归 (b) Diffusion Policy 拟合。验证回归输出收敛到 \(0\)(两峰均值,错误),而 Diffusion Policy 采样能各 50% 命中 \(\pm 1\)
  4. [思考题] 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

\[\mathcal{M} = (S, A, P, R, \gamma)\]
  • 状态:\(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)

两条臂各有自己的策略,但共享全局奖励:

\[\pi_L(a_L | o_L), \quad \pi_R(a_R | o_R)\]

两种范式的工程对比

特性 集中式 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\)):

\[P_{feasible,single} = p^7 \approx 10\% \quad (p \approx 0.73)$$ $$P_{feasible,dual} = p^{14} \approx 1\% \quad (\text{各维独立假设下})\]

实际上,双臂的可行空间比例远低于 1%,因为: - 两臂之间的碰撞约束额外排除大量配置 - 协调任务中两臂必须满足运动学耦合(如共持物体) - 力约束(内力不能过大/过小)进一步收缩可行域

随机探索效率

在 PPO 中,初始策略输出高斯噪声。对于 14D 高斯分布:

\[\pi_0(a) = \mathcal{N}(0, \sigma^2 I_{14})\]

采样落入可行域的概率极低——实验表明,双臂 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:对称性利用

对于对称任务(两臂角色可互换),可以利用镜像不变性:

\[\pi(s_L, s_R) = \text{mirror}(\pi(s_R, s_L))\]

具体实现:

# 对称性数据增强:每条轨迹自动生成镜像版本
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 思想,扩展到双臂场景:

\[a = [K_L, x_{d,L}, K_R, x_{d,R}, f_{int,ref}]\]

其中: - \(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%

关键观察

  1. 同构遥操作(ACT/ALOHA)的 gap 最小(8-13%)——因为训练数据直接来自真机遥操作,不存在 sim-to-real 转换
  2. 异构仿真→真机(PerAct2/Chitnis)的 gap 最大(24-28%)——接触模型和运动学标定是主要误差来源
  3. 力反馈增强(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}\)

经验公式(双臂搬运任务)

\[r(s, a) = \underbrace{r_{reach}}_{\text{接近物体}} + \underbrace{r_{grasp}}_{\text{抓取成功}} + \underbrace{r_{lift}}_{\text{抬起高度}} + \underbrace{r_{place}}_{\text{放置精度}} + \underbrace{r_{force}}_{\text{内力控制}} + \underbrace{r_{safe}}_{\text{安全惩罚}}\]

每一项的设计细节:

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 或
            通信延迟显著时才考虑

练习

  1. [A 型 -- 双臂 RL 训练] 在 robosuite TwoArmLift 中用 PPO 训练双臂策略。分别用 (a) joint position action (b) 阻抗 action \([K_{abs}, x_{abs}, f_{int}]\)。对比 500K 步后的成功率。提示:使用 stable-baselines3 + robosuite wrapper
  2. [A 型 -- 对称性消融] 在对称的双臂搬运任务中,对比 (a) 不使用对称性 (b) replay buffer 镜像增强 (c) 策略网络共享参数。记录 500K 步的学习曲线
  3. [跨章综合题] 结合 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.stateobservation.images.<cam>actiontimestamp。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,训练时可跳过

练习

  1. [编程] 使用 HDF5 格式编写一个最小化的双臂数据采集脚本:在 robosuite TwoArmLift 中录制 10 条 episode,包含 qpos(14D)、images(1 camera)和 action(14D)。加载后验证数据形状和值范围是否正确
  2. [分析] 对比 ALOHA HDF5 格式和 LeRobot 格式的字段映射关系。编写一个 adapter 函数,将 ALOHA HDF5 数据转换为 LeRobot 的 canonical schema,确保 observation.stateobservation.images.<cam>action 三个字段正确映射
  3. [思考题] 如果采集数据的时间戳有 \(\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.pyACTPolicy 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 的设计初衷)是突破数据瓶颈的两条主要路径。

练习

  1. [文献调研] 阅读 Bi-ACT(Buamanee-Kobayashi 2024)论文,对比其"四通道双边控制 + 模仿学习"与标准 ALOHA-ACT 在软物体操作上的成功率差异。从 D05 的透明度理论出发,分析力反馈通道提供的信息增益为什么在软物体场景下特别显著
  2. [思考题] PerAct2 使用语言条件驱动双臂任务选择。如果将 D03 的 Grasp Matrix 理论与语言条件策略结合——例如用语言指令指定"左手固定,右手旋转"——你认为 Grasp Matrix 可以作为策略网络的约束还是输入特征?讨论两种方案的优劣
  3. [跨章综合题] 结合 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.pyall_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 不含冻结编码器