# Human-In-the-Loop 数据收集

Human-In-the-Loop (HIL) 数据收集允许您通过在真实机器人上部署已训练的策略，并由人类操作员在必要时进行监控和干预，来改进该策略。干预数据（恢复动作和纠正）会与自主片段一起被记录，从而生成更丰富的训练数据集，教会策略如何处理失败。

---

## 为什么需要人在回路？

标准行为克隆仅在成功的演示数据上训练策略。在部署过程中，微小的误差可能会累积，将机器人推入训练期间从未见过的状态（分布偏移）。人类在环（HIL）数据收集通过以下方式解决这一问题：

- 在真实机器人上运行训练好的策略
- 在机器人即将失败时由人类介入
- 将人类的恢复和纠正记录为训练数据
- 在合并数据集上微调策略

这将生成一种策略，它不仅知道如何执行任务，还知道在出现问题时如何恢复。

---

## 工作原理

在 HIL 会话期间，人类操作员在每个回合内遵循以下循环：

1. **观看**策略自主运行
2. **暂停** 当故障即将发生时，机器人保持当前位置
3. **接管控制**，通过远程操作将机器人恢复到良好状态（恢复），然后纠正其行为
4. **将控制权交还给策略**，策略将恢复自主执行
5. 在回合期间，根据需要重复步骤 2–4
6. 任务完成后，**结束该回合**，保存并进入下一次 rollout

默认情况下，仅记录由人类控制的片段（恢复和纠正），且每次纠正都会成为一个独立的 episode。使用 `--strategy.record_autonomous=true` 时，自主片段也会被记录：策略和人类可以多次交替控制，自主执行、恢复和纠正会被捕获在一条连续的轨迹中。在这两种模式下，机器人在每次控制权交接后都会从其当前状态继续运行（即使发生了干预，也无需重置）。收集完成后，合并后的数据集（原始演示 + HIL 数据）将用于微调策略。

该过程可以迭代重复：部署、收集、微调、再重复。每一轮都针对当前策略的失效模式。

```
┌─────────────────────────────────────────────────────────────────────────┐
│  Policy v0 (trained on demos)                                           │
│       ↓                                                                 │
│  HIL Collection (target current failure modes) → Fine-tune → Policy v1  │
│       ↓                                                                 │
│  HIL Collection (target new failure modes) → Fine-tune → Policy v2      │
│       ↓                                                                 │
│  ... (repeat until satisfactory performance)                            │
└─────────────────────────────────────────────────────────────────────────┘
```

---

## 硬件要求

### 遥操作要求

`lerobot-rollout --strategy.type=dagger` 模式需要能够执行以下操作的**带有活动电机的遥操作器**：

- 以编程方式启用/禁用扭矩
- 移动至目标位置（以在暂停时镜像机器人状态）

暂停时，主臂会移动以匹配机器人的位置，从而在策略和人类之间平滑地切换控制权。如果发生跳变，这些跳变会被记录到修正数据中，导致策略学习到不连贯的轨迹。

**兼容的遥操作器：**

- `bi_openarm_mini` - 双手操作 OpenArm Mini
- `so100_leader` / `so101_leader` - SO100 / SO101 主臂
- `bi_so_leader` - 双手 SO100 / SO101 主臂

> [!IMPORTANT]
> 提供的命令默认使用 `bi_openarm_follower` + `bi_openarm_mini`。SO100 / SO101 的设置方式相同，例如使用 `--robot.type=so101_follower` 搭配 `--teleop.type=so101_leader`。

---

## 脚本

使用 `lerobot-rollout` 并配合 `--strategy.type=dagger` 进行 HIL 数据收集。使用 `--inference.type=sync|rtc|remote` 选择推理后端：

| 模式                     | 标志                      | 模型                                                                                                 |
| ------------------------ | ------------------------- | ------------------------------------------------------------------------------------------------------ |
| 标准（默认）       | _（无需标志）_        | ACT、Diffusion Policy                                                                                  |
| 实时分块（RTC） | `--inference.type=rtc`    | Pi0, Pi0.5, SmolVLA                                                                                    |
| 远程                   | `--inference.type=remote` | 由 `lerobot-policy-server` 提供的检查点；请参阅 [远程部署要求](./remote_inference) |

---

## 分步指南

### 步骤 1：预训练基础策略

首先，在您的演示数据集上训练一个策略。此示例训练了 ACT，它将在第 2 步中以标准推理方式运行：

```bash
lerobot-train \
    --dataset.repo_id=${HF_USER}/demo-dataset \
    --policy.type=act \
    --policy.repo_id=${HF_USER}/act_pretrain \
    --output_dir=outputs/pretrain \
    --batch_size=32 \
    --steps=50000
```

### 步骤 2：收集 HIL 数据

**标准推理（ACT、Diffusion Policy）：**

