From ad529924f1a8ce35a18eeae1752ec3c972493903 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 27 Sep 2023 10:32:35 -0500 Subject: [PATCH] Code duplication cleanup for smart position logic (#2840) --- src/mesh/NodeDB.h | 8 +++++++ src/modules/PositionModule.cpp | 40 +++++++++++++++++----------------- src/modules/PositionModule.h | 9 ++++++++ 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index 0f43376ba..51c1b3043 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -212,6 +212,14 @@ inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t d return defaultInterval * 1000; } +inline uint32_t getConfiguredOrDefault(uint32_t configured, uint32_t defaultValue) +{ + if (configured > 0) + return configured; + + return defaultValue; +} + /// Sometimes we will have Position objects that only have a time, so check for /// valid lat/lon static inline bool hasValidPosition(const meshtastic_NodeInfoLite *n) diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index 937625cec..5292ba209 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -193,26 +193,19 @@ int32_t PositionModule::runOnce() const meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // should guarantee there is now a position if (hasValidPosition(node2)) { - // The minimum distance to travel before we are able to send a new position packet. - const uint32_t distanceTravelThreshold = - config.position.broadcast_smart_minimum_distance > 0 ? config.position.broadcast_smart_minimum_distance : 100; - // The minimum time (in seconds) that would pass before we are able to send a new position packet. const uint32_t minimumTimeThreshold = getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30); - // Determine the distance in meters between two points on the globe - float distanceTraveledSinceLastSend = - GeoCoord::latLongToMeter(lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, node->position.latitude_i * 1e-7, - node->position.longitude_i * 1e-7); + auto smartPosition = getDistanceTraveledSinceLastSend(node->position); - if ((abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold) && msSinceLastSend >= minimumTimeThreshold) { + if (smartPosition.hasTraveledOverThreshold && msSinceLastSend >= minimumTimeThreshold) { bool requestReplies = currentGeneration != radioGeneration; currentGeneration = radioGeneration; LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, " "minTimeInterval=%ims)\n", - localPosition.timestamp, abs(distanceTraveledSinceLastSend), distanceTravelThreshold, + localPosition.timestamp, smartPosition.distanceTraveled, smartPosition.distanceThreshold, msSinceLastSend, minimumTimeThreshold); sendOurPosition(NODENUM_BROADCAST, requestReplies); @@ -232,6 +225,20 @@ int32_t PositionModule::runOnce() return 5000; // to save power only wake for our callback occasionally } +struct SmartPosition PositionModule::getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition) +{ + // The minimum distance to travel before we are able to send a new position packet. + const uint32_t distanceTravelThreshold = getConfiguredOrDefault(config.position.broadcast_smart_minimum_distance, 100); + + // Determine the distance in meters between two points on the globe + float distanceTraveledSinceLastSend = GeoCoord::latLongToMeter( + lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, currentPosition.latitude_i * 1e-7, currentPosition.longitude_i * 1e-7); + + return SmartPosition{.distanceTraveled = abs(distanceTraveledSinceLastSend), + .distanceThreshold = distanceTravelThreshold, + .hasTraveledOverThreshold = abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold}; +} + void PositionModule::handleNewPosition() { meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum()); @@ -241,20 +248,13 @@ void PositionModule::handleNewPosition() uint32_t msSinceLastSend = now - lastGpsSend; if (hasValidPosition(node2)) { - // The minimum distance to travel before we are able to send a new position packet. - const uint32_t distanceTravelThreshold = - config.position.broadcast_smart_minimum_distance > 0 ? config.position.broadcast_smart_minimum_distance : 100; - - // Determine the distance in meters between two points on the globe - float distanceTraveledSinceLastSend = GeoCoord::latLongToMeter( - lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, node->position.latitude_i * 1e-7, node->position.longitude_i * 1e-7); - - if ((abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold)) { + auto smartPosition = getDistanceTraveledSinceLastSend(node->position); + if (smartPosition.hasTraveledOverThreshold) { bool requestReplies = currentGeneration != radioGeneration; currentGeneration = radioGeneration; LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims)\n", - localPosition.timestamp, abs(distanceTraveledSinceLastSend), distanceTravelThreshold, msSinceLastSend); + localPosition.timestamp, smartPosition.distanceTraveled, smartPosition.distanceThreshold, msSinceLastSend); sendOurPosition(NODENUM_BROADCAST, requestReplies); // Set the current coords as our last ones, after we've compared distance with current and decided to send diff --git a/src/modules/PositionModule.h b/src/modules/PositionModule.h index 8f7047432..3114f31e1 100644 --- a/src/modules/PositionModule.h +++ b/src/modules/PositionModule.h @@ -46,6 +46,15 @@ class PositionModule : public ProtobufModule, private concu /** Does our periodic broadcast */ virtual int32_t runOnce() override; + + private: + struct SmartPosition getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition); +}; + +struct SmartPosition { + float distanceTraveled; + uint32_t distanceThreshold; + bool hasTraveledOverThreshold; }; extern PositionModule *positionModule;