N-channel dwell-1 hopping — closes the standard-driver FHSS series (exp 5/5)#322
Merged
Conversation
…xp 5/5) #273 was framed as escaping MCC's two-context limit by rewriting the inactive context ("ping-pong"). That needs a running MCC scheduler, which #271 proved never engages here — and the premise is moot: the exp-4 dwell-1 data plane runs over the synchronous channel switch, which has no context limit, so N channels is just channel_index(slot, N). This delivers exp-5's real goal over that data plane and records the MCC ping-pong mechanism as a no-go inherited from #271. dwelltx generalises to any N (DEVOURER_DWELL_CHANNELS=c0,c1,...; HopSchedule was already N-general, no library change). dwell1_ab.py spawns one oracle per channel and attributes each slot to the strongest-RSSI oracle so near-field adjacent-channel leakage isn't miscounted as a wrong-channel while a true mis-air still surfaces; keyed attribution reuses hop_rx_probe.py's SipHash port (Python order matches the C++ on-air order slot-for-slot). dwell1_parity.sh sweeps hop_parity_check across AGC buckets. On-air (RTL8822BU DUT, four oracles incl. an 8852BU): 3-channel and 4-channel each 100,020 dwell-1 slots with ZERO wrong-channel and zero duplicates (96.7 % / 95.4 % delivered); late-enqueue drops deterministically (613/614), zero mis-aired; keyed 3-channel delivered wrong-channel-free with a single receiver acquiring + re-acquiring from cold restart; register parity 6/6 from UNII-1 to UNII-3 (cross AGC bucket). Benchmark: switch cost (~2 ms), admit jitter (~110-130 us) and delivery are flat from 2 to 4 channels — no per-channel penalty; MCC/ping-pong rows N/A (never runs). Full note: docs/n-channel-hopping.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #273. Final experiment of the standard-driver FHSS series.
#273 was framed around escaping MCC's two-context limit by rewriting the inactive MCC context while the active one carries traffic ("ping-pong"). That needs a running MCC scheduler, which #271 proved never engages here — and the premise is moot: the exp-4 dwell-1 data plane runs over the ordinary synchronous channel switch, which has no context limit, so N channels is just
channel_index(slot, N). This delivers exp-5's real goal — arbitrary N-channel dwell-1 hopping with the same rigor — over that data plane, and records the MCC ping-pong mechanism as a no-go inherited from #271.Almost entirely reuse
dwelltxgeneralises to any N (DEVOURER_DWELL_CHANNELS=c0,c1,…;HopSchedule::channel_index(slot, n)and its Fisher-Yates permutation were already N-general — no library change).dwell1_ab.pyspawns one oracle per channel and attributes each slot to the strongest-RSSI oracle, so near-field adjacent-channel leakage isn't miscounted as a wrong-channel while a true mis-air still surfaces (the wrong oracle would then be strongest). Keyed attribution reuses the SipHash-2-4 + Fisher-Yates port intests/hop_rx_probe.py— the Python order matches the C++ on-air order slot-for-slot.dwell1_parity.shsweepshop_parity_check.shacross AGC buckets.On-air results (RTL8822BU DUT, four oracles incl. an 8852BU)
Benchmark — flat scaling
Transition cost, jitter and delivery are flat from 2 to 4 channels — a hop is one synchronous retune regardless of how many channels the schedule spans, so N-channel hopping carries no per-channel penalty. The ping-pong-MCC / fixed-A/B-MCC rows are N/A: MCC never runs (#271).
Go/no-go: N-channel dwell-1 hopping works and needed none of MCC's context juggling; the ping-pong mechanism is a no-go. This closes the five-experiment series — the synchronous switch plus a caller-side admission scheduler is the deterministic per-slot FHSS data plane, scaling cleanly to arbitrary N. Full note:
docs/n-channel-hopping.md.🤖 Generated with Claude Code