Skip to content

feat(coordinator): add Swarm (PIBT+LNS+BVC) planner and more#8

Open
BrokenHypocrite wants to merge 1 commit into
DDeGonge:mainfrom
BrokenHypocrite:feature/swarm-planner
Open

feat(coordinator): add Swarm (PIBT+LNS+BVC) planner and more#8
BrokenHypocrite wants to merge 1 commit into
DDeGonge:mainfrom
BrokenHypocrite:feature/swarm-planner

Conversation

@BrokenHypocrite

Copy link
Copy Markdown

Swarm planner, trajectory playback, and Play Chess mode

Adds a complete, collision-free multi-robot planner to the coordinator, plus the
features to use it. All additive: existing planners and the wave-dispatch flow are
unchanged unless the new options are selected.

1. Swarm planner (planning/swarm/, planning/swarm_planner.py)

New planner registered as "Swarm (PIBT+LNS)". Self-contained (standard library
plus planning.base_planner and config only).

  • PIBT (priority inheritance with backtracking) plans the choreography on an
    8-connected cell grid. Complete by construction: where EnhancedConflictPlanner
    gets stuck, PIBT makes boxed-in pieces step aside and flow back.
  • MAPF-LNS refines the plan for lower total travel (fewer and shorter moves).
  • Buffered Voronoi Cells execute it as continuous, collision-free motion.
  • plan_moves() forward-simulates the whole pipeline and returns each piece's
    actual sampled trajectory as wave-ordered MoveCommands, so the open-loop robots
    replay a provably collision-free path.
  • Optimal interchangeable-piece assignment (any pawn to any pawn square, etc.) and
    in-bounds waypoint clamping.

2. Smooth trajectory playback (simulation/simulator.py)

  • New play_trajectory() advances all pieces in lockstep along the synchronized
    trajectory (continuous, arc-like, collision-free), then rotates each to its
    commanded final heading.
  • Used automatically for planners that set produces_trajectory (added to
    base_planner.py). The existing rotate/translate wave dispatch is untouched for
    the discrete planners.
  • Wiring in main_window.py and path_planning_tab.py routes trajectory planners
    to the player in simulator mode.

3. Play Chess mode (gui/tabs/play_chess_tab.py, gui/chessboard_widget.py)

New tab. Rules via python-chess.

  • Click a piece to highlight its legal destination squares.
  • Click a legal square to execute the move with the selected planner: captures go
    to the graveyard, castling moves the king and rook, en passant clears the
    bypassed pawn, and promotion auto-queens via the spare queen.
  • Turn indicator, SAN move list, check/checkmate/stalemate.
  • Hot-seat (no engine opponent).

4. Board size set to 57.15 mm / 2.25 in (config.py)

Changed BOARD.SQUARE_SIZE_MM from 50 to 57.15 mm for two reasons:

  • Standard FIDE/USCF tournament square.
  • Clearance for the motion planner. A MiniBot is about 31 mm across, so at 50 mm
    the gap between pieces on adjacent squares is only about 19 mm and the
    buffered-Voronoi routing deadlocks or detours often. At 57.15 mm (about a 26 mm
    gap) dense resets stay collision-free and efficient.

All piece coordinates derive from SQUARE_SIZE_MM, so they scale together. The
rationale is documented in config.py and planning/swarm/README.md.

Dependencies

Adds python-chess (see requirements.txt, alongside pyqt6 and pyserial).

Tests

Headless self-tests, run from firmware/MiniBot_Coordinator/:

  • python planning/swarm/_selftest.py: plan solved, wave-ordered, collision-free.
  • python planning/swarm/_selftest_playback.py: playback completes, stays
    collision-free through interpolation, motion continuous, headings reached.
  • python gui/tabs/_selftest_chess.py: normal, capture, castle, en passant, and
    promotion produce correct targets and dispatch through the planner.

Limitations

  • Promotion auto-queens via one spare queen per side (no underpromotion UI; a
    second same-side promotion logs a message and keeps the logical board correct).
  • Play Chess "New Game" snaps to the start (it does not animate the reset).
  • Real-hardware (serial) mode still sends discrete position commands; the smooth
    player is a simulator-playback feature.

…y playback, and Play Chess mode

A complete, collision-free multi-robot planner plus the coordinator features to use it. Additive: existing planners and the wave-dispatch flow are unchanged when these are not selected.

Swarm planner (planning/swarm/, swarm_planner.py, base_planner.produces_trajectory): self-contained PIBT (priority inheritance + backtracking) + MAPF-LNS flowtime refinement + Buffered Voronoi Cell execution. Complete by construction where EnhancedConflictPlanner can get stuck. Registered as 'Swarm (PIBT+LNS)'. plan_moves forward-simulates the pipeline and emits each piece's collision-free sampled trajectory as wave-ordered MoveCommands, with optimal interchangeable-piece assignment and in-bounds waypoint clamping.

Smooth trajectory playback (simulation/simulator.py + main_window/path_planning wiring): play_trajectory() advances all pieces in lockstep along the synchronized trajectory (continuous, arc-like, collision-free) then rotates each to its commanded heading. Used automatically for trajectory planners; the discrete wave dispatch is untouched for the others.

Play Chess mode (gui/tabs/play_chess_tab.py + chessboard_widget.py): a tab where you click a piece to see legal moves (via python-chess) and click a legal square to move it with the selected planner - captures to graveyard, castling, en passant, and auto-queen promotion via the spare queen. Hot-seat.

Board size set to 57.15 mm (2.25 in tournament square): standard sizing, and the clearance the buffered-Voronoi motion needs between ~31 mm pieces to stay collision-free and efficient (see planning/swarm/README.md and config.BOARD). Adds python-chess dependency (requirements.txt). Self-tests: planning/swarm/_selftest*.py, gui/tabs/_selftest_chess.py.
@BrokenHypocrite

BrokenHypocrite commented Jul 2, 2026

Copy link
Copy Markdown
Author

This PR mostly just adds an additional path planning algorithm and a way to test it in a Play Chess mode. The one thing I did change is the board's cell size, from 50mm to 57.15mm. There is a massive difference in how easily the planner can route pieces with this change and 2.25in (57.15mm) is a nice size imo since it is tournament size. There is still more improvements that can be made to this planner but I believe it is a good starting point. If you have any questions you can reach me at brokenhypocrite@gmail.com or on discord, username: brokenhypocrite

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