humanoidhumanoidreinforcement-learningunitree-g1isaac-labresidual-rlsim-to-realmanipulation

SteadyTray: Dạy Unitree G1 bưng khay bằng Residual RL

Hướng dẫn chi tiết reproduce SteadyTray trên IsaacLab — humanoid Unitree G1 bưng khay không rơi đồ bằng kiến trúc Residual RL hai tầng.

Nguyễn Anh Tuấn19 tháng 4, 202610 phút đọc
SteadyTray: Dạy Unitree G1 bưng khay bằng Residual RL

Bạn nghĩ robot hình người bưng ly cà phê đi qua hành lang mà không sánh ra ngoài là chuyện hiển nhiên? Trong thực tế đây là một trong những bài toán khó nhất của humanoid control: mỗi bước chân là một cú sốc truyền lên tay, khay nghiêng vài độ là ly đổ. Nhóm ArcLab (UC San Diego) vừa phát hành SteadyTray — framework RL cho phép Unitree G1 bưng khay chứa ly, cốc, dụng cụ phẫu thuật qua địa hình gồ ghề, chịu cả va đập bên ngoài, với tỉ lệ thành công 96.9%.

Bài viết này sẽ mổ xẻ paper, giải thích tại sao "residual policy" là chìa khóa, rồi hướng dẫn bạn reproduce lại kết quả trên IsaacLab từ đầu đến khi deploy policy lên MuJoCo.

Robot hình người trong môi trường nghiên cứu — minh họa bài toán humanoid manipulation khi vừa di chuyển vừa giữ vật

Tại sao bưng khay khó đến vậy?

Với con người, bưng khay là kỹ năng vô thức. Nhưng robot humanoid phải đối mặt với ba mâu thuẫn kinh điển:

  1. Locomotion sinh perturbation: Mỗi bước chân tạo ra gia tốc theo phương z (landing impact) và rung lắc theo phương xy. Gia tốc này lan qua hông, lưng, vai, cuối cùng truyền vào khay.
  2. End-to-end RL collapse: Nếu train một policy duy nhất học cả đi lẫn giữ khay, agent thường "chọn dễ" — đứng yên hoặc bước rất chậm để giảm perturbation, kết quả là không track được command velocity.
  3. Sim-to-real gap tích lũy: Sai số simulation nhỏ (friction, inertia, latency) khi truyền qua chuỗi khớp dài sẽ khuếch đại ở đầu khay. Policy học trong sim thường không sống sót trên robot thật.

SteadyTray giải quyết cả ba bằng một kiến trúc gọi là ReST-RL (REsidual STabilization RL).

Ý tưởng cốt lõi: Tách bạch locomotion và stabilization

Thay vì học từ đầu, ReST-RL đóng băng một policy locomotion đã train sẵn (có thể tracking velocity tốt), rồi huấn luyện một residual module chỉ phụ trách việc sinh ra các "hiệu chỉnh nhỏ" để giữ khay thăng bằng.

Công thức tổng thể của biến thể Residual Action:

a_final = α_base · a_base(s) + α_residual · a_residual(s, s_priv) + q_default
  • a_base(s): action từ locomotion policy (frozen)
  • a_residual(·): action hiệu chỉnh từ module mới
  • q_default: joint position mặc định
  • α_base, α_residual: hệ số pha trộn (thường α_base = 1, α_residual nhỏ)

Biến thể thứ hai — Residual FiLM — còn tinh vi hơn: không cộng vào action, mà điều biến feature của policy gốc bằng scale/shift (Feature-wise Linear Modulation):

y'_i = y_i · (1 + γ_{t,i}) + β_{t,i}

Với γ, β sinh bởi residual encoder. Kết quả: FiLM học nhanh hơn và ổn định hơn action-adapter, vì nó không cần "đánh lại" hành vi locomotion đã đúng.

Kiến trúc chi tiết

Observation space

