# Coordinates and calibration

The rider frame is right handed: +X forward, +Y left, +Z up. Left lean is a negative X rotation, displayed as a positive lateral angle. Forward lean is positive Y. Axial left turn is positive Z. Vector components retain their right handed signs; display lateral alone reverses sign.

The core requires an active device-to-reference quaternion. Capture stores original quaternions, matrices, gravity, gyro, acceleration and timestamps unchanged. The capture adapter checks a consistent direct or transposed relationship between raw matrix and active quaternion, then checks gravity direction across tilted samples. It records quaternion conversion as `identity` or `quaternion conjugate` in `RotationConvention`, with matrix relationship separately in `capturedAttitude`. The legacy `quaternion conjugate / matrix transpose` value remains readable for existing sessions. Unknown/unverified conventions yield an error, never a guessed angle. Gravity verification establishes rotation direction; it does not prove physical rider signs.

Neutral capture covers 2.5 sensor seconds with strictly increasing timestamps, maximum 0.1-second gaps, maximum 0.15 rad/s gyro magnitude (calibration policy version 2; prior saved policies retain their own thresholds) and 0.08 g user acceleration. Canonical quaternions are normalized and hemisphere aligned before a normalized multi-sample mean. RMS geodesic dispersion must be at most 0.02 radians, and every sample deviation at most 0.05 radians. These experimental defaults, actual duration, dispersion, and every input sample are saved in the calibration. Only the latest full 2.5-second window is selected; early tap/mount movement can age out without restarting. Both rate/acceleration and orientation-dispersion checks run before leaving neutral. Selected samples remain raw: identity/stationary poses may leave the adapter convention unverified until tilted gestures. Fit happens after both gestures and a capture snapshot establishes the convention.

Spoken calibration is enabled by default: mount the phone, set volume, tap Calibrate, listen for a three-second countdown, then follow LEFT, CENTER, FORWARD, CENTER. Sampling for a stage starts after its spoken instruction finishes. A lean of at least 0.12 rad held for 0.6 s within 0.05 rad of its latest orientation advances automatically; the intermediate return before forward requires entering within 0.10 rad of the original neutral and holding for 0.6 s without exceeding 0.12 rad or 0.15 rad/s. This hysteresis prevents small boundary crossings from continually resetting the hold; it never changes the original neutral. Every active spoken-calibration stage repeats a stage-specific waiting instruction after 4 host seconds of silence, without interrupting speech or resetting collection/deadlines. This includes missing sensor data and final validation. Intermediate return steps fail with a specific center message after 15 sensor seconds. The final return after forward is an audible advisory only: once its instruction finishes, the next sample triggers fitting from the original neutral and both saved leans. No third center hold or replacement neutral is required; `guidedFinalReturnAdvisory=1` records this policy. Other movement stages time out after 30 sensor seconds. Missing sensor delivery or stalled speech times out after 15 host seconds. A failed stage explains the issue and permits retry; cancellation/interruption suppresses queued completions. These are experimental thresholds requiring mounted validation. Turn off spoken calibration for manual Continue controls. Optional automatic recording starts only after the success announcement, after the final return instruction and successful sensor/fit checks.

After neutral, deliberately lean LEFT, then FORWARD. Each gesture requires 0.3 sensor seconds with ordered samples and maximum 0.1-second gaps, and a peak rotation of 0.12–1.2 radians. SO(3) rotation vectors within 80% of peak and in the peak hemisphere determine each axis. This avoids cancellation when returning toward center. Negative left identifies X. Forward is orthogonalized against X, and their cross product identifies Z. The sine of the angle between gesture axes must be at least 0.5. Short, moving, weak, or near-collinear setup fails with retry; the prior successful calibration survives until replacement succeeds. Record is unavailable during setup; setup is rejected while recording.

For a standard screen-out portrait mount, device +Y points up, +Z points forward, and +X points left. `CalibrationSolver.fitStandardMount` supplies that fixed basis only after both guided gesture axes pass a 0.15-radian alignment/sign check. It saves all gesture evidence and the tolerance. An oblique mount uses the guided fitted basis instead. A stationary neutral alone never identifies arbitrary mounting yaw.

For canonical current quaternion q and neutral q0, relative device rotation is `inverse(q0) * q`. With fixed device-to-rider basis B, rider rotation is `B * Rrelative * transpose(B)`. The implementation transforms the relative rotation vector by B and exponentiates it, which is the same conjugation. Current device gyro and user acceleration are rotated first by Rrelative into neutral device coordinates, then by B into rider coordinates. Neither captured measurements nor raw streams are rewritten.

Plot/display angles decompose the rider quaternion using intrinsic XYZ (matrix `Rz * Ry * Rx`). Values are radians internally and convert to degrees for display. Decomposition is singular at forward pitch ±90 degrees; roll/yaw can jump near that singularity and wrap at ±180 degrees. Calibration uses shortest SO(3) rotation vectors instead of Euler subtraction; rotations near 180 degrees have inherent axis ambiguity. Refit after any mounting change. Arbitrary-reference yaw may drift: this code does not conceal drift by automatic recalibration.

Synthetic coordinate proofs are not physical evidence. James must verify neutral/left/right/forward/back/axial signs and repeat neutral with the rigidly mounted physical phone.

Guided capture allows up to two automatic retries for step timeouts or usable-gesture evidence failures. Similar axes repeat forward while preserving center/left; ambiguous weak/short gesture evidence repeats both leans with the original neutral. Invalid sensor/transport evidence is not bypassed. Separate shareable attempt logs retain rejection codes and stage snapshots even when no recording is created. See `validation/calibration-retries-and-logs.md`.