```bash
lerobot-rollout --strategy.type=dagger \
    --robot.type=bi_openarm_follower \
    --robot.left_arm_config.port=can1 \
    --robot.left_arm_config.side=left \
    --robot.right_arm_config.port=can0 \
    --robot.right_arm_config.side=right \
    --robot.cameras='{left_wrist: {type: opencv, index_or_path: "/dev/video0", width: 1280, height: 720, fps: 30}, right_wrist: {type: opencv, index_or_path: "/dev/video4", width: 1280, height: 720, fps: 30}, base: {type: opencv, index_or_path: "/dev/video2", width: 640, height: 480, fps: 30}}' \
    --teleop.type=bi_openarm_mini \
    --teleop.left_arm_config.port=/dev/ttyACM0 \
    --teleop.right_arm_config.port=/dev/ttyACM1 \
    --policy.path=outputs/pretrain/checkpoints/last/pretrained_model \
    --dataset.repo_id=${HF_USER}/rollout_hil_dataset \
    --dataset.single_task="Fold the T-shirt properly" \
    --dataset.fps=30 \
    --strategy.num_episodes=50 \
    --interpolation_multiplier=2
```

使用 `--interpolation_multiplier=N` 时，机器人每个策略动作会接收 `N` 个插值命令（控制以 `fps × N` Hz 运行），而策略推理和数据集录制仍保持 `--fps`，因此录制的数据集与其声明的 FPS 一致。

**使用 RTC 处理大型模型（Pi0、Pi0.5、SmolVLA）：**

对于推理延迟较高的模型，请启用 RTC 以实现流畅执行。这需要 VLA 基础策略，例如 Pi0、Pi0.5 或 SmolVLA，而不是第 1 步中的 ACT 策略：

```bash
lerobot-rollout --strategy.type=dagger \
    --inference.type=rtc \
    --inference.rtc.execution_horizon=20 \
    --inference.rtc.max_guidance_weight=5.0 \
    --inference.rtc.prefix_attention_schedule=LINEAR \
    --robot.type=bi_openarm_follower \
    --robot.left_arm_config.port=can1 \
    --robot.left_arm_config.side=left \
    --robot.right_arm_config.port=can0 \
    --robot.right_arm_config.side=right \
    --robot.cameras='{left_wrist: {type: opencv, index_or_path: "/dev/video0", width: 1280, height: 720, fps: 30}, right_wrist: {type: opencv, index_or_path: "/dev/video4", width: 1280, height: 720, fps: 30}, base: {type: opencv, index_or_path: "/dev/video2", width: 640, height: 480, fps: 30}}' \
    --teleop.type=bi_openarm_mini \
    --teleop.left_arm_config.port=/dev/ttyACM0 \
    --teleop.right_arm_config.port=/dev/ttyACM1 \
    --policy.path=outputs/pretrain/checkpoints/last/pretrained_model \
    --dataset.repo_id=${HF_USER}/rollout_hil_rtc_dataset \
    --dataset.single_task="Fold the T-shirt properly" \
    --dataset.fps=30 \
    --strategy.num_episodes=50 \
    --interpolation_multiplier=3
```

**控制项：**

| 密钥     | 操作                                                                  |
| ------- | ----------------------------------------------------------------------- |
| `Space` | 暂停策略 / 恢复策略                                    |
| `Tab`   | 开始/停止校正（仅在暂停时可用）；校正内容将被记录 |
| `Enter` | 将数据集推送到 Hub（仅更正模式）                     |
| `ESC`   | 停止会话                                                        |

可以使用 USB 脚踏板代替键盘，方法是使用 `--strategy.input_device=pedal`。有关所有 DAgger 标志，请参阅 [策略部署](./inference)。

**HIL 协议：**

1. 观看策略自主运行（遥操作处于空闲/自由状态）
2. 当您发现即将失败时，按 `Space` 键以 **暂停**
   - 策略停止
   - 遥操作者移动以匹配机器人位置（力矩已启用）
   - 暂停期间未记录任何帧
3. 按 `Tab` 键以 **接管控制**
   - 遥操作扭矩已禁用，可自由移动
   - **恢复**：通过远程操作将机器人恢复到良好状态
   - **更正**：修正行为
   - 所有移动均会被记录
4. 再次按 `Tab` 结束修正，然后按 `Space` **将控制权交还给策略**
   - Policy 从当前状态恢复自主执行
   - 您可以随时再次进行干预（重复步骤 2–4）
5. 在默认模式下，每次纠正都会作为独立的 episode 保存。使用 `--strategy.record_autonomous=true` 时，所有内容都会被记录并自动拆分为 episode。
6. 按 `ESC` 停止会话

**脚踏板设置（Linux）：**

如果使用 USB 脚踏开关（PCsensor FootSwitch），请确保可以访问：

```bash
sudo setfacl -m u:$USER:rw /dev/input/by-id/usb-PCsensor_FootSwitch-event-kbd
```

### 步骤 3：合并数据集

`lerobot-rollout` 会在数据集名称中添加时间戳，因此第 2 步中的 HIL 数据集将保存为 `your-username/rollout_hil_dataset_YYYYMMDD_HHMMSS`。请在下方使用该完整名称。

HIL 数据集包含一个额外的 `intervention` 列，用于标记由人类控制的帧，而只有在特征相同的情况下才能合并数据集。请先删除该列，然后将 HIL 数据与您的演示数据合并：

```bash
lerobot-edit-dataset \
    --repo_id ${HF_USER}/rollout_hil_dataset_YYYYMMDD_HHMMSS \
    --new_repo_id ${HF_USER}/hil_dataset_no_intervention \
    --operation.type remove_feature \
    --operation.feature_names "['intervention']"

lerobot-edit-dataset \
    --new_repo_id ${HF_USER}/demo_plus_hil \
    --operation.type merge \
    --operation.repo_ids "['${HF_USER}/demo-dataset', '${HF_USER}/hil_dataset_no_intervention']"
```

两个数据集还必须使用相同的机器人、相机和 fps。有关更多合并选项，请参阅 [使用数据集工具](./using_dataset_tools#merge-datasets)。

### 步骤 4：微调策略

在步骤 1 的**合并**数据集上微调策略：

```bash
lerobot-train \
    --dataset.repo_id=${HF_USER}/demo_plus_hil \
    --policy.path=outputs/pretrain/checkpoints/last/pretrained_model \
    --policy.repo_id=${HF_USER}/act_hil_finetune \
    --output_dir=outputs/hil_finetune \
    --steps=20000
```

然后部署微调后的策略，并从步骤 2 开始重复，以针对其剩余的失败模式。

---

## 高效 HIL 数据收集技巧

### 何时进行干预

当您看到以下内容时进行干预：

- 即将犯下不可挽回错误的机器人
- 机器人犹豫不决或表现出行为不确定的状态
- 机器人偏离预期轨迹

### 恢复：通过远程操作回到良好状态

在恢复过程中，通过远程操作将机器人恢复到以下状态：

- 机器人处于熟悉的、分布内的配置中
- 当前子任务仍然可以完成
- 恢复轨迹本身也是有价值的训练数据

### 修正质量

在纠正过程中：

- 提供**可靠且干净**的轨迹
- 完整完成当前子任务
- 不要过度纠正或添加不必要的动作

---

## 相关工作

这种 HIL 数据采集方法建立在交互式模仿学习的理念之上：

- **DAgger**（Ross 等人，2011）提出了核心思想：不仅使用专家演示进行训练，还针对_学习者_访问的状态向专家查询修正。这通过迭代收集在线策略数据，打破了标准行为克隆中复合错误的循环。

- **HG-DAgger**（Kelly 等人，2019）使这一方法在机器人领域变得实用：人类专家监控机器人，仅在必要时介入，而非为每个状态进行标注。自主控制与人类控制之间的切换，正是本处脚本中使用的暂停 → 接管 → 返回策略循环。

- **RaC**（Hu 等人，2025）通过将干预措施显式分解为**恢复**（通过遥操作回到良好状态）和**纠正**（从该状态演示正确行为），将该循环扩展至长时程任务。这种分解正是`lerobot-rollout`中 DAgger 策略所遵循的协议。

- **π0.6/RECAP**（Physical Intelligence，2025）在 VLA 模型上以大规模应用了相同的迭代式收集与微调循环，表明即使是大型预训练策略，也能从针对其自身失败模式的人工纠正中显著受益。π0.6 是使用 RECAP 进行训练的。

```bibtex
@article{ross2011dagger,
  title={A Reduction of Imitation Learning and Structured Prediction to No-Regret Online Learning},
  author={Ross, Stéphane and Gordon, Geoffrey and Bagnell, Drew},
  journal={Proceedings of the Fourteenth International Conference on Artificial Intelligence and Statistics},
  year={2011}
}

@article{kelly2019hgdagger,
  title={HG-DAgger: Interactive Imitation Learning with Human Experts},
  author={Kelly, Michael and Sidrane, Chelsea and Driggs-Campbell, Katherine and Kochenderfer, Mykel J},
  journal={arXiv preprint arXiv:1810.02890},
  year={2019}
}

@article{hu2025rac,
  title={RaC: Robot Learning for Long-Horizon Tasks by Scaling Recovery and Correction},
  author={Hu, Zheyuan and Wu, Robyn and Enock, Naveen and Li, Jasmine and Kadakia, Riya and Erickson, Zackory and Kumar, Aviral},
  journal={arXiv preprint arXiv:2509.07953},
  year={2025}
}

@article{pi2025recap,
  title={π0.6: a VLA That Learns From Experience},
  author={Physical Intelligence},
  year={2025}
}
```

