Joystick: Fix EMA filter sticking and slew buttons not repeating#2440
Open
cfuture81 wants to merge 1 commit into
Open
Joystick: Fix EMA filter sticking and slew buttons not repeating#2440cfuture81 wants to merge 1 commit into
cfuture81 wants to merge 1 commit into
Conversation
cd19709 to
e2bdb78
Compare
Two issues reported after the joystick driver refactor (906f3a0): 1. D-pad (HAT) axes get stuck in non-zero state after release when using 'Two Separate Axes' mode for mount motion. Also affects analog sticks where the EMA delays the return to zero. Root cause: The EMA low-pass filter in axisEvent() doesn't track zero-ward movement quickly enough. For digital HAT axes (which only emit events on press/release), the EMA lingers above the dead zone indefinitely. For analog sticks, the EMA delays the zero-crossing, causing sticky motion. Fix: Apply EMA smoothing only on deflection (magnitude increasing away from center). On release (magnitude decreasing toward center), track the raw value instantly. This preserves jitter smoothing during stick deflection while ensuring both analog sticks and digital D-pads reach zero without delay. 2. Slew Rate Up/Down buttons only register the first press. Root cause: processButton() calls processSlewPresets(1, angle) which has a one-shot gate (m_slewPresetArmed). The gate is re-armed only when mag < 0.5 — a path designed for analog joystick pairs returning to center. Button-driven calls always pass mag=1.0, so the re-arm condition is never reached after the first press fires and disarms. Fix: Set m_slewPresetArmed = true before calling processSlewPresets from the button path. Tested-by: Pti-Jean (AstroArch, Hori Fighting Commander ONE) - Setting EMA alpha=1.0 confirmed as workaround for issue 1 - Issue 2 is a pure logic bug with no user workaround
e2bdb78 to
1ab6cca
Compare
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.
Problem
Two issues reported after the joystick driver refactor (906f3a0):
D-pad axes get stuck after release: When using "Two Separate Axes" mode for mount motion, pressing and releasing the D-pad starts motion but it never stops. The user has to press Stop manually.
Slew Rate Up/Down buttons only work once: First press changes the speed, subsequent presses are ignored.
Root Cause
Issue 1: EMA filter residual on HAT axes
The EMA low-pass filter in
axisEvent()computes:HAT/D-pad axes only emit events on press (value=32767) and release (value=0). After release:
EMA = 0.5 * 0 + 0.5 * 16383 = 8192processAxis()sees perpetual non-zero = perpetual motionIssue 2: One-shot gate never re-arms for button events
processButton()callsprocessSlewPresets(1, angle)which has a one-shot gate (m_slewPresetArmed). The gate re-arms only whenmag < 0.5— designed for analog joystick pairs returning to center. Button-driven calls always passmag=1.0, so after the first press fires and disarms, subsequent presses are blocked.Fix
When the raw axis value is exactly 0, snap EMA to zero immediately. Preserves smoothing for analog sticks while ensuring digital axes return to idle on release.
Set
m_slewPresetArmed = truebefore callingprocessSlewPresetsfrom the button path.Testing