Nav2 Navigation Stack - humble  humble
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  using post_callback_t = void ();
46  using pre_callback_t = void ();
47 
51  ParametersHandler() = default;
52 
57  explicit ParametersHandler(
58  const rclcpp_lifecycle::LifecycleNode::WeakPtr & parent);
59 
63  void start();
64 
70  rcl_interfaces::msg::SetParametersResult dynamicParamsCallback(
71  std::vector<rclcpp::Parameter> parameters);
72 
78  inline auto getParamGetter(const std::string & ns);
79 
84  template<typename T>
85  void addPostCallback(T && callback);
86 
91  template<typename T>
92  void addPreCallback(T && callback);
93 
99  template<typename T>
100  void setDynamicParamCallback(T & setting, const std::string & name);
101 
106  std::mutex * getLock()
107  {
108  return &parameters_change_mutex_;
109  }
110 
116  template<typename T>
117  void addDynamicParamCallback(const std::string & name, T && callback);
118 
119 protected:
127  template<typename SettingT, typename ParamT>
128  void getParam(
129  SettingT & setting, const std::string & name, ParamT default_value,
130  ParameterType param_type = ParameterType::Dynamic);
131 
138  template<typename ParamT, typename SettingT, typename NodeT>
139  void setParam(SettingT & setting, const std::string & name, NodeT node) const;
140 
146  template<typename T>
147  static auto as(const rclcpp::Parameter & parameter);
148 
149  std::mutex parameters_change_mutex_;
150  rclcpp::Logger logger_{rclcpp::get_logger("MPPIController")};
151  rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr
152  on_set_param_handler_;
153  rclcpp_lifecycle::LifecycleNode::WeakPtr node_;
154  std::string node_name_;
155 
156  bool verbose_{false};
157 
158  std::unordered_map<std::string, std::function<get_param_func_t>>
159  get_param_callbacks_;
160 
161  std::vector<std::function<pre_callback_t>> pre_callbacks_;
162  std::vector<std::function<post_callback_t>> post_callbacks_;
163 };
164 
165 inline auto ParametersHandler::getParamGetter(const std::string & ns)
166 {
167  return [this, ns](
168  auto & setting, const std::string & name, auto default_value,
169  ParameterType param_type = ParameterType::Dynamic) {
170  getParam(
171  setting, ns.empty() ? name : ns + "." + name,
172  std::move(default_value), param_type);
173  };
174 }
175 
176 template<typename T>
177 void ParametersHandler::addDynamicParamCallback(const std::string & name, T && callback)
178 {
179  get_param_callbacks_[name] = callback;
180 }
181 
182 template<typename T>
184 {
185  post_callbacks_.push_back(callback);
186 }
187 
188 template<typename T>
190 {
191  pre_callbacks_.push_back(callback);
192 }
193 
194 template<typename SettingT, typename ParamT>
196  SettingT & setting, const std::string & name,
197  ParamT default_value,
198  ParameterType param_type)
199 {
200  auto node = node_.lock();
201 
202  nav2_util::declare_parameter_if_not_declared(
203  node, name, rclcpp::ParameterValue(default_value));
204 
205  setParam<ParamT>(setting, name, node);
206 
207  if (param_type == ParameterType::Dynamic) {
208  setDynamicParamCallback(setting, name);
209  }
210 }
211 
212 template<typename ParamT, typename SettingT, typename NodeT>
214  SettingT & setting, const std::string & name, NodeT node) const
215 {
216  ParamT param_in{};
217  node->get_parameter(name, param_in);
218  setting = static_cast<SettingT>(param_in);
219 }
220 
221 template<typename T>
222 void ParametersHandler::setDynamicParamCallback(T & setting, const std::string & name)
223 {
224  if (get_param_callbacks_.find(name) != get_param_callbacks_.end()) {
225  return;
226  }
227 
228  auto callback = [this, &setting, name](const rclcpp::Parameter & param) {
229  setting = as<T>(param);
230 
231  if (verbose_) {
232  RCLCPP_INFO(logger_, "Dynamic parameter changed: %s", std::to_string(param).c_str());
233  }
234  };
235 
236  addDynamicParamCallback(name, callback);
237 
238  if (verbose_) {
239  RCLCPP_INFO(logger_, "Dynamic Parameter added %s", name.c_str());
240  }
241 }
242 
243 template<typename T>
244 auto ParametersHandler::as(const rclcpp::Parameter & parameter)
245 {
246  if constexpr (std::is_same_v<T, bool>) {
247  return parameter.as_bool();
248  } else if constexpr (std::is_integral_v<T>) {
249  return parameter.as_int();
250  } else if constexpr (std::is_floating_point_v<T>) {
251  return parameter.as_double();
252  } else if constexpr (std::is_same_v<T, std::string>) {
253  return parameter.as_string();
254  } else if constexpr (std::is_same_v<T, std::vector<int64_t>>) {
255  return parameter.as_integer_array();
256  } else if constexpr (std::is_same_v<T, std::vector<double>>) {
257  return parameter.as_double_array();
258  } else if constexpr (std::is_same_v<T, std::vector<std::string>>) {
259  return parameter.as_string_array();
260  } else if constexpr (std::is_same_v<T, std::vector<bool>>) {
261  return parameter.as_bool_array();
262  }
263 }
264 
265 } // namespace mppi
266 
267 #endif // NAV2_MPPI_CONTROLLER__TOOLS__PARAMETERS_HANDLER_HPP_
Handles getting parameters and dynamic parmaeter changes.
rcl_interfaces::msg::SetParametersResult dynamicParamsCallback(std::vector< rclcpp::Parameter > parameters)
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.
void addDynamicParamCallback(const std::string &name, T &&callback)
Set a parameter to a dynamic parameter callback.
auto getParamGetter(const std::string &ns)
Get an object to retreive parameters.
void setParam(SettingT &setting, const std::string &name, NodeT node) const
Set a parameter.
std::mutex * getLock()
Get mutex lock for changing parameters.
void setDynamicParamCallback(T &setting, const std::string &name)
Set a parameter to a dynamic parameter callback.
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.