Jariullah Safi hace 4 meses
padre
commit
0fe77ff943
Se han modificado 2 ficheros con 42 adiciones y 7 borrados
  1. 15 0
      OpenController/report45.cpp
  2. 27 7
      OpenControllerDeckSide/input_source.py

+ 15 - 0
OpenController/report45.cpp

@@ -1,5 +1,6 @@
 #include "report45.h"
 #include "triton.h"
+#include <Arduino.h>
 #include <string.h>
 
 // Write a signed 16-bit value little-endian at rep[2+off] (the same indexing triton.h's s16off reads).
@@ -14,6 +15,14 @@ static inline void put_u16(uint8_t *rep, int off, uint16_t v)
 	rep[2 + off] = (uint8_t)(v & 0xFF);
 	rep[2 + off + 1] = (uint8_t)((v >> 8) & 0xFF);
 }
+// Write an unsigned 32-bit value little-endian at rep[2+off].
+static inline void put_u32(uint8_t *rep, int off, uint32_t v)
+{
+	rep[2 + off + 0] = (uint8_t)(v & 0xFF);
+	rep[2 + off + 1] = (uint8_t)((v >> 8) & 0xFF);
+	rep[2 + off + 2] = (uint8_t)((v >> 16) & 0xFF);
+	rep[2 + off + 3] = (uint8_t)((v >> 24) & 0xFF);
+}
 
 void buildReport45(uint8_t *out, uint8_t seq)
 {
@@ -46,6 +55,12 @@ void buildReport45(uint8_t *out, uint8_t seq)
 	put_s16(out, 24, g_in.rpy);
 	put_u16(out, 26, g_in.rpp);
 
+	// IMU timestamp: report[30..33] = free-running MICROSECOND counter (u32 LE), per IBEX_REIMPL_SPEC
+	// report-0x45 layout. CRITICAL for gyro: Steam integrates angular velocity as gyro * dt where dt is
+	// the delta of THIS timestamp between reports -- leaving it 0 makes dt=0 so the gyro never moves the
+	// view on the host, no matter how correct the gyro values are. off 28 -> rep[30].
+	put_u32(out, 28, micros());
+
 	// IMU: accel @0x22 (offset 32), gyro @0x28 (offset 38) -- inverse of imuFrom45
 	put_s16(out, 32, g_in.ax);
 	put_s16(out, 34, g_in.ay);

+ 27 - 7
OpenControllerDeckSide/input_source.py

@@ -106,6 +106,28 @@ _OFF_LSTICK_X, _OFF_LSTICK_Y = 48, 50
 _OFF_RSTICK_X, _OFF_RSTICK_Y = 52, 54
 _OFF_LPAD_P, _OFF_RPAD_P = 56, 58   # u16 trackpad pressure
 
+# ── IMU axis remap: Deck IMU -> SC2 report-0x45 IMU ──────────────────────────
+# The Deck and the SC2 mount their IMUs in different orientations, so the raw Deck axes do NOT line up
+# with the gyro/accel convention Steam expects from an SC2. accel and gyro MUST use the SAME remap (shared
+# handedness) or the host's sensor fusion mixes axes intermittently (see memory: switch-imu-fusion).
+# Each entry = (source_axis, sign): source_axis 0=x 1=y 2=z indexes the raw Deck (x,y,z); sign flips it.
+# CALIBRATE empirically: in Steam's gyro test, rotate the Deck about one physical axis, see which on-screen
+# axis moves and which way, then swap the source / flip the sign here. Default = identity pass-through.
+IMU_GYRO_MAP = ((0, +1), (1, +1), (2, +1))    # -> (gx, gy, gz)
+IMU_ACCEL_MAP = ((0, +1), (1, +1), (2, +1))   # -> (ax, ay, az)
+# Deck->SC2 gyro sensitivity ratio. Both are int16 IMUs at similar full-scale, so 1.0 is the start point;
+# bump if the on-screen rotation is too slow, drop it if too fast/jittery.
+IMU_GYRO_SCALE = 1.0
+
+
+def _clamp16(v):
+    return -32768 if v < -32768 else 32767 if v > 32767 else int(v)
+
+
+def _remap3(src, mapping, scale=1.0):
+    """src = (x, y, z) raw; mapping = 3x (source_axis, sign). Returns the remapped, clamped triple."""
+    return tuple(_clamp16(src[ax] * sign * scale) for ax, sign in mapping)
+
 
 def _s16(b, off):
     return struct.unpack_from("<h", b, off)[0]
@@ -140,13 +162,11 @@ def decode_deck(rpt, state):
     state["rpy"] = _s16(rpt, _OFF_RPAD_Y)
     state["lpp"] = _u16(rpt, _OFF_LPAD_P)   # trackpad pressure (u16)
     state["rpp"] = _u16(rpt, _OFF_RPAD_P)
-    # IMU
-    state["ax"] = _s16(rpt, _OFF_ACCEL)
-    state["ay"] = _s16(rpt, _OFF_ACCEL + 2)
-    state["az"] = _s16(rpt, _OFF_ACCEL + 4)
-    state["gx"] = _s16(rpt, _OFF_GYRO)
-    state["gy"] = _s16(rpt, _OFF_GYRO + 2)
-    state["gz"] = _s16(rpt, _OFF_GYRO + 4)
+    # IMU: raw Deck accel/gyro -> SC2 axes via the shared remap (calibrate IMU_*_MAP in Steam's gyro test).
+    araw = (_s16(rpt, _OFF_ACCEL), _s16(rpt, _OFF_ACCEL + 2), _s16(rpt, _OFF_ACCEL + 4))
+    graw = (_s16(rpt, _OFF_GYRO), _s16(rpt, _OFF_GYRO + 2), _s16(rpt, _OFF_GYRO + 4))
+    state["ax"], state["ay"], state["az"] = _remap3(araw, IMU_ACCEL_MAP)
+    state["gx"], state["gy"], state["gz"] = _remap3(graw, IMU_GYRO_MAP, IMU_GYRO_SCALE)
     return True