Switch 2 magnetometer calibration¶
Status: implemented in the canonical Switch 2 motion runtime and covered by deterministic software tests. Live-controller magnetic-environment validation is still required.
Source basis and fit quality¶
The calibration model is adapted from Switch2Connect commit
61ac6642ce12fe7217e38a860b14863b18ca7e28,
src/controller.py::_fit_full_soft_iron_calibration. An explicit calibration
session retains at most 20,000 finite raw magnetic samples. A full ellipsoid
fit is adopted only when it has at least 500 samples, more than 25 raw units of
range on every axis, full algebraic rank, a positive ellipsoid, correction
condition no greater than 3, at least seven of eight orientation octants, RMS
relative residual no greater than 0.08, and P95 residual no greater than 0.15.
When the full fit fails but a sufficiently covered min/max capture still produces a finite, invertible, well-conditioned matrix, the donor-compatible diagonal min/max correction is adopted. Otherwise the attempt is rejected and the previous calibration remains active.
Runtime ownership¶
Each physical IMU owns its calibration. A Pro Controller has one owner; a
standalone Joy-Con has one side; a joined Joy-Con runtime retains independent
left and right owners and adopts a two-side calibration attempt atomically.
The raw sample is transformed as matrix * (raw - bias) before the existing
quality-gated magnetic yaw assist. Completing or loading a fit clears the
magnetometer cache, increments the magnetic calibration epoch, and resets yaw
learning so raw and calibrated coordinate histories can never mix.
The ordinary report path adds only the finite check, bias subtraction, and fixed 3x3 multiply. It allocates nothing and creates no mapper, scheduler, thread, or queue. Ellipsoid fitting and sample-buffer allocation occur only on the user-invoked calibration control path.
UI and lifecycle¶
The Switch 2 Controls profile section exposes Start, Complete, and Cancel controls for the currently selected physical Switch 2 controller. While a session is collecting, transport input continues to drain normally, but the logical DS4Windows controller publishes neutral input. This prevents the figure-eight motion from driving a game and matches Switch2Connect's output suppression. Cancel and rejected completion immediately restore ordinary publication without replacing the prior fit.
The UI reports sample count, adopted model, octant coverage, RMS residual, and P95 residual. Calibration is physical-controller data rather than profile policy; the adjacent 9-axis assist checkbox remains the per-profile opt-in.
Persistent identity¶
Successful fits use the existing DPAPI-protected install-key boundary to derive an install-local HMAC pseudonym from the stable Bluetooth association identity or USB container identity. Neither the Bluetooth address, Windows DeviceId, USB path, container GUID, serial, bond, nor key material reaches the runtime, UI, logs, filenames, or records.
Records are fixed-size and versioned, repeat the expected 16-byte pseudonym, contain only the validated bias/matrix/reference/model, carry a truncated SHA-256 corruption digest, and are replaced atomically. Loading occurs before runtime activation. Malformed, corrupt, mismatched, or ill-conditioned records are ignored and cannot enter motion projection.
Verification¶
Switch2MagnetometerCalibrationTests covers full off-diagonal ellipsoid
recovery, diagonal fallback, narrow-axis rejection, cancel/non-finite input,
and zero allocations over 20,000 warm transforms.
Switch2RuntimeInputDeviceTests covers calibration-time neutral publication,
completion/cancel recovery, full-fit adoption, persistent write, and reconnect
load. Switch2MagnetometerCalibrationFileStoreTests covers byte-exact record
size, opaque naming, round trip, digest corruption, different-peer rejection,
single-bind ownership, and pre-activation adoption. The broader Switch 2 suite
also covers production Bluetooth and USB composition with the optional
persistence boundary.