VR Teleoperation¶
Control robots using a VR headset and controllers.
Supported Headsets¶
Headset |
Support Level |
Modes |
Notes |
|---|---|---|---|
Pico Enterprise |
Recommended |
Web, XRoboToolkit |
USB shared networking (USB 网络共享); its own App, not the consumer Pico App |
Pico consumer |
Supported |
Web, XRoboToolkit |
Different headset App from Enterprise; no USB-tether path documented here |
Meta Quest |
Supported |
Web, XRoboToolkit |
Good consumer availability |
Pico Enterprise vs consumer
Treat Pico Enterprise and Pico consumer as different SKUs. Each edition has its own headset App.
USB shared networking (USB 网络共享) — Pico Enterprise can share a network with the ROS 2 PC over USB. That is an Enterprise capability; it is not the consumer Pico path.
Different Apps — Enterprise and consumer Pico use different headset Apps. Install the App that matches the headset edition. The fa-py-libraries README’s XRoboToolkit path is “XRoboToolkit App + PC Service” versus browser WebXR; it does not name a single store listing for both Pico editions.
Store listings, extra package names, and ADB steps are in the headset / fa-py-libraries READMEs when they document them.
Pico Recommended
Pico Enterprise is the preferred Pico SKU for VR teleop (USB 网络共享, matching Enterprise App, lower-latency tracking / 更跟手). Consumer Pico and Meta Quest still work with the WebXR (./run.sh vr) and XRoboToolkit (./run.sh vr-xrt) backends.
Prerequisites¶
Working robot demo (mock, sim, or real)
VR headset (Pico Enterprise recommended; Pico consumer or Meta Quest also used)
fa-py-libraries installed
Network between the headset and the ROS 2 machine (Wi-Fi, or USB 网络共享 on Pico Enterprise)
enable_vr: truein the robot description’sconfig/ocs2/target_manager.yaml(most robots default off)
Before the controller will consume VR targets, set enable_vr: true in that YAML. Related fields on the same file: vr_update_rate (used when VR is on) and vr_follow_frame (full-body follow frame; see Troubleshooting).
Overview¶
VR teleoperation publishes end-effector pose targets from VR controller tracking. The MPC controller then generates joint trajectories to follow these targets.
How the arm complies with those poses depends on the robot. Two different paths are used with VR teleop:
Path |
Robots |
Who provides compliance |
What the controller commands |
|---|---|---|---|
MIT-mode force control |
HighTorque (高擎) Panthera HT; ARX (方舟无限) arms |
Controller + hardware interface in MIT / |
Force-capable / MIX when the interfaces allow it |
Vendor joint impedance |
Tianji (天玑); Rokae (珞石) |
Vendor stack, exposed on the hardware interface |
Position only |
Payload identification (负载辨识) belongs to the vendor-impedance path (Tianji / Rokae), not the MIT path. Details below.
Force control and compliance¶
MIT-mode force control (Panthera HT / ARX)¶
Use this path on Panthera HT and ARX arms. The hardware interface must run a force-capable MIT configuration; the controller then tracks VR poses with that mix of position / velocity / effort.
HighTorque Panthera HT — ht-ros2-control README:
HI
control_mode:=mit(default; older namefull_controlstill accepted)The driver sends position + velocity + effort + kp/kd (
pos_vel_tqe_kp_kd)Stiffness is HI parameters
joint_kp/joint_kd(rqt /ros2 param), not kp/kd command interfacesOther documented HI modes:
effort(torque only),position(position only)
ARX arms — arx-ros2-control README:
Arms support only
full_control/ MIT MIX. Othercontrol_modevalues in xacro are warned and ignoredwrite()always sends position + velocity + effortMIT
kp/kdcome from HIjoint_k_gains/joint_d_gains(no kp/kd command interface)README mapping: OCS2 trajectory → position; OCS2
future_input→ velocity; OCS2 effort → gravity / static feedforward torque
Controller — ocs2_arm_controller README — Interface Configuration:
Mode is auto-detected from the robot config (no extra launch flag named
force:=)Position-only: command
position; stateposition+velocityForce / MIX: command
position,velocity,effort,kp,kdall present; YAMLforce_gainsis[kp, kd]ARX documents OCS2 MIX as pos + vel + effort with kp/kd on the HI. HT notes that when kp/kd are not command interfaces, OCS2 may stay in position mode; gravity compensation then uses
ht_gravity_compensationor largerjoint_kp(same HT README)
Bring the robot up with the lean-branch ./quick_start.sh / hardware:=real path on HighTorque Panthera HT or ARX Lift 2S, then start VR as below.
This MIT path is not isomorphic teleop. Master–slave mode:=mit / effort on Panthera HT is Isomorphic Teleop.
Vendor joint impedance (Tianji / Rokae)¶
Use this path on Tianji (天玑) and Rokae (珞石). The controller only sends joint position. Joint impedance / compliance is the vendor feature, switched on the hardware interface.
Tianji — marvin-ros2-control README:
Command interfaces: joint
positiononly. State:position,velocity,effortRuntime
ctrl_mode:POSITION/JOINT_IMPEDANCE/CART_IMPEDANCE/POWER_OFFJoint impedance gains:
joint_k_gains/joint_d_gains(7 values). Cartesian:cart_k_gains/cart_d_gainsExample:
ros2 param set /<hardware_node> ctrl_mode JOINT_IMPEDANCE
Rokae — same pattern (position commands; compliance in the vendor HI). Parameter names are in the private rokae-ros2-control README after access. Overview: Hardware Interfaces.
Internal FA robots that use Tianji / Rokae arms live in fa-deploy-ws Setup. Extra robot IDs and launch flags are in that workspace README after access.
Payload identification (负载辨识)¶
负载辨识 is only on the Tianji / Rokae (vendor impedance) path. It is not an MIT / OCS2 force_gains procedure.
Public, verified Tianji wizard (semi-automatic tool-dynamics ID on CCS): marvin-ros2-control scripts/tool_dyn_identify_wizard.py, installed as ros2 run marvin_ros2_control tool_dyn_identify_wizard (CMakeLists.txt install(PROGRAMS … RENAME tool_dyn_identify_wizard)).
The wizard banner is 机械臂负载辨识向导(工具动力学参数辨识 / CCS). It connects to the Marvin controller IP, collects no-load then loaded PVT trajectories, and prints 10-D tool dynamics (m, mx, my, mz, ixx, …). Those values match HI parameters left_dyn_param / right_dyn_param on the same README.
There is no public open-deploy-ws payload-ID flow. Internal on-site Tianji payload identification is in the private fa-deploy-ws README after access (default branch is typically fa-w2). Use that README’s script names — they are not listed here.
Setup¶
1. Install fa-py-libraries¶
cd ~/
git clone https://github.com/fiveages-sim/fa-py-libraries.git
cd fa-py-libraries
./init.sh all
HTTPS is the public clone. SSH (git clone git@github.com:fiveages-sim/fa-py-libraries.git) is optional if you already have keys.
What ./init.sh all does: submodules + Python 3.12 env + ros2_robot_interface / ros2-viser / vr_pose_publisher.
2. Start Robot Demo¶
source ~/open-deploy-ws/install/setup.bash
ros2 launch ocs2_arm_controller demo.launch.py
3. Start VR Bridge¶
In a new terminal, from fa-py-libraries (README commands — there is no ./run.sh vr --mode):
cd ~/fa-py-libraries
./run.sh vr
This starts the Vuer/WebXR VR pose publisher.
VR Modes¶
Both Pico and Meta Quest support two connection modes:
Mode |
Connection |
Setup |
Latency |
Command |
|---|---|---|---|---|
Web (WebXR) |
Browser-based |
Easy |
Higher |
|
XRoboToolkit |
Native app + PC Service |
Requires app install |
Lower |
|
Web Mode (WebXR)¶
Browser-based VR using Vuer — works on both Pico and Meta Quest:
./run.sh vr
Open the displayed URL on your VR headset’s browser. No app installation required.
XRoboToolkit Mode¶
Native application for lower latency — recommended for production. From the fa-py-libraries README:
./init.sh install-xrobotoolkit-pc-service
./init.sh install-xrobotoolkit
./run.sh vr-xrt-service
./run.sh vr-xrt
Requires the edition-matching XRoboToolkit App on the headset (Enterprise App ≠ consumer Pico App) plus PC Service. ./run.sh vr-xrt-service stop shuts down the PC Service.
Topics¶
VR teleoperation publishes to:
Topic |
Type |
Description |
|---|---|---|
|
|
Left hand target pose |
|
|
Right hand target pose |
|
|
Head tracking |
|
|
Controller trigger state |
Arm Following¶
Configure which arm follows which controller:
# In configuration or launch
teleop_config:
left_arm: "left_controller"
right_arm: "right_controller"
# or for single arm:
right_arm: "any_controller"
Safety¶
Motion Limits
VR teleoperation can command rapid motions. When using real hardware:
Start with low speed limits
Keep hand on emergency stop
Clear the robot workspace
Use workspace limits in software
Network Setup¶
The headset and the ROS 2 PC must be on a reachable network (same Domain ID; Zenoh or DDS as needed).
Pico Enterprise: USB shared networking (USB 网络共享) is supported — tether the headset to the PC over USB so they share a network. Follow the headset’s own USB-network UI; this page does not list ADB or
usb0commands.Pico consumer / Meta Quest: use the usual Wi-Fi (or other IP) path. Do not assume USB 网络共享.
Then:
Confirm both devices can reach each other
Configure ROS 2 domain or Zenoh bridge if they are not on one LAN
Set firewall rules for ROS 2 ports
Verification¶
VR bridge logs show tracking data
ros2 topic echo /teleop/right_ee_poseshows updatesRobot follows VR controller motion
Troubleshooting¶
No tracking data¶
Check VR device is properly tracked
Verify browser/app has WebXR permissions
Check network (Wi-Fi, or USB 网络共享 on Pico Enterprise)
Confirm the headset App matches the Pico edition (Enterprise vs consumer)
High latency¶
Prefer Pico Enterprise (USB 网络共享 when possible)
Use XRoboToolkit (
./run.sh vr-xrt) instead of WebXRUse wired / USB-tethered networking when the headset edition supports it
Reduce update rate in configuration
Check for network congestion
Robot doesn’t follow¶
Confirm
enable_vr: truein the description’sconfig/ocs2/target_manager.yaml(most robots default off)Verify controller is in teleop mode (
UPDATEafter entering OCS2)Check target poses are within workspace
Ensure no safety limits are triggered
base_footprint missing (全身 / FULL_BODY)¶
FULL_BODY may warn that base_footprint does not exist (lookupTransform target_frame). Default vr_follow_frame is base_footprint. Set vr_follow_frame in config/ocs2/target_manager.yaml to the robot’s real base (for example base_link).
Next Steps¶
Isomorphic Teleop for master–slave joint following (Panthera HT
mode:=mit/effort— not the VR MIT path above)FSM and Topics for mode control
ocs2_arm_controller —
force_gainsand MIX detectionmarvin-ros2-control — Tianji position +
JOINT_IMPEDANCEvr_pose_publisher — published
/teleop/*topics