humanoidhumanoidvladata-collectionisaac-lablerobotunitree-g1grootteleoperation

GR00T N1 + G1 (Bài 2): thu data trong Isaac Lab và xr_teleoperate → LeRobot

Hướng dẫn thu data cho GR00T N1 theo hai track: Isaac Lab simulation teleop (không cần robot) và xr_teleoperate thật trên G1 — đều ra LeRobot format cho bước fine-tune.

Nguyễn Anh Tuấn3 tháng 6, 20266 phút đọcCập nhật: 6 thg 6, 2026
GR00T N1 + G1 (Bài 2): thu data trong Isaac Lab và xr_teleoperate → LeRobot

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:

  1. Mở app xr_teleoperate (cần sideload APK)
  2. Dùng tay để điều khiển tay robot — movement tự retarget
  3. Bóp ngón tay = đóng gripper
  4. 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


Bài viết liên quan

NT

Nguyễn Anh Tuấn

Robotics & AI Engineer. Building VnRobo — sharing knowledge about robot learning, VLA models, and automation.

Khám phá VnRobo

Bài viết liên quan

GR00T N1 + G1 (Bài 5): sim2real transfer, domain randomization, và eval với humanoid-bench
humanoid

GR00T N1 + G1 (Bài 5): sim2real transfer, domain randomization, và eval với humanoid-bench

6/6/20266 phút đọc
NT
GR00T N1 + G1 (Bài 3): fine-tune GR00T N1 — GPU, config, training script
humanoid

GR00T N1 + G1 (Bài 3): fine-tune GR00T N1 — GPU, config, training script

4/6/20265 phút đọc
NT
GR00T N1 + Unitree G1: kiến trúc WBC+VLA decoupled từ 6Hz đến 500Hz
humanoid

GR00T N1 + Unitree G1: kiến trúc WBC+VLA decoupled từ 6Hz đến 500Hz

2/6/20266 phút đọc
NT