Skip to content

dotbot/swarm: add the Swarm API with demos and collision avoidance#276

Open
geonnave wants to merge 44 commits into
DotBots:developfrom
geonnave:sdk-charging-station
Open

dotbot/swarm: add the Swarm API with demos and collision avoidance#276
geonnave wants to merge 44 commits into
DotBots:developfrom
geonnave:sdk-charging-station

Conversation

@geonnave

@geonnave geonnave commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Adds the Python Swarm API (from dotbot.swarm import Swarm): a live fleet object over a running controller (REST + ws/status), per-bot verbs (set_color, goto, move_to, follow), fleet handles, events, link-budget pacing of all downlink sends, and swarm.map_size(). Ships a dotbot/examples/sdk_demo/ suite (LED + motion demos) meant to run unchanged in the simulator and on the testbed.

The centerpiece is collision avoidance. Motion demos used to command straight lines through occupied space; real robots collide. The SDK now offers it at two levels:

  • Swarm.connect/run(..., collision_avoidance=True) (or the --collision-avoidance flag injected by Swarm.run): every motion command is shepherded through buffered Voronoi cells (Zhou et al., RA-L 2017) - each bot only ever steps inside the region closer to it than to any neighbour, shrunk by a safety buffer, plus arena-wall planes. Needs positions only (the 2 Hz LH2 feed; no velocity estimates), emits exactly one waypoint per bot per tick, paced to the gateway downlink budget. Separation is the guarantee; arrival stays best-effort (TimeoutError surfaces blocked goals). stop()/move_raw() bypass it.
  • dotbot.swarm.avoid exposes the pure geometry (bvc_waypoint, safe_hop) for custom control loops.

The shepherd is grounded in firmware behavior: DotBots arc while turning (never pivot), a waypoint within the threshold is "already reached" and moves nothing, positions glitch, and a gateway sustains ~80 cmd/s. Hence the heading-aware yield/short-bite turning rules, the scaled hop thresholds with a 60 mm floor, the LH2 glitch gate in Bot, and the contact guard that stops a bot pinned against a neighbour instead of letting it grind.

Also fixes a controller crash seen with ~50 real bots: concurrent notify_clients tasks writing the same websocket trip an AssertionError deep in the websockets protocol; sends are now serialized per connection and a failing client is dropped instead of killing the controller.

Validated in the simulator with a collision monitor that interpolates between position samples (zero collisions across all motion demos, including an all-cross swap benchmark with naive user code), plus short metric runs on the real ~56-bot fleet that drove the tolerance work. 427 unit tests pass, including the BVC geometry and position-gating suites.

Note: the package was renamed from dotbot/sdk/ to dotbot/swarm/ within this PR - "SDK" names the whole pydotbot package in the docs branding, so a dotbot.sdk subpackage was redundant. dotbot swarm (CLI, fleet ops) and Swarm (Python, fleet control) intentionally share the noun: one fleet, two rungs; dotbot swarm --help now points at the Python rung.

geonnave added 30 commits June 5, 2026 19:49
Cancelling pending command tasks on shutdown dropped a final
fire-and-forget command (e.g. a closing stop()), leaving a bot driving
on its last move_raw. Draining them with a timeout lets the stop land.

AI-assisted: Claude Opus 4.8
Two latent bugs surfaced by `--bots`, which generates low
leading-zero addresses and leaves direction unset. Frame routing
used hex(addr)[2:], dropping leading zeros, so such a bot never
matched its own command/uplink frames and ignored waypoints. And
the unset-direction sentinel (-1000) reached the control loop as a
bogus heading; it now maps to 0 like theta.

AI-assisted: Claude Opus 4.8
AI-assisted: Claude Opus 4.8
@codecov

codecov Bot commented Jun 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 39.01720% with 1241 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.66%. Comparing base (6f11e9c) to head (9df0f42).
⚠️ Report is 24 commits behind head on develop.

Files with missing lines Patch % Lines
dotbot/swarm/swarm.py 38.46% 120 Missing ⚠️
dotbot/swarm/_shepherd.py 20.00% 92 Missing ⚠️
dotbot/examples/sdk_demo/_lib.py 23.36% 82 Missing ⚠️
.../examples/charging_station/charging_station_sdk.py 25.92% 80 Missing ⚠️
...ot/examples/work_and_charge/work_and_charge_sdk.py 24.46% 71 Missing ⚠️
dotbot/patterns.py 16.04% 68 Missing ⚠️
dotbot/examples/sdk_demo/distribute.py 17.50% 66 Missing ⚠️
dotbot/swarm/_backend.py 29.03% 66 Missing ⚠️
dotbot/swarm/bot.py 53.38% 62 Missing ⚠️
...naming_game/minimum_naming_game_with_motion_sdk.py 24.67% 58 Missing ⚠️
... and 26 more
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop     #276      +/-   ##
===========================================
- Coverage    83.27%   76.66%   -6.62%     
===========================================
  Files          119      158      +39     
  Lines        11120    13252    +2132     
  Branches       570      569       -1     
===========================================
+ Hits          9260    10159     +899     
- Misses        1857     3089    +1232     
- Partials         3        4       +1     
Files with missing lines Coverage Δ
dotbot/adapter.py 76.74% <100.00%> (+0.55%) ⬆️
dotbot/cli/swarm.py 50.00% <100.00%> (-16.67%) ⬇️
dotbot/controller_app.py 97.00% <100.00%> (+0.09%) ⬆️
dotbot/events.py 100.00% <100.00%> (ø)
dotbot/server.py 94.85% <100.00%> (+0.03%) ⬆️
dotbot/swarm/__init__.py 100.00% <100.00%> (ø)
dotbot/swarm/events.py 100.00% <100.00%> (ø)
dotbot/tests/test_swarm_avoid.py 100.00% <100.00%> (ø)
dotbot/rest.py 77.46% <42.85%> (-1.11%) ⬇️
dotbot/swarm/action.py 63.63% <63.63%> (ø)
... and 34 more

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

geonnave added 5 commits June 11, 2026 12:11
The whole pydotbot package is branded the DotBot SDK, so an sdk
subpackage inside it was redundant. swarm names the thing the API
drives and deliberately pairs with the dotbot swarm CLI namespace:
one fleet, operated from the CLI, driven from Python.

AI-assisted: Claude Fable 5
@geonnave geonnave changed the title dotbot/sdk: add the Swarm SDK with demos and collision avoidance dotbot/swarm: add the Swarm SDK with demos and collision avoidance Jun 12, 2026
@geonnave geonnave changed the title dotbot/swarm: add the Swarm SDK with demos and collision avoidance dotbot/swarm: add the Swarm API with demos and collision avoidance Jun 12, 2026
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