Bridge Interfaces
bridge_node owns a PyBulletFleet simulation core and exposes selected ROS 2
interfaces. It can export a conventional per-robot API, a compact fleet API, or
both. Exported endpoints are independent from how an RMF adapter controls the
simulation.
ROS communication patterns
Choose the public ROS boundary by the client that owns the command loop. The per-robot and fleet paths may be enabled together for debugging, but they are alternative ways for a client to communicate with the same simulation core.
flowchart LR
subgraph clients[External ROS processes]
app1["Robot App 1"]
appn["Robot App N"]
fleet[Fleet application]
end
subgraph bridge[bridge_node]
per_robot[Per-robot handlers]
fleet_api[Fleet ROS API]
end
core[PyBulletFleet simulation core]
app1 <-->|ROS 2 per-robot endpoints| per_robot
appn <-->|ROS 2 per-robot endpoints| per_robot
fleet <-->|ROS 2 fleet endpoints| fleet_api
per_robot <-->|In-process Python| core
fleet_api <-->|In-process Python| core
linkStyle 0,1,2 stroke:#1976d2,stroke-width:3px
linkStyle 3,4 stroke:#616161,stroke-width:2px
Blue links are ROS 2 communication; gray links are in-process Python calls.
The arrows are bidirectional because commands flow toward the simulator while
state, feedback, and diagnostics flow back to the client.
Robot App 1 and Robot App N represent the per-robot pattern: one ROS
namespace and handler set is created for every selected robot.
Boundary |
ROS graph shape |
Typical client |
Choose it when |
|---|---|---|---|
Per-robot API |
One namespace and handler set per selected robot |
Nav2-like Robot App, RViz, manual debugging |
The client expects standard robot topics, services, or actions |
Fleet ROS API ( |
One batched state stream and named command endpoints |
Fleet manager or load-test client |
The client commands or observes many robots together |
per_robot_api.include_robots and exclude_robots limit which Agents receive
per-robot endpoints. The Fleet ROS API currently has simulation-wide Agent scope;
it is not automatically restricted by a manager or the per-robot filters.
Per-robot API
Enable this API when existing tools expect one ROS namespace per robot. A robot can publish odometry, joint state, path, current goal, diagnostics, and TF; it can accept velocity, goal-pose, path, trajectory, and joint commands. It also provides navigation, path-following, trajectory, attach, and generic-action services/actions as appropriate for the enabled interface groups.
Direction |
Topic |
Type |
Description |
|---|---|---|---|
Pub |
|
|
Odometry and |
Pub |
|
|
Joint positions and velocities |
Pub |
|
|
Current planned path |
Pub |
|
|
Active navigation goal |
Pub |
|
|
Robot diagnostics |
Sub |
|
|
Velocity command |
Sub |
|
|
Fire-and-forget navigation goal |
Sub |
|
|
Path to follow |
Sub |
|
|
Joint trajectory command |
Sub |
|
|
Direct joint-position command |
Per-robot action servers are navigate_to_pose, follow_path,
follow_joint_trajectory, and execute_action_blocking; the per-robot
services are toggle_attach and attach_object. The non-blocking generic
action topic is /{robot}/execute_action.
Fleet ROS API
Use the Fleet ROS API (fleet_api) when an external client works on a whole
fleet. It reduces
ROS graph size by replacing repeated per-robot state and command endpoints with
batched endpoints:
Endpoint |
Purpose |
|---|---|
|
One |
|
Batched navigation command, as topic or service |
|
Batched stop command, as topic or service |
|
Batched attach/detach command, as topic or service |
|
Batched generic action command, as topic or service |
|
Batched joint-position command, as topic or service |
Pose-bearing fleet commands include a ROS header. header.frame_id identifies
the command frame (normally odom); header.stamp records the command issue
time. Clients should treat service responses and command acknowledgements as
the command-ingress result, not as proof that every robot has completed motion.
Actor visibility and current scope
An Agent represents any active simulated actor, not only a robot owned by the
ROS/RMF client. This includes mock people, robots owned by another system, and
jointed devices. Today the Fleet ROS API is global: FleetStateProvider publishes
every sim.agents entry in /fleet/states, and FleetCommandDispatcher can
resolve every uniquely named Agent. A separate AgentManager does not alter
that scope.
For per-robot endpoints, use per_robot_api.include_robots or
exclude_robots to avoid creating ROS interfaces for mock actors. If a fleet
state must contain only a controlled fleet, disable the fleet state endpoint or
provide that filtered state through an integration/plugin for now. Selective
fleet-state publication and named Fleet ROS API scopes are planned; see the
roadmap.
Simulation services
The bridge can also expose simulation_interfaces services for spawning,
deleting, querying, moving, stepping, pausing, and resetting entities. These
are useful for test harnesses and scenario tools, but are separate from the
fleet command API.
Dynamic spawning
/sim/spawn_entity creates an Agent from a URDF at runtime. It accepts
the entity name, a URDF uri (including package:// URIs or a known model
name), initial_pose, and allow_renaming. The bridge resolves the URI and
creates the agent with its default dynamic-spawn configuration.
It is intentionally a small interoperability service, not a serialized
AgentSpawnParams API: it cannot set a controller, motion limits, mass,
collision settings, user_data, or arbitrary mesh/shape parameters. It also
does not currently create a passive SimObject, despite the generic
SpawnEntity service name. For a fully configured robot or object, define it
in the bridge YAML scenario (or create it through the Python API) before
starting the simulation.
Scale guidance
Fleet endpoints are the preferred public interface for high robot counts. The latest 1000-robot Docker measurement reached 9.37x real time in fleet mode; per-robot and hybrid modes add substantial ROS interface and bridge overhead. The measurement does not isolate DDS graph cost from message handling, serialization, callbacks, TF, or endpoint handlers. The benchmark also records that per-robot publication latency is not equivalent to end-to-end motion completion. Read the benchmark results and the bridge performance notes before setting production thresholds.
For framework developers, the transport-neutral state and command abstractions behind these endpoints are described in the Fleet API architecture page.