forked from unom/punktfunk
G16 leg 2. A DualSense over USB to an Android phone, streaming to a Linux host, flat and face up: |accel| = 0.811 g where 1.000 is owed. Magnitude is frame-invariant, so this is unambiguous regardless of the separate axis question below, and it came from a 27-second static average — no sampling error in it. `DsDevice` said so plainly: "Gyro/accel stay in raw device units". It read the i16s out of the pad's report and forwarded them verbatim. But raw device units are not wire units — the wire is fixed at 10000 LSB/g and the pads' native resolution is the 8192 that hid-playstation calls DS_ACC_RES_PER_G. 8192/10000 = 0.819 predicted against 0.811 measured. Acceleration is now rescaled on both the DualSense and DualShock 4 parse paths, clamped because the multiplier is >1 and a real near-full-scale slam would otherwise wrap the i16 into an impossible acceleration in the opposite direction. Two things deliberately NOT done. Gyro is left alone. It is almost certainly low by the same mechanism, but it cannot be corrected with a nominal constant the way acceleration can: the still average shows this pad's accel calibration is near-identity (~1% off), while the gyro's emphatically is not — a near-identity gyro calibration would imply 1024 LSB per deg/s, i.e. ±32 deg/s full scale, which no controller has. Fixing gyro means reading the pad's calibration feature report and applying its own numbers, which also removes acceleration's residual 1% bias. `HidUsbLink` can SET_REPORT but has no GET_REPORT path yet, so that is a real change rather than a constant, and it is owed. I tried to pin the gyro factor by integrating the on-glass rotations instead: a nominal 90 deg yaw integrated to ~88.5 deg through the Apple client (correct) and ~62.7 deg through Android. Directionally consistent, but the readout samples at 5 Hz and a ~1 s rotation is badly undersampled, so that ratio is not a constant anyone should ship. Recorded, not used. The axis frame is also left alone. This leg puts gravity on Y where the Apple leg put it on Z, so at least one client's frame is wrong — but Android forwards the pad's own axis order un-remapped, which makes its reading evidence about the hardware rather than about us, and resolving it needs the bare-metal reference reading G16 step 1 calls for. Every bare-metal Linux box was unreachable (Deck down, HTPC down, .25 is another KVM guest). Rescaling does not touch axis order, so this fix stands however that resolves. Gate: `:kit:compileDebugKotlin` and `:kit:testDebugUnitTest` green, JNI libs built clean at the API-28 floor across 3 ABIs. On-glass re-verification owed: re-run the at-rest reading and expect 0.99-1.00 g.