Skip to content

marilib: add a slot-level mari network simulator - #179

Draft
trifuns wants to merge 10 commits into
DotBots:mainfrom
trifuns:marilib-sim
Draft

trifuns wants to merge 10 commits into
DotBots:mainfrom
trifuns:marilib-sim

Conversation

@trifuns

@trifuns trifuns commented Oct 13, 2026 •

Copy link
Copy Markdown

Adds marilib.sim, a slot-level model of one mari gateway and its nodes. It sits behind marilib's gateway adapter, so MarilibEdge, the mari-edge TUI and anything built on them (the PyDotBot controller and simulator) run against it unchanged. The goal is to answer scaling questions (how many nodes, what loss, what load) without a bench, while staying faithful to the firmware rather than to a hand-written idea of it.

Approach

  • Constants come from the firmware. Schedules, slot timing and MAC constants are parsed from firmware/mari/ at load time. When marilib is installed without the repo, it falls back to firmware_snapshot.json, which python -m marilib.sim.snapshot writes and the test suite checks against the sources. The simulator carries no hand-copied protocol constant.
  • The engine follows mac.c. One step is one slot, processed in the order new_slot_synced runs it: timeouts first, then the cell's radio activity. It covers beacons, joins, keep-alives, disconnects and handovers. The node queue reproduces the firmware's 32-entry ring buffer, including its empty/full ambiguity (32 adds without a pop reads as empty), so loss from that bug shows up in the sim the same way it does on hardware.
  • The links are static per-node PDRs, uplink and downlink, read from the PyDotBot simulator's world file ([network] defaults plus per-robot overrides). A distance channel was tried first and then dropped: it let the node count leak into the PDR, which reproduces a selection bias rather than the radio.
  • What runs on each node is pluggable (NodeApp). The default SyntheticApp sends the 03app_node status packet and answers metrics probes. A host application such as the PyDotBot simulator can supply its own uplinks under its own next_proto.
  • mari-sim CLI. It runs a network live under the mari-edge TUI or as fast as it goes. It takes scripted events (nodes added, removed or moved, the gateway halted or reset) and load storms, and logs runs in the same format as the bench. mari-sim verify prints formation time, RTT and PDR beside the hardware reference campaign. It asserts nothing, because the hardware reference is one campaign and the comparison is for a person to read.
  • The load tester moved from examples/mari_edge_stats.py into marilib.metrics, so the simulator and the bench share one implementation. The example now calls it.

Validation

  • Unit tests: 85 tests under tests/sim, covering the firmware parsing and snapshot drift, MAC behaviour, wire format, link models, invariants and the CLI.
  • End to end: the simulator has been used through the PyDotBot simulator for a multi-robot consensus experiment.
    • At 5 robots, it was compared against the same experiment on the bench.
    • At 100 robots, it was run with a PDR sweep.
    • The PyDotBot side is a separate PR.
Lines added Files
Generated firmware snapshot +1383 1 firmware_snapshot.json, written by marilib.sim.snapshot
Tests +862 8
Source +2660 17 includes the load tester moved out of examples/ (-118 there)
Total +4905 / -120 26

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant