This tutorial walks through running whole-body XR teleoperation on the Unitree G1
humanoid robot. The application combines AGILE locomotion, bimanual inverse kinematics,
and finger control, all driven by an XR headset.
You will first run the application in MuJoCo simulation, then deploy on real hardware.
Set up your development environment by following the instructions in getting started.
(Optional) Install dependencies for any sensors you want to use by following the sensor-specific guides.
Note
We strongly recommend installing all sensor dependencies before starting any quickstarts.
Some sensor dependencies require restarting the development environment during installation, which will interrupt the quickstart process.
Set up the Intel RealSense camera by following the
RealSense setup tutorial.
For Docker environments, the RealSense setup tutorial adds the realsense
Docker image key and rebuilds the Isaac ROS environment with
isaac-rosactivate--build-local.
Set up the Unitree G1 with the host machine connected to it by following these guides:
Make sure to repeat this step in every terminal created inside the Isaac ROS environment. Because this package was built from source, the enclosing workspace must be sourced for ROS to be able to find the package’s contents.
CloudXR requires certain network ports to be open. Depending on your firewall configuration, you may need to open them manually.
For Quest and PICO headsets (WebXR Client), at the minimum, the CloudXR runtime and WebSocket Secure proxy ports must be open. If ufw is enabled, run:
sudoufwallow47998/udp
sudoufwallow49100,48322/tcp
If you are running the WebXR client from source and ufw is enabled, also open the web server ports:
sudoufwallow8080,8443/tcp
Start the CloudXR runtime. Be sure to review and accept the EULA:
python3-misaacteleop.cloudxr
Tip
To accept the EULA prompt in non-interactive settings, pass the flag:
python3-misaacteleop.cloudxr--accept-eula
In a new terminal, activate the Isaac ROS environment:
If the CloudXR runtime is running on Thor, make sure to set the VideoCodec to H.264,
otherwise the headset will fail to connect.
Warning
The world frame of the headset is defined as the position of the headset and controllers
at the moment of connection. Stand still and face the robot before connecting to establish
a consistent world frame. To reset the world frame, disconnect and reconnect the headset
while stationary.
This opens the MuJoCo viewer with the G1 robot. The virtual gantry holds the robot
upright during startup. Press G to toggle the gantry on/off, and use [ / ]
to shorten or lengthen the rope. It is recommended to disable the gantry once the robot
is stable. The robot may oscillate at startup and will only stabilize once the controller
is active.
Note
In simulation, blend_ratio defaults to 1.0 so the policy is active
immediately.
With the controllers in your hands, start moving them. You should see the robot’s arms
track your movements in the MuJoCo viewer.
Warning
Before operating on real hardware:
Ensure the working area is free of any persons or other potential hazards.
Always start with blend_ratio at 0.0. You can increase from 0.0 to 1.0 in a single step since the ratio is smoothed internally.
Ensure the waist yaw joint is close to zero before launching. It is uncontrolled and will be held at its current position, so a rotated torso can degrade balance.
Have the disable command ready (refer to the disable step below).
Set up the network — clone isaac_ros_robots and run the setup script outside the docker container on the host machine:
The script will interactively guide you through the network setup. Make sure to select
the network interface that is physically connected to the G1 robot.
RViz opens automatically with 6-DOF interactive markers for each wrist.
The /ik_controller/reference_pose topic
replaces the /xr_teleop/ee_poses topic in this mode.
In the RViz Displays panel, find the IK Target Marker display and set
its Interactive Markers Namespace to /ik_controller_marker. You can
then drag the wrist markers to command the arms.