Feature: Repeated sending for DIRECT-route packets with echo-cancellation (improves delivery, reduces floods)#2670
Conversation
|
Some information about the 3 commits:
|
|
This seems very similar to #2367. |
|
After mcsim-simulation runs and internal tests on real hardware I released firmware packages named "ufo_0.1" for repeaters, companions and room-servers at https://github.com/usrflo/MeshCore/releases. This firmware is based on MeshCore-dev v1.16.0 with application of this pull request. It would be great to get some feedback on this feature. @wlockwood? |
|
To recognize propagated TRACE packages a special detection was required as TRACE packages differ in using path and body fields. In the simulation with a relatively stable chain of repeaters (TOPOLOGY, BEHAVIOR) I got the following results: Without repeated sending (max.resend 0) With repeated sending (max.resend 2) |
|
After the last bugfix I tested the firmware on the following hardware device chain: Without repeated sending: 81 of 100 packages were delivered Side note:
See the according firmware release ufo_0.5 at https://github.com/usrflo/MeshCore/releases To give an idea about the measurement: I used 2 observers to check the details on the two separated locations. One sample: |
|
Today's merges were a setback; I will try to find the reason. So long this pull request is set back to draft. |
|
Good numbers again, I fixed the timing issues of the last commits. The following problems are addressed in the changes of the last days:
Last results with the test chain Companion1->Rep1->Rep2->Rep3->Companion2, 50 direct messages in a 10 second interval, up to 2 package repetitions (default). Every ACK is counted as success: |
- Added max_resend_attempts preference to control the number of resend attempts for direct packets. - Enhanced the Dispatcher class to manage packet resends, including a new resendPacket method and logic to handle retransmission delays. - Updated the Packet class to include sending_attempts and final_hop_ack_resend flags for tracking retransmission state. - Modified the Mesh class to cancel pending final-hop resends upon receiving ACKs, preventing unnecessary retransmissions. - Introduced a dedicated ACK deduplication mechanism in SimpleMeshTables to handle multiple ACKs efficiently. - Updated CommonCLI to support configuration of max_resend_attempts via CLI commands. - Improved packet hash calculation and comparison logic to support the new resend functionality.
…ted fixed latency
The noise-floor calibration sampled only RSSI values below the current floor + threshold, a one-way ratchet: it accepted ever-lower samples but never recovered upward, so _noise_floor drifted to the -120 clamp and stayed there. That left the RSSI-margin LBT (isChannelActive with interference_threshold, plus isResendChannelActive / isChannelNoisy on the feature branches that consume _noise_floor) permanently over-sensitive — resends and dwell-gated TX deferred even on a quiet channel. Replace the ratcheted block mean with the median of the 64-sample block: - accepts every idle (!isReceivingPacket) sample — no downward bias; - median rejects transient interference spikes (high and low outliers) and recovers in BOTH directions; - _noise_floor is written only after a full block, so the previous value stays valid while the next block is sampled — no reset-to-0 and thus no permissive LBT window (margin = RSSI - 0) during reconvergence. resetAGC no longer forces _noise_floor = 0 (the stuck-ratchet workaround); it only discards the in-progress block so a fresh one is measured after the analog frontend reset. Verified: Heltec_v3_repeater firmware build (compiles RadioLibWrappers.cpp against real RadioLib). Co-Authored-By: Claude <noreply@anthropic.com>
81e7fe2 to
8acdb11
Compare
|
Last update: the max wait time limit - used as a window to cancel packages prepared to be resended - needs to be calculated according to the airtime / package size. |
…tection to be replaced by _prefs.interference_threshold when the currentRSSI problem is solved, possibly via PR meshcore-dev#2933
Repeated-sending - current state and the safeguards that keep it stableA resend is a redundant retransmission of a DIRECT (acknowledged-path) packet, queued by the originator and auto-cancelled when a downstream relay's forward — or the destination's ACK — is overheard. The logic only ever adds a retry that can be called off, and sheds/collisions are guarded as follows. Safeguards
If you like to test this PR it's recommended to use: This PR ist part of the ufo firmware, latest build at time of writing: v0.6 |
Relates to #1342.
Motivation
Direct messages over multi-hop paths fail silently when a single hop misses a packet due to temporary radio interference or channel congestion. The sending node then falls back to a flood — which is both unreliable under load and consumes significant airtime. In my tests most incoming paths with a length of 3 hops couldn't be reused in back traces: a far too low number that should be increased by an error correction.
What this PR does
This branch adds conditional repeated sending for DIRECT-route packets at the repeater level:
max_resend_attemptsre-transmissions (default: 2, configurable 0–3 viaset max.resend).loop()call, minimising the race window between echo detection and retransmit timer expiry._acks[]inSimpleMeshTables) to keep deduplication cheap (4-byte compare, no SHA-256) and to prevent ACK entries from evicting long-lived flood-packet hashes.Comparison with PR #2367 (HALO)
This implementation shares the same goal as #2367 — improve direct-path reliability — but uses a different strategy. Both branches were applied to mcsim (including fixes to make the simulator timing-accurate for retransmit scenarios, see simulator commits) and run against the same standardised test scenario.
Test topology: 3 repeaters between Alice and Bob, all links of marginal/bad quality
Test: 10 random seeds × 20 DMs each = 200 deliveries total
halo-direct-path-retries(#2367)repeated-sending-2(this PR)Key advantages of this approach:
Delivery rate vs. resend attempts (mcsim, retry_showcase topology)
max_resend_attemptsA value of 2–3 is a good compromise between reliable delivery and channel efficiency.
CLI
No new commands are needed —
max_resend_attemptsis already exposed: