GR00T N1 + G1 (Bài 2): thu data trong Isaac Lab và xr_teleoperate → LeRobot
Đây là bài 2 trong series GR00T N1 + Unitree G1. Bài trước giải thích kiến trúc decoupled. Bài này: thu data thực tế — hai track tùy theo bạn có hardware hay không.
Track A (không có G1): Isaac Lab simulation teleop → LeRobot
Track B (có G1 thật): xr_teleoperate với Meta Quest 3 → LeRobot
Output của cả hai track đều là cùng một format: LeRobot dataset — input chuẩn cho GR00T N1 fine-tune.
LeRobot format là gì?
LeRobot là format dataset chuẩn của HuggingFace cho robot learning. GR00T N1 dùng format này vì nó đủ general cho mọi robot.
dataset/
├── meta/
│ └── info.json ← robot type, joints, camera names, fps
├── data/
│ └── chunk-000/
│ ├── episode_000000/ ← một demo
│ │ ├── observation.images.left_wrist.mp4
│ │ ├── observation.images.right_wrist.mp4
│ │ ├── observation.images.head.mp4
│ │ └── data.parquet ← joint states + actions + timestamps
│ ├── episode_000001/
│ └── ...
└── stats.json ← mean/std cho normalization
Một data.parquet chứa:
timestamp | obs/joint_pos (29,) | obs/joint_vel (29,) | action/left_ee_pose (7,) | action/right_ee_pose (7,) | action/gripper (2,)
Track A: Isaac Lab simulation (không cần G1)
Cài đặt Isaac Lab
# Cần Isaac Sim 4.x (free từ NVIDIA Omniverse launcher)
# Sau đó cài Isaac Lab
git clone https://github.com/isaac-sim/IsaacLab.git
cd IsaacLab
# Cài vào Python environment của Isaac Sim
./isaaclab.sh --install
# Verify
python -c "import isaaclab; print('OK')"
Clone Isaac-GR00T và teleop env
git clone https://github.com/NVIDIA/Isaac-GR00T.git
cd Isaac-GR00T
# Cài dependencies
pip install -e ".[isaaclab]"
# Xem danh sách task environments
ls getting_started/demo_collection/
Thu data bằng keyboard teleop
GR00T repo cung cấp sẵn teleop controller cho G1 trong Isaac Lab:
cd Isaac-GR00T
# Chạy teleop environment — G1 trong Isaac Sim
python getting_started/demo_collection/collect_demos_teleop.py \
--robot g1 \
--task PickPlace \
--num_demos 50 \
--output_dir ./data/g1_pickplace \
--teleop_device keyboard
# Keyboard controls trong sim:
# WASD — di chuyển end-effector trái
# IJKL — di chuyển end-effector phải
# Q/E — up/down
# Space — gripper toggle
# Enter — save demo, bắt đầu demo mới
# Esc — discard demo hiện tại
Thay robot khác trong Isaac Lab
# Trong collect_demos_teleop.py, robot được load qua URDF path:
robot_cfg = RobotCfg(
urdf_path="robots/g1/g1.urdf", # ← đổi đường dẫn
joint_config="robots/g1/joint_config.yaml" # ← đổi config
)
# Ví dụ cho Agility Digit:
robot_cfg = RobotCfg(
urdf_path="robots/digit/digit.urdf",
joint_config="robots/digit/joint_config.yaml"
)
Convert sang LeRobot format
# Sau khi thu đủ demos, convert sang LeRobot
python getting_started/demo_collection/convert_to_lerobot.py \
--input_dir ./data/g1_pickplace \
--output_dir ./data/g1_pickplace_lerobot \
--robot g1 \
--fps 30
# Verify dataset
python -c "
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset
ds = LeRobotDataset('./data/g1_pickplace_lerobot')
print(f'Episodes: {ds.num_episodes}')
print(f'Frames: {ds.num_frames}')
print(f'Keys: {ds.features.keys()}')
"
Track B: xr_teleoperate với G1 thật
Hardware cần
- Unitree G1 với SDK
unitree_sdk2 - Meta Quest 3 ($499) — khuyến nghị vì rẻ và dễ setup
- Một workstation kết nối cùng mạng LAN với G1
Cài đặt
git clone https://github.com/unitreerobotics/xr_teleoperate.git
cd xr_teleoperate
pip install -r requirements.txt
# Cài Unitree SDK
pip install unitree_sdk2py
# Kết nối G1:
# 1. Bật G1, kết nối LAN cable workstation ↔ G1
# 2. Set IP: sudo ifconfig eth0 192.168.123.100 (theo Unitree docs)
# 3. Verify: ping 192.168.123.161 (G1 default IP)
Chạy teleoperation
# Terminal 1: khởi động robot controller
python teleop/robot_controller.py \
--robot g1 \
--mode arm_only # hoặc whole_body nếu muốn cả chân
# Terminal 2: kết nối Meta Quest
python teleop/quest_receiver.py \
--quest_ip 192.168.123.XXX # IP của Quest trong LAN
# Terminal 3: bắt đầu thu data
python teleop/record_demo.py \
--output_dir ./demos/g1_task1 \
--task_name "pick_red_cup" \
--cameras left_wrist right_wrist head
Trong Quest:
- Mở app xr_teleoperate (cần sideload APK)
- Dùng tay để điều khiển tay robot — movement tự retarget
- Bóp ngón tay = đóng gripper
- Nhìn hướng nào → head camera record hướng đó
Convert sang LeRobot
python convert/convert_xr_to_lerobot.py \
--input_dir ./demos/g1_task1 \
--output_dir ./data/g1_task1_lerobot \
--robot g1
# Với robot khác — xr_teleoperate hỗ trợ bất kỳ robot nào có joint names:
python convert/convert_xr_to_lerobot.py \
--input_dir ./demos/your_robot_task \
--output_dir ./data/your_robot_lerobot \
--robot_config path/to/your/joint_config.yaml
Data quality checklist
Trước khi chạy fine-tune, verify dataset:
python getting_started/demo_collection/verify_dataset.py \
--dataset_dir ./data/g1_pickplace_lerobot
# Checks sẽ chạy:
# [x] Số episodes >= 50 (minimum)
# [x] Không có NaN trong joint positions
# [x] Camera frames sync với joint data (< 5ms offset)
# [x] Demo length 5-30 giây (quá ngắn hoặc quá dài đều bad)
# [x] Success rate > 80% (không thu demo fail quá nhiều)
Tips thu data tốt:
| Tip | Lý do |
|---|---|
| Thu ít nhất 50 demos cho task đơn giản, 200+ cho task phức tạp | Policy cần đủ variance để generalize |
| Thay đổi vị trí object mỗi 5 demos | Tránh policy overfit vào 1 vị trí cụ thể |
| Demo tốc độ vừa phải — không quá nhanh, không quá chậm | Joint velocity phải nằm trong operating range |
| Record cả demos fail (nhưng label riêng) | Dùng để data augmentation sau |
| Camera frame rate nhất quán (30Hz) | Inconsistent FPS làm hỏng temporal modeling |
Kiểm tra dataset trực quan
# Replay một episode trong Isaac Sim để verify
python getting_started/demo_collection/replay_demo.py \
--dataset_dir ./data/g1_pickplace_lerobot \
--episode_idx 0 \
--robot g1
# Hoặc xem video từng camera
python -c "
import cv2, numpy as np
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset
ds = LeRobotDataset('./data/g1_pickplace_lerobot')
# Lấy frames từ episode 0
for frame in ds.get_episode_frames(0, camera='observation.images.left_wrist'):
cv2.imshow('left_wrist', frame)
cv2.waitKey(33) # 30fps
"
Tóm tắt: output cần có trước bài 3
./data/g1_pickplace_lerobot/
├── meta/info.json ← robot: g1, cameras: 3, fps: 30
├── data/chunk-000/
│ ├── episode_000000/ ... episode_000049/
│ └── (ít nhất 50 episodes)
└── stats.json
Bài tiếp theo: Fine-tune GR00T N1 với dataset vừa thu.
Nguồn tham khảo
- Isaac-GR00T data collection guide
- xr_teleoperate README
- LeRobot dataset format docs
- Isaac Lab installation