feat(oled): IMU gyro calibration + centred, correct-direction tilt dot

Rework the Gyro Tilt screen (and the tilt->RGB lightbar) using the DS5's
own factory IMU calibration, and fix two long-standing tilt-dot quirks.
All three are display-only — the host input report (every gyro + accel
axis) is still forwarded byte-for-byte, so in-game motion is unaffected.

- Calibration: parse feature report 0x05 (already cached by bt.cpp) into
  per-axis bias + sensitivity and apply (raw-bias)*sens to the accel the
  tilt visuals use, keeping the +-8192 == 1g scale. Re-read per connection
  so it tracks across the 4 pairing slots; sanity-gated with raw fallback.
  New side-effect-free bt_peek_feature() accessor (never issues an L2CAP
  request, safe to poll). Parse/apply mirror SDL's SDL_hidapi_ps5.c (zlib).
- Centred when flat: drive the dot from X (roll) + Z (pitch) instead of
  X + Y. Gravity rests on Y when flat, so the old Y mapping pegged the dot
  to the bottom edge at rest; it now sits centred.
- Direction: negate both axes so the dot follows the tilt (tilt left -> dot
  left, tilt forward -> dot up) instead of mirroring it.

Also fold in this session's charge-ETA robustness fix: cap each timed 10%
step at 30 min and take the median over the last 5 steps, so one slow step
can't balloon the estimate (was reading ~222m at 70% off a single ~47-min
step). Shares src/oled.cpp with the gyro work.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
MarcelineVPQ
2026-05-25 07:16:51 -06:00
co-authored by Claude Opus 4.7
parent 7e21a1fbea
commit c7e6c5b914
4 changed files with 143 additions and 7 deletions
+4
View File
@@ -22,6 +22,10 @@ void bt_send_control(uint8_t *data, uint16_t len);
void bt_write(const uint8_t *data, uint16_t len);
void bt_get_signal_strength(int8_t *rssi);
std::vector<uint8_t> get_feature_data(uint8_t reportId,uint16_t len);
// Side-effect-free read of an already-cached feature report (empty vector if it
// hasn't arrived yet). Unlike get_feature_data(), never issues an L2CAP request,
// so it is safe to poll every frame — used by the OLED IMU-calibration parse.
std::vector<uint8_t> bt_peek_feature(uint8_t reportId);
void init_feature();
void set_feature_data(uint8_t reportId, uint8_t* data,uint16_t len);