Nav2 Navigation Stack - lyrical  lyrical
ROS 2 Navigation Stack
static_layer.cpp
1 /*********************************************************************
2  *
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2008, 2013, Willow Garage, Inc.
6  * Copyright (c) 2015, Fetch Robotics, Inc.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of Willow Garage, Inc. nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  * Author: Eitan Marder-Eppstein
37  * David V. Lu!!
38  *********************************************************************/
39 
40 #include "nav2_costmap_2d/static_layer.hpp"
41 
42 #include <algorithm>
43 #include <string>
44 
45 #include "pluginlib/class_list_macros.hpp"
46 #include "tf2/convert.hpp"
47 #include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
48 #include "nav2_ros_common/validate_messages.hpp"
49 
50 #define EPSILON 1e-5
51 
53 
54 using nav2_costmap_2d::NO_INFORMATION;
55 using nav2_costmap_2d::LETHAL_OBSTACLE;
56 using nav2_costmap_2d::INSCRIBED_INFLATED_OBSTACLE;
57 using nav2_costmap_2d::FREE_SPACE;
58 using rcl_interfaces::msg::ParameterType;
59 
60 namespace nav2_costmap_2d
61 {
62 
64 : map_buffer_(nullptr)
65 {
66 }
67 
69 {
70 }
71 
72 void
74 {
75  global_frame_ = layered_costmap_->getGlobalFrameID();
76 
77  getParameters();
78 
79  rclcpp::QoS map_qos = nav2::qos::StandardTopicQoS(); // initialize to default
80  if (map_subscribe_transient_local_) {
82  }
83 
84  RCLCPP_INFO(
85  logger_,
86  "Subscribing to the map topic (%s) with %s durability",
87  map_topic_.c_str(),
88  map_subscribe_transient_local_ ? "transient local" : "volatile");
89 
90  auto node = node_.lock();
91  if (!node) {
92  throw std::runtime_error{"Failed to lock node"};
93  }
94 
95  map_sub_ = node->create_subscription<nav_msgs::msg::OccupancyGrid>(
96  map_topic_,
97  std::bind(&StaticLayer::incomingMap, this, std::placeholders::_1),
98  map_qos);
99 
100  if (subscribe_to_updates_) {
101  RCLCPP_INFO(logger_, "Subscribing to updates");
102  map_update_sub_ = node->create_subscription<map_msgs::msg::OccupancyGridUpdate>(
103  map_topic_ + "_updates",
104  std::bind(&StaticLayer::incomingUpdate, this, std::placeholders::_1));
105  }
106 }
107 
108 void
110 {
111  auto node = node_.lock();
112  // Add callback for dynamic parameters
113  post_set_params_handler_ = node->add_post_set_parameters_callback(
114  std::bind(
116  this, std::placeholders::_1));
117  on_set_params_handler_ = node->add_on_set_parameters_callback(
118  std::bind(
120  this, std::placeholders::_1));
121 }
122 
123 void
125 {
126  auto node = node_.lock();
127  if (post_set_params_handler_ && node) {
128  node->remove_post_set_parameters_callback(post_set_params_handler_.get());
129  }
130  post_set_params_handler_.reset();
131  if (on_set_params_handler_ && node) {
132  node->remove_on_set_parameters_callback(on_set_params_handler_.get());
133  }
134  on_set_params_handler_.reset();
135 }
136 
137 void
139 {
140  has_updated_data_ = true;
141  setCurrent(false);
142 }
143 
144 void
146 {
147  int temp_lethal_threshold = 0;
148  double temp_tf_tol = 0.0;
149 
150  auto node = node_.lock();
151  if (!node) {
152  throw std::runtime_error{"Failed to lock node"};
153  }
154 
155  enabled_ = node->declare_or_get_parameter(name_ + "." + "enabled", true);
156  subscribe_to_updates_ = node->declare_or_get_parameter(
157  name_ + "." + "subscribe_to_updates", false);
158  footprint_clearing_enabled_ = node->declare_or_get_parameter(
159  name_ + "." + "footprint_clearing_enabled", false);
160  restore_cleared_footprint_ = node->declare_or_get_parameter(
161  name_ + "." + "restore_cleared_footprint", true);
162  map_topic_ = node->declare_or_get_parameter(
163  name_ + "." + "map_topic", std::string("map"));
164  map_topic_ = joinWithParentNamespace(map_topic_);
165  map_subscribe_transient_local_ = node->declare_or_get_parameter(
166  name_ + "." + "map_subscribe_transient_local", true);
167  node->get_parameter("track_unknown_space", track_unknown_space_);
168  node->get_parameter("use_maximum", use_maximum_);
169  node->get_parameter("lethal_cost_threshold", temp_lethal_threshold);
170  node->get_parameter("inscribed_obstacle_cost_value", inscribed_obstacle_cost_value_);
171  node->get_parameter("unknown_cost_value", unknown_cost_value_);
172  node->get_parameter("trinary_costmap", trinary_costmap_);
173  node->get_parameter("transform_tolerance", temp_tf_tol);
174 
175  // Enforce bounds
176  lethal_threshold_ = std::max(std::min(temp_lethal_threshold, 100), 0);
177  map_received_ = false;
178  map_received_in_update_bounds_ = false;
179 
180  transform_tolerance_ = tf2::durationFromSec(temp_tf_tol);
181 }
182 
183 void
184 StaticLayer::processMap(const nav_msgs::msg::OccupancyGrid & new_map)
185 {
186  RCLCPP_DEBUG(logger_, "StaticLayer: Process map");
187 
188  unsigned int size_x = new_map.info.width;
189  unsigned int size_y = new_map.info.height;
190 
191  RCLCPP_DEBUG(
192  logger_,
193  "StaticLayer: Received a %d X %d map at %f m/pix", size_x, size_y,
194  new_map.info.resolution);
195 
196  // resize costmap if size, resolution or origin do not match
197  Costmap2D * master = layered_costmap_->getCostmap();
198  if (!layered_costmap_->isRolling() && (master->getSizeInCellsX() != size_x ||
199  master->getSizeInCellsY() != size_y ||
200  !isEqual(master->getResolution(), new_map.info.resolution, EPSILON) ||
201  !isEqual(master->getOriginX(), new_map.info.origin.position.x, EPSILON) ||
202  !isEqual(master->getOriginY(), new_map.info.origin.position.y, EPSILON) ||
203  !layered_costmap_->isSizeLocked()))
204  {
205  // Update the size of the layered costmap (and all layers, including this one)
206  RCLCPP_INFO(
207  logger_,
208  "StaticLayer: Resizing costmap to %d X %d at %f m/pix", size_x, size_y,
209  new_map.info.resolution);
210 
211  double fmod_x = std::fmod(new_map.info.origin.position.x, new_map.info.resolution);
212  double fmod_y = std::fmod(new_map.info.origin.position.y, new_map.info.resolution);
213 
214  if (std::abs(fmod_x) > EPSILON || std::abs(fmod_y) > EPSILON) {
215  RCLCPP_WARN(
216  logger_,
217  "StaticLayer: Costmap origin coordinates are not perfectly aligned with the resolution. "
218  "This may cause misalignment aliasing between rolling and non-rolling costmaps.\n"
219  "Map origin: (%.f, %.f) | Resolution: %.f",
220  new_map.info.origin.position.x, new_map.info.origin.position.y,
221  new_map.info.resolution);
222  }
223 
224  layered_costmap_->resizeMap(
225  size_x, size_y, new_map.info.resolution,
226  new_map.info.origin.position.x,
227  new_map.info.origin.position.y,
228  true);
229  } else if (size_x_ != size_x || size_y_ != size_y || // NOLINT
230  !isEqual(resolution_, new_map.info.resolution, EPSILON) ||
231  !isEqual(origin_x_, new_map.info.origin.position.x, EPSILON) ||
232  !isEqual(origin_y_, new_map.info.origin.position.y, EPSILON))
233  {
234  // only update the size of the costmap stored locally in this layer
235  RCLCPP_INFO(
236  logger_,
237  "StaticLayer: Resizing static layer to %d X %d at %f m/pix", size_x, size_y,
238  new_map.info.resolution);
239  resizeMap(
240  size_x, size_y, new_map.info.resolution,
241  new_map.info.origin.position.x, new_map.info.origin.position.y);
242  }
243 
244  unsigned int index = 0;
245 
246  // we have a new map, update full size of map
247  std::lock_guard<Costmap2D::mutex_t> guard(*getMutex());
248 
249  // initialize the costmap with static data
250  for (unsigned int i = 0; i < size_y; ++i) {
251  for (unsigned int j = 0; j < size_x; ++j) {
252  unsigned char value = new_map.data[index];
253  costmap_[index] = interpretValue(value);
254  ++index;
255  }
256  }
257 
258  map_frame_ = new_map.header.frame_id;
259 
260  x_ = y_ = 0;
261  width_ = size_x_;
262  height_ = size_y_;
263  has_updated_data_ = true;
264 
265  setCurrent(true);
266 }
267 
268 void
270 {
271  // If we are using rolling costmap, the static map size is
272  // unrelated to the size of the layered costmap
273  if (!layered_costmap_->isRolling()) {
274  Costmap2D * master = layered_costmap_->getCostmap();
275  resizeMap(
276  master->getSizeInCellsX(), master->getSizeInCellsY(), master->getResolution(),
277  master->getOriginX(), master->getOriginY());
278  }
279 }
280 
281 unsigned char
282 StaticLayer::interpretValue(unsigned char value)
283 {
284  // check if the static value is above the unknown or lethal thresholds
285  if (track_unknown_space_ && value == unknown_cost_value_) {
286  return NO_INFORMATION;
287  } else if (!track_unknown_space_ && value == unknown_cost_value_) {
288  return FREE_SPACE;
289  } else if (value == inscribed_obstacle_cost_value_) {
290  return INSCRIBED_INFLATED_OBSTACLE;
291  } else if (value >= lethal_threshold_) {
292  return LETHAL_OBSTACLE;
293  } else if (trinary_costmap_) {
294  return FREE_SPACE;
295  }
296 
297  double scale = static_cast<double>(value) / lethal_threshold_;
298  return scale * LETHAL_OBSTACLE;
299 }
300 
301 void
302 StaticLayer::incomingMap(const nav_msgs::msg::OccupancyGrid::ConstSharedPtr & new_map)
303 {
304  if (!nav2::validateMsg(*new_map)) {
305  RCLCPP_ERROR(logger_, "Received map message is malformed. Rejecting.");
306  return;
307  }
308  if (!map_received_) {
309  processMap(*new_map);
310  map_received_ = true;
311  return;
312  }
313  std::lock_guard<Costmap2D::mutex_t> guard(*getMutex());
314  map_buffer_ = new_map;
315  setCurrent(false);
316 }
317 
318 void
319 StaticLayer::incomingUpdate(map_msgs::msg::OccupancyGridUpdate::ConstSharedPtr update)
320 {
321  if (!nav2::validateMsg(*update)) {
322  RCLCPP_ERROR(logger_, "Received map update is malformed. Rejecting.");
323  return;
324  }
325 
326  std::lock_guard<Costmap2D::mutex_t> guard(*getMutex());
327  if (update->y < static_cast<int32_t>(y_) ||
328  y_ + height_ < update->y + update->height ||
329  update->x < static_cast<int32_t>(x_) ||
330  x_ + width_ < update->x + update->width)
331  {
332  RCLCPP_WARN(
333  logger_,
334  "StaticLayer: Map update ignored. Exceeds bounds of static layer.\n"
335  "Static layer origin: %d, %d bounds: %d X %d\n"
336  "Update origin: %d, %d bounds: %d X %d",
337  x_, y_, width_, height_, update->x, update->y, update->width,
338  update->height);
339  return;
340  }
341 
342  if (update->header.frame_id != map_frame_) {
343  RCLCPP_WARN(
344  logger_,
345  "StaticLayer: Map update ignored. Current map is in frame %s "
346  "but update was in frame %s",
347  map_frame_.c_str(), update->header.frame_id.c_str());
348  return;
349  }
350 
351  unsigned int di = 0;
352  for (unsigned int y = 0; y < update->height; y++) {
353  unsigned int index_base = (update->y + y) * size_x_;
354  for (unsigned int x = 0; x < update->width; x++) {
355  unsigned int index = index_base + x + update->x;
356  costmap_[index] = interpretValue(update->data[di++]);
357  }
358  }
359 
360  has_updated_data_ = true;
361 }
362 
363 
364 void
366  double robot_x, double robot_y, double robot_yaw, double * min_x,
367  double * min_y,
368  double * max_x,
369  double * max_y)
370 {
371  if (!map_received_) {
372  map_received_in_update_bounds_ = false;
373  return;
374  }
375  map_received_in_update_bounds_ = true;
376 
377  std::lock_guard<Costmap2D::mutex_t> guard(*getMutex());
378 
379  // If there is a new available map, load it.
380  if (map_buffer_) {
381  processMap(*map_buffer_);
382  map_buffer_ = nullptr;
383  }
384 
385  if (!layered_costmap_->isRolling() ) {
386  if (!(has_updated_data_ || has_extra_bounds_)) {
387  return;
388  }
389  }
390 
391  useExtraBounds(min_x, min_y, max_x, max_y);
392 
393  if (layered_costmap_->isRolling()) {
394  // For rolling costmaps the global_frame (e.g. odom) differs from the
395  // map frame. mapToWorld() returns coordinates in the map frame, but
396  // the layered costmap interprets bounds in its global_frame. Report
397  // bounds that cover the full rolling window using the robot pose,
398  // which is already in the correct frame. updateCosts() handles the
399  // per-cell map↔odom transform itself.
400  Costmap2D * master = layered_costmap_->getCostmap();
401  double half_w = master->getSizeInMetersX() / 2.0;
402  double half_h = master->getSizeInMetersY() / 2.0;
403  *min_x = std::min(robot_x - half_w, *min_x);
404  *min_y = std::min(robot_y - half_h, *min_y);
405  *max_x = std::max(robot_x + half_w, *max_x);
406  *max_y = std::max(robot_y + half_h, *max_y);
407  } else {
408  double wx, wy;
409 
410  mapToWorld(x_, y_, wx, wy);
411  *min_x = std::min(wx, *min_x);
412  *min_y = std::min(wy, *min_y);
413 
414  mapToWorld(x_ + width_, y_ + height_, wx, wy);
415  *max_x = std::max(wx, *max_x);
416  *max_y = std::max(wy, *max_y);
417  }
418 
419  has_updated_data_ = false;
420 
421  updateFootprint(robot_x, robot_y, robot_yaw, min_x, min_y, max_x, max_y);
422 }
423 
424 void
426  double robot_x, double robot_y, double robot_yaw,
427  double * min_x, double * min_y,
428  double * max_x,
429  double * max_y)
430 {
431  if (!footprint_clearing_enabled_) {return;}
432 
433  transformFootprint(robot_x, robot_y, robot_yaw, getFootprint(), transformed_footprint_);
434 
435  for (unsigned int i = 0; i < transformed_footprint_.size(); i++) {
436  touch(transformed_footprint_[i].x, transformed_footprint_[i].y, min_x, min_y, max_x, max_y);
437  }
438 }
439 
440 void
442  nav2_costmap_2d::Costmap2D & master_grid,
443  int min_i, int min_j, int max_i, int max_j)
444 {
445  std::lock_guard<Costmap2D::mutex_t> guard(*getMutex());
446  if (!enabled_) {
447  return;
448  }
449  if (!map_received_in_update_bounds_) {
450  static int count = 0;
451  // throttle warning down to only 1/10 message rate
452  if (++count == 10) {
453  RCLCPP_WARN(logger_, "Can't update static costmap layer, no map received");
454  count = 0;
455  }
456  return;
457  }
458 
459  std::vector<MapLocation> map_region_to_restore;
460  if (footprint_clearing_enabled_) {
461  map_region_to_restore.reserve(100);
462  getMapRegionOccupiedByPolygon(transformed_footprint_, map_region_to_restore);
463  setMapRegionOccupiedByPolygon(map_region_to_restore, nav2_costmap_2d::FREE_SPACE);
464  }
465 
466  if (!layered_costmap_->isRolling()) {
467  // if not rolling, the layered costmap (master_grid) has same coordinates as this layer
468  if (!use_maximum_) {
469  updateWithTrueOverwrite(master_grid, min_i, min_j, max_i, max_j);
470  } else {
471  updateWithMax(master_grid, min_i, min_j, max_i, max_j);
472  }
473  } else {
474  // If rolling window, the master_grid is unlikely to have same coordinates as this layer
475  unsigned int mx, my;
476  double wx, wy;
477  // Might even be in a different frame
478  geometry_msgs::msg::TransformStamped transform;
479  try {
480  transform = tf_->lookupTransform(
481  map_frame_, global_frame_, tf2::TimePointZero,
482  transform_tolerance_);
483  } catch (tf2::TransformException & ex) {
484  RCLCPP_ERROR(logger_, "StaticLayer: %s", ex.what());
485  return;
486  }
487  // Copy map data given proper transformations
488  tf2::Transform tf2_transform;
489  tf2::fromMsg(transform.transform, tf2_transform);
490 
491  for (int i = min_i; i < max_i; ++i) {
492  for (int j = min_j; j < max_j; ++j) {
493  // Convert master_grid coordinates (i,j) into global_frame_(wx,wy) coordinates
494  layered_costmap_->getCostmap()->mapToWorld(i, j, wx, wy);
495  // Transform from global_frame_ to map_frame_
496  tf2::Vector3 p(wx, wy, 0);
497  p = tf2_transform * p;
498  // Set master_grid with cell from map
499  if (worldToMap(p.x(), p.y(), mx, my)) {
500  if (!use_maximum_) {
501  master_grid.setCost(i, j, getCost(mx, my));
502  } else {
503  master_grid.setCost(i, j, std::max(getCost(mx, my), master_grid.getCost(i, j)));
504  }
505  }
506  }
507  }
508  }
509 
510  if (footprint_clearing_enabled_ && restore_cleared_footprint_) {
511  // restore the map region occupied by the polygon using cached data
512  restoreMapRegionOccupiedByPolygon(map_region_to_restore);
513  }
514  setCurrent(true);
515 }
516 
524 bool StaticLayer::isEqual(double a, double b, double epsilon)
525 {
526  return std::abs(a - b) < epsilon;
527 }
528 
529 rcl_interfaces::msg::SetParametersResult StaticLayer::validateParameterUpdatesCallback(
530  const std::vector<rclcpp::Parameter> & parameters)
531 {
532  rcl_interfaces::msg::SetParametersResult result;
533  result.successful = true;
534  for (const auto & parameter : parameters) {
535  const auto & param_type = parameter.get_type();
536  const auto & param_name = parameter.get_name();
537  if (param_name.find(name_ + ".") != 0) {
538  continue;
539  }
540 
541  if (param_name == name_ + "." + "map_subscribe_transient_local" ||
542  param_name == name_ + "." + "map_topic" ||
543  param_name == name_ + "." + "subscribe_to_updates")
544  {
545  RCLCPP_WARN(
546  logger_, "%s is not a dynamic parameter "
547  "cannot be changed while running. Rejecting parameter update.", param_name.c_str());
548  } else if (param_type == ParameterType::PARAMETER_BOOL && // NOLINT
549  param_name == name_ + "." + "restore_cleared_footprint")
550  {
551  if (!footprint_clearing_enabled_) {
552  RCLCPP_WARN(
553  logger_, "restore_cleared_footprint cannot be used "
554  "when footprint_clearing_enabled is False. Rejecting parameter update.");
555  result.successful = false;
556  }
557  }
558  }
559  return result;
560 }
561 
562 void
564  const std::vector<rclcpp::Parameter> & parameters)
565 {
566  std::lock_guard<Costmap2D::mutex_t> guard(*getMutex());
567 
568  for (const auto & parameter : parameters) {
569  const auto & param_type = parameter.get_type();
570  const auto & param_name = parameter.get_name();
571  if (param_name.find(name_ + ".") != 0) {
572  continue;
573  }
574 
575  if (param_type == ParameterType::PARAMETER_BOOL) {
576  if (param_name == name_ + "." + "enabled" && enabled_ != parameter.as_bool()) {
577  enabled_ = parameter.as_bool();
578 
579  x_ = y_ = 0;
580  width_ = size_x_;
581  height_ = size_y_;
582  has_updated_data_ = true;
583  setCurrent(false);
584  } else if (param_name == name_ + "." + "footprint_clearing_enabled") {
585  footprint_clearing_enabled_ = parameter.as_bool();
586  } else if (param_name == name_ + "." + "restore_cleared_footprint") {
587  restore_cleared_footprint_ = parameter.as_bool();
588  }
589  }
590  }
591 }
592 
593 } // namespace nav2_costmap_2d
A QoS profile for latched, reliable topics with a history of 10 messages.
A QoS profile for standard reliable topics with a history of 10 messages.
A 2D costmap provides a mapping between points in the world and their associated "costs".
Definition: costmap_2d.hpp:69
void mapToWorld(unsigned int mx, unsigned int my, double &wx, double &wy) const
Convert from map coordinates to world coordinates.
Definition: costmap_2d.cpp:280
void resizeMap(unsigned int size_x, unsigned int size_y, double resolution, double origin_x, double origin_y)
Resize the costmap.
Definition: costmap_2d.cpp:111
unsigned char getCost(unsigned int mx, unsigned int my) const
Get the cost of a cell in the costmap.
Definition: costmap_2d.cpp:265
bool worldToMap(double wx, double wy, unsigned int &mx, unsigned int &my) const
Convert from world coordinates to map coordinates.
Definition: costmap_2d.cpp:292
double getResolution() const
Accessor for the resolution of the costmap.
Definition: costmap_2d.cpp:578
double getSizeInMetersY() const
Accessor for the y size of the costmap in meters.
Definition: costmap_2d.cpp:563
double getSizeInMetersX() const
Accessor for the x size of the costmap in meters.
Definition: costmap_2d.cpp:558
void setMapRegionOccupiedByPolygon(const std::vector< MapLocation > &polygon_map_region, unsigned char new_cost_value)
Sets the given map region to desired value.
Definition: costmap_2d.cpp:421
void restoreMapRegionOccupiedByPolygon(const std::vector< MapLocation > &polygon_map_region)
Restores the corresponding map region using given map region.
Definition: costmap_2d.cpp:430
bool getMapRegionOccupiedByPolygon(const std::vector< geometry_msgs::msg::Point > &polygon, std::vector< MapLocation > &polygon_map_region)
Gets the map region occupied by polygon.
Definition: costmap_2d.cpp:438
unsigned int getSizeInCellsX() const
Accessor for the x size of the costmap in cells.
Definition: costmap_2d.cpp:548
double getOriginY() const
Accessor for the y origin of the costmap.
Definition: costmap_2d.cpp:573
unsigned int getSizeInCellsY() const
Accessor for the y size of the costmap in cells.
Definition: costmap_2d.cpp:553
double getOriginX() const
Accessor for the x origin of the costmap.
Definition: costmap_2d.cpp:568
void setCost(unsigned int mx, unsigned int my, unsigned char cost)
Set the cost of a cell in the costmap.
Definition: costmap_2d.cpp:275
void touch(double x, double y, double *min_x, double *min_y, double *max_x, double *max_y)
Abstract class for layered costmap plugin implementations.
Definition: layer.hpp:60
std::string joinWithParentNamespace(const std::string &topic)
Definition: layer.cpp:83
void setCurrent(bool current)
Set whether the data in the layer is up to date.
Definition: layer.hpp:147
const std::vector< geometry_msgs::msg::Point > & getFootprint() const
Convenience function for layered_costmap_->getFootprint().
Definition: layer.cpp:70
bool isRolling()
If this costmap is rolling or not.
Costmap2D * getCostmap()
Get the costmap pointer to the master costmap.
void resizeMap(unsigned int size_x, unsigned int size_y, double resolution, double origin_x, double origin_y, bool size_locked=false)
Resize the map to a new size, resolution, or origin.
bool isSizeLocked()
Get if the size of the costmap is locked.
Takes in a map generated from SLAM to add costs to costmap.
void getParameters()
Get parameters of layer.
virtual ~StaticLayer()
Static Layer destructor.
virtual void deactivate()
Deactivate this layer.
bool has_updated_data_
frame that map is located in
void updateParametersCallback(const std::vector< rclcpp::Parameter > &parameters)
Apply parameter updates after validation This callback is executed when parameters have been successf...
unsigned char interpretValue(unsigned char value)
Interpret the value in the static map given on the topic to convert into costs for the costmap to uti...
StaticLayer()
Static Layer constructor.
virtual void matchSize()
Match the size of the master costmap.
virtual void onInitialize()
Initialization process of layer on startup.
void updateFootprint(double robot_x, double robot_y, double robot_yaw, double *min_x, double *min_y, double *max_x, double *max_y)
Clear costmap layer info below the robot's footprint.
virtual void activate()
Activate this layer.
void incomingUpdate(map_msgs::msg::OccupancyGridUpdate::ConstSharedPtr update)
Callback to update the costmap's map from the map_server (or SLAM) with an update in a particular are...
bool isEqual(double a, double b, double epsilon)
Check if two double values are equal within a given epsilon.
std::string global_frame_
The global frame for the costmap.
void processMap(const nav_msgs::msg::OccupancyGrid &new_map)
Process a new map coming from a topic.
virtual void updateCosts(nav2_costmap_2d::Costmap2D &master_grid, int min_i, int min_j, int max_i, int max_j)
Update the costs in the master costmap in the window.
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 incomingMap(const nav_msgs::msg::OccupancyGrid::ConstSharedPtr &new_map)
Callback to update the costmap's map from the map_server.
virtual void updateBounds(double robot_x, double robot_y, double robot_yaw, double *min_x, double *min_y, double *max_x, double *max_y)
Update the bounds of the master costmap by this layer's update dimensions.
virtual void reset()
Reset this costmap.
void transformFootprint(double x, double y, double theta, const std::vector< geometry_msgs::msg::Point > &footprint_spec, std::vector< geometry_msgs::msg::Point > &oriented_footprint)
Given a pose and base footprint, build the oriented footprint of the robot (list of Points)
Definition: footprint.cpp:112