mirror of
https://github.com/meshtastic/firmware.git
synced 2026-05-19 14:25:28 -04:00
Enhance GPS search failure handling backoff logic
This commit is contained in:
1
.claude/worktrees/naughty-payne-60fdb7
Submodule
1
.claude/worktrees/naughty-payne-60fdb7
Submodule
Submodule .claude/worktrees/naughty-payne-60fdb7 added at f2923590bc
@@ -15,6 +15,7 @@ void GPSUpdateScheduling::informGotLock()
|
|||||||
searchEndedMs = millis();
|
searchEndedMs = millis();
|
||||||
LOG_DEBUG("Took %us to get lock", (searchEndedMs - searchStartedMs) / 1000);
|
LOG_DEBUG("Took %us to get lock", (searchEndedMs - searchStartedMs) / 1000);
|
||||||
updateLockTimePrediction();
|
updateLockTimePrediction();
|
||||||
|
consecutiveFailures = 0; // Drop back to fast cadence as soon as we acquire any fix
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search finished without obtaining a fix. We still need to mark the end time so
|
// Search finished without obtaining a fix. We still need to mark the end time so
|
||||||
@@ -24,7 +25,9 @@ void GPSUpdateScheduling::informGotLock()
|
|||||||
void GPSUpdateScheduling::informSearchFailed()
|
void GPSUpdateScheduling::informSearchFailed()
|
||||||
{
|
{
|
||||||
searchEndedMs = millis();
|
searchEndedMs = millis();
|
||||||
LOG_DEBUG("GPS search ended without fix after %us", (searchEndedMs - searchStartedMs) / 1000);
|
consecutiveFailures++;
|
||||||
|
LOG_DEBUG("GPS search ended without fix after %us (consecutive failures: %u)", (searchEndedMs - searchStartedMs) / 1000,
|
||||||
|
consecutiveFailures);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear old lock-time prediction data.
|
// Clear old lock-time prediction data.
|
||||||
@@ -35,6 +38,7 @@ void GPSUpdateScheduling::reset()
|
|||||||
searchEndedMs = 0;
|
searchEndedMs = 0;
|
||||||
searchCount = 0;
|
searchCount = 0;
|
||||||
predictedMsToGetLock = 0;
|
predictedMsToGetLock = 0;
|
||||||
|
consecutiveFailures = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// How many milliseconds before we should next search for GPS position
|
// How many milliseconds before we should next search for GPS position
|
||||||
@@ -46,6 +50,21 @@ uint32_t GPSUpdateScheduling::msUntilNextSearch()
|
|||||||
// Target interval (seconds), between GPS updates
|
// Target interval (seconds), between GPS updates
|
||||||
uint32_t updateInterval = Default::getConfiguredOrDefaultMs(config.position.gps_update_interval, default_gps_update_interval);
|
uint32_t updateInterval = Default::getConfiguredOrDefaultMs(config.position.gps_update_interval, default_gps_update_interval);
|
||||||
|
|
||||||
|
// After a failed search, back off: indoors / no-sky environments will keep failing,
|
||||||
|
// so wake at most once per broadcast interval rather than once per gps_update_interval.
|
||||||
|
// Capped at 1 hour so a user-configured very-long broadcast interval still retries
|
||||||
|
// periodically (in case conditions change). Reset on any successful lock.
|
||||||
|
if (consecutiveFailures > 0) {
|
||||||
|
constexpr uint32_t failureRetryCapMs = 60UL * 60UL * 1000UL; // 1 hour cap
|
||||||
|
uint32_t broadcastSecs =
|
||||||
|
Default::getConfiguredOrMinimumValue(config.position.position_broadcast_secs, default_broadcast_interval_secs);
|
||||||
|
uint32_t failureSleepMs = broadcastSecs * 1000UL;
|
||||||
|
if (failureSleepMs > failureRetryCapMs)
|
||||||
|
failureSleepMs = failureRetryCapMs;
|
||||||
|
if (updateInterval < failureSleepMs)
|
||||||
|
updateInterval = failureSleepMs;
|
||||||
|
}
|
||||||
|
|
||||||
// Check how long until we should start searching, to hopefully hit our target interval
|
// Check how long until we should start searching, to hopefully hit our target interval
|
||||||
uint32_t dueAtMs = searchEndedMs + updateInterval;
|
uint32_t dueAtMs = searchEndedMs + updateInterval;
|
||||||
uint32_t compensatedStart = dueAtMs - predictedMsToGetLock;
|
uint32_t compensatedStart = dueAtMs - predictedMsToGetLock;
|
||||||
@@ -81,14 +100,18 @@ bool GPSUpdateScheduling::isUpdateDue()
|
|||||||
bool GPSUpdateScheduling::searchedTooLong()
|
bool GPSUpdateScheduling::searchedTooLong()
|
||||||
{
|
{
|
||||||
constexpr uint32_t oneMinuteMs = 60UL * 1000UL;
|
constexpr uint32_t oneMinuteMs = 60UL * 1000UL;
|
||||||
constexpr uint32_t maxSearchClampMs = 15UL * oneMinuteMs; // Hard cap: 15 minutes is always too long
|
constexpr uint32_t maxSearchClampMs = 15UL * oneMinuteMs; // Hard cap: 15 minutes is always too long
|
||||||
|
constexpr uint32_t postFailureSearchMs = 5UL * oneMinuteMs; // Tighter dwell once we know the environment is hostile
|
||||||
uint32_t elapsed = elapsedSearchMs();
|
uint32_t elapsed = elapsedSearchMs();
|
||||||
|
|
||||||
// Anything over 15 minutes is too long, regardless of the broadcast interval.
|
// Anything over 15 minutes is too long, regardless of the broadcast interval.
|
||||||
// TODO: Make a smarter algorithm that backs off the search dwell time when not getting a lock.
|
|
||||||
if (elapsed > maxSearchClampMs)
|
if (elapsed > maxSearchClampMs)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// After a prior failed search, shorten the dwell
|
||||||
|
if (consecutiveFailures > 0 && elapsed > postFailureSearchMs)
|
||||||
|
return true;
|
||||||
|
|
||||||
uint32_t minimumOrConfiguredSecs =
|
uint32_t minimumOrConfiguredSecs =
|
||||||
Default::getConfiguredOrMinimumValue(config.position.position_broadcast_secs, default_broadcast_interval_secs);
|
Default::getConfiguredOrMinimumValue(config.position.position_broadcast_secs, default_broadcast_interval_secs);
|
||||||
uint32_t maxSearchMs = Default::getConfiguredOrDefaultMs(minimumOrConfiguredSecs, default_broadcast_interval_secs);
|
uint32_t maxSearchMs = Default::getConfiguredOrDefaultMs(minimumOrConfiguredSecs, default_broadcast_interval_secs);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class GPSUpdateScheduling
|
|||||||
uint32_t searchEndedMs = 0;
|
uint32_t searchEndedMs = 0;
|
||||||
uint32_t searchCount = 0;
|
uint32_t searchCount = 0;
|
||||||
uint32_t predictedMsToGetLock = 0;
|
uint32_t predictedMsToGetLock = 0;
|
||||||
|
uint32_t consecutiveFailures = 0; // Count of search cycles that ended without a fix; reset on lock
|
||||||
|
|
||||||
const float weighting = 0.2; // Controls exponential smoothing of lock-times prediction. 20% weighting of "latest lock-time".
|
const float weighting = 0.2; // Controls exponential smoothing of lock-times prediction. 20% weighting of "latest lock-time".
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user