Nav2 Navigation Stack - humble  humble
ROS 2 Navigation Stack
smac_planner_hybrid.cpp
1 // Copyright (c) 2020, Samsung Research America
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. Reserved.
14 
15 #include <string>
16 #include <memory>
17 #include <vector>
18 #include <algorithm>
19 #include <limits>
20 
21 #include "Eigen/Core"
22 #include "nav2_smac_planner/smac_planner_hybrid.hpp"
23 
24 // #define BENCHMARK_TESTING
25 
26 namespace nav2_smac_planner
27 {
28 
29 using namespace std::chrono; // NOLINT
30 using rcl_interfaces::msg::ParameterType;
31 using std::placeholders::_1;
32 
34 : _a_star(nullptr),
35  _collision_checker(nullptr, 1, nullptr),
36  _smoother(nullptr),
37  _costmap(nullptr),
38  _costmap_downsampler(nullptr)
39 {
40 }
41 
43 {
44  RCLCPP_INFO(
45  _logger, "Destroying plugin %s of type SmacPlannerHybrid",
46  _name.c_str());
47 }
48 
50  const rclcpp_lifecycle::LifecycleNode::WeakPtr & parent,
51  std::string name, std::shared_ptr<tf2_ros::Buffer>/*tf*/,
52  std::shared_ptr<nav2_costmap_2d::Costmap2DROS> costmap_ros)
53 {
54  _node = parent;
55  auto node = parent.lock();
56  _logger = node->get_logger();
57  _clock = node->get_clock();
58  _costmap = costmap_ros->getCostmap();
59  _costmap_ros = costmap_ros;
60  _name = name;
61  _global_frame = costmap_ros->getGlobalFrameID();
62 
63  RCLCPP_INFO(_logger, "Configuring %s of type SmacPlannerHybrid", name.c_str());
64 
65  int angle_quantizations;
66  double analytic_expansion_max_length_m;
67  bool smooth_path;
68 
69  // General planner params
70  nav2_util::declare_parameter_if_not_declared(
71  node, name + ".downsample_costmap", rclcpp::ParameterValue(false));
72  node->get_parameter(name + ".downsample_costmap", _downsample_costmap);
73  nav2_util::declare_parameter_if_not_declared(
74  node, name + ".downsampling_factor", rclcpp::ParameterValue(1));
75  node->get_parameter(name + ".downsampling_factor", _downsampling_factor);
76 
77  nav2_util::declare_parameter_if_not_declared(
78  node, name + ".angle_quantization_bins", rclcpp::ParameterValue(72));
79  node->get_parameter(name + ".angle_quantization_bins", angle_quantizations);
80  _angle_bin_size = 2.0 * M_PI / angle_quantizations;
81  _angle_quantizations = static_cast<unsigned int>(angle_quantizations);
82 
83  nav2_util::declare_parameter_if_not_declared(
84  node, name + ".tolerance", rclcpp::ParameterValue(0.25));
85  _tolerance = static_cast<float>(node->get_parameter(name + ".tolerance").as_double());
86  nav2_util::declare_parameter_if_not_declared(
87  node, name + ".allow_unknown", rclcpp::ParameterValue(true));
88  node->get_parameter(name + ".allow_unknown", _allow_unknown);
89  nav2_util::declare_parameter_if_not_declared(
90  node, name + ".max_iterations", rclcpp::ParameterValue(1000000));
91  node->get_parameter(name + ".max_iterations", _max_iterations);
92  nav2_util::declare_parameter_if_not_declared(
93  node, name + ".max_on_approach_iterations", rclcpp::ParameterValue(1000));
94  node->get_parameter(name + ".max_on_approach_iterations", _max_on_approach_iterations);
95  nav2_util::declare_parameter_if_not_declared(
96  node, name + ".smooth_path", rclcpp::ParameterValue(true));
97  node->get_parameter(name + ".smooth_path", smooth_path);
98 
99  nav2_util::declare_parameter_if_not_declared(
100  node, name + ".minimum_turning_radius", rclcpp::ParameterValue(0.4));
101  node->get_parameter(name + ".minimum_turning_radius", _minimum_turning_radius_global_coords);
102  nav2_util::declare_parameter_if_not_declared(
103  node, name + ".cache_obstacle_heuristic", rclcpp::ParameterValue(false));
104  node->get_parameter(name + ".cache_obstacle_heuristic", _search_info.cache_obstacle_heuristic);
105  nav2_util::declare_parameter_if_not_declared(
106  node, name + ".reverse_penalty", rclcpp::ParameterValue(2.0));
107  node->get_parameter(name + ".reverse_penalty", _search_info.reverse_penalty);
108  nav2_util::declare_parameter_if_not_declared(
109  node, name + ".change_penalty", rclcpp::ParameterValue(0.0));
110  node->get_parameter(name + ".change_penalty", _search_info.change_penalty);
111  nav2_util::declare_parameter_if_not_declared(
112  node, name + ".non_straight_penalty", rclcpp::ParameterValue(1.2));
113  node->get_parameter(name + ".non_straight_penalty", _search_info.non_straight_penalty);
114  nav2_util::declare_parameter_if_not_declared(
115  node, name + ".cost_penalty", rclcpp::ParameterValue(2.0));
116  node->get_parameter(name + ".cost_penalty", _search_info.cost_penalty);
117  nav2_util::declare_parameter_if_not_declared(
118  node, name + ".retrospective_penalty", rclcpp::ParameterValue(0.015));
119  node->get_parameter(name + ".retrospective_penalty", _search_info.retrospective_penalty);
120  nav2_util::declare_parameter_if_not_declared(
121  node, name + ".analytic_expansion_ratio", rclcpp::ParameterValue(3.5));
122  node->get_parameter(name + ".analytic_expansion_ratio", _search_info.analytic_expansion_ratio);
123  nav2_util::declare_parameter_if_not_declared(
124  node, name + ".analytic_expansion_max_length", rclcpp::ParameterValue(3.0));
125  node->get_parameter(name + ".analytic_expansion_max_length", analytic_expansion_max_length_m);
126  _search_info.analytic_expansion_max_length =
127  analytic_expansion_max_length_m / _costmap->getResolution();
128 
129  nav2_util::declare_parameter_if_not_declared(
130  node, name + ".max_planning_time", rclcpp::ParameterValue(5.0));
131  node->get_parameter(name + ".max_planning_time", _max_planning_time);
132  nav2_util::declare_parameter_if_not_declared(
133  node, name + ".lookup_table_size", rclcpp::ParameterValue(20.0));
134  node->get_parameter(name + ".lookup_table_size", _lookup_table_size);
135 
136  nav2_util::declare_parameter_if_not_declared(
137  node, name + ".motion_model_for_search", rclcpp::ParameterValue(std::string("DUBIN")));
138  node->get_parameter(name + ".motion_model_for_search", _motion_model_for_search);
139  _motion_model = fromString(_motion_model_for_search);
140  if (_motion_model == MotionModel::UNKNOWN) {
141  RCLCPP_WARN(
142  _logger,
143  "Unable to get MotionModel search type. Given '%s', "
144  "valid options are MOORE, VON_NEUMANN, DUBIN, REEDS_SHEPP, STATE_LATTICE.",
145  _motion_model_for_search.c_str());
146  }
147 
148  if (_max_on_approach_iterations <= 0) {
149  RCLCPP_INFO(
150  _logger, "On approach iteration selected as <= 0, "
151  "disabling tolerance and on approach iterations.");
152  _max_on_approach_iterations = std::numeric_limits<int>::max();
153  }
154 
155  if (_max_iterations <= 0) {
156  RCLCPP_INFO(
157  _logger, "maximum iteration selected as <= 0, "
158  "disabling maximum iterations.");
159  _max_iterations = std::numeric_limits<int>::max();
160  }
161 
162  // convert to grid coordinates
163  if (!_downsample_costmap) {
164  _downsampling_factor = 1;
165  }
166  _search_info.minimum_turning_radius =
167  _minimum_turning_radius_global_coords / (_costmap->getResolution() * _downsampling_factor);
168  _lookup_table_dim =
169  static_cast<float>(_lookup_table_size) /
170  static_cast<float>(_costmap->getResolution() * _downsampling_factor);
171 
172  // Make sure its a whole number
173  _lookup_table_dim = static_cast<float>(static_cast<int>(_lookup_table_dim));
174 
175  // Make sure its an odd number
176  if (static_cast<int>(_lookup_table_dim) % 2 == 0) {
177  RCLCPP_INFO(
178  _logger,
179  "Even sized heuristic lookup table size set %f, increasing size by 1 to make odd",
180  _lookup_table_dim);
181  _lookup_table_dim += 1.0;
182  }
183 
184  // Initialize collision checker
185  _collision_checker = GridCollisionChecker(_costmap, _angle_quantizations, node);
186  _collision_checker.setFootprint(
187  _costmap_ros->getRobotFootprint(),
188  _costmap_ros->getUseRadius(),
189  findCircumscribedCost(_costmap_ros));
190 
191  // Initialize A* template
192  _a_star = std::make_unique<AStarAlgorithm<NodeHybrid>>(_motion_model, _search_info);
193  _a_star->initialize(
194  _allow_unknown,
195  _max_iterations,
196  _max_on_approach_iterations,
197  _max_planning_time,
198  _lookup_table_dim,
199  _angle_quantizations);
200 
201  // Initialize path smoother
202  if (smooth_path) {
203  SmootherParams params;
204  params.get(node, name);
205  _smoother = std::make_unique<Smoother>(params);
206  _smoother->initialize(_minimum_turning_radius_global_coords);
207  }
208 
209  // Initialize costmap downsampler
210  if (_downsample_costmap && _downsampling_factor > 1) {
211  _costmap_downsampler = std::make_unique<CostmapDownsampler>();
212  std::string topic_name = "downsampled_costmap";
213  _costmap_downsampler->on_configure(
214  node, _global_frame, topic_name, _costmap, _downsampling_factor);
215  }
216 
217  _raw_plan_publisher = node->create_publisher<nav_msgs::msg::Path>("unsmoothed_plan", 1);
218 
219  RCLCPP_INFO(
220  _logger, "Configured plugin %s of type SmacPlannerHybrid with "
221  "maximum iterations %i, max on approach iterations %i, and %s. Tolerance %.2f."
222  "Using motion model: %s.",
223  _name.c_str(), _max_iterations, _max_on_approach_iterations,
224  _allow_unknown ? "allowing unknown traversal" : "not allowing unknown traversal",
225  _tolerance, toString(_motion_model).c_str());
226 }
227 
229 {
230  RCLCPP_INFO(
231  _logger, "Activating plugin %s of type SmacPlannerHybrid",
232  _name.c_str());
233  _raw_plan_publisher->on_activate();
234  if (_costmap_downsampler) {
235  _costmap_downsampler->on_activate();
236  }
237  auto node = _node.lock();
238  // Add callback for dynamic parameters
239  _dyn_params_handler = node->add_on_set_parameters_callback(
240  std::bind(&SmacPlannerHybrid::dynamicParametersCallback, this, _1));
241 }
242 
244 {
245  RCLCPP_INFO(
246  _logger, "Deactivating plugin %s of type SmacPlannerHybrid",
247  _name.c_str());
248  _raw_plan_publisher->on_deactivate();
249  if (_costmap_downsampler) {
250  _costmap_downsampler->on_deactivate();
251  }
252  _dyn_params_handler.reset();
253 }
254 
256 {
257  RCLCPP_INFO(
258  _logger, "Cleaning up plugin %s of type SmacPlannerHybrid",
259  _name.c_str());
260  _a_star.reset();
261  _smoother.reset();
262  if (_costmap_downsampler) {
263  _costmap_downsampler->on_cleanup();
264  _costmap_downsampler.reset();
265  }
266  _raw_plan_publisher.reset();
267 }
268 
269 nav_msgs::msg::Path SmacPlannerHybrid::createPlan(
270  const geometry_msgs::msg::PoseStamped & start,
271  const geometry_msgs::msg::PoseStamped & goal)
272 {
273  std::lock_guard<std::mutex> lock_reinit(_mutex);
274  steady_clock::time_point a = steady_clock::now();
275 
276  std::unique_lock<nav2_costmap_2d::Costmap2D::mutex_t> lock(*(_costmap->getMutex()));
277 
278  // Downsample costmap, if required
279  nav2_costmap_2d::Costmap2D * costmap = _costmap;
280  if (_costmap_downsampler) {
281  costmap = _costmap_downsampler->downsample(_downsampling_factor);
282  _collision_checker.setCostmap(costmap);
283  }
284 
285  // Set collision checker and costmap information
286  _collision_checker.setFootprint(
287  _costmap_ros->getRobotFootprint(),
288  _costmap_ros->getUseRadius(),
289  findCircumscribedCost(_costmap_ros));
290  _a_star->setCollisionChecker(&_collision_checker);
291 
292  // Set starting point, in A* bin search coordinates
293  unsigned int mx_start, my_start, mx_goal, my_goal;
294  if (!costmap->worldToMap(start.pose.position.x, start.pose.position.y, mx_start, my_start)) {
295  throw std::runtime_error("Start pose is out of costmap!");
296  }
297 
298  double orientation_bin_start = std::round(tf2::getYaw(start.pose.orientation) / _angle_bin_size);
299  while (orientation_bin_start < 0.0) {
300  orientation_bin_start += static_cast<float>(_angle_quantizations);
301  }
302  // This is needed to handle precision issues
303  if (orientation_bin_start >= static_cast<float>(_angle_quantizations)) {
304  orientation_bin_start -= static_cast<float>(_angle_quantizations);
305  }
306  unsigned int start_orientation_bin_int =
307  static_cast<unsigned int>(orientation_bin_start);
308  _a_star->setStart(mx_start, my_start, start_orientation_bin_int);
309 
310  // Set goal point, in A* bin search coordinates
311  if (!costmap->worldToMap(goal.pose.position.x, goal.pose.position.y, mx_goal, my_goal)) {
312  throw std::runtime_error("Goal pose is out of costmap!");
313  }
314  double orientation_bin_goal = std::round(tf2::getYaw(goal.pose.orientation) / _angle_bin_size);
315  while (orientation_bin_goal < 0.0) {
316  orientation_bin_goal += static_cast<float>(_angle_quantizations);
317  }
318  // This is needed to handle precision issues
319  if (orientation_bin_goal >= static_cast<float>(_angle_quantizations)) {
320  orientation_bin_goal -= static_cast<float>(_angle_quantizations);
321  }
322  unsigned int goal_orientation_bin_int =
323  static_cast<unsigned int>(orientation_bin_goal);
324  _a_star->setGoal(mx_goal, my_goal, goal_orientation_bin_int);
325 
326  // Setup message
327  nav_msgs::msg::Path plan;
328  plan.header.stamp = _clock->now();
329  plan.header.frame_id = _global_frame;
330  geometry_msgs::msg::PoseStamped pose;
331  pose.header = plan.header;
332  pose.pose.position.z = 0.0;
333  pose.pose.orientation.x = 0.0;
334  pose.pose.orientation.y = 0.0;
335  pose.pose.orientation.z = 0.0;
336  pose.pose.orientation.w = 1.0;
337 
338  // Corner case of start and goal being on the same cell
339  if (std::floor(mx_start) == std::floor(mx_goal) &&
340  std::floor(my_start) == std::floor(my_goal) &&
341  start_orientation_bin_int == goal_orientation_bin_int)
342  {
343  pose.pose = start.pose;
344  pose.pose.orientation = goal.pose.orientation;
345  plan.poses.push_back(pose);
346 
347  // Publish raw path for debug
348  if (_raw_plan_publisher->get_subscription_count() > 0) {
349  _raw_plan_publisher->publish(plan);
350  }
351 
352  return plan;
353  }
354 
355  // Compute plan
356  NodeHybrid::CoordinateVector path;
357  int num_iterations = 0;
358  std::string error;
359  try {
360  if (!_a_star->createPath(
361  path, num_iterations, _tolerance / static_cast<float>(costmap->getResolution())))
362  {
363  if (num_iterations < _a_star->getMaxIterations()) {
364  error = std::string("no valid path found");
365  } else {
366  error = std::string("exceeded maximum iterations");
367  }
368  }
369  } catch (const std::runtime_error & e) {
370  error = "invalid use: ";
371  error += e.what();
372  }
373 
374  if (!error.empty()) {
375  RCLCPP_WARN(
376  _logger,
377  "%s: failed to create plan, %s.",
378  _name.c_str(), error.c_str());
379  return plan;
380  }
381 
382  // Convert to world coordinates
383  plan.poses.reserve(path.size());
384  for (int i = path.size() - 1; i >= 0; --i) {
385  pose.pose = getWorldCoords(path[i].x, path[i].y, costmap);
386  pose.pose.orientation = getWorldOrientation(path[i].theta);
387  plan.poses.push_back(pose);
388  }
389 
390  // Publish raw path for debug
391  if (_raw_plan_publisher->get_subscription_count() > 0) {
392  _raw_plan_publisher->publish(plan);
393  }
394 
395  // Find how much time we have left to do smoothing
396  steady_clock::time_point b = steady_clock::now();
397  duration<double> time_span = duration_cast<duration<double>>(b - a);
398  double time_remaining = _max_planning_time - static_cast<double>(time_span.count());
399 
400 #ifdef BENCHMARK_TESTING
401  std::cout << "It took " << time_span.count() * 1000 <<
402  " milliseconds with " << num_iterations << " iterations." << std::endl;
403 #endif
404 
405  // Smooth plan
406  if (_smoother && num_iterations > 1) {
407  _smoother->smooth(plan, costmap, time_remaining);
408  }
409 
410 #ifdef BENCHMARK_TESTING
411  steady_clock::time_point c = steady_clock::now();
412  duration<double> time_span2 = duration_cast<duration<double>>(c - b);
413  std::cout << "It took " << time_span2.count() * 1000 <<
414  " milliseconds to smooth path." << std::endl;
415 #endif
416 
417  return plan;
418 }
419 
420 rcl_interfaces::msg::SetParametersResult
421 SmacPlannerHybrid::dynamicParametersCallback(std::vector<rclcpp::Parameter> parameters)
422 {
423  rcl_interfaces::msg::SetParametersResult result;
424  std::lock_guard<std::mutex> lock_reinit(_mutex);
425 
426  bool reinit_collision_checker = false;
427  bool reinit_a_star = false;
428  bool reinit_downsampler = false;
429  bool reinit_smoother = false;
430 
431  for (auto parameter : parameters) {
432  const auto & type = parameter.get_type();
433  const auto & name = parameter.get_name();
434 
435  if (type == ParameterType::PARAMETER_DOUBLE) {
436  if (name == _name + ".max_planning_time") {
437  reinit_a_star = true;
438  _max_planning_time = parameter.as_double();
439  } else if (name == _name + ".tolerance") {
440  _tolerance = static_cast<float>(parameter.as_double());
441  } else if (name == _name + ".lookup_table_size") {
442  reinit_a_star = true;
443  _lookup_table_size = parameter.as_double();
444  } else if (name == _name + ".minimum_turning_radius") {
445  reinit_a_star = true;
446  if (_smoother) {
447  reinit_smoother = true;
448  }
449  _minimum_turning_radius_global_coords = static_cast<float>(parameter.as_double());
450  } else if (name == _name + ".reverse_penalty") {
451  reinit_a_star = true;
452  _search_info.reverse_penalty = static_cast<float>(parameter.as_double());
453  } else if (name == _name + ".change_penalty") {
454  reinit_a_star = true;
455  _search_info.change_penalty = static_cast<float>(parameter.as_double());
456  } else if (name == _name + ".non_straight_penalty") {
457  reinit_a_star = true;
458  _search_info.non_straight_penalty = static_cast<float>(parameter.as_double());
459  } else if (name == _name + ".cost_penalty") {
460  reinit_a_star = true;
461  _search_info.cost_penalty = static_cast<float>(parameter.as_double());
462  } else if (name == _name + ".analytic_expansion_ratio") {
463  reinit_a_star = true;
464  _search_info.analytic_expansion_ratio = static_cast<float>(parameter.as_double());
465  } else if (name == _name + ".analytic_expansion_max_length") {
466  reinit_a_star = true;
467  _search_info.analytic_expansion_max_length =
468  static_cast<float>(parameter.as_double()) / _costmap->getResolution();
469  }
470  } else if (type == ParameterType::PARAMETER_BOOL) {
471  if (name == _name + ".downsample_costmap") {
472  reinit_downsampler = true;
473  _downsample_costmap = parameter.as_bool();
474  } else if (name == _name + ".allow_unknown") {
475  reinit_a_star = true;
476  _allow_unknown = parameter.as_bool();
477  } else if (name == _name + ".cache_obstacle_heuristic") {
478  reinit_a_star = true;
479  _search_info.cache_obstacle_heuristic = parameter.as_bool();
480  } else if (name == _name + ".smooth_path") {
481  if (parameter.as_bool()) {
482  reinit_smoother = true;
483  } else {
484  _smoother.reset();
485  }
486  }
487  } else if (type == ParameterType::PARAMETER_INTEGER) {
488  if (name == _name + ".downsampling_factor") {
489  reinit_a_star = true;
490  reinit_downsampler = true;
491  _downsampling_factor = parameter.as_int();
492  } else if (name == _name + ".max_iterations") {
493  reinit_a_star = true;
494  _max_iterations = parameter.as_int();
495  if (_max_iterations <= 0) {
496  RCLCPP_INFO(
497  _logger, "maximum iteration selected as <= 0, "
498  "disabling maximum iterations.");
499  _max_iterations = std::numeric_limits<int>::max();
500  }
501  } else if (name == _name + ".max_on_approach_iterations") {
502  reinit_a_star = true;
503  _max_on_approach_iterations = parameter.as_int();
504  if (_max_on_approach_iterations <= 0) {
505  RCLCPP_INFO(
506  _logger, "On approach iteration selected as <= 0, "
507  "disabling tolerance and on approach iterations.");
508  _max_on_approach_iterations = std::numeric_limits<int>::max();
509  }
510  } else if (name == _name + ".angle_quantization_bins") {
511  reinit_collision_checker = true;
512  reinit_a_star = true;
513  int angle_quantizations = parameter.as_int();
514  _angle_bin_size = 2.0 * M_PI / angle_quantizations;
515  _angle_quantizations = static_cast<unsigned int>(angle_quantizations);
516  }
517  } else if (type == ParameterType::PARAMETER_STRING) {
518  if (name == _name + ".motion_model_for_search") {
519  reinit_a_star = true;
520  _motion_model = fromString(parameter.as_string());
521  if (_motion_model == MotionModel::UNKNOWN) {
522  RCLCPP_WARN(
523  _logger,
524  "Unable to get MotionModel search type. Given '%s', "
525  "valid options are MOORE, VON_NEUMANN, DUBIN, REEDS_SHEPP.",
526  _motion_model_for_search.c_str());
527  }
528  }
529  }
530  }
531 
532  // Re-init if needed with mutex lock (to avoid re-init while creating a plan)
533  if (reinit_a_star || reinit_downsampler || reinit_collision_checker || reinit_smoother) {
534  // convert to grid coordinates
535  if (!_downsample_costmap) {
536  _downsampling_factor = 1;
537  }
538  _search_info.minimum_turning_radius =
539  _minimum_turning_radius_global_coords / (_costmap->getResolution() * _downsampling_factor);
540  _lookup_table_dim =
541  static_cast<float>(_lookup_table_size) /
542  static_cast<float>(_costmap->getResolution() * _downsampling_factor);
543 
544  // Make sure its a whole number
545  _lookup_table_dim = static_cast<float>(static_cast<int>(_lookup_table_dim));
546 
547  // Make sure its an odd number
548  if (static_cast<int>(_lookup_table_dim) % 2 == 0) {
549  RCLCPP_INFO(
550  _logger,
551  "Even sized heuristic lookup table size set %f, increasing size by 1 to make odd",
552  _lookup_table_dim);
553  _lookup_table_dim += 1.0;
554  }
555 
556  auto node = _node.lock();
557 
558  // Re-Initialize A* template
559  if (reinit_a_star) {
560  _a_star = std::make_unique<AStarAlgorithm<NodeHybrid>>(_motion_model, _search_info);
561  _a_star->initialize(
562  _allow_unknown,
563  _max_iterations,
564  _max_on_approach_iterations,
565  _max_planning_time,
566  _lookup_table_dim,
567  _angle_quantizations);
568  }
569 
570  // Re-Initialize costmap downsampler
571  if (reinit_downsampler) {
572  if (_downsample_costmap && _downsampling_factor > 1) {
573  std::string topic_name = "downsampled_costmap";
574  _costmap_downsampler = std::make_unique<CostmapDownsampler>();
575  _costmap_downsampler->on_configure(
576  node, _global_frame, topic_name, _costmap, _downsampling_factor);
577  }
578  }
579 
580  // Re-Initialize collision checker
581  if (reinit_collision_checker) {
582  _collision_checker = GridCollisionChecker(_costmap, _angle_quantizations, node);
583  _collision_checker.setFootprint(
584  _costmap_ros->getRobotFootprint(),
585  _costmap_ros->getUseRadius(),
586  findCircumscribedCost(_costmap_ros));
587  }
588 
589  // Re-Initialize smoother
590  if (reinit_smoother) {
591  SmootherParams params;
592  params.get(node, _name);
593  _smoother = std::make_unique<Smoother>(params);
594  _smoother->initialize(_minimum_turning_radius_global_coords);
595  }
596  }
597  result.successful = true;
598  return result;
599 }
600 
601 } // namespace nav2_smac_planner
602 
603 #include "pluginlib/class_list_macros.hpp"
Abstract interface for global planners to adhere to with pluginlib.
A 2D costmap provides a mapping between points in the world and their associated "costs".
Definition: costmap_2d.hpp:68
bool worldToMap(double wx, double wy, unsigned int &mx, unsigned int &my) const
Convert from world coordinates to map coordinates.
Definition: costmap_2d.cpp:287
double getResolution() const
Accessor for the resolution of the costmap.
Definition: costmap_2d.cpp:531
void setCostmap(CostmapT costmap)
Set the current costmap object to use for collision detection.
A costmap grid collision checker.
void setFootprint(const nav2_costmap_2d::Footprint &footprint, const bool &radius, const double &possible_inscribed_cost)
A constructor for nav2_smac_planner::GridCollisionChecker for use when irregular bin intervals are ap...
void configure(const rclcpp_lifecycle::LifecycleNode::WeakPtr &parent, std::string name, std::shared_ptr< tf2_ros::Buffer > tf, std::shared_ptr< nav2_costmap_2d::Costmap2DROS > costmap_ros) override
Configuring plugin.
void activate() override
Activate lifecycle node.
void cleanup() override
Cleanup lifecycle node.
void deactivate() override
Deactivate lifecycle node.
rcl_interfaces::msg::SetParametersResult dynamicParametersCallback(std::vector< rclcpp::Parameter > parameters)
Callback executed when a paramter change is detected.
nav_msgs::msg::Path createPlan(const geometry_msgs::msg::PoseStamped &start, const geometry_msgs::msg::PoseStamped &goal) override
Creating a plan from start and goal poses.
Parameters for the smoother cost function.
void get(std::shared_ptr< rclcpp_lifecycle::LifecycleNode > node, const std::string &name)
Get params from ROS parameter.
Definition: types.hpp:70