Clear other axis that is in deadzone threshold
Clear the second axis when an axis event causes a second axis to be within the deadzone threshold.
I'm seeing drift on multiple gamepads due to what I believe is an issue with the deadzone filter, as describe by the below flow, with tiny_*
here meaning drift values).
- You press the gamepad axis - two events are received by gilrs
-
axis_x = large_value_x
- gilrs stores that as state, and sends event through -
axis_y = large_value_y
- gilrs stores that as state, and sends event through
-
- You release the gamepad axis - but it has a slight drift. Now, if the x axis event comes before y (and same thing the other way around), gilrs receives these two events:
-
axis_x = tiny_value_x
- gilrs sees that the new axis value would benew_axis_state = (tiny_value_x, large_value_y)
, and checksmagnitude(new_axis_state) > deadzone_threshold
, so it updates state and sends aaxis_x=tiny_value_x
event through. -
axis_y = tiny_value_y
- gilrs sees that the new axis value would benew_axis_state = (tiny_value_x, tiny_value_y)
, and checksmagnitude(new_axis_state) < deadzone_threshold
- so it setsnew_axis_state = (tiny_value_x, 0.0)
, and sends aaxis_y=0.0
event.
-
Now the gilrs state is incorrectly (axis_x, axis_y) = (tiny_value_x, 0.0)
, and the latest axis_x
event delivered was axis_x = tiny_value_x
, which causes drift.
This change only applies the fix if update_state
is true, as otherwise we risk an infinite loop, since we do not know what state we currently have. A more invasive change could be to add a field like Event::synthetic
, so that the deadzone filter knows not to send the additional event once it encounters a synthetic event. Let me know if you want that approach, or some alternative solution.
Merge request reports
Activity
Thanks! Adding anything to
Event
would be breaking change and I would prefer to fix this keeping current API.One other way to fix this without requiring
update_state == true
would be to keep filter specific state inGamepadData
. If I'm not mistaken, we only require to keep onebool
for each pair of left sticks, right sticks and dpad to determine if we already reset other axis value.@Arvamer Thanks! I have updated the PR to store flags in
GamepadData
if the last sent values were non-zero for each axis, and used that to know if they need to be reset. What do you think?enabled an automatic merge when the pipeline for ed73e630 succeeds