wholebody-vlaclonemoe-policyteleoperationunitree-g1apple-vision-prolidar-odometrywholebody-vlahumanoidsim2real

CLONE: MoE teleop và chọn stack

Triển khai CLONE cho G1 với Apple Vision Pro, LiDAR odometry, MoE policy và bảng chọn stack whole-body VLA.

Nguyễn Anh Tuấn11 tháng 6, 202617 phút đọc
CLONE: MoE teleop và chọn stack

Vì sao bài cuối chọn CLONE?

bài 1 về OpenWBT, ta bắt đầu bằng một stack có thể debug trong MuJoCo/Isaac để hiểu teleop whole-body. Bài 4 về VIRAL chuyển trọng tâm sang RGB sim2real: policy nhìn ảnh và proprioception để làm loco-manipulation. Bài 5 về FRoM-W1 lại hỏi một câu khác: liệu prompt văn bản có thể sinh motion toàn thân rồi retarget sang G1 không? CLONE là bài kết thúc hợp lý vì nó quay lại vấn đề rất thực dụng của lab: làm sao điều khiển Unitree G1 thật trong thời gian dài bằng Apple Vision Pro mà robot không drift khỏi operator.

Repo humanoid-clone/CLONE mô tả CLONE là một whole-body teleoperation system dùng Mixture-of-Experts policyclosed-loop error correction. Trang project humanoid-clone.github.io giải thích pipeline gồm ba phần: curate/augment dữ liệu AMASS đã retarget, train teacher policy với privileged information, distill sang MoE student policy, rồi deploy thật bằng LiDAR odometry để lấy state humanoid real-time. Paper CLONE trên arXiv nhấn mạnh cùng điểm: đầu vào chỉ cần head tracking và hand tracking từ một MR headset thương mại, cụ thể Apple Vision Pro trong code deploy, nhưng hệ thống vẫn duy trì whole-body coordination và hạn chế drift qua feedback toàn cục.

Nếu bạn mới vào chủ đề này, nên đọc thêm WholeBodyVLA open-source guide để nắm các khái niệm policy, teleop, retargeting và whole-body control. Nếu trọng tâm của bạn là robot nhìn bằng camera rồi đi qua sim2real, bài GR00T VisualSim2Real trên G1 là nền tốt trước khi so sánh CLONE với VIRAL.

Nếu bạn chỉ muốn chạy demo trong simulator, CLONE không phải lựa chọn nhẹ nhất. Nhưng nếu mục tiêu là thu demonstration dài hạn trên G1 thật, có đi bộ, cúi người, nhặt đồ, đặt đồ vào vị trí xa, lau bàn hoặc thao tác cần robot quay lại đúng nơi operator đang nhìn, CLONE trả lời đúng pain point. Teleop open-loop thường đẹp trong clip ngắn, nhưng sau vài mét robot và operator lệch khung tọa độ. Khi lệch đủ lớn, người điều khiển tưởng tay robot ở một chỗ, trong khi base thật đã drift sang chỗ khác. CLONE đóng vòng bằng LiDAR odometry và pose từ Vision Pro để liên tục sửa sai.

Nguồn kỹ thuật nên mở song song

Nguồn Dùng để làm gì Chi tiết cần nhớ
CLONE README Tổng quan repo, license, checkpoint/deploy status Repo đã release early checkpoint và deploy document
deploy/README.md Cài bare-metal trên server PC và G1 PC2 Dùng Unitree G1 EDU 29-DoF, Apple Vision Pro, router, PC Linux
deploy/Docker_README.md Cài nhanh bằng Docker Compose Có container trên G1 và container trên server PC
CLONE project page Hiểu MoE, LiDAR odometry, AVP tracking và data curation MoE student policy được distill từ teacher có privileged information
CLONE paper Hiểu động cơ khoa học và kết quả real-world Paper báo cáo drift tịnh tiến 12 cm trên quỹ đạo 8,9 m và mean tracking error 5,1 cm
FAST_LIO_LOCALIZATION Gói localization ROS1 được deploy trên G1 PC2 CLONE dùng LiDAR odometry để đưa pose robot vào vòng feedback
VisionProTeleop Backend AVP stream được CLONE acknowledge và tích hợp qua VisionWrapper Dùng pose head và hai tay từ Apple Vision Pro

Mental model: CLONE có bốn vòng chạy song song

Beginner nên nhìn CLONE như bốn service chạy đồng thời, không phải một script duy nhất:

Apple Vision Pro
  head pose + left/right hand pose
        |
        v
deploy/g1_server.py
  VisionWrapper + MoE policy + ROS2 LowCmd publisher
        |
        v
lowcmd_buffer topic at ~50 Hz
        |
        v
deploy/lowcmd_publisher.py
  relay to lowcmd topic at 1 kHz with CRC
        |
        v
Unitree G1 motors

G1 PC2 LiDAR odometry
  FAST_LIO_LOCALIZATION + Livox driver
        |
        v
deploy/g1_localization/pos_server.py
  ROS1 /localization -> ZeroMQ PUB
        |
        v
deploy/g1_localization/pos_client.py inside localization.py
  smoothed global pose -> shared memory -> g1_server.py

Phần dễ nhầm là g1_server.py không trực tiếp publish xuống topic motor cuối cùng. Trong code, nó publish LowCmd sang topic lowcmd_buffer ở tần số control khoảng 50 Hz. Script deploy/lowcmd_publisher.py subscribe lowcmd_buffer, giữ command mới nhất, tính CRC bằng teleop.crc.CRC, rồi publish sang topic lowcmd với HZ = 1000. Đây là lớp relay quan trọng vì Unitree low-level control thường cần dòng lệnh ổn định và đều hơn tần số inference policy.

Một điểm nữa: deploy/g1_server.py đặt POLICY_PATH = 'models/g1_student_moel.pt'. Vì script thường được chạy từ thư mục deploy, checkpoint thực tế nằm ở deploy/models/g1_student_moel.pt. Đây là early student checkpoint cho G1, tên moel trong file path nhiều khả năng ám chỉ MoE locomotion/teleop student mà repo release cho real-world deployment. Bài này không hướng dẫn retrain policy; ta dùng checkpoint có sẵn và tập trung vào hệ thống deploy.

Phần cứng tối thiểu

Theo deploy/README.mddeploy/Docker_README.md, cấu hình tham chiếu gồm:

Thành phần Vai trò Ghi chú thực tế
Unitree G1 EDU 29-DoF Robot thật chạy low-level command Bắt đầu bằng Debug Mode theo tài liệu Unitree, không chạy trong không gian đông người
Apple Vision Pro Theo dõi 3D head pose và 6D hand pose Cần cùng mạng với server PC, dùng App Streamer hoặc backend avp_stream/vuer
Router Mạng nội bộ ổn định G1 và server PC nên cắm Ethernet; AVP dùng Wi-Fi cùng router
Server PC Linux Chạy policy server, ROS2/Unitree SDK, VisionWrapper Nên có GPU CUDA nếu muốn giảm latency, dù code tự fallback sang CPU
G1 PC2 Chạy LiDAR odometry ROS1 CLONE hướng dẫn copy deploy/onboard lên PC2
Livox/MID360 LiDAR stack Odometry toàn cục tương đối localization_server.sh launch FAST-LIO localization và Livox driver

Nếu bạn chưa có G1 thật, đừng cố "fake" bài này trên laptop rồi kỳ vọng kết quả tương đương. CLONE là stack deploy robot thật. Bạn vẫn có thể đọc code để học kiến trúc closed-loop, nhưng giá trị chính nằm ở việc nối MR headset, odometry và low-level command trên phần cứng.

Cách triển khai bằng Docker

Docker path là đường dễ bắt đầu hơn vì README đã đóng gói hai môi trường: một trên G1 PC và một trên server PC. Trước khi chạy, cài Docker V2 và Docker Compose V2 trên cả hai máy. Sau đó copy thư mục on_g1 sang G1 PC, build image, up container và vào container để start localization.

# Trên G1 PC
cd on_g1
docker compose build
docker compose up -d

docker exec -it on-g1 bash
cd deploy_onboard
bash localization_server.sh

