Nav2 Navigation Stack - jazzy  jazzy
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 
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 
104  template<typename T>
105  void setDynamicParamCallback(T & setting, const std::string & name);
106 
111  std::mutex * getLock()
112  {
113  return &parameters_change_mutex_;
114  }
115 
121  template<typename T>
122  void addDynamicParamCallback(const std::string & name, T && callback);
123 
124 protected:
132  template<typename SettingT, typename ParamT>
133  void getParam(
134  SettingT & setting, const std::string & name, ParamT default_value,
135  ParameterType param_type = ParameterType::Dynamic);
136 
143  template<typename ParamT, typename SettingT, typename NodeT>
144  void setParam(SettingT & setting, const std::string & name, NodeT node) const;
145 
151  template<typename T>
152  static auto as(const rclcpp::Parameter & parameter);
153 
154  std::mutex parameters_change_mutex_;
155  rclcpp::Logger logger_{rclcpp::get_logger("MPPIController")};
156  rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr
157  on_set_param_handler_;
158  rclcpp_lifecycle::LifecycleNode::WeakPtr node_;
159  std::string node_name_;
160 
161  bool verbose_{false};
162 
163  std::unordered_map<std::string, std::function<get_param_func_t>>
164  get_param_callbacks_;
165 
166  std::vector<std::function<pre_callback_t>> pre_callbacks_;
167  std::vector<std::function<post_callback_t>> post_callbacks_;
168 };
169 
170 inline auto ParametersHandler::getParamGetter(const std::string & ns)
171 {
172  return [this, ns](
173  auto & setting, const std::string & name, auto default_value,
174  ParameterType param_type = ParameterType::Dynamic) {
175  getParam(
176  setting, ns.empty() ? name : ns + "." + name,
177  std::move(default_value), param_type);
178  };
179 }
180 
181 template<typename T>
182 void ParametersHandler::addDynamicParamCallback(const std::string & name, T && callback)
183 {
184  get_param_callbacks_[name] = callback;
185 }
186 
187 template<typename T>
189 {
190  post_callbacks_.push_back(callback);
191 }
192 
193 template<typename T>
195 {
196  pre_callbacks_.push_back(callback);
197 }
198 
199 template<typename SettingT, typename ParamT>
201  SettingT & setting, const std::string & name,
202  ParamT default_value,
203  ParameterType param_type)
204 {
205  auto node = node_.lock();
206 
207  nav2_util::declare_parameter_if_not_declared(
208  node, name, rclcpp::ParameterValue(default_value));
209 
210  setParam<ParamT>(setting, name, node);
211 
212  if (param_type == ParameterType::Dynamic) {
213  setDynamicParamCallback(setting, name);
214  }
215 }
216 
217 template<typename ParamT, typename SettingT, typename NodeT>
219  SettingT & setting, const std::string & name, NodeT node) const
220 {
221  ParamT param_in{};
222  node->get_parameter(name, param_in);
223  setting = static_cast<SettingT>(param_in);
224 }
225 
226 template<typename T>
227 void ParametersHandler::setDynamicParamCallback(T & setting, const std::string & name)
228 {
229  if (get_param_callbacks_.find(name) != get_param_callbacks_.end()) {
230  return;
231  }
232 
233  auto callback = [this, &setting, name](const rclcpp::Parameter & param) {
234  setting = as<T>(param);
235 
236  if (verbose_) {
237  RCLCPP_INFO(logger_, "Dynamic parameter changed: %s", std::to_string(param).c_str());
238  }
239  };
240 
241  addDynamicParamCallback(name, callback);
242 
243  if (verbose_) {
244  RCLCPP_INFO(logger_, "Dynamic Parameter added %s", name.c_str());
245  }
246 }
247 
248 template<typename T>
249 auto ParametersHandler::as(const rclcpp::Parameter & parameter)
250 {
251  if constexpr (std::is_same_v<T, bool>) {
252  return parameter.as_bool();
253  } else if constexpr (std::is_integral_v<T>) {
254  return parameter.as_int();
255  } else if constexpr (std::is_floating_point_v<T>) {
256  return parameter.as_double();
257  } else if constexpr (std::is_same_v<T, std::string>) {
258  return parameter.as_string();
259  } else if constexpr (std::is_same_v<T, std::vector<int64_t>>) {
260  return parameter.as_integer_array();
261  } else if constexpr (std::is_same_v<T, std::vector<double>>) {
262  return parameter.as_double_array();
263  } else if constexpr (std::is_same_v<T, std::vector<std::string>>) {
264  return parameter.as_string_array();
265  } else if constexpr (std::is_same_v<T, std::vector<bool>>) {
266  return parameter.as_bool_array();
267  }
268 }
269 
270 } // namespace mppi
271 
272 #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.
~ParametersHandler()
Destructor for mppi::ParametersHandler.