107 lines
5.1 KiB
Markdown
107 lines
5.1 KiB
Markdown
# Move Calibration Protocol
|
|
|
|
Mimir owns Move calibration and sensor fusion. Muninn owns source-local facts:
|
|
camera marker candidates, USB controller IMU/button state, and local Move light
|
|
commands. Odin discovers and projects the surfaces. Fensalir consumes Mimir's
|
|
resolved poses after Mimir has earned them.
|
|
|
|
## Current Stream Shape
|
|
|
|
- Starfire should run Muninn as a local capture/control daemon. Its Move stream
|
|
address is `muninn:starfire:move-evidence`.
|
|
- Nightwing runs Muninn for its USB Move and local camera witnesses. Its Move
|
|
stream address is `muninn:nightwing:move-evidence`.
|
|
- Mimir on Starfire publishes resolved pose frames at
|
|
`mimir:starfire:move-controller-poses`.
|
|
- Quest can participate as an external tracked VR reference over USB:
|
|
`quest:usb:headset-pose`, `quest:usb:left-controller-pose`, and
|
|
`quest:usb:right-controller-pose`.
|
|
- Starfire ASIO/Scarlett loopback can provide cue timing, but it is not a Move
|
|
pose authority.
|
|
|
|
The Move hot path is CultMesh stream frames. On the same host, those frames use
|
|
shared-memory bytes rings. Across hosts, the remote peer still crosses the
|
|
Verse/network boundary. The current Raven program media bridge is not same-host
|
|
zero-copy into Mimir/Fensalir; it sends CultNet/CultMesh media documents and
|
|
lowers to local UDP for OBS compatibility.
|
|
|
|
## Required Capture Phases
|
|
|
|
1. `preflight-streams`: hold both Moves still and visible; prove stream freshness,
|
|
clock skew, and controller ids.
|
|
2. `dark-stillness`: lights off, both Moves still; estimate gyro bias, gravity,
|
|
and magnetometer baseline.
|
|
3. `lit-stillness`: light one Move at a time, then both; map light commands to
|
|
controllers and measure centroid stability.
|
|
4. `axis-sweeps`: slow pitch/yaw/roll sweeps; fit gyro scale, accelerometer
|
|
frame, and optical angular consistency.
|
|
5. `figure-eight`: broad figure-eight motion; fit magnetometer hard/soft iron
|
|
and cross-axis coupling.
|
|
6. `quest-reference`: optional Quest headset/controller reference with the Move
|
|
between the two Quest controllers in front of the headset.
|
|
7. `validation-pass`: held-out free motion; promote only if triangulated optical
|
|
residuals and IMU prediction residuals pass.
|
|
|
|
## Quest Access Preflight
|
|
|
|
The Quest must be authorized for USB debugging before Starfire Muninn can query
|
|
it. Muninn owns the access surface:
|
|
|
|
```powershell
|
|
muninn serve --store C:\Meta\Odin\state\muninn.telemetry.cc --host starfire --quest-adb --quest-serial 1WMHHB68PG1515
|
|
```
|
|
|
|
When the Quest is authorized, Muninn publishes `muninn.quest_access.v1` and
|
|
advertises `muninn:<host>:quest-input`, `muninn:<host>:quest-poses`, and
|
|
`muninn:<host>:quest-warped-video-input`. Mimir consumes the access/pose
|
|
surfaces as calibration evidence; it does not own Quest USB access.
|
|
|
|
```powershell
|
|
muninn quest-access-status --store C:\Meta\Odin\state\muninn.telemetry.cc
|
|
```
|
|
|
|
ADB authorization proves USB access, device identity, and basic headset state
|
|
only. It does not expose Quest headset or controller poses; those still require
|
|
a Quest/OpenXR witness bridge that publishes pose samples through Muninn. The
|
|
current calibration protocol can still run without Quest, but Quest poses are
|
|
the preferred external reference when the headset and both controllers are
|
|
sitting around the Move.
|
|
|
|
## Data Products
|
|
|
|
- `mimir.move_fusion_rig_calibration.v1`: camera intrinsics/extrinsics, clock
|
|
association policy, and gyro unit scale.
|
|
- `mimir.move_imu_calibration.v1`: per-controller gyro bias/scale,
|
|
accelerometer gravity frame, magnetometer correction, and noise estimates.
|
|
- `mimir.move_controller_identity_map.v1`: stable association between Muninn
|
|
USB ids, light receipts, and optical orb identities.
|
|
- `mimir.move_calibration_receipt.v1`: sample counts, residuals, rejected
|
|
phases, and promotion decision.
|
|
|
|
## Optical Sphere Fit Authority
|
|
|
|
`MimirMoveSphereCalibrationFitter` owns the bounded two-Eye optical fit after a
|
|
collection session reaches `Fitting`. Eye 0 defines the tracking-space gauge.
|
|
The fitter jointly estimates both focal lengths and Eye 1's rigid pose from
|
|
same-frame, same-Move correspondences, using a deterministic 80/20 training and
|
|
held-out partition. A robust training consensus may reject contaminated marker
|
|
pairs, but promotion also requires at least 65 percent of the untouched
|
|
held-out pairs to agree and must pass the session's median and P95 reprojection
|
|
limits.
|
|
|
|
The physical orb radius is an explicit input; it is never guessed by the
|
|
solver. PSMoveAPI's reported blob radius is a color-segmentation result, not a
|
|
calibrated sphere silhouette. It may seed or weight depth only after the
|
|
per-camera radius response has been validated. A fresh PSMoveAPI position age
|
|
is also not optical confidence and must not be interpreted as one.
|
|
|
|
## Preflight Command
|
|
|
|
```powershell
|
|
dotnet run --project .\src\Mimir.BufferSmoke\Mimir.BufferSmoke.csproj -- --move-calibration-protocol-smoke --output artifacts\move-calibration\protocol.cc
|
|
```
|
|
|
|
That writes the typed protocol as `mimir.move_calibration_protocol.v1` into a
|
|
CultCache receipt. The real hardware runner should consume this document plus
|
|
Muninn's `muninn.quest_access.v1` when Quest is available, then append capture
|
|
receipts instead of inventing a parallel checklist.
|