Fix compass heading direction, add magnetic declination and heading offset

- Fix atan2 sign bug: atan2(-yHeading, xHeading) per Freescale AN4248 eq.22.
  The previous atan2(yHeading, xHeading) produced counter-clockwise angles,
  causing East/West to be swapped relative to compass convention.

- Add imuSetMagneticDeclination() (T:146, field "decl") to correct the
  offset between magnetic north and true north (iPhone shows true north).
  Value is persisted in imuConfig.json across reboots.

- Add imuSetHeadingOffset() (T:147, field "off") to compensate for sensor
  mounting orientation on the rover. Also persisted.

- Persist decl and hOff in imuConfig.json (version 2, backwards compatible).

- Fix calibration feedback for web interface: T:126 now includes calDone=1
  (success) or calDone=0 (fail) once after calibration completes, plus
  decl and hOff fields. Calibration start message explains polling procedure.

- Remove duplicate #include <nvs_flash.h> and unused Adafruit ICM20948
  includes that caused build failures when libraries were not installed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Josh
2026-04-23 21:46:00 +02:00
co-authored by Claude Sonnet 4.6
parent 6f1391d1e9
commit 9b0a5a9926
6 changed files with 296 additions and 188 deletions
+25 -20
View File
@@ -20,23 +20,28 @@ typedef struct imu_st_sensor_data_float
float Z;
}IMU_ST_SENSOR_DATA_FLOAT;
void imuInit();
void imuDataGet(EulerAngles *pstAngles,
IMU_ST_SENSOR_DATA_FLOAT *pstGyroRawData,
IMU_ST_SENSOR_DATA_FLOAT *pstAccelRawData,
IMU_ST_SENSOR_DATA *pstMagnRawData);
bool imuRecalibrate();
void imuGetMagnOffsets(IMU_ST_SENSOR_DATA *pstMagnOffset);
void imuSetMagnOffsets(int16_t offsetX, int16_t offsetY, int16_t offsetZ);
bool imuHasHeadingCalibration();
bool imuHasStoredMagnCalibration();
bool imuIsMagnCalibrationRunning();
uint8_t imuGetMagnCalibrationProgress();
bool imuStartMagnCalibration(uint32_t durationMs = 12000);
bool imuLoadMagnCalibration();
bool imuSaveMagnCalibration();
float imuGetTemperature();
void imuAHRSupdate(float gx, float gy, float gz, float ax, float ay, float az, float mx, float my, float mz);
float invSqrt(float x);
#endif
void imuInit();
void imuDataGet(EulerAngles *pstAngles,
IMU_ST_SENSOR_DATA_FLOAT *pstGyroRawData,
IMU_ST_SENSOR_DATA_FLOAT *pstAccelRawData,
IMU_ST_SENSOR_DATA *pstMagnRawData);
bool imuRecalibrate();
void imuGetMagnOffsets(IMU_ST_SENSOR_DATA *pstMagnOffset);
void imuSetMagnOffsets(int16_t offsetX, int16_t offsetY, int16_t offsetZ);
bool imuHasHeadingCalibration();
bool imuHasStoredMagnCalibration();
bool imuIsMagnCalibrationRunning();
uint8_t imuGetMagnCalibrationProgress();
bool imuStartMagnCalibration(uint32_t durationMs = 12000);
bool imuLoadMagnCalibration();
bool imuSaveMagnCalibration();
float imuGetTemperature();
void imuAHRSupdate(float gx, float gy, float gz, float ax, float ay, float az, float mx, float my, float mz);
float invSqrt(float x);
void imuSetMagneticDeclination(float deg);
float imuGetMagneticDeclination();
void imuSetHeadingOffset(float deg);
float imuGetHeadingOffset();
int8_t imuPopLastCalStatus();
#endif