Free Fleet Adapter
The free fleet adapter formerly known as Free Fleet, allows users to integrate standalone mobile robots to form a heterogeneous fleet, to work with Open-RMF.
The free_fleet_adapter
implements the Easy Full Control fleet adapter API, and communicates with individual robots over Zenoh bridges. Out-of-the-box, it supports robots running ROS 1 Navigation as well as ROS 2 Navigation2.
Check out the simulation examples for more information.
Below is the ideal integration architecture of several robots that are running either ROS 2 Navigation2 or ROS 1 Navigation.
With Zenoh bridges, users should be able to integrate their robot as-is, without additional namespacing. The Zenoh bridges are responsible for filtering topics to reduce network traffic, and to namespace the various Zenoh keys, which the free_fleet_adapter
operates on. Handling message definitions across domains have been greatly simplified too, thanks to pycdr2
for ROS 2 messages and rosbags
for ROS 1 messages.
ROS 2 Navigation2
For ROS 2 Navigation2, the integration is enabled by zenoh-bridge-ros2dds. With an appropriately configured bridge running on the robot, the free_fleet_adapter
is able to communicate and control the robot, via its navigation behavior trees.
The Navigation2 integration currently uses the simple navigate_to_pose
behavior to provide navigation commands from point to point following the RMF waypoints defined. Support for utilizing more Navigation2 behaviors or custom behaviors is on the roadmap, but in the meantime, contributions are always welcome!
Below is an example of the robot defined in the fleet configuration file, you can find the file here. Take note of the defined navigation_stack
, this allows the free_fleet_adapter
to pick the Nav2RobotAdapter
for this particular robot.
...
robots:
nav2_tb3:
charger: "tb3_charger"
responsive_wait: False # Should responsive wait be on/off for this specific robot? Overrides the fleet-wide setting.
# For Nav2RobotAdapter
navigation_stack: 2
initial_map: "L1"
maps:
L1:
map_url: "/opt/ros/jazzy/share/nav2_bringup/maps/tb3_sandbox.yaml"
,,,
Below is an example of the Zenoh configuration file used by the zenoh-bridge-ros2dds
on the robot. The Zenoh keys are namespaced by the namespace
parameter, while we are able to filter and rate-limit ROS 2 topics, services, actions to reduce network traffic. With the client
mode, the bridge will seek to connect to a locally available Zenoh router.
{
plugins: {
ros2dds: {
namespace: "/nav2_tb3",
allow: {
publishers: [".*/tf", ".*/battery_state"],
subscribers: [],
service_servers: [],
service_clients: [],
action_servers: [".*/navigate_to_pose"],
action_clients: [],
},
pub_max_frequencies: [".*/navigate_to_pose/*=1", ".*/battery_state=1"],
},
},
// Zenoh related configurations
mode: "client",
connect: {
endpoints: []
},
listen: {
endpoints: []
},
}
Check out our integration test setup to get a better idea on how this integration can be deployed.
ROS 1 Navigation Stack
The ROS 1 Navigation integration has only been tested in simulation and in ROS 1 Noetic, and is currently still using a fork of zenoh-plugin-ros1, to support bridge namespacing. This will be updated after contributions to upstream has been made.
For ROS 1 Navigation, the integration is enabled by zenoh-bridge-ros1. Similarly, with an appropriately configured bridge running on the robot, the free_fleet_adapter
is able to communicate and control the robot, via the move_base
topics.
Below is an example of the robot defined in the fleet configuration file, you can find the file here. Take note of the defined navigation_stack
, this allows the free_fleet_adapter
to pick the Nav1RobotAdapter
for this particular robot.
...
robots:
nav1_tb3:
charger: "tb3_charger"
responsive_wait: False # Should responsive wait be on/off for this specific robot? Overrides the fleet-wide setting.
# For Nav1RobotAdapter
navigation_stack: 1
initial_map: "L1"
maps:
L1:
# The nav1 robot will generally no access to this nav2_bringup package, this should point to where the nav1 map is stored.
map_url: "/tmp/navigation2/nav2_bringup/maps/tb3_sandbox.yaml"
,,,
Below is an example of the Zenoh configuration file used by the zenoh-bridge-ros1
on the robot. The Zenoh keys are namespaced by the bridge_namespace
parameter, while we are able to filter ROS 1 topics and services to reduce network traffic. With the client
mode, the bridge will seek to connect to a locally available Zenoh router.
{
plugins: {
ros1: {
bridge_namespace: "nav1_tb3",
subscriber_bridging_mode: "disabled",
publisher_bridging_mode: "disabled",
service_bridging_mode: "disabled",
client_bridging_mode: "disabled",
// Zenoh -> ROS 1
subscriber_topic_custom_bridging_mode: {
"/move_base_simple/goal": "auto",
"/move_base/cancel": "auto",
},
// ROS 1 -> Zenoh
publisher_topic_custom_bridging_mode: {
"/tf": "auto",
"/battery_state": "auto",
"/move_base/status": "auto"
},
},
},
// Zenoh related configurations
mode: "client",
connect: {
endpoints: []
},
listen: {
endpoints: []
},
}
Check out our integration test setup to get a better idea on how this integration can be deployed.
Custom Navigation Stack
Users looking to integrate their own custom navigation stack, can implement the abstract interfaces in RobotAdapter
here.
The implementation will need a name, for the free_fleet_adapter
to correctly allocate adapters to each connected robot. This name is configured in the robot's configuration in the fleet configuration file. For example, Navigation2 is just 2
, while ROS 1 Navigation is 1
.
Contributions are always welcome!