PlayStation BT IMU: guard against accel-as-gyro offset shift (macOS side-to-side) (#83)#84
Draft
petegordon wants to merge 1 commit into
Draft
PlayStation BT IMU: guard against accel-as-gyro offset shift (macOS side-to-side) (#83)#84petegordon wants to merge 1 commit into
petegordon wants to merge 1 commit into
Conversation
…ide-to-side) (#83) First pass at the macOS BT DualSense "side to side" fusion bug. The IMU-offset probe already runs on Bluetooth (the docstring claiming USB-only was stale); the gap was the selection in init(), which trusted the documented offset whenever its at-rest ACCEL looked ~1g — without checking gyro. A byte-shifted offset (e.g. macOS/IOKit including the leading report-ID byte in the BT 0x31 DataView) reads an accel axis AS a gyro axis, so its at-rest "gyro" sits near gravity (~8192). Fusion integrates that as rotation → the model swings side to side, exactly the in-game symptom. - Extract the selection into a testable `_chooseImuOffset(probe)` and add an accel-as-gyro guard: reject the default when its at-rest |gyro| is pinned near gravity, and recover the cleanest candidate (~1g accel AND near-zero gyro). The high-gyro gate means a small real bias / a handled pad never trips it, so the existing off-by-2 still-pad protection is preserved. - Add raw-bytes + length diagnostic logging on the probe so a macOS BT 0x31 capture (the key unknown) is one console line away. - Fix the stale "USB only" probe docstring. - Tests: default-kept, macOS accel-as-gyro recovery, off-by-2 still-pad protection, and motion fallback (89 pass). Hardware-verification pending: needs a real macOS + DualSense BT capture to confirm the exact byte mechanism (length/report-ID-byte) and that the fix lands the correct orientation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017NiS2a4jZ877XgftkH1Dd1
🔎 PR #84 preview — test it in isolation🌐 Web overlay: https://lab.usersfirst.games/pr-preview/pr-84/overlay/ 💻 Desktop installers (prerelease): https://github.com/UsersFirst/tandemonium-controller-lab/releases/tag/pr-84
Updated for 0f37142. Web preview and prerelease are torn down when this PR closes. |
This was referenced Jun 21, 2026
Add committed macOS-BT DualSense 0x31 IMU fixture + golden offset-probe test (#83 acceptance #4)
#85
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First pass at #83 — DualSense over Bluetooth on macOS fusing to a wrong, side-to-side orientation (USB is fine). Draft: needs a real macOS + DualSense BT capture to confirm before merge.
What I found
The IMU-offset probe already runs on Bluetooth (
_probeConfig()handles0x31/0x11) — the docstring claiming "USB only" was stale. The real gap was the selection ininit(): it trusted the documented offset whenever its at-rest accel looked ~1g, without checking gyro.A byte-shifted offset — e.g. macOS/IOKit including the leading report-ID byte in the BT
0x31event.data— reads an accelerometer axis as a gyro axis, so its at-rest "gyro" sits near gravity (~8192 raw). Fusion integrates that as rotation → the model swings hard side to side, exactly the in-game symptom. The old accel-only check let such a shifted default still score "plausible" and win.Change
_chooseImuOffset(probe)with an accel-as-gyro guard: reject the documented default when its at-rest|gyro|is pinned near gravity, and recover the cleanest candidate (≈1g accel and near-zero gyro).0x31capture (length / report-ID-byte presence) is one console line away — that's the key unknown.Tests (89 pass, +4)
chooseImuOffsetkeeps the documented default when it's clean.I can't run macOS + DualSense BT here, so this is a robustness fix targeting the documented accel-as-gyro failure mode, not a confirmed root-cause fix. To close the loop, on a macOS BT session grab the new console lines:
That tells us (a) the real
event.databyteLength vs USB, (b) whether the report-ID byte is present, and (c) which offset is actually clean — which confirms whether this fix lands the right orientation or whether the true offset is outside the current candidate set[16, 15, 17](easy follow-up to widen).Fixes #83 once verified.
🤖 Generated with Claude Code
https://claude.ai/code/session_017NiS2a4jZ877XgftkH1Dd1
Generated by Claude Code