Script deploy/onboard/localization_server.sh làm ba việc theo thứ tự:

cd nav/rosws/fastlio_localization
source devel/setup.bash
roslaunch fast_lio_localization localization_mid360.launch &

cd ../livox_ros_driver2
source devel/setup.bash
roslaunch livox_ros_driver2 msg_MID360.launch &

cd ~/teleoperation
python pos_server.py &

Nói đơn giản: FAST-LIO localization tạo topic odometry, Livox driver đưa dữ liệu MID360 vào ROS1, còn pos_server.py đọc /localization rồi publish pose qua ZeroMQ. Trong source deploy/g1_localization/pos_server.py, node subscribe nav_msgs/Odometry từ topic /localization, lấy positionorientation, rồi gửi (position, quat) qua port 6006. Đây là cầu nối giữa ROS1 onboard và policy server ở máy ngoài.

Trên server PC, build container trong thư mục deploy, bật quyền X11 nếu cần MuJoCo viewer, rồi chạy container:

# Trên server PC
xhost +local:docker
cd deploy
docker compose build
docker compose up -d

Terminal thứ nhất giữ relay 1 kHz:

docker exec -it clone_unitree_server bash
python3 deploy/lowcmd_publisher.py

Terminal thứ hai chạy policy server:

docker exec -it clone_unitree_server bash
python3 deploy/g1_server.py

Trước khi chạy g1_server.py, sửa đúng IP của Apple Vision Pro trong config.py. File mặc định của repo có VISION_WRAPPER_BACKEND = 'avp_stream', VISION_PRO_IP = '192.168.123.8', VISION_PRO_DELTA_H = -0.54USE_DEX_HANDS = True. IP AVP có thể xem trong Wi-Fi settings hoặc màn hình App Streamer trước khi bấm Start.

Cách triển khai bare-metal

Nếu không dùng Docker, deploy/README.md yêu cầu bạn tự chuẩn bị ROS 2 trên server PC, cài Unitree ROS 2 SDK, clone repo và pip install -r requirements.txt. Trên G1 PC2, hướng dẫn cài Livox driver cho ROS1 theo FAST_LIO, cài FAST_LIO_LOCALIZATION, rồi copy deploy/onboard sang PC2. README cũng nhắc nếu thiếu localization_mid360.launch hoặc mid360.yaml, hãy kiểm tra deploy/onboard/launchdeploy/onboard/misc.

Luồng chạy bare-metal gần giống Docker:

# G1 PC2
cd <thu_muc_onboard_da_copy>
bash localization_server.sh
# Apple Vision Pro
# Mở Tracking Streamer nếu dùng avp_stream
# Server PC, terminal 1
python deploy/lowcmd_publisher.py
# Server PC, terminal 2
python deploy/g1_server.py

Khi robot đã đứng trong Debug Mode, operator căn chỉnh vị trí người và humanoid bằng nút R1/R2 trên remote. Trong g1_server.py, callback low-level state parse wireless remote. R1 gọi reset Vision Pro, R2 reset localization, L1 bật policy, L2 dừng policy. Đây không phải chi tiết phụ. Với robot thật, thứ tự vận hành nên là: kiểm tra E-stop vật lý, kiểm tra không gian trống, start odometry, start relay, start policy server, align pose bằng R1/R2, rồi mới bấm L1.

MoE policy trong CLONE giải quyết vấn đề gì?

Một policy MLP đơn khối thường khó học cùng lúc đi bộ thẳng, quay người, cúi xuống, vươn tay, squat, nhặt vật dưới đất và thao tác bàn. Các hành vi này có contact pattern khác nhau. Đi bộ cần nhịp chân ổn định; cúi người cần kiểm soát center of mass; thao tác tay cần ưu tiên pose cổ tay; quay người cần yaw base và waist phối hợp. Nếu nhồi tất cả vào một policy monolithic nhỏ, policy dễ trung bình hóa hành vi: đủ ổn để đứng và đi nhẹ, nhưng yếu khi operator làm động tác nằm ngoài phân phối.

