Static Wi-Fi mesh: the family where nothing moves¶
Varies: mobility, switched off. This is the paper base field (50 nodes,
1500 × 300 m, 20 CBR flows, 900 s) with pause = 900, so every node holds its
t = 0 position for the whole run. It is the community-network / Freifunk-class
static Wi-Fi mesh family, one of the four families of the family axis
(#484,
roadmap).
← Benchmark index · Metrics · Methodology · Regimes
Provenance: measured at
ce81eefe, the #496 timer-jitter fix, afterv1.6.0. Every AntHocNet row on this page before496 was measured with the ns-3 adapter's hello timer phase-locked across all¶
nodes. That artifact is kept below as the dated pre-#496 record, and it is reproducible with
--ns3::anthocnet::RoutingProtocol::TimerJitter=0. The four baselines are byte-identical across all three runs, which is the control that proves only AntHocNet moved. Like the grid and TCP pages, these numbers are not comparable with thev1.3.0-pinned sweep pages. The raw per-seed cells are committed next to this page:results/cells/static-mesh-jitter.txt(current),results/cells/static-mesh-cap200ms.txtandresults/cells/static-mesh-cap1s.txt(pre-#496). The #494 cap re-measure arms areresults/cells/static-mesh-jitter-cap1s.txtandresults/cells/paper-mobile-jitter-cap1s.txt. Run IDs are in Provenance below.
Re-measured for v2.2.0 (2026-10-16). The v2.2.0 campaign re-ran every cell on this page as its control generation, at a8a16991, with the shipped defaults and the same 20 seeds. Every ##RUN## row is byte-identical to the cells this page cites. No default moved, so the numbers here stand as v2.2.0's. The control cells are results/cells/static-mesh-v220.txt. What the campaign's four knobs do on this family is in network-regimes.md §7.
Why this family, and why it is framed rather than built¶
The #298 family scan
put the static mesh first on the list because it costs nothing: the
sparse-static cell of the taxonomy is this
network. This page adds no harness work. What it adds:
- 20 seeds at current defaults, because the per-merge scenario page runs at the 10-run floor with 120 s runs;
- the exact oracle as an upper bound (on the disk channel it is
approx=0, a proven bound); - the family's reading of the results.
With nothing moving, the regime removes everything AntHocNet was designed around (network-regimes.md):
- no link churn to track;
- no route to repair;
- proactive maintenance that pays for a topology that never changes.
Whatever AntHocNet loses here, it loses to its own machinery.
Restated at v2.4.0: family-native baselines (ADR-0026)¶
Current numbers: v2.4.0. From v2.4.0 every family is compared against its own protocols plus its oracle (ADR-0026). These cells are the v2.4.0 control campaign at the shipped defaults (no default moved), 20 seeds, mean ± 95 % t-interval. AntHocNet's rows and every kept baseline row are byte-identical to v2.3.0's. The blocks below this one are the dated record of their campaigns; their migrant rows are retired, not deleted.
Native set: AntHocNet, OLSR, IEEE 802.11s HWMP (#708), the oracle. Retired: AODV, DSDV. Every arm runs 802.11a at a fixed 6 Mbit/s and PeerLink::MaxBeaconLoss=20 (the plan has why), so these rows are not paired with the 802.11b record below.
| protocol | PDR % ± 95 % CI | delay99 ms | NRL |
|---|---|---|---|
| AntHocNet | 99.34 ± 0.26 | 1.7 | 4.17 |
| OLSR | 99.98 ± 0.02 | 1.5 | 1.78 |
| HWMP | 91.00 ± 1.15 | 1098.2 | 49.48 |
| oracle | 99.94 ± 0.09 | 1.6 | 0.00 |
AntHocNet − oracle -0.60 [-0.90, -0.30] pp; against the best native baseline (olsr, 99.98 %): dPDR -0.65 [-0.91, -0.39] pp, d delay99 +0.20 [+0.05, +0.40] ms, d NRL +2.40 [+2.19, +2.61] (PAIRED-WORSE). OLSR leads the family, as it did on 802.11b. HWMP is third: AntHocNet − HWMP is +8.34 pp [+7.10, +9.58], delay99 −1097 ms, NRL −45.3, all paired-significant. At ns-3's default MaxBeaconLoss of 2, HWMP collapses to 56.5 % on this field (finding on #708).
Restated at v2.3.0 defaults (quiet mode on)¶
Dated record: v2.3.0 defaults (superseded by the v2.4.0 block above). v2.3.0 turns quiet mode on by default (#571, the v2.3.0 campaign). AntHocNet's rows below are the campaign's
quietarm. Every baseline row is the campaign'scontrol, and the attribution control found those identical to the v2.2.0 corpus. 20 seeds, paired per seed; a bold difference is one whose 95 % t-interval excludes zero.Quiet mode's effect here, paired against v2.2.0's AntHocNet: NRL 4.51 → 4.11 (−8.6 %, paired 95 % CI [−0.47, −0.32]) and delay99 10.3 → 9.6 ms, with PDR unchanged. OLSR still leads on NRL (1.78): the hellos and the capped probing remain.
Provenance. The campaign's runs at
main,54cdfae7..cc230126. Cells:results/cells/<cell>-v230-published.txt, composed bytools/bench/compose_cell.pyfrom the campaign's<cell>-v230.txt(control) and<cell>-v230-quiet.txt. Tables recomputed from the cells'##RUN##rows (t-intervals; delay99 by bootstrap).static mesh
protocol PDR % delay99 (ms, bootstrap) NRL anthocnet 99.33 ± 0.23 9.6 [8.6, 10.8] 4.11 ± 0.13 aodv 97.28 ± 0.40 215.7 [189.2, 246.1] 17.53 ± 1.20 olsr 99.82 ± 0.16 7.3 [6.4, 8.3] 1.78 ± 0.03 dsdv 99.66 ± 0.12 122.8 [108.5, 136.3] 8.55 ± 0.18 oracle 99.94 ± 0.09 6.0 [5.0, 7.0] 0.00 ± 0.00
AntHocNet minus ΔPDR (pp) Δdelay99 (ms) ΔNRL aodv +2.05 [+1.66, +2.43] -206.1 [-237.4, -174.8] -13.42 [-14.60, -12.24] olsr -0.49 [-0.71, -0.27] +2.3 [+1.8, +2.8] +2.34 [+2.20, +2.48] dsdv -0.32 [-0.50, -0.15] -113.2 [-127.7, -98.8] -4.43 [-4.67, -4.19] The blocks below are the dated v2.2.0 record (quiet mode off). Their baseline rows are unchanged; where AntHocNet's numbers disagree with this block, this block is current. Diagnostic tables below (drop causes, paths, handovers, churn) describe the v2.2.0 runs.
Restated on CBR sources (#521)¶
Re-measured on constant-bit-rate sources. Until #521 every source ran ns-3's default 1 s on / 1 s off, so this field was offered 0.5 pkt/s per flow, not the stated 1 pkt/s.
Provenance. Run
37172238042atmain@d26ae640, with the knobs of the published dispatch: 20 seeds, 900 s,pause=900, disk,3.42-opt. Cell:results/cells/static-mesh-cbr521.txt.scenario_check.py results: 0 FAIL (the #230 path-diversity WARN only).bench_parsecolumn mapping is OK (25 checks). OLSR's PDR is offered-based (#510).
Reproduce:
make reproduce FIG=family-static-meshre-renders it from the committed data and diffs the PNG;MODE=rerun NS3DIR=…re-measures a cell first (#621).Bars: mean of 20 seeds, AntHocNet highlighted; whiskers: 95 % CI (t for PDR and NRL, bootstrap for delay99); vertical line: the oracle control. Drawn by
ns3/tools/family-charts.pyfrom the committed cellstatic-mesh-v230-published.txt: since v2.3.0 it shows the v2.3.0 generation (the block above), and the table below is the dated v2.2.0 record.
protocol PDR % mean delay (ms) delay99 (ms, bootstrap) NRL energy (mJ/bit) anthocnet 99.34 ± 0.34 3.55 ± 0.39 10.3 [9.2, 11.6] 4.51 ± 0.18 4.534 ± 0.040 aodv 97.28 ± 0.40 14.38 ± 1.74 215.7 [188.8, 246.1] 17.53 ± 1.20 4.644 ± 0.048 dsdv 99.66 ± 0.12 7.72 ± 0.93 122.8 [108.5, 136.3] 8.55 ± 0.18 4.511 ± 0.035 olsr 99.82 ± 0.16 2.47 ± 0.24 7.3 [6.4, 8.3] 1.78 ± 0.03 4.492 ± 0.035 oracle (exact) 99.94 ± 0.09 2.56 ± 0.28 6.0 [5.0, 7.0] 0.00 4.475 ± 0.036 Verdicts: - AntHocNet still beats AODV on every metric, paired per seed: - PDR +2.05 pp [+1.70, +2.40]; -
delay99−205 ms [−237, −174]; - NRL −13.03 [−14.21, −11.84]; - energy per bit −0.110 mJ [−0.128, −0.092]; - all p ≤ 9.6 × 10⁻⁵. - OLSR still wins the static mesh: +0.49 pp over AntHocNet [+0.19, +0.78] at 1.78 NRL. - DSDV also delivers marginally more than AntHocNet (+0.32 pp [+0.02, +0.62], p = 0.029). - One claim changes. AntHocNet'sdelay99is no longer inside the oracle's interval: 10.3 vs 6.0 ms, paired +4.35 ms [+3.51, +5.19]. It stays far below DSDV's 122.8 ms. - AntHocNet's drop book isroute=0.37 [setup=0.09 reconv=0.27],chan=0.31.The tables below are the dated pre-#521 record (
ce81eefe). Where they disagree with this block, this block is current.
Results (20 seeds, 95 % CIs)¶
Current defaults (TimerJitter = 0.05, ReconvHoldCap = 200 ms):
| protocol | PDR % | mean delay (ms) | delay99 (ms, bootstrap) | NRL |
|---|---|---|---|---|
| anthocnet | 99.28 ± 0.25 | 3.70 ± 0.33 | 10.5 [9.3, 11.8] | 8.84 ± 0.27 |
| aodv | 95.98 ± 0.44 | 23.47 ± 2.54 | 266.7 [239.8, 297.1] | 39.39 ± 1.95 |
| dsdv | 99.68 ± 0.08 | 8.54 ± 1.19 | 125.3 [112.0, 138.2] | 17.04 ± 0.35 |
| olsr | 100.00 ± 0.00 | 2.54 ± 0.23 | 6.7 [5.8, 7.6] | 3.56 ± 0.07 |
| oracle (exact) | 100.00 ± 0.00 | 2.67 ± 0.30 | 11.3 [10.8, 11.8] | 0.00 |
The AntHocNet drop book is route=0.44 [reconv=0.36], with chan=0.27.
What #496 changed¶
Before #496, the ns-3 adapter started every node's hello timer at t ≈ 0 with no
jitter, so all 50 nodes beaconed at exactly t = 1, 2, 3 … s. Hidden terminals
collided on the same broadcasts every second. Two lost hellos in a row evict a
live neighbour, so the field tore down every link about every 15 s while no
node moved: about 93k spurious evictions per run. Each eviction pruned routes,
flooded LinkFail notes, and held data as HOLD_RECONV. The NS-2 adapter
(removed in v2.0.0) always jittered this timer; the ns-3 port lost it.
Paired AntHocNet, fixed timer vs the old one, same seeds and same 200 ms cap
(bench_parse --ab, n = 20):
| metric | change | 95 % CI | Wilcoxon p |
|---|---|---|---|
| dPDR | +11.28 pp | [+9.10, +13.45] | 1.9 × 10⁻⁶ |
| delay99 | −143 ms | [−167, −120] | 1.9 × 10⁻⁶ |
| NRL | −22.37 | [−23.61, −21.12] | 1.9 × 10⁻⁶ |
The dPDR is positive on 20 / 20 seeds: PAIRED-IMPROVED on every metric.
The cap, re-measured on the fixed timer (#494)¶
With the timer fixed, ReconvHoldCap = 1 s against the 200 ms default, paired
on the same seeds (bench_parse --ab, n = 20). The mobile paper cell
(pause = 0) is included because #371 picked the cap on mobile cells.
| cell | PDR 200 ms → 1 s | dPDR [95 % CI] | delay99 200 ms → 1 s | NRL change |
|---|---|---|---|---|
| static mesh | 99.28 → 99.55 | +0.26 [+0.04, +0.49] pp, p = 0.011; 11 / 20 seeds up, 3 down | 10.5 → 10.4 ms (p = 0.57) | −0.01 (p = 0.90) |
| paper mobile | 96.19 → 97.50 | +1.31 [+1.06, +1.55] pp, 20 / 20 seeds | 345.6 → 555.0 ms (+209 [+172, +249]) | +0.42 [+0.27, +0.57] |
On the static field the cap is now close to irrelevant: reconv is 0.36 % at
200 ms. On mobile, 1 s buys 1.3 pp by holding packets longer, and pushes the
tail above AODV's 510.9 ms. That is the trade #371 priced, so 200 ms stays.
Pre-#496 record (TimerJitter = 0)¶
Kept because #494 and the first version of this page were measured here, and
because it is the evidence for #496. Both rows are the same field, seeds and
binary, differing only in ReconvHoldCap.
| protocol | PDR % | mean delay (ms) | delay99 (ms, bootstrap) | NRL |
|---|---|---|---|---|
| anthocnet, 200 ms | 88.00 ± 2.24 | 12.06 ± 1.70 | 153.6 [130.1, 177.3] | 31.20 ± 1.46 |
| anthocnet, 1 s | 97.97 ± 0.33 | 26.70 ± 3.43 | 588.8 [510.1, 661.0] | 29.68 ± 1.14 |
The drop books were route=11.52 [reconv=11.51] at 200 ms and
route=1.34 [reconv=1.33] at 1 s. The 1 s cap recovered most of the lost
packets by holding them long enough to outlast the spurious break, at a
588 ms tail. The fixed timer removes the break instead, and beats both rows on
every metric.
What the family says¶
- With the timer fixed, AntHocNet beats AODV on every metric here. It delivers 99.28 % vs 95.98 % (disjoint CIs). Its delay99 is 10.5 ms vs 266.7 ms, and its NRL is 8.84 vs 39.39. Its tail is also below DSDV's (125.3 ms) and within the oracle's interval (11.3 ms [10.8, 11.8]).
- OLSR still wins the static mesh, as expected on a topology that never
changes: 100 % delivery at 3.56 NRL. That is the Babel / BATMAN-adv home
turf discussed below. AntHocNet's 0.7 pp gap to OLSR is
route=0.44+chan=0.27. OLSR's 100 % predates #510, which counts the sends stock OLSR refuses at the source. The offered-based estimate from this cell's own throughput is 99.95 %, so the ordering and the gap are unchanged. - The first version of this page measured a timer bug, not the family. Its
headline, that the 200 ms
ReconvHoldCapcosts about 10 pp here and that #371's "beats AODV on every metric" does not hold for static meshes (#494), was the #496 artifact. Re-measured on the fixed timer, 1 s adds only +0.26 pp here and costs 209 ms of mobile tail, so the 200 ms default stands (see above).
The native comparator: 802.11s HWMP (#708)¶
Under ADR-0026 this family is compared against its own protocols: OLSR (community meshes) and IEEE 802.11s HWMP, the standard's path selection. AODV and DSDV are MANET protocols migrated in; their rows above stay as the dated record of their campaigns and leave the plan from the v2.4.0 control campaign.
--protocols=hwmp runs stock ns-3 802.11s (MeshHelper, Dot11sStack), one
mesh point per node, on the same field, channel and seeds. Two things differ
from the cells above, and both are deliberate:
- The radio is 802.11a at a fixed 6 Mbit/s (
--standard=80211a --rateManager=constant6). ns-3 tunes every mesh interface to 5 GHz channel 100, so 802.11s does not run on 802.11b at all. The maintainer's decision (2026-10-19) moves the whole static-mesh cell, every arm, to that radio from the v2.4.0 campaign on; real 802.11s deployments are 5 GHz too. The disk channel ignores frequency, so the topology is the one measured above. The 802.11b rows on this page stay the dated record and are not paired with the 802.11a ones. - HWMP routes below IP. How each harness book maps onto layer-2 path selection (NRL from the PREQ/PREP/PERR/RANN frames, hops from the mesh's own relays, peering and beacons reported apart) is in metrics.md.
The arm passes the per-PR delivery smoke (#439)
and its own anchor, mesh-hwmp-shortest: on a static disk field it must
converge to the oracle's shortest path (mean hops in [1.00, 1.10] × the
oracle's). The 20-seed AntHocNet, OLSR, HWMP and oracle cell on 802.11a is
measured in the v2.4.0 control campaign and published here with it.
Threats to validity¶
- Missing baselines. The protocols a real community mesh runs are Babel (RFC 8966) and BATMAN-adv. Neither has a maintained ns-3 port; see the dated modern-baseline survey for the evidence and the decision. OLSR is the closest ns-3-available stand-in, and it is already at the oracle here. 802.11s HWMP, the standard's own path selection, is stock ns-3 and joins from v2.4.0 (above).
- HWMP is ns-3's model of it. The arm runs ns-3's
dot11sat its shipped defaults (on-demand mode, no root portal, the airtime metric). It is one implementation of the standard, not a deployed mesh stack. - Channel. The disk channel at 300 m is idealised: a link either exists perfectly or not at all. Real meshes are shaped by interference and fading. The grid shows the tail ordering inverting under Nakagami fading, so a fading arm of this family is the natural follow-up.
- One field. This is the paper base field with mobility removed. It is not a measured community-network topology.
Provenance¶
| arm | run | commit | image | seeds |
|---|---|---|---|---|
current (TimerJitter 0.05, cap 200 ms) |
36595249953 | ce81eefe |
ns3:3.42-opt |
1–20 |
| pre-#496, cap 200 ms | 36261077793 | 4fffedcc |
ns3:3.42-opt |
1–20 |
| pre-#496, cap 1 s | 36269605435 | 0c524697 |
ns3:3.42-opt |
1–20 |
| #494 re-measure: cap 1 s, fixed timer | 36767457453 | 4c8482fd |
ns3:3.42-opt |
1–20 |
| #494 re-measure: paper mobile, cap 1 s | 36767461455 | 4c8482fd |
ns3:3.42-opt |
1–20 |
control: ce81eefe at TimerJitter=0 |
36595255598 | ce81eefe |
ns3:3.42-opt |
1–20 |
All cells:
scenario_check.py results: WARN only, 0 FAIL;bench_parsecolumn mapping: OK (25 checks each);- baselines (aodv, olsr, dsdv, oracle): byte-identical per-seed rows across every arm;
- the control run reproduces the pre-#496 200 ms AntHocNet rows byte for
byte, so
TimerJitter=0is exactly the old timer.
Reproduce with a campaign plan cell (workflow: paper-benchmark.yml, which
tools/bench/campaign.py translates for benchmark-cell.yml since v2.5.0,
746) using `nNodes=50 time=900 runs=20¶
areaX=1500 pause=900 speed=20 range=300 propagation=range
protocols=anthocnet,aodv,olsr,dsdv,oracle version=3.42-opt. For the pre-#496
arms, addextraArgs=--ns3::anthocnet::RoutingProtocol::TimerJitter=0, plus--ns3::anthocnet::RoutingProtocol::ReconvHoldCap=1sfor the 1 s row.
The #494 arms add onlyReconvHoldCap=1sand runprotocols=anthocnet(pause=0for the mobile one); their 200 ms partners areresults/cells/static-mesh-jitter.txtandresults/cells/paper-mobile-jitter.txt.4c8482fdcarries the same code asce81eefe` (it differs only by a docs refresh).
