sl-controls f02ed8172a feat: gyro bias calibration on boot — fixes yaw drift (issues #21, #23)
On boot, before the main loop, sample 1000 gyro readings (~1s) while
board is held still. Compute per-axis mean offset (sensor-frame raw LSBs)
and subtract from all subsequent readings in mpu6000_read().

- mpu6000_calibrate(): LED1+LED2 solid ON during 1s sample window,
  resets filter state to zero once bias is known
- mpu6000_is_calibrated(): gate; main loop blocks arming and USB
  streaming until calibration completes
- Bias subtracted in sensor frame before CW270 axis transform + scale,
  so all three axes (pitch/roll/yaw rate) benefit
- config.h: GYRO_CAL_SAMPLES=1000
- No flash storage — recalibrate fresh each boot (bias varies with temp)

Closes #21 (3.5°/s yaw drift), #23 (gyro bias calibration on boot).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 17:42:24 -05:00

32 lines
895 B
C

#ifndef MPU6000_H
#define MPU6000_H
#include <stdint.h>
#include <stdbool.h>
typedef struct {
float pitch; // degrees, filtered (complementary filter)
float pitch_rate; // degrees/sec (raw gyro pitch axis)
float roll; // degrees, filtered (complementary filter)
float yaw; // degrees, gyro-integrated (drifts — no magnetometer)
float accel_x; // g
float accel_z; // g
} IMUData;
bool mpu6000_init(void);
/*
* Sample gyro for ~1s to compute per-axis bias offsets.
* Must be called after mpu6000_init() with the board held still.
* Blocks ~1s. LED1+LED2 solid during calibration.
* IWDG must NOT be running when this is called (call before safety_init()).
*/
void mpu6000_calibrate(void);
/* Returns true once mpu6000_calibrate() has completed. */
bool mpu6000_is_calibrated(void);
void mpu6000_read(IMUData *data);
#endif