From b0abc78ace48d21ca5b8b58afb0482d759733cb0 Mon Sep 17 00:00:00 2001 From: Steve Macenski Date: Wed, 29 May 2024 11:06:50 -0700 Subject: [PATCH] adding mutex lock around map resizing due to dynamic parameter changes and associated processes (#4373) --- nav2_costmap_2d/include/nav2_costmap_2d/costmap_2d_ros.hpp | 1 + nav2_costmap_2d/src/costmap_2d_ros.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/nav2_costmap_2d/include/nav2_costmap_2d/costmap_2d_ros.hpp b/nav2_costmap_2d/include/nav2_costmap_2d/costmap_2d_ros.hpp index 69f2cfefa1..7f95dec1bb 100644 --- a/nav2_costmap_2d/include/nav2_costmap_2d/costmap_2d_ros.hpp +++ b/nav2_costmap_2d/include/nav2_costmap_2d/costmap_2d_ros.hpp @@ -371,6 +371,7 @@ class Costmap2DROS : public nav2_util::LifecycleNode std::atomic stop_updates_{false}; std::atomic initialized_{false}; std::atomic stopped_{true}; + std::mutex _dynamic_parameter_mutex; std::unique_ptr map_update_thread_; ///< @brief A thread for updating the map rclcpp::Time last_publish_{0, 0, RCL_ROS_TIME}; rclcpp::Duration publish_cycle_{1, 0}; diff --git a/nav2_costmap_2d/src/costmap_2d_ros.cpp b/nav2_costmap_2d/src/costmap_2d_ros.cpp index 104aae7fe2..b039a8554f 100644 --- a/nav2_costmap_2d/src/costmap_2d_ros.cpp +++ b/nav2_costmap_2d/src/costmap_2d_ros.cpp @@ -511,6 +511,9 @@ Costmap2DROS::mapUpdateLoop(double frequency) // Execute after start() will complete plugins activation if (!stopped_) { + // Lock while modifying layered costmap and publishing values + std::scoped_lock lock(_dynamic_parameter_mutex); + // Measure the execution time of the updateMap method timer.start(); updateMap(); @@ -711,6 +714,7 @@ Costmap2DROS::dynamicParametersCallback(std::vector parameter { auto result = rcl_interfaces::msg::SetParametersResult(); bool resize_map = false; + std::lock_guard lock_reinit(_dynamic_parameter_mutex); for (auto parameter : parameters) { const auto & type = parameter.get_type(); @@ -806,6 +810,7 @@ Costmap2DROS::dynamicParametersCallback(std::vector parameter layered_costmap_->resizeMap( (unsigned int)(map_width_meters_ / resolution_), (unsigned int)(map_height_meters_ / resolution_), resolution_, origin_x_, origin_y_); + updateMap(); } result.successful = true;