GR00T N1 + G1 (Bài 5): sim2real transfer, domain randomization, và eval với humanoid-bench
Đây là bài cuối trong series GR00T N1 + Unitree G1. Bài trước deploy stack lên G1. Bài này: làm cho nó thực sự hoạt động đáng tin cậy ngoài sim — sim2real transfer — và đo performance một cách khoa học.
Sim2real gap là gì và tại sao nó quan trọng
Khi train trong Isaac Sim và deploy lên G1 thật, bạn sẽ gặp "sim2real gap" — behavior trong sim tốt nhưng trên real robot lại khác. Nguyên nhân chính:
Sim: Real robot:
├── Lý tưởng frition ├── Carpet/tile/dust thay đổi friction
├── Exact joint torques ├── Motor backlash, gear compliance
├── Zero sensor noise ├── IMU noise, encoder jitter
├── Tức thì actuator ├── Actuator delay ~5-10ms
├── Perfect mass params ├── Payload, component wear
└── No cable drag └── Cable tension affects joints
Không có sim nào perfect. Mục tiêu là thu hẹp gap đủ để policy từ sim vẫn hoạt động trên real.
Domain Randomization trong Isaac Lab
Giải pháp chính: randomize simulation parameters trong quá trình training để policy learn robust hơn.
# Isaac Lab domain randomization config
# File: groot_wbc/configs/domain_rand_g1.yaml
domain_randomization:
enabled: true
# Friction randomization
ground_friction:
range: [0.5, 1.5] # thực tế: 0.6–1.2 tùy sàn
sample_per_episode: true # đổi mỗi episode
robot_friction:
range: [0.3, 0.8] # joint-level friction
# Mass randomization (±20%)
body_mass:
range: [0.8, 1.2] # scale factor
per_body: true
# Actuator delay
actuator_delay_ms:
range: [0, 15] # 0–15ms random delay
# Sensor noise
imu_noise:
gyro_std: 0.02 # rad/s
accel_std: 0.1 # m/s²
joint_encoder_noise:
std: 0.005 # rad, per joint
# Push perturbations (làm robot mạnh hơn với external forces)
random_push:
enabled: true
force_range: [0, 50] # N
interval_s: [3, 8] # mỗi 3-8 giây
direction: "random"
Áp dụng trong training:
python scripts/finetune.py \
--config configs/finetune_g1_pickplace.yaml \
--domain_rand configs/domain_rand_g1.yaml
Domain randomization thường tăng training time ~30% nhưng sim2real transfer tốt hơn rõ rệt.
Actuator Modeling: thu hẹp gap quan trọng nhất
Actuator delay là nguồn sim2real gap lớn nhất. G1 dùng servo motors với ~8ms delay:
# Thêm actuator model vào Isaac Lab env
# File: groot_wbc/envs/g1_env.py
from isaaclab.actuators import DelayedPDActuator
actuator_cfg = DelayedPDActuator(
joint_names_expr=[".*"], # tất cả joints
effort_limit=150.0,
velocity_limit=5.0,
# PD params (khớp với real robot)
stiffness={".*shoulder.*": 150.0, ".*elbow.*": 80.0, ".*hip.*": 200.0},
damping={".*shoulder.*": 10.0, ".*elbow.*": 5.0, ".*hip.*": 15.0},
# Delay modeling
delay_range=(0.005, 0.012), # 5–12ms delay range
# Gear compliance
gear_ratio={".*": 1.0},
armature={".*": 0.01}, # rotor inertia
)
Sau khi thêm actuator model, performance trong sim sẽ giảm nhẹ nhưng transfer sang real tốt hơn.
Evaluate với humanoid-bench
Trước khi nói "policy hoạt động," cần có số liệu cụ thể. humanoid-bench là standard để compare với papers.
Cài đặt
git clone https://github.com/carlosferrazza/humanoid-bench.git
cd humanoid-bench
pip install -e .
# Thêm G1 model
cp groot_wbc/robots/g1/g1.xml humanoid_bench/assets/robots/
Chạy eval
# Eval task: pick-and-place
python humanoid_bench/evaluate.py \
--robot g1 \
--task "h1_pick_place" # hoặc task tương đương cho G1
--policy_checkpoint ./runs/g1_pickplace/checkpoint_best/ \
--num_episodes 100 \
--seed 42
# Output:
# Task: h1_pick_place | Robot: G1
# Episodes: 100
# Success rate: 82/100 = 82%
# Mean episode time: 14.3s ± 2.1s
# Grasp success: 91/100 = 91%
# Place success: 82/100 (given grasp)
Metrics quan trọng
| Metric | Ý nghĩa | Target |
|---|---|---|
| Success rate | Hoàn thành task | ≥ 80% sim, ≥ 60% real |
| Grasp success | Grasping đúng vật | ≥ 90% |
| Mean episode time | Nhanh hay chậm | < 20s cho pick-place đơn giản |
| Balance fall rate | Robot có ngã không | 0% trong evaluation |
Eval trên real robot
# Với G1 thật — chạy eval qua Unitree SDK
python humanoid_bench/evaluate_real.py \
--robot g1 \
--policy_checkpoint ./runs/g1_pickplace/checkpoint_best/ \
--num_episodes 20 \ # ít hơn vì real robot chậm hơn
--task "pick_place_red_cup"
Debug guide: failure modes thường gặp
1. Robot mất balance khi tay vươn ra xa
Triệu chứng: G1 ngã về phía trước khi tay extend > 0.5m.
Nguyên nhân: SONIC CoM estimation không đúng khi arm configuration thay đổi.
Fix:
# groot_wbc/configs/sonic_g1.yaml
com_compensation:
arm_mass_fraction: 0.15 # tăng từ 0.10 nếu robot nặng tay
update_rate_hz: 50 # tăng để CoM update nhanh hơn
2. Tay jerk khi nhận target mới từ N1
Triệu chứng: Arm movement không mượt, giật mỗi ~150ms (khớp N1 inference rate).
Nguyên nhân: GEAR không smooth transition giữa target mới và target cũ.
Fix:
# groot_wbc/configs/gear_g1.yaml
target_smoothing:
enabled: true
alpha: 0.3 # EMA filter — 0.1 (rất mượt) đến 0.9 (responsive)
3. Gripper không nhả vật
Triệu chứng: Gripper close OK nhưng không open đúng lúc.
Nguyên nhân: N1 không predict gripper open đủ mạnh, hoặc threshold quá cao.
Fix:
# Giảm ngưỡng để gripper dễ open hơn
action_config:
gripper_open_threshold: 0.3 # từ 0.5 xuống 0.3
4. Object không được nhận diện đúng vị trí
Triệu chứng: Tay vươn ra vị trí sai, lệch 5-10cm.
Nguyên nhân: Camera calibration sai hoặc lighting khác với lúc train.
Fix:
- Recalibrate wrist cameras (chạy
scripts/calibrate_cameras.py) - Thu thêm data trong lighting conditions đa dạng hơn
5. Sim2real gap lớn — policy dùng được trong sim nhưng fail real
Nguyên nhân phổ biến: actuator delay không được model trong sim.
Fix nhanh: thêm actuator_delay_ms: [5, 12] vào domain rand config và retrain ~50 epochs.
Cải thiện policy — nếu performance chưa đủ
Theo thứ tự thử:
- Thu thêm data — thêm 50 demos, đặc biệt từ failure cases
- Tăng data diversity — lighting khác nhau, object position khác nhau
- Tăng domain randomization — friction range rộng hơn, push force lớn hơn
- Fine-tune thêm từ checkpoint tốt nhất, với lr thấp hơn (1e-5)
- Kiểm tra camera calibration — nguyên nhân hay bị bỏ qua nhất
Tổng kết series
Từ 5 bài, bạn đã đi qua đầy đủ pipeline:
| Bài | Input | Output |
|---|---|---|
| 1: Architecture | — | Hiểu kiến trúc decoupled |
| 2: Data | Robot + sim | LeRobot dataset |
| 3: Training | LeRobot dataset | GR00T N1 checkpoint |
| 4: Deploy | Checkpoint + G1 | Stack running trên robot |
| 5: Eval (bài này) | Stack trên robot | Benchmark numbers + fixes |
Adapt cho robot khác: bài 1, 2, 4 đều có "adapt guide" cụ thể — swap URDF + joint config là 80% công việc.
Nguồn tham khảo
- GR00T-WBC paper (arxiv:2506.08000)
- humanoid-bench (arxiv:2312.03586)
- Isaac Lab domain randomization docs
- Sim2real survey for legged robots (arxiv:2109.14635)