diff --git a/examples/companion_radio/ui-new/CompassScreen.h b/examples/companion_radio/ui-new/CompassScreen.h index 5b472dfe..2fdfc225 100644 --- a/examples/companion_radio/ui-new/CompassScreen.h +++ b/examples/companion_radio/ui-new/CompassScreen.h @@ -13,14 +13,7 @@ class CompassScreen : public UIScreen { UITask* _task; - static bool gpsValid() { -#if ENV_INCLUDE_GPS == 1 - LocationProvider* loc = sensors.getLocationProvider(); - return loc && loc->isValid(); -#else - return false; -#endif - } + bool gpsValid() const { int32_t lat, lon; return _task->currentLocation(lat, lon); } // Midpoint circle (DisplayDriver has no circle primitive). static void drawCircle(DisplayDriver& d, int cx, int cy, int r) { diff --git a/examples/companion_radio/ui-new/NearbyScreen.h b/examples/companion_radio/ui-new/NearbyScreen.h index 832ba6f0..3726ee8b 100644 --- a/examples/companion_radio/ui-new/NearbyScreen.h +++ b/examples/companion_radio/ui-new/NearbyScreen.h @@ -111,17 +111,8 @@ class NearbyScreen : public UIScreen { void refresh() { _count = 0; - _own_gps = false; _own_lat = _own_lon = 0; - -#if ENV_INCLUDE_GPS == 1 - LocationProvider* loc = sensors.getLocationProvider(); - if (loc && loc->isValid()) { - _own_lat = loc->getLatitude(); - _own_lon = loc->getLongitude(); - _own_gps = true; - } -#endif + _own_gps = _task->currentLocation(_own_lat, _own_lon); int nc = the_mesh.getNumContacts(); for (int i = 0; i < nc && _count < MAX_NEARBY; i++) { diff --git a/examples/companion_radio/ui-new/TrailScreen.h b/examples/companion_radio/ui-new/TrailScreen.h index c1a5304a..8b84ff4b 100644 --- a/examples/companion_radio/ui-new/TrailScreen.h +++ b/examples/companion_radio/ui-new/TrailScreen.h @@ -357,17 +357,7 @@ private: bool selIsStart() const { return hasStart() && _wp_sel == 0; } int wpIndex() const { return _wp_sel - (hasStart() ? 1 : 0); } // index into WaypointStore - static bool ownPos(int32_t& lat, int32_t& lon) { -#if ENV_INCLUDE_GPS == 1 - LocationProvider* loc = sensors.getLocationProvider(); - if (loc && loc->isValid()) { - lat = (int32_t)loc->getLatitude(); - lon = (int32_t)loc->getLongitude(); - return true; - } -#endif - return false; - } + bool ownPos(int32_t& lat, int32_t& lon) const { return _task->currentLocation(lat, lon); } void handleMarkHere() { int32_t lat, lon; diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index 2db6ce7d..8ed157ea 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -1942,11 +1942,17 @@ void UITask::loop() { // Insert a GPS fix into the course-over-ground ring, rejecting gross outliers // (a jump implying an impossible speed) so one bad fix can't swing the heading. void UITask::pushCogFix(int32_t lat, int32_t lon) { + static const uint32_t COG_MAX_GAP_MS = 15000; // GPS gap longer than this → window is stale uint32_t now = millis(); if (_cog_count > 0) { const CogFix& prev = _cog[(_cog_head + _cog_count - 1) % COG_RING]; uint32_t dt = now - prev.ms; - if (dt > 0) { + if (dt > COG_MAX_GAP_MS) { + // GPS was lost for a while: the old fixes are far in the past, so a + // window spanning them would imply a bogus "teleport" heading. Restart + // the ring from this fix (the last-good _cog_deg is kept for display). + _cog_head = 0; _cog_count = 0; + } else if (dt > 0) { float dist_m = geo::haversineKm(prev.lat, prev.lon, lat, lon) * 1000.0f; float speed = dist_m / (dt / 1000.0f); // m/s if (speed > 50.0f) return; // > 180 km/h between fixes → reject @@ -1978,6 +1984,16 @@ bool UITask::currentCourse(int& deg_out) const { return true; } +bool UITask::currentLocation(int32_t& lat, int32_t& lon) const { + LocationProvider* loc = _sensors ? _sensors->getLocationProvider() : nullptr; + if (loc && loc->isValid()) { + lat = (int32_t)loc->getLatitude(); + lon = (int32_t)loc->getLongitude(); + return true; + } + return false; +} + void UITask::saveWaypoints() { DataStore* ds = the_mesh.getDataStore(); if (!ds) return; diff --git a/examples/companion_radio/ui-new/UITask.h b/examples/companion_radio/ui-new/UITask.h index 108a31da..2323d524 100644 --- a/examples/companion_radio/ui-new/UITask.h +++ b/examples/companion_radio/ui-new/UITask.h @@ -152,6 +152,10 @@ public: // Current course over ground in degrees (0..359), or false if not enough // recent movement to derive a stable heading. Independent of trail logging. bool currentCourse(int& deg_out) const; + // Current GPS position (1e6-scaled degrees), false when there's no usable + // fix. Single source of truth for "where am I", shared by the nav / compass + // / map screens so the LocationProvider lookup isn't duplicated per screen. + bool currentLocation(int32_t& lat, int32_t& lon) const; void playMelody(const char* melody); void stopMelody(); bool isMelodyPlaying();