Nav2 Navigation Stack - rolling  main
ROS 2 Navigation Stack
parameters_handler.hpp
1 // Copyright (c) 2022 Samsung Research America, @artofnothingness Alexey Budyakov
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 #ifndef NAV2_MPPI_CONTROLLER__TOOLS__PARAMETERS_HANDLER_HPP_
16 #define NAV2_MPPI_CONTROLLER__TOOLS__PARAMETERS_HANDLER_HPP_
17 
18 #include <functional>
19 #include <string>
20 #include <type_traits>
21 #include <unordered_map>
22 #include <utility>
23 #include <vector>
24 
25 #include "nav2_ros_common/lifecycle_node.hpp"
26 #include "nav2_ros_common/node_utils.hpp"
27 #include "rclcpp/rclcpp.hpp"
28 #include "rclcpp/parameter_value.hpp"
29 #include "rclcpp_lifecycle/lifecycle_node.hpp"
30 
31 namespace mppi
32 {
36 enum class ParameterType { Dynamic, Static };
37 
43 {
44 public:
45  using get_param_func_t = void (const rclcpp::Parameter & param,
46  rcl_interfaces::msg::SetParametersResult & result);
47  using post_callback_t = void ();
48  using pre_callback_t = void ();
52  ParametersHandler() = default;
53 
58  explicit ParametersHandler(
59  const nav2::LifecycleNode::WeakPtr & parent, std::string & name);
60 
65 
69  void start();
70 
76  rcl_interfaces::msg::SetParametersResult dynamicParamsCallback(
77  std::vector<rclcpp::Parameter> parameters);
78 
84  inline auto getParamGetter(const std::string & ns);
85 
90  template<typename T>
91  void addPostCallback(T && callback);
92 
97  template<typename T>
98  void addPreCallback(T && callback);
99 
106  template<typename T>
107  void setParamCallback(
108  T & setting, const std::string & name, ParameterType param_type = ParameterType::Dynamic);
109 
114  std::mutex * getLock()
115  {
116  return &parameters_change_mutex_;
117  }
118 
132  template<typename T>
133  void addParamCallback(const std::string & name, T && callback);
134 
135 protected:
143  template<typename SettingT, typename ParamT>
144  void getParam(
145  SettingT & setting, const std::string & name, ParamT default_value,
146  ParameterType param_type = ParameterType::Dynamic);
147 
154  template<typename ParamT, typename SettingT>
155  void setParam(
156  SettingT & setting,
157  const std::string & name,
158  nav2::LifecycleNode::SharedPtr node) const;
159 
165  template<typename T>
166  static auto as(const rclcpp::Parameter & parameter);
167 
168  std::mutex parameters_change_mutex_;
169  rclcpp::Logger logger_{rclcpp::get_logger("MPPIController")};
170  rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr
171  on_set_param_handler_;
172  nav2::LifecycleNode::WeakPtr node_;
173  std::string node_name_;
174  std::string name_;
175 
176  bool verbose_{false};
177 
178  std::unordered_map<std::string, std::function<get_param_func_t>> get_param_callbacks_;
179  std::unordered_map<std::string, std::function<get_param_func_t>> get_pre_callbacks_;
180 
181  std::vector<std::function<pre_callback_t>> pre_callbacks_;
182  std::vector<std::function<post_callback_t>> post_callbacks_;
183 };
184 
185 inline auto ParametersHandler::getParamGetter(const std::string & ns)
186 {
187  return [this, ns](
188  auto & setting, const std::string & name, auto default_value,
189  ParameterType param_type = ParameterType::Dynamic) {
190  getParam(
191  setting, ns.empty() ? name : ns + "." + name,
192  std::move(default_value), param_type);
193  };
194 }
195 
196 template<typename T>
197 void ParametersHandler::addParamCallback(const std::string & name, T && callback)
198 {
199  get_param_callbacks_[name] = callback;
200 }
201 
202 template<typename T>
204 {
205  post_callbacks_.push_back(callback);
206 }
207 
208 template<typename T>
210 {
211  pre_callbacks_.push_back(callback);
212 }
213 
214 template<typename SettingT, typename ParamT>
216  SettingT & setting, const std::string & name,
217  ParamT default_value,
218  ParameterType param_type)
219 {
220  auto node = node_.lock();
221 
222  nav2::declare_parameter_if_not_declared(
223  node, name, rclcpp::ParameterValue(default_value));
224 
225  setParam<ParamT>(setting, name, node);
226  setParamCallback(setting, name, param_type);
227 }
228 
229 template<typename ParamT, typename SettingT>
231  SettingT & setting, const std::string & name, nav2::LifecycleNode::SharedPtr node) const
232 {
233  ParamT param_in{};
234  node->get_parameter(name, param_in);
235  setting = static_cast<SettingT>(param_in);
236 }
237 
238 template<typename T>
240  T & setting, const std::string & name, ParameterType param_type)
241 {
242  if (get_param_callbacks_.find(name) != get_param_callbacks_.end()) {
243  return;
244  }
245 
246  auto dynamic_callback =
247  [this, &setting, name](
248  const rclcpp::Parameter & param, rcl_interfaces::msg::SetParametersResult & /*result*/) {
249  setting = as<T>(param);
250  if (verbose_) {
251  RCLCPP_INFO(logger_, "Dynamic parameter changed: %s", std::to_string(param).c_str());
252  }
253  };
254 
255  auto static_callback =
256  [this, &setting, name](
257  const rclcpp::Parameter & param, rcl_interfaces::msg::SetParametersResult & result) {
258  std::string reason = "Rejected change to static parameter: " + std::to_string(param);
259  result.successful = false;
260  if (!result.reason.empty()) {
261  result.reason += "\n";
262  }
263  result.reason += reason;
264  };
265 
266  if (param_type == ParameterType::Dynamic) {
267  addParamCallback(name, dynamic_callback);
268  } else {
269  addParamCallback(name, static_callback);
270  }
271 }
272 
273 template<typename T>
274 auto ParametersHandler::as(const rclcpp::Parameter & parameter)
275 {
276  if constexpr (std::is_same_v<T, bool>) {
277  return parameter.as_bool();
278  } else if constexpr (std::is_integral_v<T>) {
279  return parameter.as_int();
280  } else if constexpr (std::is_floating_point_v<T>) {
281  return parameter.as_double();
282  } else if constexpr (std::is_same_v<T, std::string>) {
283  return parameter.as_string();
284  } else if constexpr (std::is_same_v<T, std::vector<int64_t>>) {
285  return parameter.as_integer_array();
286  } else if constexpr (std::is_same_v<T, std::vector<double>>) {
287  return parameter.as_double_array();
288  } else if constexpr (std::is_same_v<T, std::vector<std::string>>) {
289  return parameter.as_string_array();
290  } else if constexpr (std::is_same_v<T, std::vector<bool>>) {
291  return parameter.as_bool_array();
292  }
293 }
294 
295 } // namespace mppi
296 
297 #endif // NAV2_MPPI_CONTROLLER__TOOLS__PARAMETERS_HANDLER_HPP_
Handles getting parameters and dynamic parameter changes.
rcl_interfaces::msg::SetParametersResult dynamicParamsCallback(std::vector< rclcpp::Parameter > parameters)
Dynamic parameter callback.
void setParamCallback(T &setting, const std::string &name, ParameterType param_type=ParameterType::Dynamic)
Set a parameter to a dynamic parameter callback.
void addPreCallback(T &&callback)
Set a callback to process before parameter changes.
void getParam(SettingT &setting, const std::string &name, ParamT default_value, ParameterType param_type=ParameterType::Dynamic)
Gets parameter.
void setParam(SettingT &setting, const std::string &name, nav2::LifecycleNode::SharedPtr node) const
Set a parameter.
void addPostCallback(T &&callback)
Set a callback to process after parameter changes.
auto getParamGetter(const std::string &ns)
Get an object to retrieve parameters.
std::mutex * getLock()
Get mutex lock for changing parameters.
static auto as(const rclcpp::Parameter &parameter)
Converts parameter type to real types.
void start()
Starts processing dynamic parameter changes.
ParametersHandler()=default
Constructor for mppi::ParametersHandler.
~ParametersHandler()
Destructor for mppi::ParametersHandler.
void addParamCallback(const std::string &name, T &&callback)
register a function to be called when setting a parameter