CLONE dùng Mixture-of-Experts để một policy thống nhất vẫn có các nhánh chuyên môn hóa. Theo paper, teacher policy được train với privileged information, còn student MoE được distill để chạy bằng observation thực tế. Input control tối thiểu là 3D head position và 6D pose của hai wrist từ AVP. Task observation còn chứa target position/velocity, wrist orientation và trạng thái suy ra từ robot. Kết quả là student không cần mocap suit, marker ngoài phòng hay exoskeleton; nó học cách biến pose thưa của người thành full-body motion phối hợp.

Trong g1_server.py, class G1 khai báo num_actions = 29, tương ứng 29 DoF command cho G1 EDU. Code cũng thiết lập PD gains, soft joint limits, torque limits và default pose. Policy được load bằng:

POLICY_PATH = 'models/g1_student_moel.pt'
self.policy = torch.jit.load(os.path.join(file_pth, POLICY_PATH), map_location=self.env.device)

Điểm đáng học ở đây là deploy policy không chỉ là torch.load rồi publish action. Trước policy còn có preprocessing observation, history buffer, quaternion transform, calibration AVP/localization, forward kinematics để suy ra body positions. Sau policy còn có clamp joint limit, PD command, CRC và relay. Nếu bạn tự thay checkpoint, phải giữ contract observation/action giống checkpoint cũ, nếu không lỗi có thể xuất hiện dưới dạng robot run nhưng posture sai.

Closed-loop error correction hoạt động thế nào?

CLONE đóng vòng bằng cách đưa localization thật của robot trở lại observation. Trên G1 PC2, pos_server.py đọc /localization từ FAST-LIO và gửi qua ZeroMQ. Trên server PC, deploy/g1_localization/pos_client.py connect tới tcp://<server_ip>:6006, receive pickle message, giữ moving average dài 10 mẫu (ma_len = 10), rồi cập nhật positionquat. Trong deploy/localization.py, function start_service() chạy Position_Client trong thread riêng, ánh xạ shared memory giữa localization process và g1_server.py, đảo dấu một số trục (position_factor[2] *= -1, position_factor[1] *= -1) để khớp frame, rồi dùng forward kinematics compute_fk_body_pos() để tạo body position mở rộng.

Vòng feedback có thể đọc như sau:

LiDAR odometry says:
  base/head frame is now at global pose L_t

Vision Pro says:
  operator head and hands are at pose V_t

g1_server.py maintains:
  loc_offset, obs_quat, loc_delta_rot, body_pos_extend

Policy observation includes:
  current robot state + corrected global pose + target head/wrist pose

Policy output:
  29 joint position targets

Khi operator bấm R2, reset_localization() cập nhật loc_offset để vị trí robot thật khớp lại với head target và ground height hiện tại. Hàm này cũng tính heading delta giữa quaternion hiện tại và head quaternion để cập nhật loc_delta_rot. Khi operator bấm R1, reset_vision_pro() căn lại yaw giữa frame AVP và frame robot. Vì vậy CLONE không chỉ "đọc LiDAR cho vui"; nó dùng LiDAR odometry để giữ pose toàn cục của robot trong vòng policy, làm giảm drift tích lũy khi robot đi lâu.

Paper báo cáo cơ chế closed-loop dùng LiDAR odometry và AVP tracking giúp giảm drift tịnh tiến xuống 12 cm trên quỹ đạo 8,9 m, và trang arXiv HTML mô tả mean tracking error 5,1 cm trong thí nghiệm real-world. Con số này không đảm bảo bạn cũng đạt y hệt trong lab nếu Wi-Fi, LiDAR calibration, sàn, ánh sáng, latency hoặc firmware khác. Nhưng nó cho thấy hướng thiết kế đúng: long-horizon teleop cần feedback pose thật, không chỉ replay pose người theo frame tương đối.

Arm IK và dexterous hands nằm ở đâu?

CLONE deploy còn có phần tay. File deploy/teleop/robot_control/robot_arm_ik.py định nghĩa G1_29_ArmIK, dùng Pinocchio, CasADi và IPOPT để giải inverse kinematics cho hai end-effector L_eeR_ee. Code build reduced robot từ URDF g1_body29_hand14.urdf, lock các khớp chân, waist và hand joints, thêm frame ở left_wrist_yaw_jointright_wrist_yaw_joint, rồi tối ưu:

