wholebody-vlahumanoid-vlateleoperationisaac-labopenxrgr00t-wbcunitree-g1data-collection

Chọn teleoperation stack cho humanoid

So sánh keyboard, SpaceMouse, OpenXR hand tracking và GR00T WBC để chọn teleop stack theo latency, an toàn và loại action.

Nguyễn Anh Tuấn10 tháng 6, 202616 phút đọc
Chọn teleoperation stack cho humanoid

Mục tiêu của bài này

Trong bài 1 của series, chúng ta thiết kế ca pilot 2 người cho dữ liệu humanoid VLA: ai điều khiển, ai giám sát dữ liệu, cần camera/state/action nào, và khi nào nên save hoặc discard episode. Bài này đi vào quyết định rất thực tế trước khi bật record: chọn teleoperation stack nào.

Với humanoid, "teleop" không chỉ là một tay cầm điều khiển. Nó là toàn bộ đường đi từ ý định của con người đến action mà model sẽ học: keyboard hoặc SpaceMouse tạo delta SE(3), OpenXR hand tracking tạo wrist pose và finger joints, motion controller tạo pose kèm trigger, còn GR00T WholeBodyControl chia control loop, teleop loop và policy loop cho cả thân, tay, locomotion và hand. Nếu chọn sai stack, bạn vẫn có thể thu được video đẹp, nhưng action trong dataset sẽ khó học, trễ, không ổn định, hoặc nguy hiểm khi replay.

Sau bài này, bạn sẽ biết khi nào nên dùng Isaac Lab teleop_se3_agent.py với --teleop_device keyboard, spacemouse, hoặc handtracking; khi nào nên dùng OpenXR retargeters như g1_upper_body_retargeter.py; và khi nào nên chuyển sang GR00T WBC BaseConfig với body_control_device, hand_control_device, teleop_frequency=20, control_frequency=50. Nếu bạn đang chuẩn bị bước tiếp theo về ROS 2, MCAP và đồng bộ dữ liệu, quyết định teleop hôm nay sẽ quyết định schema data ngày mai.

Bảng chọn nhanh

Nhu cầu thu dữ liệu Stack nên bắt đầu Action thu được Điểm mạnh Rủi ro chính
Beginner, chỉ test pipeline, pick/place đơn giản trong sim Isaac Lab keyboard Delta SE(3), gripper binary Rẻ, dễ debug, deterministic Motion gãy khúc, demo kém tự nhiên
Pick/place cần trajectory mượt, không cần finger dexterity Isaac Lab SpaceMouse Delta SE(3), gripper binary Mượt hơn keyboard, điều khiển 6-DoF tự nhiên hơn Cần thiết bị đúng model, vẫn không thu được ngón tay
Bimanual hoặc upper-body pose cần wrist tracking Isaac Lab OpenXR handtracking Absolute hand/wrist pose, pinch/grip, hand joints qua retargeter Tự nhiên, phù hợp imitation Latency và calibration khó hơn
G1 loco-manipulation, cần thân dưới ổn định và tay phối hợp GR00T WBC / Decoupled WBC Navigate command, body/hand teleop, WBC action, state/action stream Gần robot thật, có control loop rõ Safety phức tạp, phải có operator kỷ luật
Thu dữ liệu VLA production cho humanoid GR00T WBC + data exporter + camera sync Episode đủ camera, proprio, eef, action, teleop command, prompt Có đường mở rộng sang train/eval Tốn thời gian chuẩn hóa schema và QA

Quy tắc thực dụng: keyboard để debug, SpaceMouse để thu demo SE(3) sạch, hand tracking để thu chuyển động tay tự nhiên, WBC để thu whole-body humanoid data. Đừng nhảy thẳng vào VR nếu bạn chưa replay được 10 episode keyboard. Đừng dùng keyboard để thu dữ liệu ngón tay nếu mục tiêu cuối là dexterous manipulation.

Ba lớp trong một teleop stack

Một beginner thường nghĩ teleop là "thiết bị điều khiển robot". Với humanoid VLA, nên tách thành ba lớp:

