tune delay knobs

This commit is contained in:
liquidraver
2026-04-28 13:49:08 +02:00
parent 7ecf647af8
commit bf9ad0ef40
6 changed files with 25 additions and 15 deletions
+6 -2
View File
@@ -1200,11 +1200,15 @@ uint32_t CompanionMesh::getRetransmitDelay(const mesh::Packet *packet)
uint32_t CompanionMesh::getDirectRetransmitDelay(const mesh::Packet *packet)
{
uint32_t t = _radio->getEstAirtimeFor(
uint32_t airtime = _radio->getEstAirtimeFor(
packet->getPathByteLen() + packet->payload_len + 2);
/* Jitter around Arduino direct factor 0.3 using a per-packet factor
* in the range [0.25, 0.40]. */
uint32_t factor_milli = (uint32_t)getRNG()->nextInt(250, 401);
uint32_t max_jitter = (5 * airtime * factor_milli) / 1000;
/* Floor: give downstream nodes time to finish RX processing
* and return to RX mode before we TX (~20ms settle + jitter) */
return 20 + getRNG()->nextInt(0, t / 10 + 1);
return 20 + getRNG()->nextInt(0, max_jitter + 1);
}
uint32_t CompanionMesh::getInitialFloodJitter(const mesh::Packet *packet)
+1 -1
View File
@@ -203,7 +203,7 @@ bool RepeaterDataStore::loadPrefs(NodePrefs& prefs) {
/* Migrate uninitialized backoff_multiplier (0.0 or NaN) to default */
if (prefs.backoff_multiplier == 0.0f || prefs.backoff_multiplier != prefs.backoff_multiplier) {
prefs.backoff_multiplier = 0.5f;
prefs.backoff_multiplier = 0.2f;
}
LOG_INF("Loaded prefs from %s", path);
+7 -3
View File
@@ -571,11 +571,15 @@ uint32_t RepeaterMesh::getRetransmitDelay(const mesh::Packet* packet) {
}
uint32_t RepeaterMesh::getDirectRetransmitDelay(const mesh::Packet* packet) {
uint32_t t = _radio->getEstAirtimeFor(
uint32_t airtime = _radio->getEstAirtimeFor(
packet->getPathByteLen() + packet->payload_len + 2);
/* Jitter around Arduino direct factor 0.3 using a per-packet factor
* in the range [0.25, 0.40]. */
uint32_t factor_milli = (uint32_t)getRNG()->nextInt(250, 401);
uint32_t max_jitter = (5 * airtime * factor_milli) / 1000;
/* Floor: give downstream nodes time to finish RX processing
* and return to RX mode before we TX (~20ms settle + jitter) */
return 20 + getRNG()->nextInt(0, t / 10 + 1);
* and return to RX mode before we TX (~20ms settle + jitter). */
return 20 + getRNG()->nextInt(0, max_jitter + 1);
}
bool RepeaterMesh::filterRecvFloodPacket(mesh::Packet* pkt) {
+2 -2
View File
@@ -124,12 +124,12 @@ void CommonCLI::loadPrefs(const char* path) {
_prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0.0f, 20.0f);
_prefs->tx_delay_factor = constrain(_prefs->tx_delay_factor, 0.0f, 2.0f);
_prefs->direct_tx_delay_factor = constrain(_prefs->direct_tx_delay_factor, 0.0f, 2.0f);
/* Migrate uninitialized pad bytes: NaN or out-of-range → default 0.5.
/* Migrate uninitialized pad bytes: NaN or out-of-range → default 0.2.
* 0.0 is valid (disables reactive backoff). Old firmware upgrading
* with zeroed pad bytes will get 0.0 = disabled; user can set explicitly. */
if (_prefs->backoff_multiplier != _prefs->backoff_multiplier ||
_prefs->backoff_multiplier < 0.0f || _prefs->backoff_multiplier > 10.0f) {
_prefs->backoff_multiplier = 0.5f;
_prefs->backoff_multiplier = 0.2f;
}
_prefs->backoff_multiplier = constrain(_prefs->backoff_multiplier, 0.0f, 2.0f);
/* Migrate old AF multiplier (0-9) to duty cycle percentage (0-99) */
+5 -5
View File
@@ -37,7 +37,7 @@ public:
float getContentionEstimate() const;
/* sqrt curve: MIN_FLOOD_FACTOR + FLOOD_SCALE * sqrt(est), cap 2.0.
/* Saturating curve: MIN + (MAX-MIN) * est/(est+HALFPOINT).
* Returns 0.5 during warmup. */
float getFloodDelayFactor() const;
@@ -51,10 +51,10 @@ private:
static constexpr uint32_t WINDOW_MS = 10000; /* dupe observation window; covers SF12 2-hop */
static constexpr int EMA_SHIFT = 3; /* alpha = 1/8 */
static constexpr int WARMUP_PACKETS = 4; /* min samples before EMA is trusted */
static constexpr float MIN_FLOOD_FACTOR = 0.05f; /* floor: near-zero delay in quiet networks */
static constexpr float FLOOD_SCALE = 0.170f; /* (0.5 - 0.05) / sqrt(15) */
static constexpr float MAX_FLOOD_FACTOR = 2.0f; /* ceiling: 2x base airtime */
static constexpr float DEFAULT_BACKOFF_MULT = 0.5f; /* half-airtime per dupe heard */
static constexpr float MIN_FLOOD_FACTOR = 0.40f; /* sparse mesh baseline */
static constexpr float MAX_FLOOD_FACTOR = 1.00f; /* dense mesh ceiling */
static constexpr float FLOOD_EST_HALFPOINT = 4.0f; /* midpoint: factor=0.60 at est=4 */
static constexpr float DEFAULT_BACKOFF_MULT = 0.2f; /* airtime*0.2 per dupe heard */
static constexpr uint32_t REACTIVE_HARD_CAP_MS = 2000; /* max cumulative reactive extension */
static constexpr uint32_t STALE_MS = 300000; /* 5 min: reset EMA if no traffic */
+4 -2
View File
@@ -5,7 +5,6 @@
#include <mesh/ContentionTracker.h>
#include <mesh/Packet.h>
#include <math.h>
#include <string.h>
namespace mesh {
@@ -156,7 +155,10 @@ float ContentionTracker::getFloodDelayFactor() const
float est = getContentionEstimate();
if (est <= 0.0f) return MIN_FLOOD_FACTOR;
float factor = MIN_FLOOD_FACTOR + FLOOD_SCALE * sqrtf(est);
/* Arduino-like center near 0.5 in light contention, rising smoothly
* toward 0.8 as contention increases. */
float factor = MIN_FLOOD_FACTOR + (MAX_FLOOD_FACTOR - MIN_FLOOD_FACTOR) *
(est / (est + FLOOD_EST_HALFPOINT));
if (factor > MAX_FLOOD_FACTOR) factor = MAX_FLOOD_FACTOR;
return factor;
}