Thành phần Kích thước Mô tả
Proprioception ℝ²⁹ Joint pos, joint vel, base angular vel, gravity projection
Object pose (camera) ℝ⁷ Position 3D + quaternion 4D (từ AprilTag)
Privileged (train only) ℝ²⁴ Base lin vel, tray/object vel, CoM offset
Goal ℝ³ Velocity command (v_x, v_y, ω_z)
History window H=32 Context 32 timestep gần nhất

Lưu ý privileged obs chỉ có trong training. Lúc deploy, student policy chỉ nhìn thấy proprioception + object pose qua camera — nhờ vào một pha distillation mà ta sẽ bàn sau.

Action space & control

29 DoF (đủ cho Unitree G1 phiên bản full): 12 chân, 1 torso, 14 tay (bao gồm 2 cổ tay điều khiển nghiêng khay). Policy output là target joint position, đưa xuống PD controller chạy 1 kHz, policy step tại 50 Hz.

Reward function

Reward chia thành 3 nhóm:

Nhóm locomotion (giữ từ base policy):

  • Linear XY tracking: exp(-λ_vxy · ||v_xy - v̂_xy||²)
  • Torso stability: exp(-λ_ω · ||ω_xy||²)
  • Foot impact smoothness

Nhóm tray stabilization (mới):

  • Object upright: exp(-λ_up · ||P_xy(g_obj)||²) — giữ trọng lực object vuông góc mặt khay
  • Tray orientation: exp(-λ · ||P_xy(g_tray)||²) — khay phải nằm ngang
  • Object-tray contact: 𝟙{contact} — object không rời khỏi khay

Nhóm penalty:

  • Action rate, torque, joint limit — các penalty chuẩn trong Isaac Lab humanoid env.

Training 3 giai đoạn + distillation

Stage Task Khởi tạo Output
1 Locomotion only Scratch loc_policy.pt
2 + Tray balance (không có object) Load Stage 1 tray_policy.pt
3 + Object stabilization (residual teacher, dùng privileged obs) Freeze base, train residual teacher.pt
4 Distillation sang student Student = proprio + camera only student.pt (deploy)

Distillation loss kết hợp match cả context latent và action:

L = ||z_teacher - z_student||² + ||a_teacher - a_student||²

Với learning rate thấp 5×10⁻⁵ — đủ để student bắt chước mà không "quên" những gì đã học trong locomotion.

Cài đặt môi trường

Bạn cần một máy có GPU NVIDIA (RTX 3090 trở lên khuyến nghị), CUDA 11.8+ và Docker. Paper train trên 2× RTX A6000 với 8192 parallel envs — bạn có thể giảm xuống 2048–4096 envs trên 1 GPU.

Bước 1 — Clone IsaacLab fork và SteadyTray

SteadyTray yêu cầu IsaacLab fork đặc biệt của tác giả (thêm asset khay + object randomization):

# Tạo workspace
mkdir -p ~/steadytray_ws && cd ~/steadytray_ws

# Clone IsaacLab fork
git clone https://github.com/AllenHuangGit/IsaacLab_SteadyTray.git

# Clone SteadyTray repo
git clone https://github.com/AllenHuangGit/steadytray.git
cd steadytray
git lfs pull  # tải checkpoint model/

Bước 2 — Build Docker image

Khuyến nghị dùng Docker vì IsaacLab có rất nhiều dependency phiền phức (OpenUSD, Kit SDK):

cd ~/steadytray_ws/IsaacLab_SteadyTray
./docker/container.py start
./docker/container.py enter

Sau khi vào container, mount SteadyTray:

# Trong container
cd /workspace/steadytray
python -m pip install -e source/steadytray
apt-get update && apt-get install -y git-lfs tmux

Bước 3 — Kiểm tra env

Chạy visualization để xác nhận asset load đúng:

python scripts/rsl_rl/play.py \
  --task G1-Steady-Tray-Pre-Locomotion \
  --num_envs 4 --video

