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>
32 lines
895 B
C
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
|