ROS2 Interface
TeleopXR includes a full-featured ROS2 interface that publishes XR state as ROS topics and subscribes to image topics for video streaming.
Running the Node
You can run the ROS2 node using the Python module directly. It supports two primary modes: teleop (streaming raw poses) and ik (streaming joint trajectories).
# 1. Standard Teleop Mode (Default)
python -m teleop_xr.ros2 --mode teleop
# 2. IK Mode (with Unitree H1 robot model)
python -m teleop_xr.ros2 --mode ik
Command Line Arguments
--mode: Operation mode (teleoporik). Default isteleop.--host: Host address (default:0.0.0.0)--port: Port number (default:4443)--input-mode: Input mode (controller,hand, orauto).--frame-id: The frame ID for published poses (default:xr_local).--publish-hand-tf: If set, publishes TF transforms for individual hand joints.--head-topic: ROS topic for head camera view.--wrist-left-topic: ROS topic for left wrist camera view.--wrist-right-topic: ROS topic for right wrist camera view.--extra-streams: Additional streams inkey=topicformat.
Published Topics
The node publishes the following topics (namespaced under xr/):
Poses & Tracking
xr/head/pose(geometry_msgs/PoseStamped): 6DoF pose of the headset.xr/controller_{left|right}/pose(geometry_msgs/PoseStamped): Grip pose of the controllers.xr/hand_{left|right}/joints(geometry_msgs/PoseArray): Array of poses for all 25 hand joints.
Inputs
xr/controller_{left|right}/joy(sensor_msgs/Joy): Controller button and axis states.- Buttons: Standard WebXR gamepad button mapping (Trigger, Grip, A/B/X/Y, Thumbstick Click).
- Axes: Joystick X/Y axes + Analog values for Trigger/Grip.
xr/controller_{left|right}/joy_touched(sensor_msgs/Joy): Touch/capacitive states for buttons.
Diagnostics
xr/fetch_latency_ms(std_msgs/Float64): Latency of fetching XR state on the headset.
IK Mode Topics (only in --mode ik)
/joint_trajectory(trajectory_msgs/JointTrajectory): Optimized joint configuration commands generated by the IK solver./joint_states(sensor_msgs/JointState): Subscribes to this topic to synchronize the internal robot state when IK is not actively engaged.
Subscribed Topics
Video
- Any topic specified in
--head-topic,--wrist-left-topic, etc. - Supports
sensor_msgs/Image(raw) andsensor_msgs/CompressedImage(compressed). - Note: Requires
cv_bridgefor efficient conversion. Ifcv_bridgeis missing, it falls back to a basic numpy conversion (supportingrgb8,bgr8,mono8).
TF Transforms
The node broadcasts TF transforms for:
* xr/head
* xr/controller_left/pose
* xr/controller_right/pose
* xr/hand_{side}/{joint_name} (Only if --publish-hand-tf is enabled)
All transforms are relative to the frame specified by --frame-id (default: xr_local).