<aside> ⚠️

This page is synced from GitHub. Edits will be overwritten.

Source: https://github.com/uwrealitylabs/standalone-knowledge-base/blob/main/docs/standalone-driver/Monado headset driver.md

Last synced: 2026-11-01 23:20:25 UTC

</aside>

Monado headset driver

Part of Project Standalone.

The whole driver-side package for our hardware inside the Monado fork. It runs in userspace inside monado-service; it is not a kernel driver. It has one face toward the core (xrt_device) and a lot of internal plumbing behind it. This note is the overview for standalone-driver/; it mixes the target design with Monado background.

Our code

Repo uwrealitylabs/standalone-monado-driver, branch dev at 6bbefe8. Paths relative to src/xrt/.

Piece Where State on dev
HMD device drivers/standalone/standalone_hmd.c, standalone_interface.h Skeleton derived from Monado's sample driver. get_tracked_pose (:99) answers from a relation history seeded with an identity pose; no tracker
Builder targets/common/target_builder_standalone.c, registered in targets/common/target_lists.c standalone_open_system_impl (:61) creates the HMD and assigns the head role. Receives xfctx and origin but does not use them yet; no capture or tracker
Build switch CMake option XRT_BUILD_DRIVER_STANDALONE
Frame context xfctx handed to the builder belongs to the system-devices object (targets/helpers/target_builder_helpers.c:107–118) Anything registered there is torn down with the device set

Branches: mock-camera-input → Mock capture.

Development environment: EB5 Monado Development Setup (Ubuntu 24.04 container on the EB5).

Task guides: SLAM tracer bullet from EuRoC.

Data flow

Kernel: V4L2, IIO (camera, IMU buffers)
   │
   ▼
┌─ Headset driver ─────────────────────────────────────────┐
│  Capture ──sinks──► Trackers ──state──► xrt_device       │
│  (frames, IMU)      (SLAM, hands, eyes)  (HMD, hand, eye)│
│                                                          │
│  Builder: creates and wires all at startup (not runtime) │
└───────────────────────────────┬───────────────┬──────────┘
                     poses, input│        display│
┌─ Monado core ─────────────────▼───────────────▼──────────┐
│  OpenXR state tracker ──layers──► Compositor             │
│  (maps API to xrt calls)          (swapchains, warp,     │
│                                    distortion)           │
└──────────┬──────────────────────────────┬────────────────┘
  calls,   │                       present,│ vblank
  results  ▼                               ▼
OpenXR API (apps, via client library)   Kernel: DRM/KMS (Vulkan display target)

Arrows follow the data, not who initiates. "Display" carries the display description, distortion correction, and view poses for time warp.

Push below the device, pull above it

Trigger Device call
xrLocateViews / xrLocateSpace at predicted display time get_view_poses(time) / get_tracked_pose(time)
xrLocateHandJointsEXT get_hand_tracking(time)
xrSyncActions update_inputs
Compositor, just before display (time warp) get_view_poses

In out-of-process mode, the app's call goes through Monado's client library over IPC to the service, where the device call happens.