Lớp Câu hỏi cần trả lời Ví dụ
Input device Con người dùng gì để ra lệnh? Keyboard, SpaceMouse, OpenXR hand tracking, PICO controller, Vive, Joy-Con
Retargeting Tín hiệu người được map sang robot như thế nào? SE(3) delta, absolute wrist pose, gripper pinch, G1 upper-body retargeter
Control loop Robot nhận action ở tần số nào và kiểm soát ổn định ra sao? Isaac Lab env step, GR00T WBC control_frequency=50, teleop loop 20 Hz

Khi debug, hãy log từng lớp riêng. Nếu robot giật, lỗi có thể đến từ input noisy, retargeter scale sai, frame coordinate sai, hoặc control loop nhận command quá thưa. Nếu dataset xấu, lỗi có thể không nằm ở camera mà ở action representation: model nhìn một chuyển động mượt trong video nhưng action lại là chuỗi delta khó học.

Isaac Lab teleop_se3_agent.py: tốt nhất cho SE(3) demo

Isaac Lab cung cấp script scripts/environments/teleoperation/teleop_se3_agent.py để chạy teleoperation cho các environment manipulation. Trong tài liệu chính thức, SE(3) teleoperation trả về vector 6 chiều đại diện cho thay đổi pose; keyboard và SpaceMouse được dùng với các task Franka IK, còn hand tracking dùng qua XR/CloudXR cho task absolute.

Ví dụ debug bằng keyboard:

./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
  --task Isaac-Stack-Cube-Franka-IK-Rel-v0 \
  --num_envs 1 \
  --teleop_device keyboard

Ví dụ dùng SpaceMouse:

./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
  --task Isaac-Stack-Cube-Franka-IK-Rel-v0 \
  --num_envs 1 \
  --teleop_device spacemouse

Ví dụ dùng hand tracking với task absolute:

./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
  --task Isaac-Stack-Cube-Franka-IK-Abs-v0 \
  --teleop_device handtracking \
  --device cpu

Keyboard phù hợp nhất cho giai đoạn đầu vì bạn có thể nhìn từng command. Với keyboard, các phím thường map sang di chuyển theo trục x/y/z, xoay quanh x/y/z, reset và toggle gripper. Đây là lựa chọn tốt để kiểm tra env, reset, reward, termination và recording. Nhược điểm là trajectory thường có đoạn thẳng, góc cua cứng, tốc độ không tự nhiên. Nếu bạn train imitation từ demo keyboard quá nhiều, policy dễ học kiểu chuyển động "bậc thang".

SpaceMouse là bước nâng cấp rõ ràng cho pick/place hoặc insertion đơn giản. Nó cho điều khiển 6-DoF liên tục: nghiêng để đi x/y, đẩy/kéo để đi z, vặn để rotate. Isaac Lab khuyến nghị SpaceMouse cho vận hành mượt và off-axis tốt hơn, vì demo mượt giúp policy clone hành vi dễ hơn. Lưu ý thực tế: Isaac Lab chỉ nêu tương thích với SpaceMouse Wireless và SpaceMouse Compact của 3Dconnexion; trong container, bạn có thể phải mount /dev/hidraw vào container và cấp quyền thiết bị.

Hand tracking trong Isaac Lab phù hợp khi action bạn muốn thu là absolute hand pose hoặc pinch-based interaction. Tài liệu Isaac Lab nói OpenXR dùng hand tracking của index/thumb tip để drive target pose, còn gripping dựa trên pinching. Khi dùng hand tracking, nên ưu tiên task absolute như Isaac-Stack-Cube-Franka-IK-Abs-v0, vì tay người trong XR là pose tuyệt đối trong không gian, không phải chuỗi delta keyboard.

Điểm quan trọng cho data center: teleop_se3_agent.py là công cụ tốt để tạo demo SE(3) sạch, nhưng nó không tự động giải quyết toàn bộ bài toán humanoid. Nó không nói cho bạn cách đồng bộ nhiều camera, cách lưu prompt, cách chống mode switch nguy hiểm, hay cách chia thân dưới/thân trên. Nó là lớp input và env-control, không phải production data pipeline.

OpenXR retargeters: khi cần map tay người sang G1

OpenXR trong Isaac Lab mở ra cách teleop tự nhiên hơn: lấy tracking data từ XR device, rồi dùng retargeter để biến hand pose, wrist pose hoặc motion controller thành command robot. Trong API Isaac Lab, device interface có thể nhận danh sách retargeters; khi advance() được gọi, raw device data được retarget thành tensor command. Các retargeter có thể map hand joint data sang end-effector pose, gripper state hoặc joint command.