minimize
  50 * translational_cost
  + 1 * rotation_cost
  + 0.02 * regularization_cost
  + 0.1 * smooth_cost

subject to
  lowerPositionLimit <= q <= upperPositionLimit

Kết quả solve_ik() trả về sol_q và torque feedforward từ Recursive Newton-Euler (pin.rnea). Nếu solver không hội tụ, code fallback về joint hiện tại và zero feedforward. Đây là lựa chọn an toàn hơn so với publish nghiệm IK nhiễu. Với beginner, ý chính là: pose tay từ AVP không nên map thẳng sang joint bằng công thức thủ công; CLONE dùng IK có constraint, smoothing và fallback để làm pose cổ tay bền hơn.

Nếu USE_DEX_HANDS = True, g1_server.py còn launch dex hand server qua shared memory. Phần này phụ thuộc bàn tay cụ thể của G1 EDU và setup dexterous hands. Nếu lab của bạn chưa gắn dex hands hoặc chỉ quan tâm locomotion/upper-body coarse teleop, hãy đọc kỹ config trước khi bật policy thật.

Checklist chạy an toàn cho buổi đầu

1. Cắm G1 và server PC bằng Ethernet vào cùng router.
2. Kết nối Apple Vision Pro vào Wi-Fi của cùng router.
3. Xác nhận IP của G1 PC2, server PC và Apple Vision Pro.
4. Trên G1 PC2, chạy localization_server.sh và kiểm tra /localization có dữ liệu.
5. Trên server PC, sửa VISION_PRO_IP trong config.py.
6. Chạy lowcmd_publisher.py và thấy log "Initialized".
7. Chạy g1_server.py, kiểm tra checkpoint g1_student_moel.pt load thành công.
8. Đặt robot ở Debug Mode, có người giữ E-stop hoặc remote.
9. Căn frame bằng R1/R2, bấm nhiều lần nếu cần.
10. Bấm L1 để start policy, L2 để stop ngay khi pose bất thường.

Các lỗi thường gặp:

Triệu chứng Khả năng cao Cách kiểm tra
g1_server.py không nhận AVP pose Sai VISION_PRO_IP hoặc backend stream chưa start Ping AVP, kiểm tra App Streamer, kiểm tra VISION_WRAPPER_BACKEND
Robot không nhận command dù policy chạy lowcmd_publisher.py chưa chạy hoặc topic ROS2 sai Echo lowcmd_bufferlowcmd, kiểm tra Unitree ROS2 SDK
Pose global nhảy hoặc trôi mạnh FAST-LIO/localization chưa ổn, frame trục sai, Wi-Fi jitter Kiểm tra /localization, map/launch MID360, timestamp
Bấm R1/R2 không thấy thay đổi Remote data chưa parse hoặc callback lowstate không chạy Kiểm tra lowstate topic và wireless remote bits
Tay rung khi follow wrist IK target quá xa, AVP pose nhiễu, hand calibration sai Giảm biên độ, kiểm tra robot_arm_ik.py, tắt dex hands để isolate

CLONE phù hợp với ai?

CLONE phù hợp nếu bạn có G1 thật, muốn thu dữ liệu whole-body long-horizon và chấp nhận vận hành nhiều service cùng lúc. Stack này không phải "one-click demo" cho người mới học ROS. Nhưng nó cho beginner một kiến trúc đáng bắt chước: tách localization, headset stream, policy inference, low-level relay và safety controls thành các module có boundary rõ.

Với nhóm nghiên cứu data collection, CLONE hấp dẫn vì operator chỉ cần Apple Vision Pro thay vì mocap room. Với nhóm làm VLA, nó có thể là nguồn demonstration dài: robot đi tới vật, cúi xuống, nhặt, quay lại, đặt vào thùng, trong khi global pose vẫn được sửa. Với nhóm làm sim2real locomotion, phần đáng học là cách student policy dùng history, PD gains, limit handling và relay 1 kHz để sống sót trên robot thật.

Bảng chọn stack sau 6 bài

Nhu cầu lab Stack nên chọn Vì sao
Chưa có G1 thật, muốn học whole-body teleop trong sim OpenWBT Dễ debug, ít rủi ro phần cứng, hợp để hiểu MuJoCo/Isaac và action space
Có G1, muốn teleop/collect data với headset PICO và pipeline thực dụng TWIST2 Tập trung vào robot-side data collection, Redis/low-level controller và sim2real
Có nhiều human egocentric demos, muốn tận dụng dữ liệu người cho robot policy EgoHumanoid Mạnh ở view/action alignment giữa human demo và humanoid
Cần RGB sim2real cho loco-manipulation, robot tự nhìn và hành động VIRAL Chọn khi camera observation là trung tâm và bạn cần distill privileged teacher sang RGB student
Cần text-to-motion, prompt ngôn ngữ hoặc motion generation trước khi robot tracking FRoM-W1 Hợp khi input là instruction text và bạn muốn pipeline H-GPT -> H-ACT -> G1 policy
Có G1 thật, Apple Vision Pro, LiDAR odometry, cần long-horizon teleop và data collection CLONE MoE teleop + closed-loop correction giải quyết drift trong task dài

Một cách chọn nhanh hơn:

Điều kiện Không nên chọn Nên chọn
Budget phần cứng thấp, không có humanoid thật CLONE, TWIST2 deploy thật OpenWBT, FRoM-W1 phần generation
Có G1 thật nhưng chưa có AVP CLONE đầy đủ TWIST2 hoặc OpenWBT tùy headset/controller
Cần RGB sim2real FRoM-W1, CLONE VIRAL
Cần text-to-motion VIRAL, CLONE FRoM-W1
Cần thu demonstration dài nhiều mét Open-loop teleop đơn giản CLONE
Cần dataset từ human egocentric video CLONE không phải trọng tâm EgoHumanoid
Cần baseline policy/control để hiểu G1 action space Các stack paper nặng OpenWBT trước, rồi TWIST2/CLONE

Nếu phải xếp thứ tự học cho một lab mới: bắt đầu với OpenWBT để hiểu control loop, đọc TWIST2 để thấy cách nối robot thật, đọc EgoHumanoid và VIRAL để hiểu data/pixel policy, đọc FRoM-W1 để có trục language-to-motion, rồi dùng CLONE khi đã có phần cứng đủ và cần long-horizon teleop thật.

Kết luận series

Sáu bài trong series không cạnh tranh trực tiếp nhau. Chúng là sáu câu trả lời cho sáu câu hỏi khác nhau của humanoid VLA năm 2026:

OpenWBT: làm sao có teleop whole-body dễ debug?
TWIST2: làm sao đưa teleop xuống G1 thật?
EgoHumanoid: làm sao tận dụng demonstration của người?
VIRAL: làm sao policy nhìn RGB và sim2real?
FRoM-W1: làm sao biến text thành motion và robot tracking?
CLONE: làm sao teleop whole-body lâu mà không drift?

CLONE là mảnh cuối vì nó nhắc rằng humanoid VLA không chỉ là model lớn. Trên robot thật, một policy tốt vẫn cần localization tốt, frame calibration tốt, low-level relay đều, safety stop rõ ràng và operator interface đủ trực giác. MoE policy giúp robot phối hợp chân, thân và tay; closed-loop error correction giúp operator không mất robot sau vài mét; Apple Vision Pro giúp giảm yêu cầu phần cứng mocap. Đó là hướng thực chiến nhất nếu mục tiêu của bạn là thu dữ liệu loco-manipulation dài hạn cho thế hệ humanoid foundation models tiếp theo.

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

TWIST2: PICO teleop và G1 sim2real
wholebody-vla

TWIST2: PICO teleop và G1 sim2real

11/6/202617 phút đọc
NT
VIRAL: RGB sim2real cho G1 loco-manip
wholebody-vla

VIRAL: RGB sim2real cho G1 loco-manip

11/6/202616 phút đọc
NT
OpenWBT: G1 teleop trong MuJoCo/Isaac
wholebody-vla

OpenWBT: G1 teleop trong MuJoCo/Isaac

11/6/202613 phút đọc
NT