Sunshine
Sunshine copied to clipboard
Gyro on linux host inconsistent and choppy
Is there an existing issue for this?
- [X] I have searched the existing issues
Is your issue described in the documentation?
- [X] I have read the documentation
Is your issue present in the latest beta/pre-release?
This issue is present in the latest pre-release
Describe the Bug
Gyro movement on linux host is choppy to the point of being nearly unplayable. When using "gyro as joystick," the problem is masked and gyro is still mostly usable (the cursor exhibits small choppy jumps of a few mm on screen), but when using "gyro as mouse" it's incredibly pronounced and completely unplayable (cursor flies across the screen several inches at a time).
More context:
Gyro is still when controller is placed on a flat surface and not moved at all. Gyro functions mostly smoothly when moving in large sweeping motions. Gyro does not work when holding the controller "still" in your hand, which means the problem (part of it at least), has to do with very small non-zero rotational movements.
Expected Behavior
Gyro movement is smooth in all circumstances.
Additional Context
Tested on pre-release v2024.718.23456
installed with rpm. Also tested v2024.928.45639
built from source.
Unclear if this behavior originates from Sunshine
, moonlight-android
, or inputtino
, though I think fixing in sunshine may be sufficient. The reason I believe this is, moonlight-android is actually sending proper raw signals as far as I can tell, confirmed by logging sensor values from an unrelated android app which align with sensor values when logging is added to sunshine's source code. When inspecting the final gyro output from evtest
, there are a number of "bad values" present from android's raw sensors, namely -1677721
, which is certainly not coincidental (while not exactly "relevant logs" as it relates to sunshine's logs, I've dropped the output in the "relevant logs" section below)
Believing this were potentially the sole issue, I also connected a dualsense to my android device and tested that over moonlight. These bad values did not appear in the dualsense's evtest
output, however the dualsense controller still exhibited the same choppy behavior when "held still" (but not perfectly still). I believe the reason these bad values did not appear for native dualsense gyro is that dualsense is probably simply not outputting rotational values that are quite as small in magnitude as the android sensors (unfortunately I'm not able to log the dualsense raw values as read by android, only the android device's sensors, but when adding conditional logging in sunshine for values of incredibly small magnitude, nothing logs for dualsense while there are logs present when using the android device's gyro values). I also tested an additional android device which did output these bad values as well, which additionally rules out sensor problems in my android device.
Interestingly these bad values only occur for negative values of incredibly small magnitude, which could implicate this code from inputtino
So it seems there are two issues that are perhaps interrelated here:
- Bad value conversions in inputtino for sufficiently small magnitude negative rotational vectors
- Persistent choppy gyro even when these particular bad values are not present (ie: from a real dualsense)
Ultimately this all leads me to believe a low-pass and high-pass filter applied to the gyro output in Sunshine would fix the issue entirely. It should naturally eliminate those bad values, as well as generally suppress noise from other high and low magnitude outliers (ie: smoothing the curve), without needing to touch inputtino. (Though I also realize it's possible the onus is entirely on inputtino, and I'm happy to open a corresponding issue there if you think that's the case)
Host Operating System
Linux
Operating System Version
OpenSUSE
Architecture
64 bit
Sunshine commit or version
v2024.718.23456
Package
other (self built)
GPU Type
AMD
GPU Model
Radeon 5700XT
GPU Driver/Mesa Version
24.1.7
Capture Method
X11 (Linux)
Config
channels = 2
# min_log_level = debug
Apps
No response
Relevant log output
> evtest /dev/input/event256 | grep -E "ABS_RY"
...
Event: time 1727656236.456571, type 3 (EV_ABS), code 4 (ABS_RY), value -512
Event: time 1727656236.462580, type 3 (EV_ABS), code 4 (ABS_RY), value -409
Event: time 1727656236.472656, type 3 (EV_ABS), code 4 (ABS_RY), value -153
Event: time 1727656236.482424, type 3 (EV_ABS), code 4 (ABS_RY), value -1677721
Event: time 1727656236.493868, type 3 (EV_ABS), code 4 (ABS_RY), value 358
Event: time 1727656236.508897, type 3 (EV_ABS), code 4 (ABS_RY), value 512
Event: time 1727656236.512819, type 3 (EV_ABS), code 4 (ABS_RY), value 665
Event: time 1727656236.526700, type 3 (EV_ABS), code 4 (ABS_RY), value 768
Event: time 1727656236.571569, type 3 (EV_ABS), code 4 (ABS_RY), value 358
Event: time 1727656236.574137, type 3 (EV_ABS), code 4 (ABS_RY), value 256
Event: time 1727656236.594946, type 3 (EV_ABS), code 4 (ABS_RY), value 102
Event: time 1727656236.608172, type 3 (EV_ABS), code 4 (ABS_RY), value 51
Event: time 1727656236.612705, type 3 (EV_ABS), code 4 (ABS_RY), value -1677721
Event: time 1727656236.627431, type 3 (EV_ABS), code 4 (ABS_RY), value 0
Event: time 1727656236.643387, type 3 (EV_ABS), code 4 (ABS_RY), value 102
Event: time 1727656236.660920, type 3 (EV_ABS), code 4 (ABS_RY), value 51
Event: time 1727656236.675677, type 3 (EV_ABS), code 4 (ABS_RY), value 0
Event: time 1727656236.685872, type 3 (EV_ABS), code 4 (ABS_RY), value 153
Event: time 1727656236.695369, type 3 (EV_ABS), code 4 (ABS_RY), value 102
Event: time 1727656236.704169, type 3 (EV_ABS), code 4 (ABS_RY), value 51
Event: time 1727656236.724247, type 3 (EV_ABS), code 4 (ABS_RY), value -1677721
Event: time 1727656236.744910, type 3 (EV_ABS), code 4 (ABS_RY), value -51
Event: time 1727656236.751078, type 3 (EV_ABS), code 4 (ABS_RY), value -153
Event: time 1727656236.763330, type 3 (EV_ABS), code 4 (ABS_RY), value -256
Event: time 1727656236.779288, type 3 (EV_ABS), code 4 (ABS_RY), value -204