From eb0ab06d26465632bb3ffa6211c2a6a9595aab8a Mon Sep 17 00:00:00 2001 From: medentem Date: Thu, 9 Jan 2025 08:44:15 -0600 Subject: [PATCH] decay coverage knowledge which allows us to keep coverage data around longer --- src/mesh/FloodingRouter.cpp | 41 +++++++++++++++++++++++++++---------- src/mesh/FloodingRouter.h | 2 ++ src/mesh/MeshTypes.h | 2 +- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/mesh/FloodingRouter.cpp b/src/mesh/FloodingRouter.cpp index 38ec151bf..c2a001994 100644 --- a/src/mesh/FloodingRouter.cpp +++ b/src/mesh/FloodingRouter.cpp @@ -2,6 +2,7 @@ #include "configuration.h" #include "mesh-pb-constants.h" +#include FloodingRouter::FloodingRouter() {} @@ -184,30 +185,39 @@ float FloodingRouter::calculateForwardProbability(const CoverageFilter &incoming return UNKNOWN_COVERAGE_FORWARD_PROB; } + uint32_t now = getTime(); // Count how many neighbors are NOT yet in the coverage - int uncovered = 0; - int neighbors = 0; + float totalWeight = 0.0f; + float uncoveredWeight = 0.0f; + uint8_t neighbors = 0; + uint8_t uncovered = 0; + for (auto nodeId : recentNeighbors) { - // Don't count the person we got this packet from if (nodeId == from) continue; - neighbors++; + auto nodeInfo = nodeDB->getMeshNode(nodeId); + if (!nodeInfo) + continue; + uint32_t age = now - nodeInfo->last_heard; + float recency = computeRecencyWeight(age, RECENCY_THRESHOLD_MINUTES * 60); + + totalWeight += recency; + neighbors += 1; if (!incoming.check(nodeId)) { - uncovered++; + uncoveredWeight += recency; + uncovered += 1; } } - // Calculate coverage ratio - float coverageRatio = 0.0; + float coverageRatio = 0.0f; + // coverage only exists if neighbors are more than 0 - if (neighbors > 0) { - coverageRatio = static_cast(uncovered) / static_cast(neighbors); + if (totalWeight > 0) { + coverageRatio = uncoveredWeight / totalWeight; } - // unknownNodeCoverageRatio is inherently iffy so don't scale up its contribution to the probability of rebroadcast - // This essentially makes the forward probability non-zero for nodes that have a set of "unknown" neighbors float forwardProb = BASE_FORWARD_PROB + (coverageRatio * COVERAGE_SCALE_FACTOR); // Clamp probability between 0 and 1 @@ -216,4 +226,13 @@ float FloodingRouter::calculateForwardProbability(const CoverageFilter &incoming LOG_DEBUG("CoverageRatio=%.2f, ForwardProb=%.2f (Uncovered=%d, Total=%zu)", coverageRatio, forwardProb, uncovered, neighbors); return forwardProb; +} + +float FloodingRouter::computeRecencyWeight(uint32_t age, uint32_t timeWindowSecs) +{ + // A node just heard from age=0 => weight=1.0 + // A node at the edge of timeWindowSecs => weight approaches 0. + // We clamp to [0, 1] just in case of rounding. + float ratio = 1.0f - (static_cast(age) / static_cast(timeWindowSecs)); + return std::max(std::min(ratio, 1.0f), 0.0f); } \ No newline at end of file diff --git a/src/mesh/FloodingRouter.h b/src/mesh/FloodingRouter.h index 93c0e0729..5115f6da4 100644 --- a/src/mesh/FloodingRouter.h +++ b/src/mesh/FloodingRouter.h @@ -44,6 +44,8 @@ class FloodingRouter : public Router, protected PacketHistory float calculateForwardProbability(const CoverageFilter &incoming, NodeNum from); + float computeRecencyWeight(uint32_t age, uint32_t timeWindowSecs); + public: /** * Constructor diff --git a/src/mesh/MeshTypes.h b/src/mesh/MeshTypes.h index 0d301156b..f0ad83b70 100644 --- a/src/mesh/MeshTypes.h +++ b/src/mesh/MeshTypes.h @@ -68,7 +68,7 @@ enum RxSource { // Recency threshold in minutes // Currently set to 1 hour because that is the minimum interval for nodeinfo broadcasts -#define RECENCY_THRESHOLD_MINUTES 60 +#define RECENCY_THRESHOLD_MINUTES 90 typedef int ErrorCode;