From a55b3786c152c5fd5b868b4add16d36c0425ea7f Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Mon, 16 Mar 2026 12:00:44 -0600 Subject: [PATCH] fix(bridge): reverse SDL axis remapping to recover Nintendo-native IMU axes SDL's hidapi_switch.c SendSensorUpdate() remaps Nintendo's raw sensor axes to match PlayStation convention before emitting SDL sensor events: SDL_X = -Nintendo_Y, SDL_Y = +Nintendo_Z, SDL_Z = -Nintendo_X This commit reverses that transform so the values sent to the Pico are in Nintendo's native coordinate frame: Nintendo_X_raw = -SDL_Z Nintendo_Y_raw = -SDL_X Nintendo_Z_raw = +SDL_Y Same mapping for gyro (bias subtraction happens before axis reversal). Confirmed from SDL3 hidapi_switch.c source (SDL2 uses same SDL3 backend). --- .../controller_uart_bridge.py | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/switch_pico_bridge/controller_uart_bridge.py b/src/switch_pico_bridge/controller_uart_bridge.py index 71550f6..7b280d3 100644 --- a/src/switch_pico_bridge/controller_uart_bridge.py +++ b/src/switch_pico_bridge/controller_uart_bridge.py @@ -1322,13 +1322,22 @@ def handle_sensor_update( uz -= bz ax, ay, az = ctx.last_accel + # SDL (hidapi_switch.c SendSensorUpdate) remaps Nintendo's native axes to match + # PlayStation convention before emitting sensor events: + # SDL_out[0] (X) = -(Nintendo_Y * scale) + # SDL_out[1] (Y) = +(Nintendo_Z * scale) + # SDL_out[2] (Z) = -(Nintendo_X * scale) + # We must reverse that to recover Nintendo-native values: + # Nintendo_X = -SDL_Z + # Nintendo_Y = -SDL_X + # Nintendo_Z = +SDL_Y sample = IMUSample( - accel_x=convert_accel_to_raw(ax), - accel_y=convert_accel_to_raw(ay), - accel_z=convert_accel_to_raw(az), - gyro_x=convert_gyro_to_raw(ux, config.gyro_scale), - gyro_y=convert_gyro_to_raw(uy, config.gyro_scale), - gyro_z=convert_gyro_to_raw(uz, config.gyro_scale), + accel_x=convert_accel_to_raw(-az), + accel_y=convert_accel_to_raw(-ax), + accel_z=convert_accel_to_raw(ay), + gyro_x=convert_gyro_to_raw(-uz, config.gyro_scale), + gyro_y=convert_gyro_to_raw(-ux, config.gyro_scale), + gyro_z=convert_gyro_to_raw(uy, config.gyro_scale), ) ctx.imu_samples.append(sample)