GR00T N1 + G1 (Bài 4): deploy GR00T-WBC trên Unitree G1 — GEAR + SONIC
Đây là bài 4 trong series GR00T N1 + Unitree G1. Bài trước fine-tune checkpoint. Bài này: deploy stack hoàn chỉnh lên G1 thật — VLA inference + WBC control running simultaneously.
Trước khi đọc: Deploy lên real robot luôn có rủi ro. Làm theo thứ tự trong bài này: sim trước → từng component riêng lẻ → full stack. Không bỏ qua bước nào.
Setup môi trường deploy
git clone https://github.com/NVlabs/GR00T-WholeBodyControl.git
cd GR00T-WholeBodyControl
pip install -e .
# Cài Unitree SDK2
pip install unitree_sdk2py
# Verify kết nối G1
python -c "
from unitree_sdk2py.core.channel import ChannelFactory
factory = ChannelFactory.Instance()
factory.Init(0, 'eth0') # thay eth0 bằng interface kết nối G1
print('G1 connected')
"
Kiến trúc deploy: 3 tiến trình song song
Process 1 (CPU/GPU): GR00T N1 VLA 6Hz
Process 2 (CPU): GEAR upper body 50Hz
Process 3 (CPU): SONIC locomotion 200Hz
Process 4 (LAN): G1 joint drivers 500Hz
Ba process chạy trên workstation, communicate qua shared memory + ZMQ:
[N1 inference] --ZMQ--> [GEAR] --shared mem--> [SONIC] --Unitree SDK--> [G1]
↑ camera frames ← joint states
Cấu hình G1 trong GR00T-WBC
# File cấu hình robot
cat groot_wbc/robots/g1/joint_config.yaml
# groot_wbc/robots/g1/joint_config.yaml
robot_name: "g1"
urdf_path: "robots/g1/g1.urdf"
dof: 29
# Thứ tự joint PHẢI khớp với Unitree SDK joint index
left_arm_joints:
- left_shoulder_pitch_joint # index 13
- left_shoulder_roll_joint # index 14
- left_shoulder_yaw_joint # index 15
- left_elbow_joint # index 16
- left_wrist_roll_joint # index 17
- left_wrist_pitch_joint # index 18
- left_wrist_yaw_joint # index 19
right_arm_joints:
- right_shoulder_pitch_joint # index 20
# ... tương tự
leg_joints:
- left_hip_yaw_joint # index 0
- left_hip_roll_joint # index 1
# ... 12 joints legs
waist_joint:
- waist_yaw_joint # index 12
ee_frames:
left: "left_hand_palm_link"
right: "right_hand_palm_link"
# Limits (safety)
joint_pos_limits:
left_shoulder_pitch_joint: [-2.87, 2.87] # rad
left_elbow_joint: [-0.52, 2.97]
# ... per joint
joint_vel_limits:
default: 5.0 # rad/s, per joint
Adapt cho robot khác
# groot_wbc/robots/your_robot/joint_config.yaml
robot_name: "your_robot"
urdf_path: "robots/your_robot/your_robot.urdf"
dof: 35 # đổi theo robot
# SDK-specific: mỗi robot SDK có joint ordering riêng
# Cần map URDF joint names → SDK joint indices
# Tham khảo SDK docs của robot bạn
left_arm_joints:
- "your_left_shoulder_1" # phải khớp tên trong URDF
- "your_left_shoulder_2"
# ...
# Với robot không có legs (chỉ arm):
leg_joints: []
waist_joint: []
Chạy deploy: từng bước
Bước 1: Test SONIC locomotion (không cần VLA)
Chạy SONIC trước để verify balance và locomotion hoạt động độc lập:
# Đứng yên và maintain balance
python scripts/run_sonic.py \
--robot g1 \
--mode stand \
--duration 30 # 30 giây
# Di chuyển forward
python scripts/run_sonic.py \
--robot g1 \
--mode walk \
--velocity 0.3 # m/s forward
Verify: G1 phải đứng vững, không nghiêng, không rung joint. Nếu oscillation → giảm kd trong pd_gains.yaml.
Bước 2: Test GEAR upper body (không cần VLA)
# Gửi target wrist pose thủ công để test GEAR
python scripts/test_gear.py \
--robot g1 \
--target_left "0.4 0.2 0.8 0 0 0 1" # xyz + quat
--target_right "0.4 -0.2 0.8 0 0 0 1"
Verify: Tay robot di chuyển đến target pose mượt mà, không jerk, không exceed joint limits.
Bước 3: Test GR00T N1 inference (không cần robot)
# Chạy N1 inference offline với camera images giả
python scripts/test_n1_inference.py \
--checkpoint ./runs/g1_pickplace/checkpoint_best/ \
--robot g1 \
--instruction "pick up the red cup" \
--test_images path/to/test_images/
# Output: action predictions mỗi ~150ms
# Kiểm tra output format đúng không và không có NaN
Bước 4: Full stack trong sim
# Chạy full stack (N1 + GEAR + SONIC) trong Isaac Sim trước
python scripts/run_full_stack_sim.py \
--robot g1 \
--checkpoint ./runs/g1_pickplace/checkpoint_best/ \
--task PickPlace \
--instruction "pick up the red cup" \
--render
# Phải thấy G1 sim: đứng thẳng, tay di chuyển đến object, gripper đóng lại
Bước 5: Full stack trên robot thật
Chỉ làm bước này sau khi 1-4 đều pass:
# Khởi động từng component theo thứ tự
# Terminal 1: SONIC (locomotion) — chạy trước
python groot_wbc/run_sonic.py \
--robot g1 \
--mode loco_manip # whole-body mode
# Terminal 2: GEAR (upper body) — chạy sau SONIC đã stable
python groot_wbc/run_gear.py \
--robot g1 \
--mode active
# Terminal 3: N1 VLA inference
python groot_wbc/run_n1.py \
--checkpoint ./runs/g1_pickplace/checkpoint_best/ \
--robot g1 \
--instruction "pick up the red cup"
# Terminal 4: Monitor
python scripts/monitor.py --robot g1
PD gains tuning cho G1
Gains mặc định trong GR00T-WBC đã được tune cho G1 nhưng có thể cần điều chỉnh theo firmware version:
# groot_wbc/robots/g1/pd_gains.yaml
# Upper body — arms
left_shoulder_pitch_joint: {kp: 150, kd: 10}
left_shoulder_roll_joint: {kp: 150, kd: 10}
left_shoulder_yaw_joint: {kp: 100, kd: 8}
left_elbow_joint: {kp: 80, kd: 5}
left_wrist_roll_joint: {kp: 40, kd: 3}
left_wrist_pitch_joint: {kp: 40, kd: 3}
# Lower body — legs
left_hip_yaw_joint: {kp: 200, kd: 15}
left_hip_roll_joint: {kp: 200, kd: 15}
left_hip_pitch_joint: {kp: 300, kd: 20}
left_knee_joint: {kp: 300, kd: 20}
left_ankle_pitch_joint: {kp: 60, kd: 4}
left_ankle_roll_joint: {kp: 40, kd: 3}
Khi nào tăng kp: Robot chậm phản ứng, không đạt target pose đúng giờ.
Khi nào tăng kd: Oscillation/rung sau khi đạt target.
Quy tắc: tăng kp cho đến khi có oscillation, rồi tăng kd để dập oscillation.
Safety checklist trước khi run real robot
[ ] E-stop sẵn sàng và đã test (Unitree remote hoặc kill switch cứng)
[ ] G1 đứng trên sàn phẳng, không có vật cản trong 1m xung quanh
[ ] Joint limits đã set trong joint_config.yaml
[ ] Velocity cap đã bật: max_joint_vel: 3.0 (rad/s)
[ ] Torque cap đã bật: max_torque: 80.0 (Nm) per joint
[ ] SONIC đã test stand mode ≥ 60 giây không fall
[ ] GEAR đã test arm movement không self-collision
[ ] Workstation kết nối LAN ổn định (không wireless)
[ ] Monitor terminal đang chạy
[ ] Người thứ 2 sẵn sàng E-stop nếu có sự cố
Bài tiếp theo: Sim2real + Evaluation với humanoid-bench.
Nguồn tham khảo
- GR00T-WholeBodyControl GitHub
- GR00T-WBC paper (arxiv:2506.08000)
- Unitree SDK2 Python
- HOVER paper (arxiv:2501.01595)