Với Unitree G1 trong môi trường locomanipulation, config Isaac Lab hiện có hai nhóm device đáng chú ý:

teleop_devices:
  handtracking:
    - G1TriHandUpperBodyRetargeterCfg
    - G1LowerBodyStandingRetargeterCfg
  motion_controllers:
    - G1TriHandUpperBodyMotionControllerRetargeterCfg
    - G1LowerBodyStandingMotionControllerRetargeterCfg

Ý nghĩa thực tế:

Device key Dùng khi Tín hiệu chính Ghi chú
handtracking Muốn bắt chuyển động bàn tay/ngón tay tự nhiên OpenXR hand joints, wrist pose, pinch Config G1 dùng 2 * 26 OpenXR hand joints cho hai tay
motion_controllers Muốn điều khiển ổn định hơn bằng controller vật lý Controller pose, button, trigger Ít nhiễu ngón tay hơn, dễ training operator hơn

g1_upper_body_retargeter.py thuộc nhóm retargeter này: nó biến tín hiệu người thành target upper-body/hand cho G1. Trong config locomanipulation G1, retargeter upper body đi cùng lower-body standing retargeter, nghĩa là robot không chỉ có tay; nó còn cần trạng thái thân dưới ổn định trong lúc tay làm việc. Config cũng đặt XR anchor vào pelvis của robot, cố định height và dùng chế độ rotation theo pelvis yaw có smoothing. Đây là chi tiết nhỏ nhưng quan trọng: nếu anchor bị trôi hoặc xoay sai, người điều khiển cảm thấy tay "không ở cùng thế giới" với robot.

Beginner nên hiểu retargeting bằng một ví dụ đơn giản. Tay người và tay robot không cùng chiều dài, joint limit, palm frame hoặc finger topology. Nếu bạn copy trực tiếp joint người sang joint robot, robot có thể tự đâm vào thân, vượt joint limit hoặc tạo pose không IK được. Retargeter là nơi bạn nói: wrist người map sang left_wrist_yaw_link, pinch map sang gripper close, ngón tay người map sang joint hand robot qua scale và clamp, lower body giữ standing policy.

Checklist trước khi dùng OpenXR retargeter:

Kiểm tra Cách nghĩ đúng
Coordinate frame Wrist pose đang ở OpenXR frame, USD/world frame hay robot pelvis frame?
Anchor Người điều khiển đứng ở đâu so với robot? Anchor có follow pelvis không?
Calibration Pose neutral của người có khớp pose neutral robot không?
Joint limits Retargeter có clamp target vào range an toàn không?
Visualization Có bật target pose/joint visualization trước khi chạy real-time không?
Data schema Dataset lưu raw hand tracking, retargeted action, hay cả hai?

Với data VLA, tôi khuyến nghị lưu cả hai mức nếu storage cho phép: raw-ish teleop signal để debug, và action thật gửi vào robot để train/replay. Khi episode hỏng, bạn cần biết lỗi đến từ người, tracker, retargeter hay controller.

GR00T WBC BaseConfig: khi nhiệm vụ là whole-body

GR00T WholeBodyControl không chỉ là một input device. Nó là stack whole-body control cho humanoid, có tài liệu Decoupled WBC cho Unitree G1, control loop, teleoperation stack và data exporter. Tài liệu GR00T WBC mô tả stack hỗ trợ policy whole-body, teleop và exporter; phần Decoupled WBC chạy run_g1_control_loop.py, sau đó terminal khác chạy run_teleop_policy_loop.py với --hand_control_device--body_control_device. Tài liệu cũng cho ví dụ PICO controller cho hand/body coordinated control, cùng data collection helper tạo tmux session cho control, camera forwarder, viewer và exporter.

Trong source BaseConfig, các field quan trọng là:

control_frequency = 50
body_control_device = "dummy"
hand_control_device = "dummy"
teleop_frequency = 20
data_collection_frequency = 20

Và khi chạy teleop/data collection, bạn thường override bằng CLI:

python decoupled_wbc/control/main/teleop/run_teleop_policy_loop.py \
  --hand_control_device=pico \
  --body_control_device=pico

Hoặc trong data collection:

python decoupled_wbc/scripts/deploy_g1.py \
  --interface sim \
  --simulator robocasa \
  --image-publish \
  --hand_control_device=pico \
  --body_control_device=pico

Tại sao teleop_frequency=20 nhưng control_frequency=50? Vì teleop input của con người không cần cập nhật nhanh như vòng điều khiển robot. Người điều khiển tạo command ở khoảng 20 Hz là đủ cho intent và pose target; controller cần chạy nhanh hơn để giữ ổn định, interpolate, xử lý state và gửi action đều. Nếu bạn cố đẩy teleop lên quá cao qua WiFi hoặc XR stream không ổn định, bạn có thể tăng jitter. Nếu control loop quá thấp, robot phản ứng chậm và mất ổn định. Tách hai tần số là thiết kế hợp lý.

GR00T WBC phù hợp khi action bạn muốn thu không còn là "dịch end-effector 3 cm sang trái". Với humanoid, action có thể gồm:

Action cần học Stack phù hợp
Navigate command: tiến/lùi/trái/phải/yaw GR00T WBC planner hoặc controller joystick
Upper-body reach trong khi thân dưới giữ thăng bằng GR00T WBC hoặc Isaac Lab G1 OpenXR retargeter
Hand grasp đơn giản bằng trigger PICO/controller hoặc SpaceMouse gripper
Finger dexterity chi tiết OpenXR hand tracking, Manus/LeapMotion nếu stack hỗ trợ
Whole-body pose/motion PICO full-body teleop hoặc SONIC/GR00T WBC mode

Tài liệu PICO VR Whole-body Teleop của GR00T WBC đặc biệt nhấn mạnh safety. Có các mode như POSE, PLANNER, PLANNER_FROZEN_UPPER và VR_3PT; có calibration full và calibration khi switch vào VR_3PT; emergency stop có thể qua PICO controller hoặc phím O ở C++ terminal. Điểm beginner cần nhớ: mode switch là lúc nguy hiểm nhất. Nếu người điều khiển đứng lệch pose robot rồi bật POSE hoặc VR_3PT, robot có thể snap sang pose người và tạo chuyển động mạnh.

Chọn theo latency

Latency không chỉ là số millisecond. Với data collection, latency ảnh hưởng cả safety lẫn chất lượng action.

Stack Latency cảm nhận Vì sao Khi chấp nhận được
Keyboard Thấp, dễ đoán Event rời rạc, ít sensor Debug, scripted reset, thao tác đơn giản
SpaceMouse Thấp đến trung bình HID liên tục, ít xử lý retarget SE(3) manipulation mượt
OpenXR handtracking Trung bình, có jitter Tracking, streaming, retargeting, render Upper-body/hand natural demo trong sim
GR00T WBC PICO/VR Trung bình đến cao nếu mạng yếu XR stream, teleop loop, policy/control loop Whole-body data khi đã có safety operator

Đừng chỉ hỏi "stack nào nhanh nhất?". Hãy hỏi "latency này có ổn định không?". Latency 80 ms nhưng ổn định có thể dễ điều khiển hơn latency 30-150 ms dao động. Với hand tracking, jitter nhỏ ở ngón tay có thể tạo action hand noisy. Với locomotion, command trễ có thể làm operator overcorrect: robot đi quá target, operator kéo ngược, dataset có nhiều dao động.

Một log tối thiểu nên có:

timing:
  input_timestamp: 1718000000.100
  retarget_timestamp: 1718000000.118
  action_publish_timestamp: 1718000000.122
  robot_state_timestamp: 1718000000.140
  camera_timestamp: 1718000000.151
  episode_frame_index: 42

Bài 3 về ROS 2/MCAP sẽ đi sâu hơn, nhưng ngay từ bài này hãy đặt tên timestamp rõ. Nếu không, khi train lỗi, bạn sẽ không biết model học từ action đúng thời điểm hay action bị lệch 2-3 frame.

Chọn theo an toàn

Safety của humanoid khác robot arm. Robot arm có thể dừng ở joint target; humanoid còn balance, foot contact, base drift và mode switch.

Checklist an toàn theo stack:

Stack Gate tối thiểu
Keyboard/SpaceMouse trong sim Reset environment bằng R, giới hạn workspace, termination khi object/robot rơi
Hand tracking trong sim Teleop inactive mặc định, chỉ START khi operator đã nhìn visualization
G1 OpenXR retargeting Anchor/calibration check, joint limit, target visualization, lower-body standing state
GR00T WBC sim Operator phải biết stop policy, reset sim, discard trajectory
GR00T WBC real robot Safety operator riêng, vùng trống, emergency stop đã test, không switch mode khi pose lệch

Trong teleop_se3_agent.py, hand tracking được xử lý thận trọng hơn: khi XR được bật, teleoperation có thể bắt đầu ở trạng thái inactive, rồi START mới apply command. Đây là pattern nên copy sang stack của bạn. Input device có thể luôn stream, nhưng robot chỉ nên apply action khi gate đúng: robot ở trạng thái sẵn sàng, operator nhìn thấy scene, calibration pass, và data captain đã bật record.

Chọn theo loại hành động cần thu

Nếu chỉ thu pick/place trên bàn, bạn không cần whole-body VR. Nếu thu "đi đến bàn, cúi người, nhấc hộp, đặt lên kệ", keyboard SE(3) không đủ. Chọn stack bằng cách viết action schema trước:

action_schema:
  base:
    type: velocity_command
    fields: [vx, vy, yaw_rate]
  upper_body:
    type: eef_pose_or_delta
    fields: [left_wrist, right_wrist]
  hand:
    type: gripper_or_joint
    fields: [left_hand, right_hand]
  safety:
    type: mode_state
    fields: [teleop_active, planner_mode, emergency_stop]

Sau đó map schema sang device:

Nếu schema cần Đừng dùng Nên dùng
eef_delta đơn giản Full VR ngay từ đầu Keyboard/SpaceMouse
eef_absolute_pose Keyboard-only OpenXR handtracking hoặc motion controller
hand_joint SpaceMouse gripper binary Hand tracking, Manus, LeapMotion nếu đã ổn định
base velocity Pure arm teleop WBC planner, joystick/controller
whole-body pose SE(3) arm-only PICO/VR whole-body teleop + WBC

Một lỗi phổ biến là thu data bằng stack dễ nhất, rồi hy vọng model học được task khó hơn. Nếu dataset không có hand joints, model không tự học dexterity. Nếu dataset không có base command, model không học navigation. Nếu dataset không có mode state, model không biết lúc nào robot đang planner, pose hoặc frozen-upper mode.

Khuyến nghị triển khai cho data center nhỏ

Với một team 2-4 người mới bắt đầu humanoid VLA data, tôi sẽ đi theo bốn nấc:

  1. Keyboard trong Isaac Lab: thu 10 episode, replay được, kiểm tra state/action shape, xác nhận save/discard.
  2. SpaceMouse trong Isaac Lab: thu 30-50 episode mượt hơn, đo thời gian reset và tỷ lệ success.
  3. OpenXR handtracking hoặc motion controller trong sim: bật visualization, log raw input + retargeted action, kiểm tra calibration.
  4. GR00T WBC sim trước real: chạy control loop 50 Hz, teleop 20 Hz, data collection 20 Hz, có data captain và safety operator.

Đến khi chuyển sang real G1, đừng thay cả thiết bị, task, camera và exporter cùng lúc. Giữ task đơn giản, giữ object ít, chạy sim trước, rồi chỉ đổi interface sang real khi emergency stop đã được diễn tập. Nếu cần đọc thêm về dữ liệu G1 và GR00T N1 theo hướng fine-tune, xem bài GR00T N1 + G1: thu data trong Isaac Lab và xr_teleoperate. Nếu muốn nhìn rộng hơn các repo VLA/WBC đang dùng trong hệ sinh thái humanoid, xem VLA + WBC repos cho humanoid.

Nguồn kỹ thuật

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

Pilot 2 người cho dữ liệu humanoid VLA
wholebody-vla

Pilot 2 người cho dữ liệu humanoid VLA

10/6/202615 phút đọc
NT
Synthetic data và QA bằng Isaac Lab
wholebody-vla

Synthetic data và QA bằng Isaac Lab

10/6/202613 phút đọc
NT
Scale 20 người và eval whole-body VLA
wholebody-vla

Scale 20 người và eval whole-body VLA

10/6/202615 phút đọc
NT