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_.odom_topic = node->declare_or_get_parameter("odom_topic", std::string("odom"));
51  params_.odom_duration = node->declare_or_get_parameter("odom_duration", 0.3);
52  params_.search_window = node->declare_or_get_parameter("search_window", 2.0);
53 
54  RCLCPP_INFO(
55  logger_,
56  "Controller frequency set to %.4fHz",
57  params_.controller_frequency);
58 
59  RCLCPP_INFO(logger_, "getting progress checker plugins..");
60  params_.progress_checker_ids = node->declare_or_get_parameter("progress_checker_plugins",
61  default_progress_checker_ids_);
62  if (params_.progress_checker_ids == default_progress_checker_ids_) {
63  for (size_t i = 0; i < default_progress_checker_ids_.size(); ++i) {
64  nav2::declare_parameter_if_not_declared(
65  node, default_progress_checker_ids_[i] + ".plugin",
66  rclcpp::ParameterValue(default_progress_checker_types_[i]));
67  }
68  }
69 
70  RCLCPP_INFO(logger_, "getting goal checker plugins..");
71  params_.goal_checker_ids = node->declare_or_get_parameter("goal_checker_plugins",
72  default_goal_checker_ids_);
73  if (params_.goal_checker_ids == default_goal_checker_ids_) {
74  for (size_t i = 0; i < default_goal_checker_ids_.size(); ++i) {
75  nav2::declare_parameter_if_not_declared(
76  node, default_goal_checker_ids_[i] + ".plugin",
77  rclcpp::ParameterValue(default_goal_checker_types_[i]));
78  }
79  }
80 
81  RCLCPP_INFO(logger_, "getting controller plugins..");
82  params_.controller_ids = node->declare_or_get_parameter("controller_plugins",
83  default_controller_ids_);
84  if (params_.controller_ids == default_controller_ids_) {
85  for (size_t i = 0; i < default_controller_ids_.size(); ++i) {
86  nav2::declare_parameter_if_not_declared(
87  node, default_controller_ids_[i] + ".plugin",
88  rclcpp::ParameterValue(default_controller_types_[i]));
89  }
90  }
91 
92  RCLCPP_INFO(logger_, "getting path handler plugins..");
93  params_.path_handler_ids = node->declare_or_get_parameter("path_handler_plugins",
94  default_path_handler_ids_);
95  if (params_.path_handler_ids == default_path_handler_ids_) {
96  for (size_t i = 0; i < default_path_handler_ids_.size(); ++i) {
97  nav2::declare_parameter_if_not_declared(
98  node, default_path_handler_ids_[i] + ".plugin",
99  rclcpp::ParameterValue(default_path_handler_types_[i]));
100  }
101  }
102 
103  params_.controller_types.resize(params_.controller_ids.size());
104  params_.goal_checker_types.resize(params_.goal_checker_ids.size());
105  params_.progress_checker_types.resize(params_.progress_checker_ids.size());
106  params_.path_handler_types.resize(params_.path_handler_ids.size());
107 
108  for (size_t i = 0; i != params_.progress_checker_ids.size(); i++) {
109  try {
110  params_.progress_checker_types[i] = nav2::get_plugin_type_param(
111  node, params_.progress_checker_ids[i]);
112  } catch (const std::exception & ex) {
113  throw std::runtime_error(
114  std::string("Failed to get type for progress_checker '") +
115  params_.progress_checker_ids[i] + "': " + ex.what());
116  }
117  }
118 
119  for (size_t i = 0; i != params_.goal_checker_ids.size(); i++) {
120  try {
121  params_.goal_checker_types[i] =
122  nav2::get_plugin_type_param(node, params_.goal_checker_ids[i]);
123  } catch (const std::exception & ex) {
124  throw std::runtime_error(
125  std::string("Failed to get type for goal_checker '") +
126  params_.goal_checker_ids[i] + "': " + ex.what());
127  }
128  }
129 
130  for (size_t i = 0; i != params_.controller_ids.size(); i++) {
131  try {
132  params_.controller_types[i] = nav2::get_plugin_type_param(node, params_.controller_ids[i]);
133  } catch (const std::exception & ex) {
134  throw std::runtime_error(
135  std::string("Failed to get type for controller plugins '") +
136  params_.controller_types[i] + "': " + ex.what());
137  }
138  }
139 
140  for (size_t i = 0; i != params_.path_handler_ids.size(); i++) {
141  try {
142  params_.path_handler_types[i] = nav2::get_plugin_type_param(node,
143  params_.path_handler_ids[i]);
144  } catch (const std::exception & ex) {
145  throw std::runtime_error(
146  std::string("Failed to get type for path handler plugins '") +
147  params_.path_handler_types[i] + "': " + ex.what());
148  }
149  }
150 }
151 
152 rcl_interfaces::msg::SetParametersResult ParameterHandler::validateParameterUpdatesCallback(
153  const std::vector<rclcpp::Parameter> & parameters)
154 {
155  rcl_interfaces::msg::SetParametersResult result;
156  result.successful = true;
157  for (const auto & parameter : parameters) {
158  const auto & param_type = parameter.get_type();
159  const auto & param_name = parameter.get_name();
160  // If we are trying to change the parameter of a plugin we can just skip it at this point
161  // as they handle parameter changes themselves and don't need to lock the mutex
162  if (param_name.find('.') != std::string::npos) {
163  continue;
164  }
165  if (param_type == ParameterType::PARAMETER_DOUBLE) {
166  if (parameter.as_double() < 0.0 && param_name != "failure_tolerance") {
167  RCLCPP_WARN(
168  logger_, "The value of parameter '%s' is incorrectly set to %f, "
169  "it should be >=0. Ignoring parameter update.",
170  param_name.c_str(), parameter.as_double());
171  result.successful = false;
172  }
173  }
174  }
175  return result;
176 }
177 
178 void
180  const std::vector<rclcpp::Parameter> & parameters)
181 {
182  for (const auto & parameter : parameters) {
183  const auto & param_type = parameter.get_type();
184  const auto & param_name = parameter.get_name();
185 
186  // If we are trying to change the parameter of a plugin we can just skip it at this point
187  // as they handle parameter changes themselves and don't need to lock the mutex
188  if (param_name.find('.') != std::string::npos) {
189  continue;
190  }
191 
192  if (!mutex_.try_lock()) {
193  RCLCPP_WARN(
194  logger_,
195  "Unable to dynamically change Parameters while the controller is currently running");
196  return;
197  }
198 
199  if (param_type == ParameterType::PARAMETER_DOUBLE) {
200  if (param_name == "min_x_velocity_threshold") {
201  params_.min_x_velocity_threshold = parameter.as_double();
202  } else if (param_name == "min_y_velocity_threshold") {
203  params_.min_y_velocity_threshold = parameter.as_double();
204  } else if (param_name == "min_theta_velocity_threshold") {
205  params_.min_theta_velocity_threshold = parameter.as_double();
206  } else if (param_name == "failure_tolerance") {
207  params_.failure_tolerance = parameter.as_double();
208  } else if (param_name == "search_window") {
209  params_.search_window = parameter.as_double();
210  }
211  }
212  mutex_.unlock();
213  }
214 }
215 
216 } // 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.