Nav2 Navigation Stack - kilted  kilted
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_util/node_utils.hpp"
26 #include "rclcpp/rclcpp.hpp"
27 #include "rclcpp/parameter_value.hpp"
28 #include "rclcpp_lifecycle/lifecycle_node.hpp"
29 
30 namespace mppi
31 {
35 enum class ParameterType { Dynamic, Static };
36 
42 {
43 public:
44  using get_param_func_t = void (const rclcpp::Parameter & param,
45  rcl_interfaces::msg::SetParametersResult & result);
46  using post_callback_t = void ();
47  using pre_callback_t = void ();
51  ParametersHandler() = default;
52 
57  explicit ParametersHandler(
58  const rclcpp_lifecycle::LifecycleNode::WeakPtr & parent, std::string & name);
59 
64 
68  void start();
69 
75  rcl_interfaces::msg::SetParametersResult dynamicParamsCallback(
76  std::vector<rclcpp::Parameter> parameters);
77 
83  inline auto getParamGetter(const std::string & ns);
84 
89  template<typename T>
90  void addPostCallback(T && callback);
91 
96  template<typename T>
97  void addPreCallback(T && callback);
98 
105  template<typename T>
106  void setParamCallback(
107  T & setting, const std::string & name, ParameterType param_type = ParameterType::Dynamic);
108 
113  std::mutex * getLock()
114  {
115  return &parameters_change_mutex_;
116  }
117 
131  template<typename T>
132  void addParamCallback(const std::string & name, T && callback);
133 
134 protected:
142  template<typename SettingT, typename ParamT>
143  void getParam(
144  SettingT & setting, const std::string & name, ParamT default_value,
145  ParameterType param_type = ParameterType::Dynamic);
146 
153  template<typename ParamT, typename SettingT, typename NodeT>
154  void setParam(SettingT & setting, const std::string & name, NodeT node) const;
155 
161  template<typename T>
162  static auto as(const rclcpp::Parameter & parameter);
163 
164  std::mutex parameters_change_mutex_;
165  rclcpp::Logger logger_{rclcpp::get_logger("MPPIController")};
166  rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr
167  on_set_param_handler_;
168  rclcpp_lifecycle::LifecycleNode::WeakPtr node_;
169  std::string node_name_;
170  std::string name_;
171 
172  bool verbose_{false};
173 
174  std::unordered_map<std::string, std::function<get_param_func_t>> get_param_callbacks_;
175  std::unordered_map<std::string, std::function<get_param_func_t>> get_pre_callbacks_;
176 
177  std::vector<std::function<pre_callback_t>> pre_callbacks_;
178  std::vector<std::function<post_callback_t>> post_callbacks_;
179 };
180 
181 inline auto ParametersHandler::getParamGetter(const std::string & ns)
182 {
183  return [this, ns](
184  auto & setting, const std::string & name, auto default_value,
185  ParameterType param_type = ParameterType::Dynamic) {
186  getParam(
187  setting, ns.empty() ? name : ns + "." + name,
188  std::move(default_value), param_type);
189  };
190 }
191 
192 template<typename T>
193 void ParametersHandler::addParamCallback(const std::string & name, T && callback)
194 {
195  get_param_callbacks_[name] = callback;
196 }
197 
198 template<typename T>
200 {
201  post_callbacks_.push_back(callback);
202 }
203 
204 template<typename T>
206 {
207  pre_callbacks_.push_back(callback);
208 }
209 
210 template<typename SettingT, typename ParamT>
212  SettingT & setting, const std::string & name,
213  ParamT default_value,
214  ParameterType param_type)
215 {
216  auto node = node_.lock();
217 
218  nav2_util::declare_parameter_if_not_declared(
219  node, name, rclcpp::ParameterValue(default_value));
220 
221  setParam<ParamT>(setting, name, node);
222  setParamCallback(setting, name, param_type);
223 }
224 
225 template<typename ParamT, typename SettingT, typename NodeT>
227  SettingT & setting, const std::string & name, NodeT node) const
228 {
229  ParamT param_in{};
230  node->get_parameter(name, param_in);
231  setting = static_cast<SettingT>(param_in);
232 }
233 
234 template<typename T>
236  T & setting, const std::string & name, ParameterType param_type)
237 {
238  if (get_param_callbacks_.find(name) != get_param_callbacks_.end()) {
239  return;
240  }
241 
242  auto dynamic_callback =
243  [this, &setting, name](
244  const rclcpp::Parameter & param, rcl_interfaces::msg::SetParametersResult & /*result*/) {
245  setting = as<T>(param);
246  if (verbose_) {
247  RCLCPP_INFO(logger_, "Dynamic parameter changed: %s", std::to_string(param).c_str());
248  }
249  };
250 
251  auto static_callback =
252  [this, &setting, name](
253  const rclcpp::Parameter & param, rcl_interfaces::msg::SetParametersResult & result) {
254  std::string reason = "Rejected change to static parameter: " + std::to_string(param);
255  result.successful = false;
256  if (!result.reason.empty()) {
257  result.reason += "\n";
258  }
259  result.reason += reason;
260  };
261 
262  if (param_type == ParameterType::Dynamic) {
263  addParamCallback(name, dynamic_callback);
264  } else {
265  addParamCallback(name, static_callback);
266  }
267 }
268 
269 template<typename T>
270 auto ParametersHandler::as(const rclcpp::Parameter & parameter)
271 {
272  if constexpr (std::is_same_v<T, bool>) {
273  return parameter.as_bool();
274  } else if constexpr (std::is_integral_v<T>) {
275  return parameter.as_int();
276  } else if constexpr (std::is_floating_point_v<T>) {
277  return parameter.as_double();
278  } else if constexpr (std::is_same_v<T, std::string>) {
279  return parameter.as_string();
280  } else if constexpr (std::is_same_v<T, std::vector<int64_t>>) {
281  return parameter.as_integer_array();
282  } else if constexpr (std::is_same_v<T, std::vector<double>>) {
283  return parameter.as_double_array();
284  } else if constexpr (std::is_same_v<T, std::vector<std::string>>) {
285  return parameter.as_string_array();
286  } else if constexpr (std::is_same_v<T, std::vector<bool>>) {
287  return parameter.as_bool_array();
288  }
289 }
290 
291 } // namespace mppi
292 
293 #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 addPostCallback(T &&callback)
Set a callback to process after parameter changes.
auto getParamGetter(const std::string &ns)
Get an object to retrieve parameters.
void setParam(SettingT &setting, const std::string &name, NodeT node) const
Set a parameter.
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