Kilted to L-turtle
Moving from ROS 2 Kilted to L-Turtle, a number of stability improvements were added that we will not specifically address here.
Removed Parameter action_server_result_timeout
Removed the parameter action_server_result_timeout from all action servers after resolution within rcl and rclcpp to address early goal removal.
This is not longer required to be set.
Dock Plugin Detector Control
PR #5218 adds on-demand detector control to opennav_docking.
ChargingDock and NonChargingDock now provide pure virtual startDetectionProcess / stopDetectionProcess functions that the docking server invokes around the perception loop.
Custom dock plugins must implement the new hooks (return
trueif nothing extra is required).Simple(Non)ChargingDockgaineddetector_service_name,detector_service_timeout, andsubscribe_toggleparameters so a detector service can be triggered only while detections are needed.See Docking Server for the updated parameter reference and YAML example.
Added Corner Smoothing functionality to route_server
In PR #5226 the ability to stitch two successive edges in route_server with a smooth circular arc has been added. Below is an example of two successive edges forming a corner being smoothed with a radius of one. The red lines are the edges of the route graph and the green line is the resultant path that can be used by a local planner.
New parameters include smooth_corners which enable or disable corner smoothing and smoothing_radius which specifies the radius of the corner to fit to a corner. The tangents of the starting and ending points of the circular arc will match the tangent of the edges that form the corner. In the event that two edges are basically straight, no corner arc is added and regular linear interpolation is done. In addition to that, if the corner arc requires a starting point and ending point that’s longer than the edge lengths, then it will not add a corner arc.
Added NonblockingSequence Control Node
In PR #5325 a new Nav2 specific behavior tree control node has been added. The new behavior tree control node, NonblockingSequence, allows every child node in the sequence to be ticked through even if one of the child node returns RUNNING. This is done to prevent long running child nodes from blocking the sequence.
For additional details regarding the NonblockingSequence please see the Nav2 specific node walkthrough and NonblockingSequence configuration guide.
MPPI Optimal Trajectory Validator Plugin
The MPPI controller now has a plugin, OptimalTrajectoryValidator, which can be used to validate an output trajectory for execution.
This can be used to check for collisions, margin from obstacles, distance from a path, progress being made, etc.
By default, it uses the DefaultOptimalTrajectoryValidator which checks for collisions.
Note that kinematic and dynamic constraints are not required to be checked as the Optimizer ensures these constraints are met.
Added PersistentSequence and PauseResumeController Control Nodes
In PR #5247 two new Nav2 specific behavior tree control nodes have been added.
The PauseResumeController adds services to pause and resume execution of the tree. Related to this, the PersistentSequence control node allows the child index to be exposed to the behavior tree through a bidirectional port. This allows the sequence to be continued on resume where it was paused.
Option to use point_cloud_transport
In PR #5264, option to use point_cloud_transport has been added. This enables transporting PointClouds using compression libraries (such as Draco, Zstd, Zlib, etc.) to reduce network traffic and work around DDS limitations in low-bandwidth environments.
Default value:
"raw"- Usessensor_msgs/msg/PointCloud2with no compression.
Configuration guide
If your sensor already publishes compressed streams (e.g., Seterolabs ZED X Cameras), you can enable this option in the costmap layers that ingest pointcloud sensor streams (i.e. obstacle, voxel) and in the collision monitor as well.
Example costmap layer configuration:
<costmap_layer>:
observation_sources: pointcloud
pointcloud:
data_type: "PointCloud2"
topic: /intel_realsense_r200_depth/points # Change this to your topic
transport_type: "raw" # Change this to your compressed format (zlib, draco, zstd)
Similarly for the collision monitor config:
collision_monitor:
ros__parameters:
observation_sources: ["pointcloud"]
pointcloud:
type: "pointcloud"
topic: /intel_realsense_r200_depth/points # Change this to your topic
transport_type: "raw" # Change this to your compressed format (zlib, draco, zstd)
See transport_type in Collision Monitor Node for more information.
Performance Metrics
Below are measured bandwidth values for different transport types with default parameters:
Transport Type |
Bandwidth (KB) |
|---|---|
raw |
593.63 |
draco |
443.28 |
zstd |
64.33 |
zlib |
121.95 |
Add BehaviorTree SubTrees Support
The BehaviorTree engine now supports SubTrees in different files within directory(s) set through bt_search_directories parameter. This allows you to modularize your behavior trees into smaller components that can be reused across different trees.
The interface now supports passing the behavior tree file or ID as input to the loadBehaviorTree method of the BT action server.
Each behavior tree is now strictly required to have its own unique ID, therefore the need to replace MainTre to a unique ID. For example, in navigate_through_poses_w_replanning_and_recovery.xml
` `MainTree can be replaced with NavigateThroughPosesWReplanningAndRecovery.
Option to have custom window size and poly order in Savitsky-Golay Smoother
In PR #5489, option to have custom window size and polynomial order was added. Previously, the implementation used a fixed window size of 7 and a polynomial order of 3.
Default value:
window_size: 7
poly_order: 3
Vector Objects were Supported for Raster Maps
PR #5479 adds new Vector Object server into nav2_map_server package.
It reads vector objects (polygons and polygonal chains as PolygonObject.msg; and circles as CircleObject.msg) from input parameters, handles them by service calls (AddShapes.srv/GetShapes.srv/RemoveShapes.srv) and finally puts them on output raster OccupancyGrid map.
This map is typically used with costmaps by acting as an input mask for Costmap Filters.
This allows to cover such use-cases as:
adding virtual obstacles on maps, dynamic objects simulation/highlighting, hiding some areas or sticking-out robot parts, sensors noise removal, blacking-out areas on maps, adding keep-out or maximum speed restricted areas on vector basis, synthetic testing purposes, and much more.
To run Vector Object server a new vector_object_server.launch.py launch-file is being supplied.
Navigating with Vector Objects tutorial explains how launch Vector Object server and navigate with vector objects added to raster costmaps.
The information about Vector Object server parameters set-up could be found at Vector Object Server configuration guide.
Toggle collision monitor service and BT plugin
PR #5493 and PR #5532 introduce a new toggle service for the collision monitor. This service allows enabling or disabling all collision monitor polygons while keeping sensor checks within the collision monitor active.
The service is defined using a new interface, Toggle.srv:
bool enable
---
bool success
string message
This interface can be extended in the future if needed.
A corresponding Behavior Tree (BT) plugin was also created to call this service.
The plugin is based on BtServiceNode and provides the following input ports:
service_name: name of the toggle serviceserver_timeout: timeout for service callsenable: boolean flag to enable or disable the collision monitor
An example usage in a Behavior Tree XML file:
<ToggleCollisionMonitor enable="false" service_name="collision_monitor/toggle"/>
Following Server
PR #5565 adds a new Following Server into the opennav_following package.
The Following Server implements a server for following dynamic objects or specific reference frames.
This server allows the robot to follow and maintain a determined distance from a detected object or specific frame, using topic-based detection techniques or coordinate frame tracking.
The information about Following Server parameters set-up could be found at Following Server configuration guide.
The tutorial for the Following Server has been recently updated. For the latest instructions and examples, see Dynamic Object Following.
Option for MPPI to use open loop mode
In PR #5617,add new option to have open loop for MPPI. Now it have 1 more option to use last command velocity for initial state estimation instead of odometry. Useful when using low accelerations or when wheel odometry’s latency (motor response is poor) causes issues in MPPI initial state estimation.
Default value:
open_loop: false
Partial paths from Planner Server
PR #5687 adds support for outputting partial paths when planning through poses with the Planner Server. This is an alternative behavior to the existing all-or-nothing approach, where either a complete path through all poses is returned, or no path at all if any pose cannot be reached due to obstacles. While partial path output will still remain disabled by default, it can be set using the new allow_partial_planning dynamic parameter.
When this feature is used, the result from compute_path_through_poses action server will now indicate the last reached pose from the goals list in last_reached_index field.
Namespace added for primary controller parameters in Rotation Shim Controller
In PR #5654, a namespace was introduced for the primary controller parameters within the Rotation Shim Controller. This change ensures proper handling of dynamic parameter updates by grouping the primary controller’s parameters under its own namespace.
Before
plugin: "nav2_rotation_shim_controller::RotationShimController"
primary_controller: "nav2_regulated_pure_pursuit_controller::RegulatedPurePursuitController"
desired_linear_vel: 1.0
lookahead_dist: 0.6
After
plugin: "nav2_rotation_shim_controller::RotationShimController"
primary_controller:
plugin: "nav2_regulated_pure_pursuit_controller::RegulatedPurePursuitController"
desired_linear_vel: 1.0
lookahead_dist: 0.6
New CostmapSource observation type for Collision Monitor and CollisionDetector
In PR #5642, a new
CostmapSource observation type was added to both Collision Monitor and
Collision Detector, allowing them to subscribe directly to
nav2_msgs/msg/Costmap messages as an observation source. This source should be used with caution.
Options to build with isolated tests
In PR #5516, we added an option to build with isolated tests.
This allows users of rmw_zenoh_cpp to run the tests without needing to start a Zenoh router in a separate terminal.
You can enable this by building with --cmake-args -DUSE_ISOLATED_TESTS=ON.
RoundRobin wrap_around Parameter
PR #5308 adds a new wrap_around parameter to the RoundRobin behavior tree control node.
This parameter controls whether the RoundRobin node wraps around to its first child after the last one fails:
wrap_around=false(default): Node returns FAILURE instead of wrapping to first childwrap_around=true: Node wraps around to the first child and continues round-robin behavior
Breaking Change: The default behavior has changed. Previously, RoundRobin would always wrap around. Now it defaults to wrap_around=false, which means existing behavior trees will use the new non-wrap-around behavior unless explicitly configured.
This change addresses issues where RoundRobin index can become misaligned with RecoveryNode retry counter when used in recovery sequences, ensuring each recovery action is performed once and only once.
<!-- New default behavior (no wrap-around) -->
<RoundRobin wrap_around="false">
<Action_A/>
<Action_B/>
<Action_C/>
</RoundRobin>
<!-- Previous behavior (wrap-around) -->
<RoundRobin wrap_around="true">
<Action_A/>
<Action_B/>
<Action_C/>
</RoundRobin>
For additional details regarding the RoundRobin please see the RoundRobin configuration guide.
Configurable Inscribed Obstacle Cost Value for Costmap Conversion
In PR #5781, a new parameter inscribed_obstacle_cost_value is added to fix the issue where Costmap2DPublisher maps INSCRIBED_INFLATED_OBSTACLE (253) to value 99 in OccupancyGrid, but StaticLayer incorrectly converts it back to 251 instead of 253.
Default value:
inscribed_obstacle_cost_value: 99
Bond Heartbeat Period Default Value Change
In L-turtle, the default value for bond_heartbeat_period parameter has been increased from 0.1 to 0.25 seconds across all Nav2 lifecycle nodes, including the lifecycle manager. This change was implemented to reduce computational overhead and save CPU resources in systems with many nodes.
Migration note: If you have explicitly set bond_heartbeat_period to 0.1 in your configurations, you may want to remove this explicit setting to use the new default, or explicitly set it to 0.25 if you want to be explicit about the value. This value should now also be set in the lifecycle manager node as well.
Performance Impact
The following table shows the performance impact of changing the bond heartbeat period from 0.1s to 0.25s:
Bond Period (s) |
Composed CPU |
Single-Proc. CPU |
|---|---|---|
0.1 |
140% |
13% |
0.2 |
110% |
10% |
0.25 |
100% |
9% |
0.5 |
85% |
8% |
1.0 |
80% |
8% |
Note: This table should be populated with data from issue #5784 comment. Composed CPU is for all Nav2 processes combined.
Centralize Path Handler logic in Controller Server
PR #5446 centralizes path handling logic inside the controller server. Previously, each controller plugin implemented its own version of this logic.
With this change, users can now configure a path handler in the controller server:
PathHandler:
plugin: "nav2_controller::FeasiblePathHandler"
prune_distance: 2.0
enforce_path_inversion: True
enforce_path_rotation: False
inversion_xy_tolerance: 0.2
inversion_yaw_tolerance: 0.4
minimum_rotation_angle: 0.785
reject_unit_path: False
For more details, refer to the Path Handler section in the Controller Server documentation.
This update resolves the issue where Navigate Through Poses could terminate prematurely when passing near intermediate goal poses. We also introduce the following API changes as part of this fix.
GoalChecker
Previously:
virtual bool isGoalReached(
const geometry_msgs::msg::Pose & query_pose,
const geometry_msgs::msg::Pose & goal_pose,
const geometry_msgs::msg::Twist & velocity) = 0;
Now:
virtual bool isGoalReached(
const geometry_msgs::msg::Pose & query_pose,
const geometry_msgs::msg::Pose & goal_pose,
const geometry_msgs::msg::Twist & velocity,
const nav_msgs::msg::Path & transformed_global_plan) = 0;
A new argument is added: the transformed and pruned global plan from the path handler.
Controller Plugins
Previously:
virtual void setPlan(const nav_msgs::msg::Path & path) = 0;
Now:
virtual void newPathReceived(const nav_msgs::msg::Path & raw_global_path) = 0;
This callback should now only perform lightweight tasks (e.g. resetting internal state). The controller will be provided the processed plan during computeVelocityCommands().
Previously:
virtual geometry_msgs::msg::TwistStamped computeVelocityCommands(
const geometry_msgs::msg::PoseStamped & pose,
const geometry_msgs::msg::Twist & velocity,
nav2_core::GoalChecker * goal_checker) = 0;
Now:
virtual geometry_msgs::msg::TwistStamped computeVelocityCommands(
const geometry_msgs::msg::PoseStamped & pose,
const geometry_msgs::msg::Twist & velocity,
nav2_core::GoalChecker * goal_checker,
const nav_msgs::msg::Path & transformed_global_plan,
const geometry_msgs::msg::PoseStamped & global_goal) = 0;
Two new arguments are provided:
the transformed and pruned global plan from the path handler.
The last pose from the global plan.
Moreover, several parameters have also been added to / removed from individual controller plugin configurations as part of centralizing path-handling logic in the controller server.
DWB
Removed parameters
prune_planshorten_transformed_planprune_distanceforward_prune_distancetransform_tolerancepublish_global_planpublish_transformed_plan
Added parameters
path_length_tolerance
MPPI
Removed parameters
transform_toleranceprune_distancemax_robot_pose_search_distenforce_path_inversioninversion_xy_toleranceinversion_yaw_tolerance
