From e4aeaa2bb1510219e2e0fc341dbb0e2617018189 Mon Sep 17 00:00:00 2001 From: HarukiToreda <116696711+HarukiToreda@users.noreply.github.com> Date: Tue, 14 Apr 2026 23:01:20 -0400 Subject: [PATCH] Stale heading logic --- src/graphics/Screen.cpp | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 5840d5db6..0df1ac9d6 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -60,6 +60,7 @@ along with this program. If not, see . #include "main.h" #include "mesh-pb-constants.h" #include "mesh/Channels.h" +#include "mesh/Default.h" #include "mesh/generated/meshtastic/deviceonly.pb.h" #include "modules/ExternalNotificationModule.h" #include "modules/TextMessageModule.h" @@ -328,10 +329,27 @@ static void drawModuleFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int float Screen::estimatedHeading(double lat, double lon) { static double oldLat, oldLon; - static float b; + static float b = -1.0f; + static uint32_t lastHeadingAtMs = 0; + const uint32_t now = millis(); + const uint32_t gpsUpdateIntervalSecs = + Default::getConfiguredOrDefault(config.position.gps_update_interval, default_gps_update_interval); + uint32_t effectiveUpdateIntervalSecs = gpsUpdateIntervalSecs; + if (config.position.position_broadcast_smart_enabled) { + const uint32_t smartMinIntervalSecs = Default::getConfiguredOrDefault(config.position.broadcast_smart_minimum_interval_secs, + default_broadcast_smart_minimum_interval_secs); + if (smartMinIntervalSecs > effectiveUpdateIntervalSecs) { + effectiveUpdateIntervalSecs = smartMinIntervalSecs; + } + } + uint64_t headingStaleMs64 = static_cast(effectiveUpdateIntervalSecs) * 2000ULL; // two expected update windows + if (headingStaleMs64 > UINT32_MAX) { + headingStaleMs64 = UINT32_MAX; + } + const uint32_t headingStaleMs = static_cast(headingStaleMs64); if (oldLat == 0) { - // just prepare for next time + // Need at least two position points before we can infer heading. oldLat = lat; oldLon = lon; @@ -339,12 +357,20 @@ float Screen::estimatedHeading(double lat, double lon) } float d = GeoCoord::latLongToMeter(oldLat, oldLon, lat, lon); - if (d < 10) // haven't moved enough, just keep current bearing + if (d < 10) { // haven't moved enough, keep previous heading (invalid until first real movement) + if (lastHeadingAtMs != 0 && (now - lastHeadingAtMs) >= headingStaleMs) { + // Heading is stale after prolonged no-movement; force reacquire. + b = -1.0f; + oldLat = lat; + oldLon = lon; + } return b; + } b = GeoCoord::bearing(oldLat, oldLon, lat, lon) * RAD_TO_DEG; oldLat = lat; oldLon = lon; + lastHeadingAtMs = now; return b; }