PIBT (Priority Inheritance with Backtracking) demos for a DotBot swarm β collision-free multi-robot navigation on a discrete grid.
π Documentation: a three-level reproduction guide (algorithm β simulator β real
hardware) lives under docs/ and builds as a MkDocs site (mkdocs serve).
| Path | Level | Description |
|---|---|---|
sim_pibt.py |
0 | Interactive pygame viewer β animates PIBT on a small grid (edit-in-file scenario). |
sim_many_pibt.py |
0 | Headless benchmark β PIBT sweep over grid resolution Γ N Γ seeds, writes a CSV. |
simulation/ |
0 | Standalone PIBT engine (core/, algo/pibt.py) + renderers. |
simulation/main.py |
0 | Minimal non-PIBT template (random-walk coordinator). |
sim_dotbot_pibt.py |
1 | Drives the DotBot simulator through the controller API (parallel + pipelined). |
real_dotbot_pibt.py |
2 | Drives real DotBots, one waypoint per bot per step, sync barrier between steps. |
real_dotbot_pibt_batch.py |
2 | Parametrised batch test (--bots N --runs M) writing L1 metrics. |
log/ |
β | Experiment outputs β raw_logs/ and metrics CSVs. |
docs/ |
β | Documentation β roadmap, experiment reports, Inria hand-offs. |
pip install -r requirements.txtrequirements.txt pulls pydotbot[calibrate], requests, and pygame (the last one is
only used by the Level 0 viewer). The bundled simulation/ engine is added to sys.path
automatically by the scripts β no separate install needed.
Animates PIBT on a small grid and shows, at each step, the priority order, every agent's move, and the priority-inheritance chains. The scenario (grid size, start positions, goals, priorities, obstacles) is edited directly in the file β there are no CLI options.
python sim_pibt.py # launch the interactive viewer
python sim_pibt.py -d # debug mode (hides the pygame support prompt)| Key | Action |
|---|---|
Space |
pause / play |
β |
step forward |
β |
step back |
Q / Esc |
quit |
A minimal non-PIBT example (random-walk coordinator, a template for your own algorithm)
lives in simulation/main.py (python simulation/main.py).
Runs PIBT with no pygame and no hardware, sweeping grid resolution Γ number of robots Γ random seeds, and writes one CSV row per instance plus a breaking-point summary. The arena is fixed at 2000 Γ 2000 mm and the cell size varies: 4Γ4 (500 mm), 5Γ5 (400 mm), 8Γ8 (250 mm).
python sim_many_pibt.py # full sweep, 30 seeds
python sim_many_pibt.py --seeds 5 # quick smoke-test
python sim_many_pibt.py --out my.csv # custom output file| Option | Default | Description |
|---|---|---|
--seeds N |
30 |
Number of seeds per (grid, N) cell |
--out FILE |
l0_results.csv |
Output CSV file |
Drives the DotBot simulator through the controller's REST API. Sends one waypoint per bot per step and waits for all bots to arrive (synchronisation barrier) before the next step. Optimised for the simulator: waypoints are sent in parallel, and the next PIBT step is pre-computed while the bots travel.
python sim_dotbot_pibt.py # synchronised step-by-step run
python sim_dotbot_pibt.py --dry-run # print targets without sending or waiting
python sim_dotbot_pibt.py --steps 40 # cap the number of PIBT steps
python sim_dotbot_pibt.py --map-cells 8 # 8x8 grid (250 mm cells); default is 5x5 (400 mm)
python sim_dotbot_pibt.py --seed 42 # reproducible random goals| Option | Default | Description |
|---|---|---|
--dry-run |
β | Print step-by-step targets without sending or waiting |
--steps N |
30 |
Number of PIBT steps |
--map-cells N |
5 |
Grid resolution NΓN (5 β 400 mm cells, 8 β 250 mm on a 2000Γ2000 map) |
--cell-mm N |
derived | Cell size in mm (overrides --map-cells; default: map_size / --map-cells) |
--threshold N |
100 |
Arrival radius per cell in mm |
--step-timeout S |
8.0 |
Max wait (s) per step |
--settle S |
0.3 |
Pause (s) after arrival per step |
--min-bots N |
2 |
Minimum localised bots required at startup |
--base URL |
http://localhost:8000 |
Controller URL |
--seed N |
random | RNG seed for reproducible goals |
The conservative driver for real DotBots (also works against the simulator). Computes
one PIBT step, sends one waypoint per moved bot, then waits at a synchronisation barrier
that polls the bots' real LH2 positions until all have arrived. A bot that exceeds
--step-timeout is logged and skipped (no deadlock). Same options and defaults as
sim_dotbot_pibt.py.
python real_dotbot_pibt.py # real run
python real_dotbot_pibt.py --dry-run # print targets only
python real_dotbot_pibt.py --threshold 120 --step-timeout 10
python real_dotbot_pibt.py --min-bots 3| Option | Default | Description |
|---|---|---|
--dry-run |
β | Print step-by-step targets without sending or waiting |
--steps N |
30 |
Number of PIBT steps |
--map-cells N |
5 |
Grid resolution NΓN (5 β 400 mm cells, 8 β 250 mm on a 2000Γ2000 map) |
--cell-mm N |
derived | Cell size in mm (overrides --map-cells; default: map_size / --map-cells) |
--threshold N |
100 |
Arrival radius per cell in mm |
--step-timeout S |
8.0 |
Max wait (s) per step; beyond it the bot is logged and skipped |
--settle S |
0.3 |
Pause (s) after arrival per step |
--min-bots N |
2 |
Minimum localised bots required at startup |
--base URL |
http://localhost:8000 |
Controller URL |
--seed N |
random | RNG seed for reproducible goals |
Batch test harness: runs PIBT step-by-step on N real DotBots for M independent trials
and records per-run metrics and a summary under log/ (raw logs in log/raw_logs/).
python real_dotbot_pibt_batch.py --bots 8 # 8 bots, 5 runs (default)
python real_dotbot_pibt_batch.py --bots 4 --runs 10 # 4 bots, 10 runs| Option | Default | Description |
|---|---|---|
--bots N |
8 |
Number of DotBots in the batch |
--runs M |
5 |
Number of independent runs |
dotbot run simulator \
--map-size 2000x2000 \
--simulator-init-state simulator_init_state.toml
simulator_init_state.tomldefines the initial bot positions (10 bots on the centres of a 5Γ5 grid, cell = 400 mm, map = 2000Γ2000 mm). For the 8Γ8 layout usesimulator_init_state_8x8.tomltogether with--map-cells 8. See the pydotbot documentation for an example.
python sim_dotbot_pibt.py
python sim_dotbot_pibt.py --dry-runSee Level 2 for the full hardware bring-up (MQTT broker, gateway, LH2 calibration), then:
python real_dotbot_pibt.py --dry-run --seed 1
python real_dotbot_pibt.py --seed 1 --steps 20cell (gx, gy) β centre mm = (gxΓcell_mm + cell_mm//2, gyΓcell_mm + cell_mm//2)
pos (x, y) mm β cell = (int(x/cell_mm), int(y/cell_mm))
With the default --map-cells 5 and a 2000Γ2000 mm map: cell_mm=400, 5Γ5 grid
(--map-cells 8 gives cell_mm=250, 8Γ8).
sim_dotbot_pibt.py real_dotbot_pibt.py
βββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββ
Simulator only Real hardware AND simulator
Sends waypoints in parallel Sends one waypoint per bot
Pipelines next PIBT step Compute β send β wait (serial)
βββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββ
Both: one waypoint/bot/step, sync barrier on real positions
with a per-step timeout, threshold = 100 mm