Two-phase project around the VITURE Luma Ultra XR glasses on Linux:
- Phase 1 (this repo, working):
sensor-viz/— a web dashboard that visualizes every sensor the glasses expose: orientation (3DoF euler / quaternion), full 6DoF pose (position + rotation from the on-host VIO), raw IMU (gyro / accel / magnetometer), temperature, VSync, and device state (brightness, volume, display mode, electrochromic film). - Phase 2 (planned): a standalone native program that places virtual
screens in 3D space using the 6DoF tracking, with presets (ultrawide,
curved, multi-panel). Full roadmap:
docs/plan/phase2-spatial-screens.md.
┌─────────────────────┐ WebHID (3DoF euler + MCU events) ┌──────────────┐
│ Luma Ultra glasses │ ────────────────────────────────────▶│ │
│ VID 35ca │ │ sensor-viz │
│ PID 1104 (glasses) │ USB (SDK v2.0: 6DoF VIO, raw IMU) │ web app │
│ PID 1102 (HID hub) │ ──▶ bridge/viture-bridge ──WebSocket─▶│ (Vite+Three)│
└─────────────────────┘ ws://localhost:8765 └──────────────┘
Two independent data paths:
| Path | Needs | Delivers |
|---|---|---|
| WebHID (Chrome/Edge) | udev rule only | 3DoF orientation + MCU events — older models only. Not functional on Luma Ultra: its HID endpoints don't speak the classic protocol (hardware-verified; the Carina SDK uses USB control transfers instead). Use the bridge. |
| Native bridge | udev rule + make |
6DoF pose, raw accel/gyro, VSync, device state, firmware info (mag/temp: not exposed by the Luma Ultra's Carina IMU callback; older models get them via raw mode) |
The proprietary VITURE SDK binaries are not included in this repo. Fetch them (each verified by sha256) with:
./sdk/fetch-sdk.shSee sdk/README.md for exactly what this downloads and its
provenance. The WebHID-only path (below) doesn't need the SDK.
The glasses' USB/hidraw nodes are root-only by default. Install the udev rule and replug the glasses:
cd bridge && make install-udev # sudo cp 70-viture-xr.rules /etc/udev/rules.d/ + reload
# then unplug/replug the glassescd sensor-viz
npm install
npm run dev # → http://localhost:5173 (Chrome for WebHID)- Connect WebHID — pick "VITURE Luma Ultra" in the device chooser (the HID
interfaces live on the
35ca:1102companion device). - Connect Bridge — for the full 6DoF + raw IMU set, first start the bridge:
cd bridge
make # builds against sdk/ (vendored VITURE SDK v2.0)
./run.sh # ws://127.0.0.1:8765 ; --port N, --imu-freq 0..4, --verboseControls: Recenter zeroes heading + position (yaw-twist only — never tilts the reference), Level calibrates out the constant pitch offset of the sensor rig (~35° on Luma Ultra: the VIO reports the downward-angled tracking cameras' orientation, not the wearer's gaze — look straight ahead and click; persisted in localStorage), Pause freezes charts, the event log shows MCU/state events as they arrive.
spatial-screens/— phase 2 (in progress): world-anchored virtual screen renderer — 6DoF pose → fullscreen GL on the glasses, live X11 monitor capture, recenter/distance/size hotkeys (see its README; stop the bridge before running it)sensor-viz/— web app (Vite + Three.js, no other runtime deps)bridge/— native daemon: official SDK → WebSocket JSON (see header ofbridge/main.cppfor the message protocol)sdk/— official VITURE XR Glasses SDK v2.0.0 (Luma-series capable), fetched bysdk/fetch-sdk.sh; the binaries are © VITURE and not committed here (seesdk/README.mdfor provenance — not the legacy 3DoF One SDK)docs/plan/—roadmap.md(both phases),phase2-spatial-screens.md(researched feature plan for the spatial-screens program)docs/specs/— phase-1 design docreference/— cloned prior art (git-ignored): XRLinuxDriver, viture-webxr-extension (WebHID protocol), viture_virtual_display
- Luma Ultra enumerates as
35ca:1104(“VITURE Luma Ultra XR GLASSES”) plus a companion35ca:1102(“VITURE Microphone”) that carries the two 64-byte vendor HID interfaces (MCU commands/events + IMU stream) on USB interfaces 1.3/1.4. - The SDK identifies the device as type 2 (Carina) and runs its
visual-inertial odometry on the host (
libcarina_vio.so+ OpenCV), fed by the glasses' stereo tracking cameras. - Without the udev rule,
xr_device_provider_start()segfaults inside the closed SDK (USB open fails ungracefully) — install the rule before running.
This project's own source (the bridge/, sensor-viz/, and spatial-screens/
code) is released under the GNU General Public License v3.0 — see
LICENSE.
© 2026 Salvatore Mastrangelo.
The VITURE SDK under sdk/ is not covered by this license: those binaries
are © VITURE Inc. (all rights reserved) and are fetched, not redistributed —
see sdk/README.md.