Nav2 Navigation Stack - lyrical  lyrical
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 
79  rcl_interfaces::msg::SetParametersResult validateParameterUpdatesCallback(
80  const std::vector<rclcpp::Parameter> & parameters);
81 
88  void updateParametersCallback(const std::vector<rclcpp::Parameter> & parameters);
89 
95  inline auto getParamGetter(const std::string & ns);
96 
101  template<typename T>
102  void addPostCallback(T && callback);
103 
108  template<typename T>
109  void addPreCallback(const std::string & name, T && callback);
110 
117  template<typename T>
118  void setParamCallback(
119  T & setting, const std::string & name, ParameterType param_type = ParameterType::Dynamic);
120 
125  std::mutex * getLock()
126  {
127  return &parameters_change_mutex_;
128  }
129 
143  template<typename T>
144  void addParamCallback(const std::string & name, T && callback);
145 
146 protected:
154  template<typename SettingT, typename ParamT>
155  void getParam(
156  SettingT & setting, const std::string & name, ParamT default_value,
157  ParameterType param_type = ParameterType::Dynamic);
158 
165  template<typename ParamT, typename SettingT>
166  void setParam(
167  SettingT & setting,
168  const std::string & name,
169  nav2::LifecycleNode::SharedPtr node) const;
170 
176  template<typename T>
177  static auto as(const rclcpp::Parameter & parameter);
178 
179  std::mutex parameters_change_mutex_;
180  rclcpp::Logger logger_{rclcpp::get_logger("MPPIController")};
181  rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr
182  on_set_param_handler_;
183  rclcpp::node_interfaces::PostSetParametersCallbackHandle::SharedPtr
184  post_set_param_handler_;
185  nav2::LifecycleNode::WeakPtr node_;
186  std::string node_name_;
187  std::string name_;
188 
189  bool verbose_{false};
190 
191  std::unordered_map<std::string,
192  std::function<void(const rclcpp::Parameter &)>> get_param_callbacks_;
193  std::unordered_map<std::string, std::function<get_param_func_t>> get_pre_callbacks_;
194 
195  std::vector<std::function<post_callback_t>> post_callbacks_;
196 };
197 
198 inline auto ParametersHandler::getParamGetter(const std::string & ns)
199 {
200  return [this, ns](
201  auto & setting, const std::string & name, auto default_value,
202  ParameterType param_type = ParameterType::Dynamic) {
203  getParam(
204  setting, ns.empty() ? name : ns + "." + name,
205  std::move(default_value), param_type);
206  };
207 }
208 
209 template<typename T>
210 void ParametersHandler::addParamCallback(const std::string & name, T && callback)
211 {
212  get_param_callbacks_[name] = callback;
213 }
214 
215 template<typename T>
217 {
218  post_callbacks_.push_back(callback);
219 }
220 
221 template<typename T>
222 void ParametersHandler::addPreCallback(const std::string & name, T && callback)
223 {
224  get_pre_callbacks_[name] = callback;
225 }
226 
227 template<typename SettingT, typename ParamT>
229  SettingT & setting, const std::string & name,
230  ParamT default_value,
231  ParameterType param_type)
232 {
233  auto node = node_.lock();
234 
235  nav2::declare_parameter_if_not_declared(
236  node, name, rclcpp::ParameterValue(default_value));
237 
238  setParam<ParamT>(setting, name, node);
239  setParamCallback(setting, name, param_type);
240 }
241 
242 template<typename ParamT, typename SettingT>
244  SettingT & setting, const std::string & name, nav2::LifecycleNode::SharedPtr node) const
245 {
246  ParamT param_in{};
247  node->get_parameter(name, param_in);
248  setting = static_cast<SettingT>(param_in);
249 }
250 
251 template<typename T>
253  T & setting, const std::string & name, ParameterType param_type)
254 {
255  if (get_param_callbacks_.find(name) != get_param_callbacks_.end()) {
256  return;
257  }
258 
259  auto dynamic_callback =
260  [this, &setting, name](
261  const rclcpp::Parameter & param) {
262  setting = as<T>(param);
263  if (verbose_) {
264  RCLCPP_INFO(logger_, "Dynamic parameter changed: %s", std::to_string(param).c_str());
265  }
266  };
267 
268  auto static_callback =
269  [name](
270  const rclcpp::Parameter & param, rcl_interfaces::msg::SetParametersResult & result) {
271  std::string reason = "Rejected change to static parameter: " + std::to_string(param);
272  result.successful = false;
273  if (!result.reason.empty()) {
274  result.reason += "\n";
275  }
276  result.reason += reason;
277  };
278 
279  if (param_type == ParameterType::Dynamic) {
280  addParamCallback(name, dynamic_callback);
281  } else {
282  addPreCallback(name, static_callback);
283  }
284 }
285 
286 template<typename T>
287 auto ParametersHandler::as(const rclcpp::Parameter & parameter)
288 {
289  if constexpr (std::is_same_v<T, bool>) {
290  return parameter.as_bool();
291  } else if constexpr (std::is_integral_v<T>) {
292  return parameter.as_int();
293  } else if constexpr (std::is_floating_point_v<T>) {
294  return parameter.as_double();
295  } else if constexpr (std::is_same_v<T, std::string>) {
296  return parameter.as_string();
297  } else if constexpr (std::is_same_v<T, std::vector<int64_t>>) {
298  return parameter.as_integer_array();
299  } else if constexpr (std::is_same_v<T, std::vector<double>>) {
300  return parameter.as_double_array();
301  } else if constexpr (std::is_same_v<T, std::vector<std::string>>) {
302  return parameter.as_string_array();
303  } else if constexpr (std::is_same_v<T, std::vector<bool>>) {
304  return parameter.as_bool_array();
305  }
306 }
307 
308 } // namespace mppi
309 
310 #endif // NAV2_MPPI_CONTROLLER__TOOLS__PARAMETERS_HANDLER_HPP_
Handles getting parameters and dynamic parameter changes.
void setParamCallback(T &setting, const std::string &name, ParameterType param_type=ParameterType::Dynamic)
Set a parameter to a dynamic parameter callback.
rcl_interfaces::msg::SetParametersResult validateParameterUpdatesCallback(const std::vector< rclcpp::Parameter > &parameters)
Validate incoming parameter updates before applying them. This callback is triggered when one or more...
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.
void addPreCallback(const std::string &name, T &&callback)
Set a callback to process before 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.
void updateParametersCallback(const std::vector< rclcpp::Parameter > &parameters)
Apply parameter updates after validation This callback is executed when parameters have been successf...
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