Don't calibrate while device is moving
This commit is contained in:
+46
-7
@@ -34,6 +34,17 @@ static volatile bool pendingWakeRecal = false; // set only when recal is also
|
||||
// has been off long enough for thermal drift to matter (~5 minutes).
|
||||
static constexpr unsigned long RECAL_AFTER_LP_MS = 5UL * 60UL * 1000UL;
|
||||
|
||||
// Post-wake stillness gate: don't calibrate while the device is moving.
|
||||
// Each axis of the gyro must stay below RECAL_STILL_DPS for RECAL_STILL_FRAMES
|
||||
// consecutive loop ticks before calibration fires. If the device keeps moving
|
||||
// past RECAL_WAIT_MAX_MS, recal is skipped and the pre-sleep bias is kept.
|
||||
static constexpr float RECAL_STILL_DPS = 10.0f; // deg/s per axis
|
||||
static constexpr uint8_t RECAL_STILL_FRAMES = 10; // ~100 ms at 10 ms/frame
|
||||
static constexpr unsigned long RECAL_WAIT_MAX_MS = 3000; // give up after 3 s
|
||||
|
||||
static uint8_t recalStillFrames = 0;
|
||||
static unsigned long recalLastWarnMs = 0;
|
||||
|
||||
// I2C helpers - Wire1 at 0x6A (SA0 LOW on XIAO nRF52840 Sense)
|
||||
static uint8_t lsmRead(uint8_t reg) {
|
||||
Wire1.beginTransmission(LSM_ADDR);
|
||||
@@ -238,15 +249,43 @@ bool sleepManagerUpdate(unsigned long nowMs, bool idle, bool bleConnected) {
|
||||
}
|
||||
}
|
||||
|
||||
// Gyro settling after wake
|
||||
// Post-wake recalibration — gated on device being still
|
||||
if (pendingWakeRecal) {
|
||||
if (nowMs - wakeSettleMs >= 120) {
|
||||
pendingWakeRecal = false;
|
||||
wakeSettleMs = 0;
|
||||
extern void calibrateGyroBias();
|
||||
calibrateGyroBias();
|
||||
Serial.println("[SLEEP] Post-wake recal done");
|
||||
if (nowMs - wakeSettleMs < 120) return true; // initial hardware settle
|
||||
|
||||
// Sample gyro magnitude; each axis must be below threshold
|
||||
float gx = fabsf(imu.readFloatGyroX());
|
||||
float gy = fabsf(imu.readFloatGyroY());
|
||||
float gz = fabsf(imu.readFloatGyroZ());
|
||||
bool still = (gx < RECAL_STILL_DPS && gy < RECAL_STILL_DPS && gz < RECAL_STILL_DPS);
|
||||
|
||||
if (!still) {
|
||||
recalStillFrames = 0;
|
||||
// Rate-limited log so we don't flood serial while waiting
|
||||
if (nowMs - recalLastWarnMs >= 500) {
|
||||
recalLastWarnMs = nowMs;
|
||||
Serial.print("[SLEEP] Waiting for still: gx="); Serial.print(gx, 1);
|
||||
Serial.print(" gy="); Serial.print(gy, 1);
|
||||
Serial.print(" gz="); Serial.println(gz, 1);
|
||||
}
|
||||
if (nowMs - wakeSettleMs >= RECAL_WAIT_MAX_MS) {
|
||||
// Device never settled — keep pre-sleep bias rather than corrupt it
|
||||
pendingWakeRecal = false;
|
||||
recalStillFrames = 0;
|
||||
recalLastWarnMs = 0;
|
||||
Serial.println("[SLEEP] Recal skipped — device still moving after timeout");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Device is still — accumulate consecutive still frames
|
||||
if (++recalStillFrames < RECAL_STILL_FRAMES) return true;
|
||||
|
||||
pendingWakeRecal = false;
|
||||
recalStillFrames = 0;
|
||||
recalLastWarnMs = 0;
|
||||
calibrateGyroBias();
|
||||
Serial.println("[SLEEP] Post-wake recal done");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user