Skip to content
Brobot

Engineering blog

Notes on multi-agent coordination with ROS 2

Yuvraj Gargvanshi2 min readroboticsros2swarm

These are working notes from building and testing multi-agent robotic systems on ROS 2 — the communication patterns, the pain points, and the practices that survived contact with real distributed agents.

What ROS 2 gives you for free

ROS 2's node graph over DDS is a genuinely good starting point for multi-agent work. Three patterns carry most of the load:

  • Publisher/subscriber for state broadcast: each agent publishes pose, status, and intent on namespaced topics; peers subscribe to what they need. Decoupled, asynchronous, and tolerant of agents joining and leaving.
  • Services for explicit requests: "take this task," "yield this airspace." Synchronous, acknowledged, and easy to reason about — at the cost of blocking semantics you must handle carefully.
  • Namespacing to keep a fleet from becoming soup. Every agent runs the same node set under its own namespace; coordination nodes bridge across them.

The subtle early decision is QoS profiles. Reliability, durability, and history settings that work on one machine behave very differently over a real lossy link. Deciding which topics are best-effort (high-rate state) and which must be reliable (task assignment) is a design act, not a config detail.

Where coordination actually gets hard

The middleware moves messages; it does not decide anything. The hard problems live one layer up:

Task allocation. Given n agents and m tasks, who does what? Centralised allocation is simple and a single point of failure. Fully decentralised schemes (market/auction-based approaches, where agents bid on tasks against a shared cost function) degrade more gracefully — an agent that drops out simply stops bidding — but debugging emergent misallocation is its own discipline.

Shared state without shared truth. Each agent has a slightly different, slightly stale picture of the fleet. Designing behaviours that stay safe under disagreement — rather than assuming a consistent global state — is the core mindset shift from single-robot work.

Emergence cuts both ways. Simple local rules produce useful collective behaviour, and also produce failure modes nobody wrote. You do not eliminate emergence; you bound it with invariants (geofences, minimum separation, task timeouts) that hold regardless of what the collective decides.

Containerise everything, immediately

The single most valuable engineering habit in this work: Docker from day one. Multi-agent development multiplies environment problems by n — dependency drift between agents is a bug class you can simply delete by containerising the development and simulation environment.

Reproducible containers mean a coordination bug found in a five-agent simulation can be reproduced exactly, bisected, and turned into a regression test. Without that, distributed debugging is archaeology.

What we are taking into Brobot

For our own coordination stack, these notes reduce to commitments:

  1. Simulation-first, containerised, always reproducible.
  2. Decentralised allocation as the default; central coordination only as an optimisation, never a dependency.
  3. Safety invariants enforced below the coordination layer, so no emergent behaviour can violate them.
  4. QoS treated as system design, reviewed like an API contract.

Fleets are the point of Brobot. This layer is where that either becomes real or does not.