Skip to content

feat(lora): add dynamic coding rate policy#10327

Draft
Komzpa wants to merge 5 commits into
meshtastic:developfrom
Komzpa:codex/dynamic-coding-rate
Draft

feat(lora): add dynamic coding rate policy#10327
Komzpa wants to merge 5 commits into
meshtastic:developfrom
Komzpa:codex/dynamic-coding-rate

Conversation

@Komzpa
Copy link
Copy Markdown
Contributor

@Komzpa Komzpa commented Apr 28, 2026

Summary

Adds a first firmware implementation of Dynamic Coding Rate as a shared AirtimePolicy instead of backend-local heuristics.

  • classifies packets by port/priority and chooses CR 4/5 through CR 4/8 from packet class, channel pressure, retry context, relay context, duty-cycle pressure, airtime caps, and a CR 4/8 token bucket
  • applies per-packet CR through the common radio layer for RadioLib radios and the Portduino simulator, then restores the configured base CR after TX
  • observes RX coding rate from the RadioLib header path and keeps local counters / neighbor attribution without adding a MeshPacket field
  • records failed retransmissions with the actual last TX CR for that packet
  • treats retry losses as quiet only below an actual selected-region duty-cycle limit when one applies; unrestricted or duty-cycle-overridden regions do not get a synthetic quiet-loss utilization threshold
  • prevents final-retry quiet-loss escalation while the policy already considers the channel busy or congested
  • keeps reused packet storage from reusing stale packet-class cache entries
  • preserves LR11x0/LR20x0/SX128x long-interleaving static configuration when restoring the base coding rate after a DCR transmit
  • adds generated LoRa config fields, docs, and native policy tests

Dependency

Depends on meshtastic/protobufs#902 for the source LoRaConfig fields. The firmware submodule pointer is intentionally not advanced in this PR; only the generated firmware-side protobuf files are included here.

Rollout Notes

DCR is a simple on/off policy gate: DCR_OFF keeps the configured static coding rate, and DCR_ON applies per-packet coding-rate selection. There is no observe-only mode, and this PR does not reserve debug/capability fields that are not consumed by the firmware.

Hardware interop still needs real-radio validation across SX126x, SX127x/RF95, SX128x, LR11x0, static-CR nodes, and mixed DCR/static relays.

Tests

  • git diff --check
  • ./bin/test-native-docker.sh -f test_dynamic_coding_rate (16/16)
  • Docker PlatformIO build: platformio run -e heltec-v3
  • Docker PlatformIO build: platformio run -e tbeam

Attestations

  • I have tested that my proposed changes behave as described.
  • I have tested that my proposed changes do not cause any obvious regressions on the following devices:
    • Heltec (Lora32) V3
    • LilyGo T-Deck
    • LilyGo T-Beam
    • RAK WisBlock 4631
    • Seeed Studio T-1000E tracker card
    • Other: compile-only validation for heltec-v3 and tbeam; native Portduino policy tests pass. Real-radio interop remains pending as noted above.

@github-actions github-actions Bot added the enhancement New feature or request label Apr 28, 2026
@Komzpa Komzpa force-pushed the codex/dynamic-coding-rate branch from 405c8ee to a4f69a6 Compare April 28, 2026 21:07
@Komzpa Komzpa force-pushed the codex/dynamic-coding-rate branch 5 times, most recently from 9257f23 to e9c9e26 Compare April 29, 2026 10:26
@Komzpa Komzpa force-pushed the codex/dynamic-coding-rate branch from c912d15 to 3b0e4ef Compare May 3, 2026 12:44
@Komzpa Komzpa force-pushed the codex/dynamic-coding-rate branch from 3b0e4ef to 8ca98c0 Compare May 14, 2026 01:43
Komzpa added 5 commits May 24, 2026 06:24
Store the initial retransmission countdown in PendingPacket so DCR can derive retry attempts from packet state instead of sender role assumptions.

Inspired-by: @NomDeTom in meshtastic#10359
Expose only the DCR on/off mode in LoRaConfig and keep the tuned policy clamps internal for now. Meshtasticator modeling showed small knob changes can help one scenario while hurting dense collision-heavy cases, so avoid committing an oversized public config surface before field validation.
@Komzpa Komzpa force-pushed the codex/dynamic-coding-rate branch from 8ca98c0 to 46c200a Compare May 24, 2026 02:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant