Skip to content

Conversation

@Nintorch
Copy link
Contributor

@Nintorch Nintorch commented Oct 15, 2025

Closes godotengine/godot-proposals#2829
Partially supersedes #88590
Requires #111707 to be merged first

I decided to split my big SDL3 joypad features PR ( #107967 ) into several smaller PRs, starting with joypad motion sensors.

This PR adds the ability to get a joypad's motion sensors (accelerometer, gyroscope) data readings (and also a simulated gravity sensor from the accelerometer data). The reason the gravity sensor had to be simulated: libsdl-org/SDL#6555 (comment)
This PR also includes the methods to calibrate the motion sensors output. I'm not an expert in sensor calibration, so please let me know if this approach looks good enough :D
EDIT: If the gravity calculation proves to not be good enough, we can probably use https://github.com/JibbSmart/GamepadMotionHelpers (if it's better) instead in this PR or in a separate PR to not block this one

Gravity sensor calculation code was borrowed from here: https://developer.android.com/reference/android/hardware/SensorEvent#values

This PR was tested on Windows, but it should also work on Linux and macOS.

TODO:

  • Mention that it's recommended to disable the motion sensors if they're no longer needed because it can theoretically drain the controller's battery more quickly
  • InputEventJoypadGyroscope and InputEventJoypadAccelerometer (for a separate PR)
  • Input.get_joy_sensor_rate()?
  • Use GamepadMotionHelpers library for calibration (for a separate PR too?)
  • Include the accelerometer gravity part in both calibrated and non-calibrated modes (sorry for being indecisive 😅)
  • Invert the sensors axes (see also Document mobile motion sensors axes #113635 )
  • Mark the has_joy_*, set_joy_*_enabled and is_joy_*_enabled as experimental (we may or may not need to only enable/disable the motion sensors together in the future, I think)

Test project (doesn't include the calibration yet):
joypad-motion-sensors.zip

@Meorge
Copy link
Contributor

Meorge commented Oct 15, 2025

I'll try to test and review this on macOS soon!

I'm not a maintainer of course, but IMO it'd make sense to include the calibration methods as well. That way, this PR can function as a sort of all-encompassing "motion control API pack", if that makes sense. (Additionally/alternatively, it could be looked at from the perspective of, without being able to calibrate the sensors, how can we be confident the functions are working correctly?)

@Nintorch Nintorch force-pushed the joypad-motion-sensors branch from 891671d to fe9c73a Compare October 16, 2025 07:02
@Nintorch Nintorch changed the title Add motion sensors feature to joypads Add support for joypads motion sensors Oct 16, 2025
@AThousandShips AThousandShips changed the title Add support for joypads motion sensors Add support for joypad motion sensors Oct 19, 2025
@Nintorch Nintorch force-pushed the joypad-motion-sensors branch from fe9c73a to bcac074 Compare October 19, 2025 13:08
@Nintorch Nintorch force-pushed the joypad-motion-sensors branch 2 times, most recently from 68d3714 to f26b181 Compare November 12, 2025 11:28
@Nintorch
Copy link
Contributor Author

Nintorch commented Nov 14, 2025

Should I try combining the calibration process methods into one Input.calibrate_joy_motion_sensors() by using a separate thread and a completion signal? I tried once, but failed. I can try again though if that means the calibration becomes more convenient :D

if (!joy_motion.has(p_device)) {
return;
}
joy_motion[p_device].accelerometer = p_value;
Copy link
Contributor Author

@Nintorch Nintorch Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An event probably needs to be added for this.

(Should these events exist? Should they be made in this PR?)

if (!joy_motion.has(p_device)) {
return;
}
joy_motion[p_device].gyroscope = p_value;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

@Nintorch Nintorch force-pushed the joypad-motion-sensors branch from bd46062 to b84588a Compare December 4, 2025 06:58
@Nintorch
Copy link
Contributor Author

Nintorch commented Dec 4, 2025

Should this PR convert the values to degrees per second for gyroscope and g-force for accelerometer? See https://github.com/JibbSmart/GamepadMotionHelpers?tab=readme-ov-file#units , which was mentioned in the proposal: godotengine/godot-proposals#2829

EDIT: I found out that Input.get_accelerometer and Input.get_gyroscope use the same units as SDL, so no need to change the units in this PR

@akien-mga akien-mga requested a review from bruvzg December 4, 2025 09:48
@geowarin
Copy link
Contributor

geowarin commented Dec 4, 2025

I think Steam uses SDL under the hood for Steam Input, so basically issues that are reproducible in Steam can be reported to the SDL repository, AFAIK.

Hello and thanks for your awesome work @Nintorch! As a user of a dual sense edge on linux (I'm assuming that we are rare specimens), I just wanted to chime in and say that gyros work perfectly with steam input.

I don't want to block this PR or anything, as I alluded this is a pretty niche problem, but I don't want you to jump to the wrong conclusions just in case.

I can offer my help testing the PR if you want, just tell me what you need.

@Nintorch
Copy link
Contributor Author

Nintorch commented Dec 4, 2025

I think Steam uses SDL under the hood for Steam Input, so basically issues that are reproducible in Steam can be reported to the SDL repository, AFAIK.

Hello and thanks for your awesome work @Nintorch! As a user of a dual sense edge on linux (I'm assuming that we are rare specimens), I just wanted to chime in and say that gyros work perfectly with steam input.

I don't want to block this PR or anything, as I alluded this is a pretty niche problem, but I don't want you to jump to the wrong conclusions just in case.

I can offer my help testing the PR if you want, just tell me what you need.

Hello, thank you for letting me know!
May I ask if you can test the DualSense Edge gyro with this PR and the testing project Calinou provided, please? :D

@geowarin
Copy link
Contributor

geowarin commented Dec 4, 2025

I'm so sorry, I might be doing something stupid but I get gdscript errors when using the test project:

Error at (60, 5): Static function "enable_joy_gyroscope()" not found in base "GDScriptNativeClass".
image

@Nintorch
Copy link
Contributor Author

Nintorch commented Dec 4, 2025

Oh yeah, I've renamed these enable_joy_* functions back to set_joy_*_enabled, so now the test project will need to be modified 😅

@geowarin
Copy link
Contributor

geowarin commented Dec 4, 2025

Ok good news! It works perfectly for me.

Using Arch linux + KDE.
Dualsense edge controller wired and bluetooth both work with gyro.
The led color changes as expected.

@Nintorch
Copy link
Contributor Author

Nintorch commented Dec 4, 2025

That's good to hear! :)

@Nintorch Nintorch force-pushed the joypad-motion-sensors branch from b84588a to 9422c91 Compare December 4, 2025 12:49
@geowarin
Copy link
Contributor

geowarin commented Dec 4, 2025

EDIT: I just noticed that there's vector negation happening for the gyro_look variable, I think that's the reason the values are inverted:

I noticed this as well, the movement looked inverted for me until I removed the negation from line 157. I wonder why it was added? User preference or buggy controller mapping?

@Nintorch
Copy link
Contributor Author

Nintorch commented Dec 4, 2025

I removed the step_joy_motion_calibration method to make the process even easier and possibly more accurate, and I modified the way get_joy_accelerometer works, now it only returns the controller movement without the gravity value.

@Nintorch Nintorch force-pushed the joypad-motion-sensors branch 2 times, most recently from 033b32b to 9b12057 Compare December 4, 2025 14:47
@Nintorch

This comment was marked as resolved.

@Nintorch Nintorch force-pushed the joypad-motion-sensors branch from 9b12057 to f368d61 Compare December 4, 2025 15:21
@Nintorch
Copy link
Contributor Author

Nintorch commented Dec 5, 2025

I should probably state in the documentation that motion sensors is an experimental feature and its usage may change in the future based on the feedback.

@Nintorch Nintorch force-pushed the joypad-motion-sensors branch from f368d61 to 7276d80 Compare December 5, 2025 12:28
@Nintorch Nintorch force-pushed the joypad-motion-sensors branch from 7276d80 to ea31a07 Compare December 5, 2025 12:48
@Calinou
Copy link
Member

Calinou commented Dec 5, 2025

I noticed this as well, the movement looked inverted for me until I removed the negation from line 157. I wonder why it was added? User preference or buggy controller mapping?

I needed it to be inverted in earlier PRs that added gyro support, but you can safely remove the negation now.

@Nintorch
Copy link
Contributor Author

Nintorch commented Dec 5, 2025

Although, if Input.get_joy_gyroscope is inverted compared to Input.get_gyroscope (and the accelerometer and gravity ones for that matter, but I haven't tested any of them), I should be able to revert it back.

EDIT: they really are inverted compared to mobile device's orientation methods, I will need to fix that
EDIT 2: Fixed!

@Nintorch Nintorch force-pushed the joypad-motion-sensors branch from ea31a07 to b1db95b Compare December 6, 2025 17:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for controller-based motion controls (gyroscope, accelerometer, …)

6 participants