← All projects

QTM Teleop G1

Teleoperation of the Unitree G1 humanoid from Qualisys motion capture: a person moves in the mocap studio and the G1 follows in real time through the QTM stream. Recorded sessions can also be retargeted offline from FBX. Developed at the CSUSB Robotics Lab.

TeleoperationMotion CaptureRobot Learning

Architecture

Live teleop

QTM real-time stream
24 skeleton segments
→
GMR retargeting
live IK → 29 G1 joints
→
Safety filter
limits · rate · stale-data hold
→
G1 / MuJoCo
100 Hz commands + HDF5 episodes

The QTM real-time skeleton stream is retargeted every frame, filtered for safety, and sent to the G1 over DDS, or to a MuJoCo viewer in dry-run mode. Every session can be recorded as an episode for robot learning. Tested against live QTM data in dry-run mode; not yet run on the physical robot.

Offline FBX retargeting

Qualisys Lab
person moves in capture volume
→
FBX export
skeleton + global positions
→
Blender (headless)
reads skeleton data
→
GMR retargeting
inverse kinematics → G1 joints
→
MuJoCo viewer
.pkl output

Blender runs headless to parse the FBX skeleton, auto-corrects the actor's starting orientation so the robot faces forward, then GMR (General Motion Retargeting, Stanford/CMU) solves the IK mapping human motion onto the G1's body proportions before saving/visualizing the result.

Media

Overview

Requirements

  • Python 3.10+, with GMR and MuJoCo (installed by setup.sh)
  • Live teleop: QTM streaming an AIM skeleton (RT port 22223); unitree_sdk2_python to drive the robot
  • Offline: Blender 3.6 LTS+ and a Qualisys FBX export with skeleton + global positions enabled

Robot safety

  • Always dry-run in MuJoCo first (--dry-run)
  • On hardware the G1's balance controller is released: robot on a gantry, safety operator on the remote

Export requirements from QTM

  • AIM skeleton model fitted to the recording (not raw marker data)
  • Binary FBX, Z up-axis, meters, all frames
  • "Skeleton" and "Global Positions" both checked on export