Bạn sẽ thấy 4 robot G1 đứng sẵn, khay gắn trên hai tay, sẵn sàng train.

Training từng stage

Stage 1 — Locomotion cơ bản

python scripts/rsl_rl/train.py \
  --task G1-Steady-Tray-Pre-Locomotion \
  --num_envs 4096 --headless \
  --max_iterations 3000

Thời gian: ~4 giờ trên 1× A6000. Reward curve sẽ plateau khi robot đi vững ở mọi velocity trong [-1, 1] m/s.

Stage 2 — Giữ khay (chưa có object)

python scripts/rsl_rl/train.py \
  --task G1-Steady-Tray-Balance \
  --num_envs 4096 --headless \
  --resume --load_run <stage1_run_name> \
  --max_iterations 2000

Ở stage này, khay đã gắn nhưng chưa có object trên đó. Policy học cách giữ tay thăng bằng trong lúc đi.

Stage 3 — Train residual teacher với privileged obs

python scripts/rsl_rl/train.py \
  --task G1-Steady-Object-Teacher \
  --num_envs 4096 --headless \
  --resume --load_run <stage2_run_name> \
  --residual.mode film \
  --max_iterations 4000

Chú ý --residual.mode film để dùng biến thể FiLM (kết quả tốt hơn action-adapter trong hầu hết scenario). Nếu có 2 GPU:

python scripts/rsl_rl/train.py \
  --task G1-Steady-Object-Teacher \
  --num_envs 8192 --headless \
  --distributed --nproc_per_node=2 \
  --resume --load_run <stage2_run_name>

Stage 4 — Distillation sang student

python scripts/rsl_rl/train.py \
  --task G1-Steady-Object-Distillation \
  --num_envs 4096 --headless \
  --resume --load_run <stage3_run_name> \
  --distill.lr 5e-5 \
  --max_iterations 2000

Student chỉ nhìn proprioception + object pose từ camera, nhưng học được hành vi của teacher.

Domain randomization — chìa khoá sim-to-real

Đây là phần dễ bị bỏ qua nhất nhưng lại quyết định policy có survive trên robot thật hay không. Config trong source/steadytray/tasks/.../randomization_cfg.py:

Tham số Range Lý do
Robot friction [0.3, 1.0] Bề mặt thật khác carpet sim
Object mass [0.05, 1.0] kg Từ ly cà phê rỗng tới bình nước
Tray mass [0.3, 0.7] kg Dung sai vật liệu
Object radius [0.7, 1.5] × 0.03m Ly nhỏ tới cốc lớn
Object height [0.75, 2.0] × 0.1m Chai thấp tới chai cao
Torso CoM offset ±[2.5, 5, 5] cm Lỗi calibration thật
Push robot ±0.5 m/s mỗi [3, 5]s Va chạm hành lang
Push object ±0.3 m/s mỗi [2, 4]s Vật trượt trên khay
Observation delay 10–30 ms Camera latency

Nếu thiếu bất cứ dòng nào trong bảng, sim-to-real hầu như chắc chắn fail.

Dashboard RL training — visualizing reward curves, episode length, domain randomization stats

Inference: chạy policy đã train

Play trong Isaac Lab

python scripts/rsl_rl/play.py \
  --task G1-Steady-Object-Distillation \
  --num_envs 8 \
  --checkpoint model/model_9999.pt \
  --video --video_length 500

Sim2Sim sang MuJoCo (trước khi chạy robot thật)

Thư mục deploy/deploy_mujoco/ chứa script chuyển policy sang MuJoCo environment — đây là bước bắt buộc trước khi dám chạy trên hardware:

cd deploy/deploy_mujoco
python run_mujoco.py --policy ../../exported/student_film.onnx

Nếu policy stable 30s trong MuJoCo với object nặng nhất và push mạnh nhất, xác suất cao nó sẽ chạy trên G1 thật. Nếu fail, quay lại tăng domain randomization.

Kết quả từ paper

