Keep the product names distinct: VIVE Tracker 3.0 is the Lighthouse device (there is no “Quest 3.0” tracker), Meta Quest is the WebXR source, and VIVE Ultimate Tracker is the inside-out source.
Set up the source
The Tracking tab walks each source through a step-by-step flow. Each step resolves from what the host actually reports (not from ticking a box), Continue unlocks once it is resolved, a step that regresses later pulls the flow back to it, and the flow stays on a step while its action is running. Setup is complete once the sides are identified (or, for Quest, once the headset’s calibration key is saved). The equivalent CLI commands are listed alongside; see the tracker CLI reference for their flags.- Quest
- Lighthouse
- Ultimate
Quest uses the headset’s own controller tracking through WebXR, so there is no runtime to install and no tracker to bind; WebXR handedness assigns left and right. The only stored state is the calibration key that identifies the controller generation and pose datum.The client sends
1
Source
Choose Quest (the selection saves immediately). The Quest headset and the host must be on the same LAN (or use the wired Quest-over-USB link, managed under General settings → Quest).
2
Headset
Start a Quest bring-up collection run:
axol collect-data --mantis true --mantis_allow_uncalibrated true (or Start Collect data with mantis_allow_uncalibrated set under Advanced); teleop never starts the VR server. Then in the Quest browser open axol.almond.bot, enter the host, connect, accept the host’s certificate the first time, and choose Enter VR. Hold both Touch controllers.The step shows each controller’s reported WebXR profile and pose space and, when both match, a copyable common calibration key (for example quest:oculus-touch-v3:grip). Press Use this key, then Save settings. The step resolves once the saved key is a grip-space datum matching the live controllers; a stale report, a target-ray fallback, or two controllers reporting different keys is held rather than accepted.gripSpace poses (with targetRaySpace only as an older-runtime fallback), works without body/elbow tracking, and preserves lost optical tracking per side so the server can hold safely. Quest has no factory tracker→gripper transform: production collection needs a bench-measured transform for both controllers under the exact saved key; see Transforms.Start gesture and recovery
- Quest
- Lighthouse / Ultimate
Hold both rigs at the agreed start pose, release both controller grips, then press both grips together to align and engage. The controller triggers operate the grippers. In data collection, A starts and confirms a take, exactly as on Axol.If tracking is lost on either side, both sides freeze. Restore both, then release and press both grips again; recovery never resumes motion on its own. Reset returns to rest and needs the same fresh gesture.
Transforms
Absolute (Mantis) IK solves the world yaw and translation at engage time, but it does not discover where the gripper TCP sits relative to the tracker. That rigid tracker → TCP transform must come from somewhere:
Overrides and Quest measurements live in
~/.almond/mantis/tcp_transform.json, keyed per side by the identified device (survive:<codename>, ultimate:<mac>, or quest:<profile>:grip). pos is the gripper TCP origin in the tracker’s local frame in metres; quat is the TCP orientation in that frame as [qx, qy, qz, qw]. The file is edited directly (or via PUT /api/tracker/calibration/<source>); the panel does not edit transforms. The full schema, the Ultimate convention rules, and the bring-up route for a missing constant (--mantis_allow_uncalibrated true for a calibration-only capture) are in the tracker CLI reference. Production collect-data refuses to start with a missing, stale, or unapproved transform on either side.
Acceptance
Before recording training data, run a short bring-up collection run (axol collect-data --mantis true --mantis_allow_uncalibrated true, discarding every take) with the workspace clear and check, with the selected live source:
- Physical left/right, scale, every translation axis, wrist rotation, and tracker→TCP alignment. With Quest, the headset’s live URDF overlay shows the virtual arms; with Lighthouse/Ultimate, use the control panel’s mirrored view.
- Recovery: deliberately occlude or de-localize one side and confirm both freeze; restore tracking and confirm nothing moves until the start gesture is repeated.
tracker.identify binds a tracker to a side by which one you move, not by which rig it is mounted on. If the tracker bound as left sits on the rig held in the right hand, the engage fit faces the robot base backwards and every recorded pose is yawed 180° with the columns swapped. With both sides calibrated, the engage refuses this: the log reports Teleop engage rejected: both grippers face away from the robot's rest heading, the session disengages, and nothing is recorded until both grips are released and squeezed again with the rigs in the correct hands (or re-identified). Hold each rig like the robot holds its rest gripper — fingers down, tracker face up, handle towards you — when engaging; a rig pointed straight up or down is not checked.
Recording also counts frames where a hand travelled beyond Axol’s reach (out_of_reach in the episode QA line, plus a warning): the rig has no arm to stop you, but Axol cannot follow those poses on replay.
A source that jumps, drifts, swaps sides, or cannot recover cleanly is not ready for collection. Mantis teleop never tracks, and axol teleop --sim --teleop.absolute_mode true is only a generic mapping demo; physical acceptance must use the real source, Mantis selected, in a collection run.
Next steps
Teleoperation
Check the grippers from the rig triggers (no tracking).
Data Collection
Record Mantis episodes to a LeRobot dataset.
