Nav2 Navigation Stack - rolling  main
ROS 2 Navigation Stack
parameter_handler.cpp
1 // Copyright (c) 2022 Samsung Research America
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <algorithm>
16 #include <string>
17 #include <limits>
18 #include <memory>
19 #include <vector>
20 #include <utility>
21 
22 #include "nav2_controller/parameter_handler.hpp"
23 
24 namespace nav2_controller
25 {
26 
27 using nav2::declare_parameter_if_not_declared;
28 using rcl_interfaces::msg::ParameterType;
29 
31  const nav2::LifecycleNode::SharedPtr & node,
32  const rclcpp::Logger & logger)
33 : nav2_util::ParameterHandler<Parameters>(node, logger)
34 {
35  params_.controller_frequency = node->declare_or_get_parameter("controller_frequency", 20.0);
36  params_.min_x_velocity_threshold = node->declare_or_get_parameter("min_x_velocity_threshold",
37  0.0001);
38  params_.min_y_velocity_threshold = node->declare_or_get_parameter("min_y_velocity_threshold",
39  0.0001);
40  params_.min_theta_velocity_threshold =
41  node->declare_or_get_parameter("min_theta_velocity_threshold", 0.0001);
42  params_.speed_limit_topic = node->declare_or_get_parameter("speed_limit_topic",
43  std::string("speed_limit"));
44  params_.failure_tolerance = node->declare_or_get_parameter("failure_tolerance", 0.0);
45  params_.use_realtime_priority = node->declare_or_get_parameter("use_realtime_priority", false);
46  params_.publish_zero_velocity = node->declare_or_get_parameter("publish_zero_velocity", true);
47  double costmap_update_timeout_dbl = node->declare_or_get_parameter("costmap_update_timeout",
48  0.30);
49  params_.costmap_update_timeout = rclcpp::Duration::from_seconds(costmap_update_timeout_dbl);
50  params_.transform_staleness_threshold =
51  node->declare_or_get_parameter("transform_staleness_threshold", 0.0);
52  params_.odom_topic = node->declare_or_get_parameter("odom_topic", std::string("odom"));
53  params_.odom_duration = node->declare_or_get_parameter("odom_duration", 0.3);
54  params_.search_window = node->declare_or_get_parameter("search_window", 2.0);
55 
56  RCLCPP_INFO(
57  logger_,
58  "Controller frequency set to %.4fHz",
59  params_.controller_frequency);
60 
61  RCLCPP_INFO(logger_, "getting progress checker plugins..");
62  params_.progress_checker_ids = node->declare_or_get_parameter("progress_checker_plugins",
63  default_progress_checker_ids_);
64  if (params_.progress_checker_ids == default_progress_checker_ids_) {
65  for (size_t i = 0; i < default_progress_checker_ids_.size(); ++i) {
66  nav2::declare_parameter_if_not_declared(
67  node, default_progress_checker_ids_[i] + ".plugin",
68  rclcpp::ParameterValue(default_progress_checker_types_[i]));
69  }
70  }
71 
72  RCLCPP_INFO(logger_, "getting goal checker plugins..");
73  params_.goal_checker_ids = node->declare_or_get_parameter("goal_checker_plugins",
74  default_goal_checker_ids_);
75  if (params_.goal_checker_ids == default_goal_checker_ids_) {
76  for (size_t i = 0; i < default_goal_checker_ids_.size(); ++i) {
77  nav2::declare_parameter_if_not_declared(
78  node, default_goal_checker_ids_[i] + ".plugin",
79  rclcpp::ParameterValue(default_goal_checker_types_[i]));
80  }
81  }
82 
83  RCLCPP_INFO(logger_, "getting controller plugins..");
84  params_.controller_ids = node->declare_or_get_parameter("controller_plugins",
85  default_controller_ids_);
86  if (params_.controller_ids == default_controller_ids_) {
87  for (size_t i = 0; i < default_controller_ids_.size(); ++i) {
88  nav2::declare_parameter_if_not_declared(
89  node, default_controller_ids_[i] + ".plugin",
90  rclcpp::ParameterValue(default_controller_types_[i]));
91  }
92  }
93 
94  RCLCPP_INFO(logger_, "getting path handler plugins..");
95  params_.path_handler_ids = node->declare_or_get_parameter("path_handler_plugins",
96  default_path_handler_ids_);
97  if (params_.path_handler_ids == default_path_handler_ids_) {
98  for (size_t i = 0; i < default_path_handler_ids_.size(); ++i) {
99  nav2::declare_parameter_if_not_declared(
100  node, default_path_handler_ids_[i] + ".plugin",
101  rclcpp::ParameterValue(default_path_handler_types_[i]));
102  }
103  }
104 
105  params_.controller_types.resize(params_.controller_ids.size());
106  params_.goal_checker_types.resize(params_.goal_checker_ids.size());
107  params_.progress_checker_types.resize(params_.progress_checker_ids.size());
108  params_.path_handler_types.resize(params_.path_handler_ids.size());
109 
110  for (size_t i = 0; i != params_.progress_checker_ids.size(); i++) {
111  try {
112  params_.progress_checker_types[i] = nav2::get_plugin_type_param(
113  node, params_.progress_checker_ids[i]);
114  } catch (const std::exception & ex) {
115  throw std::runtime_error(
116  std::string("Failed to get type for progress_checker '") +
117  params_.progress_checker_ids[i] + "': " + ex.what());
118  }
119  }
120 
121  for (size_t i = 0; i != params_.goal_checker_ids.size(); i++) {
122  try {
123  params_.goal_checker_types[i] =
124  nav2::get_plugin_type_param(node, params_.goal_checker_ids[i]);
125  } catch (const std::exception & ex) {
126  throw std::runtime_error(
127  std::string("Failed to get type for goal_checker '") +
128  params_.goal_checker_ids[i] + "': " + ex.what());
129  }
130  }
131 
132  for (size_t i = 0; i != params_.controller_ids.size(); i++) {
133  try {
134  params_.controller_types[i] = nav2::get_plugin_type_param(node, params_.controller_ids[i]);
135  } catch (const std::exception & ex) {
136  throw std::runtime_error(
137  std::string("Failed to get type for controller plugins '") +
138  params_.controller_types[i] + "': " + ex.what());
139  }
140  }
141 
142  for (size_t i = 0; i != params_.path_handler_ids.size(); i++) {
143  try {
144  params_.path_handler_types[i] = nav2::get_plugin_type_param(node,
145  params_.path_handler_ids[i]);
146  } catch (const std::exception & ex) {
147  throw std::runtime_error(
148  std::string("Failed to get type for path handler plugins '") +
149  params_.path_handler_types[i] + "': " + ex.what());
150  }
151  }
152 }
153 
154 rcl_interfaces::msg::SetParametersResult ParameterHandler::validateParameterUpdatesCallback(
155  const std::vector<rclcpp::Parameter> & parameters)
156 {
157  rcl_interfaces::msg::SetParametersResult result;
158  result.successful = true;
159  for (const auto & parameter : parameters) {
160  const auto & param_type = parameter.get_type();
161  const auto & param_name = parameter.get_name();
162  // If we are trying to change the parameter of a plugin we can just skip it at this point
163  // as they handle parameter changes themselves and don't need to lock the mutex
164  if (param_name.find('.') != std::string::npos) {
165  continue;
166  }
167  if (param_type == ParameterType::PARAMETER_DOUBLE) {
168  if (parameter.as_double() < 0.0 && param_name != "failure_tolerance") {
169  RCLCPP_WARN(
170  logger_, "The value of parameter '%s' is incorrectly set to %f, "
171  "it should be >=0. Ignoring parameter update.",
172  param_name.c_str(), parameter.as_double());
173  result.successful = false;
174  }
175  }
176  }
177  return result;
178 }
179 
180 void
182  const std::vector<rclcpp::Parameter> & parameters)
183 {
184  for (const auto & parameter : parameters) {
185  const auto & param_type = parameter.get_type();
186  const auto & param_name = parameter.get_name();
187 
188  // If we are trying to change the parameter of a plugin we can just skip it at this point
189  // as they handle parameter changes themselves and don't need to lock the mutex
190  if (param_name.find('.') != std::string::npos) {
191  continue;
192  }
193 
194  if (!mutex_.try_lock()) {
195  RCLCPP_WARN(
196  logger_,
197  "Unable to dynamically change Parameters while the controller is currently running");
198  return;
199  }
200 
201  if (param_type == ParameterType::PARAMETER_DOUBLE) {
202  if (param_name == "min_x_velocity_threshold") {
203  params_.min_x_velocity_threshold = parameter.as_double();
204  } else if (param_name == "min_y_velocity_threshold") {
205  params_.min_y_velocity_threshold = parameter.as_double();
206  } else if (param_name == "min_theta_velocity_threshold") {
207  params_.min_theta_velocity_threshold = parameter.as_double();
208  } else if (param_name == "failure_tolerance") {
209  params_.failure_tolerance = parameter.as_double();
210  } else if (param_name == "search_window") {
211  params_.search_window = parameter.as_double();
212  } else if (param_name == "transform_staleness_threshold") {
213  params_.transform_staleness_threshold = parameter.as_double();
214  }
215  }
216  mutex_.unlock();
217  }
218 }
219 
220 } // namespace nav2_controller
Handles parameters and dynamic parameters for Controller Server.
rcl_interfaces::msg::SetParametersResult validateParameterUpdatesCallback(const std::vector< rclcpp::Parameter > &parameters) override
Validate incoming parameter updates before applying them. This callback is triggered when one or more...
void updateParametersCallback(const std::vector< rclcpp::Parameter > &parameters) override
Apply parameter updates after validation This callback is executed when parameters have been successf...
ParameterHandler(const nav2::LifecycleNode::SharedPtr &node, const rclcpp::Logger &logger)
Constructor for nav2_controller::ParameterHandler.