Method Command Track Success Tilt (rad) Vel Error (m/s)
Base policy (frozen loco) 47.4% 0.179 0.110
End-to-End RL 89.1% 0.046 0.116
ReST-RL (FiLM) 96.9% 0.046 0.106

Trong test push robot (đẩy mạnh vào hông), ReST-RL (FiLM) đạt 84.6% success so với 9.1% của base policy — khoảng cách lên tới . Tương tự với push object (đánh thẳng vào cốc trên khay): ReST-RL 74.6% vs base 25.2%.

Thí nghiệm robot thật: G1 bưng ly rượu đầy nước, dụng cụ phẫu thuật trên khay, đi qua sàn không đều, có người cố tình đẩy vai — không rơi, không tràn.

Ứng dụng thực tế

Đây không chỉ là bài toán đồ chơi. Cùng một framework có thể triển khai cho:

  • Dịch vụ nhà hàng/khách sạn: Humanoid bưng khay thức ăn, đồ uống.
  • Y tế: Robot phụ tá vận chuyển mẫu bệnh phẩm, dụng cụ tiệt trùng.
  • Kho vận: Bưng thùng hàng chưa cố định qua khu vực có bậc.
  • Gia đình: Robot gia đình cầm chén đĩa mà không rơi vỡ.

Thậm chí ReST-RL framework có thể generalize cho bất kỳ task nào có hai tầng objective xung đột — ví dụ robot mobile đeo camera và phải đi nhanh mà giữ camera ổn định, hay drone giữ payload trong bão.

Những bẫy thường gặp

  1. Bỏ qua observation delay — policy trong sim phản ứng tức thời, robot thật có latency 10-30ms. Không randomize delay → policy dao động điên cuồng khi deploy.
  2. Residual coefficient quá lớn — nếu α_residual = 1.0 từ đầu, residual ghi đè locomotion policy → robot ngã trong 10 step đầu. Nên warmup từ 0.1 lên 1.0.
  3. Skip Stage 2 — nhiều người nóng lòng nhảy thẳng từ locomotion sang object. Kết quả: policy không biết khay tồn tại, action cổ tay loạn xạ.
  4. Train distillation quá ít step — student cần ~2000 iteration để bắt kịp teacher, không nên dừng ở 500.
  5. Dùng action-adapter thay FiLM — action-adapter dễ học hơn nhưng ceiling thấp hơn 5–7% success rate so với FiLM.

Bài viết liên quan

Nguồn tham khảo

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

NEWTutorial
VLA-Adapter: Train VLA 0.5B với 9.6GB VRAM, 99.2% LIBERO
vlavla-adapteropenhelixliberoqwen2.5lorafrankaur5manipulation

VLA-Adapter: Train VLA 0.5B với 9.6GB VRAM, 99.2% LIBERO

Hướng dẫn VLA-Adapter từ OpenHelix — train VLA 0.5B trên GPU consumer 8 giờ, đạt SOTA LIBERO, deploy thật trên Franka/UR-5.

13/5/202610 phút đọc
NEWTutorial
WholeBodyVLA Tutorial: Teleop → Train → Deploy Humanoid
wholebodyvlavlahumanoidloco-manipulationiclr-2026agibot-x2teleoprl

WholeBodyVLA Tutorial: Teleop → Train → Deploy Humanoid

ICLR 2026 — pipeline thực chiến từ thu thập teleop, train unified latent VLA đến deploy whole-body loco-manipulation trên AgiBot X2.

11/5/202611 phút đọc
NEWTutorial
Booster Gym ICRA 2026: Train Humanoid T1 Sim-to-Real với Isaac Gym
humanoidisaac-gymreinforcement-learningsim2realbooster-t1icra-2026

Booster Gym ICRA 2026: Train Humanoid T1 Sim-to-Real với Isaac Gym

Hướng dẫn chi tiết Booster Gym — RL framework end-to-end open-source train humanoid Booster T1 walking từ teleop đến deploy thực tế.

6/5/202611 phút đọc