pycoordination — a Python port of coordination_oru
Hi all,
I’d like to introduce pycoordination, a Python port of
coordination_oru, the
multi-robot trajectory-envelope coordinator from Pecora et al., “A
loosely-coupled approach for multi-robot coordination, motion planning and
control”, ICAPS 2018.
Documentation (getting started, a theory-to-implementation walkthrough of the
paper, and API reference): https://pycoordination.pages.dev/
What it does
If you haven’t come across the original: coordination_oru coordinates any
number of robots sharing a workspace without discretizing the map and
without a central motion planner (i.e., without MAPF). Each robot follows its own path, planned
by whatever planner you like; the coordinator reasons over trajectory
envelopes (sweeps of the robot’s footprint around each path), finds critical
sections where envelopes overlap, and imposes precedence constraints online
so that exactly one robot commits to traversing across each contested region at a time. The
crucial properties of the original are all preserved in this port:
- Loose coupling — coordination is independent of motion planning and
control. Paths can come from any planner; robot dynamics enter only through
a forward model. - Online, continuous coordination — precedences are revised at every
control period as robots progress, using pluggable heuristics. - Deadlock handling — deadlocks are detected and resolved by replanning.
- Simulation included — RK4-integrated simulated robots, a built-in
Hybrid A* / Reeds-Shepp planner over ROS-style occupancy maps, and six
runnable example scenarios (including the original repo’s recorded paths).
New in the port: a browser-based live viewer (swept envelopes, critical-section
highlights, click-and-drag goal posting) alongside a pyglet viewer, an
asyncio-based concurrency model in place of Java threads, and packaging for
plain pip install. The Java stack (JTS, JGraphT, meta-csp) maps onto
shapely 2 / GEOS, networkx, and a small custom STP layer — the docs include a
table of exactly what was replaced with what, and line-by-line listings of
Algorithms 1 and 2 from the paper cross-referenced to the code. Like the
original, it’s GPL-3.0.
The ROS layer of the original Java project is out of scope for now — this is
the coordinator itself, usable from any Python stack (and a natural fit for a
future ROS 2 wrapper, which I’d be happy to discuss here).
Try it
pip install coordination-oru
coordination-oru-demo
One command: your browser opens with three robots on an occupancy-grid map,
and it’s interactive — click a robot, then press-drag-release anywhere on
the map to post a goal pose (RViz “2D Nav Goal” style). The built-in
Hybrid A* planner plans the path and the coordinator handles any conflicts
with the other robots’ missions, live. Re-task a driving robot and it brakes,
comes to rest, and replans to the new goal from wherever it stopped. The
repo’s examples/ folder has five more scenarios (intersections, convoys,
the original Java repo’s recorded paths), each runnable with --web-viewer,
--pyglet, or --headless.
Acknowledgement
None of this would exist without Federico Pecora, who created
coordination_oru and the research behind it at Örebro University (he is now
at ARM). The elegance of the original design is what made
a faithful port possible at all.
A note on how it was built — with AI, carefully
I want to be upfront about this: this port was crafted with AI assistance
(Claude Code), and it was not a one-prompt “translate this repo” job.
It was a slow, deliberate, human-directed effort: the Java original and the
ICAPS paper were used as the specification, the port was built module by
module, behavior was cross-checked against the original implementation
(including replaying the original repo’s recorded .path scenarios), and the
result carries a test suite and documentation that traces the paper’s
algorithms line-by-line into the code. AI did the typing; the reading,
verifying, and re-doing took many iterations and a lot of human judgment.
I think this is a realistic picture of what
AI-assisted porting of a non-trivial research codebase actually looks like,
and I’m glad to answer questions about the process as well as the software.
Feedback, issues, and PRs are very welcome.