# Сбор данных с участием человека

Сбор данных с участием человека (Human-In-the-Loop, HIL) позволяет улучшить обученную политику, развернув её на реальном роботе, пока оператор наблюдает за процессом и вмешивается при необходимости. Данные о вмешательствах (движения для восстановления и корректировки) записываются вместе с автономными сегментами, что формирует более богатый набор данных для обучения, обучающий политику справляться с ошибками.

---

## Зачем нужен Human-In-the-Loop?

Стандартное поведенческое клонирование обучает политики только на успешных демонстрациях. Во время развертывания небольшие ошибки могут накапливаться и выводить робота в состояния, которые не встречались во время обучения (сдвиг распределения). Сбор данных HIL решает эту проблему следующим образом:

- Запуск обученной политики на реальном роботе
- Вмешательство человека в момент, когда робот вот-вот совершит ошибку
- Запись восстановления и корректировок человека в качестве обучающих данных
- Доработка политики на объединённом наборе данных

Это позволяет получить политику, которая не только знает, как выполнить задачу, но и как восстановиться, если что-то пошло не так.

---

## Как это работает

В ходе сессии HIL человек-оператор выполняет следующий цикл в каждом эпизоде:

1. **Посмотреть**, как политика работает автономно
2. **Пауза**: когда сбой неизбежен, робот удерживает позицию
3. **Возьмите управление на себя** и дистанционно верните робота в рабочее состояние (восстановление), затем скорректируйте его поведение
4. **Вернуть управление политике**, политика возобновляет автономное выполнение
5. Повторяйте шаги 2–4 столько раз, сколько потребуется в течение эпизода
6. **Завершить эпизод**, когда задача выполнена, сохранить результат и перейти к следующему прогону

По умолчанию записываются только сегменты, управляемые человеком (восстановление и коррекция), и каждая коррекция становится отдельным эпизодом. С флагом `--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. Выберите backend для инференса с помощью `--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` Гц), при этом вывод политики и запись данных набора остаются на уровне `--fps`, поэтому записанный набор данных соответствует заявленному FPS.

**С RTC для больших моделей (Pi0, Pi0.5, SmolVLA):**

Для моделей с высокой задержкой вывода включите RTC для плавного выполнения. Для этого требуется базовая VLA-политика, такая как Pi0, Pi0.5 или SmolVLA, вместо политики ACT из шага 1:

```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`. См. [Policy Deployment](./inference) для всех флагов DAgger.

**Протокол HIL:**

1. Наблюдайте за автономным выполнением политики (телеуправление не активно/свободно)
2. Если вы видите, что сбой неизбежен, нажмите `Space`, чтобы **приостановить**
   - Остановка политики
   - Телеоператор перемещается для совпадения с позицией робота (момент включен)
   - Во время паузы кадры не записывались
3. Нажмите `Tab`, чтобы **взять управление**
   - Момент телеоператора отключен, свободное движение
   - **Восстановление**: Управляйте роботом дистанционно, чтобы вернуть его в рабочее состояние
   - **Исправление**: Исправьте поведение
   - Все движения записываются
4. Нажмите `Tab` ещё раз, чтобы завершить исправление, затем `Space`, чтобы **вернуть управление политике**
   - Policy возобновляет автономное выполнение из текущего состояния
   - Вы можете вмешаться снова в любой момент (повторите шаги 2–4)
5. В режиме по умолчанию каждая коррекция сохраняется как отдельный эпизод. С `--strategy.record_autonomous=true` всё записывается и автоматически разбивается на эпизоды
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` добавляет метку времени к имени набора данных, поэтому HIL-набор данных из шага 2 сохраняется как `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: Доработка Policy

Довыучите политику из шага 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 et al., 2011) ввёл ключевую идею: вместо обучения только на демонстрациях эксперта запрашивать у эксперта корректировки для состояний, которые посещает _учащийся_. Это прерывает цикл накопления ошибок, характерный для стандартного поведенческого клонирования, за счёт итеративного сбора данных в соответствии с текущей политикой.

- **HG-DAgger** (Kelly et al., 2019) сделал этот подход практичным для робототехники: человек-эксперт наблюдает за роботом и вмешивается только при необходимости, а не размечает каждое состояние. Переключение между автономным управлением и управлением человеком — это ровно тот цикл «пауза → перехват управления → возврат к политике», который используется в скриптах здесь.

- **RaC** (Hu et al., 2025) масштабирует этот цикл на задачи с длительным горизонтом, явно разлагая вмешательства на **восстановление** (телеуправление для возврата в хорошее состояние) и **коррекцию** (демонстрация правильного поведения из этого состояния). Именно это разложение представляет собой протокол, используемый стратегией DAgger в `lerobot-rollout`.

- **π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}
}
```

