|
EasyFleet
A simple-by-default framework for multi-robot, multi-capability fleets built on ROS 2
|
Fleet-wide navigation manager. More...
#include <navigation_manager_node.hpp>
Public Member Functions | |
| NavigationManagerNode (const rclcpp::NodeOptions &options=rclcpp::NodeOptions()) | |
| Declares parameters, builds the configured MapPublisherBase, publishes both the map and the routes once, sets up the robot set (static list, or dynamic capability tracking), and starts the conflict-monitoring timer. | |
| std::vector< std::string > | get_watched_robots () const |
| Robots currently being watched (for testing and tools). | |
Fleet-wide navigation manager.
Publishes one shared map on /global_map and one shared route set on /global_routes at construction, so every robot's own EasyNav instance can be pointed at the same data (by remapping its own "incoming_map"/"incoming_routes" topics) instead of each robot loading its own local copy. Both publishers use transient_local durability, so a robot that starts (and subscribes) after this node already published still receives the retained last message – no periodic re-publish timer is needed, but the process must keep running (spinning) for that durability guarantee to hold, since it's tied to the publisher's lifetime, not persisted to disk.
Also continuously monitors every robot's planned navigation path (one RobotNavigationWatcher per robot, all sharing this node – see that class'es own doc comment for why no extra rclcpp::Node/executor/thread is used) and pauses/resumes robots when compute_robots_to_pause() (see conflict_detector.hpp) detects an imminent conflict.
The robot set being watched can also change over time: unless robots.static_list is set, this node subscribes to /capabilities_status (see easyfleet_interfaces/CapabilityStatus – "its presence, not its content, is the alive signal") and, on reconcile_watchers()'s own timer, adds a RobotNavigationWatcher for any newly-heard-from robot and drops the watcher for any robot whose heartbeat has gone stale for longer than robots.staleness_sec. This – like the conflict-check below – is plain subscription callbacks plus a periodic timer on this one node; no extra rclcpp::Node, executor, or thread is created anywhere in this class.
Every robot's own EasyNav instance applies its tf_prefix to its local "map" frame (see RTTFBuffer::set_tf_info() in easynav_common), so e.g. robot_1's own map frame is literally "robot_1/map" – while /global_map and /global_routes (published above) are both stamped with the plain, unprefixed "map" frame. For the two to actually line up in one TF tree, this node also broadcasts one static, identity transform "map" -> "<robot_id>/map" per watched robot (via publish_robot_map_tf(), on /tf_static through a single tf2_ros::StaticTransformBroadcaster) as soon as that robot starts being watched – every robot in this fleet is assumed to share the exact same map, only their pose within it differs, so identity is the correct transform (see e.g. GpsLocalizer's own identical map->odom identity broadcast for the same kind of "these two frames are just aliases of each other" case).
ROS parameters:
|
explicit |
Declares parameters, builds the configured MapPublisherBase, publishes both the map and the routes once, sets up the robot set (static list, or dynamic capability tracking), and starts the conflict-monitoring timer.
| options | Standard rclcpp node options. |