39 #include "nav2_costmap_2d/obstacle_layer.hpp"
46 #include "pluginlib/class_list_macros.hpp"
47 #include "sensor_msgs/point_cloud2_iterator.hpp"
48 #include "nav2_util/raytrace_line_2d.hpp"
49 #include "nav2_costmap_2d/costmap_math.hpp"
50 #include "nav2_ros_common/node_utils.hpp"
51 #include "nav2_ros_common/interface_factories.hpp"
52 #include "rclcpp/version.h"
56 using nav2_costmap_2d::NO_INFORMATION;
57 using nav2_costmap_2d::LETHAL_OBSTACLE;
58 using nav2_costmap_2d::FREE_SPACE;
62 using rcl_interfaces::msg::ParameterType;
76 bool track_unknown_space =
false;
77 double transform_tolerance = 0.1;
80 std::string topics_string;
82 auto node = node_.lock();
84 throw std::runtime_error{
"Failed to lock node"};
87 allow_parameter_qos_overrides_ = nav2::declare_or_get_parameter(node,
88 "allow_parameter_qos_overrides",
true);
89 enabled_ = node->declare_or_get_parameter(name_ +
"." +
"enabled",
true);
90 footprint_clearing_enabled_ = node->declare_or_get_parameter(
91 name_ +
"." +
"footprint_clearing_enabled",
true);
93 name_ +
"." +
"min_obstacle_height", 0.0);
95 name_ +
"." +
"max_obstacle_height", 2.0);
96 int combination_method_param = node->declare_or_get_parameter(
97 name_ +
"." +
"combination_method", 1);
98 topics_string = node->declare_or_get_parameter(
99 name_ +
"." +
"observation_sources", std::string(
""));
100 node->get_parameter(
"track_unknown_space", track_unknown_space);
101 node->get_parameter(
"transform_tolerance", transform_tolerance);
102 double tf_filter_tolerance = nav2::declare_or_get_parameter(
104 "tf_filter_tolerance", 0.05);
109 "Subscribed to Topics: %s", topics_string.c_str());
111 rolling_window_ = layered_costmap_->
isRolling();
113 if (track_unknown_space) {
114 default_value_ = NO_INFORMATION;
116 default_value_ = FREE_SPACE;
126 std::stringstream ss(topics_string);
129 while (ss >> source) {
131 double observation_keep_time, expected_update_rate, min_obstacle_height, max_obstacle_height;
132 std::string topic, sensor_frame, data_type, transport_type;
133 bool inf_is_valid, clearing, marking;
135 topic = node->declare_or_get_parameter(
136 name_ +
"." + source +
"." +
"topic", source);
137 sensor_frame = node->declare_or_get_parameter(
138 name_ +
"." + source +
"." +
"sensor_frame", std::string(
""));
139 observation_keep_time = node->declare_or_get_parameter(
140 name_ +
"." + source +
"." +
"observation_persistence", 0.0);
141 expected_update_rate = node->declare_or_get_parameter(
142 name_ +
"." + source +
"." +
"expected_update_rate", 0.0);
143 data_type = node->declare_or_get_parameter(
144 name_ +
"." + source +
"." +
"data_type", std::string(
"LaserScan"));
145 min_obstacle_height = node->declare_or_get_parameter(
146 name_ +
"." + source +
"." +
"min_obstacle_height", 0.0);
147 max_obstacle_height = node->declare_or_get_parameter(
148 name_ +
"." + source +
"." +
"max_obstacle_height", 0.0);
149 inf_is_valid = node->declare_or_get_parameter(
150 name_ +
"." + source +
"." +
"inf_is_valid",
false);
151 marking = node->declare_or_get_parameter(
152 name_ +
"." + source +
"." +
"marking",
true);
153 clearing = node->declare_or_get_parameter(
154 name_ +
"." + source +
"." +
"clearing",
false);
155 transport_type = node->declare_or_get_parameter(
156 name_ +
"." + source +
"." +
"transport_type", std::string(
"raw"));
158 if (!(data_type ==
"PointCloud2" || data_type ==
"LaserScan")) {
161 "Only topics that use point cloud2s or laser scans are currently supported");
162 throw std::runtime_error(
163 "Only topics that use point cloud2s or laser scans are currently supported");
167 double obstacle_max_range = node->declare_or_get_parameter(
168 name_ +
"." + source +
"." +
"obstacle_max_range", 2.5);
169 double obstacle_min_range = node->declare_or_get_parameter(
170 name_ +
"." + source +
"." +
"obstacle_min_range", 0.0);
173 double raytrace_max_range = node->declare_or_get_parameter(
174 name_ +
"." + source +
"." +
"raytrace_max_range", 3.0);
175 double raytrace_min_range = node->declare_or_get_parameter(
176 name_ +
"." + source +
"." +
"raytrace_min_range", 0.0);
182 "Creating an observation buffer for source %s, topic %s, frame %s",
183 source.c_str(), topic.c_str(),
184 sensor_frame.c_str());
188 std::make_shared<ObservationBuffer>(node, topic, observation_keep_time,
189 expected_update_rate,
191 max_obstacle_height, obstacle_max_range, obstacle_min_range, raytrace_max_range,
192 raytrace_min_range, *tf_,
194 sensor_frame, tf2::durationFromSec(transform_tolerance)));
208 "Created an observation buffer for source %s, topic %s, global frame: %s, "
209 "expected update rate: %.2f, observation persistence: %.2f",
210 source.c_str(), topic.c_str(),
211 global_frame_.c_str(), expected_update_rate, observation_keep_time);
216 if (data_type ==
"LaserScan") {
217 auto sub_opt = nav2::interfaces::createSubscriptionOptions(
218 topic, allow_parameter_qos_overrides_, callback_group_);
221 #if RCLCPP_VERSION_GTE(29, 6, 0)
222 std::shared_ptr<message_filters::Subscriber<sensor_msgs::msg::LaserScan>> sub;
224 std::shared_ptr<message_filters::Subscriber<sensor_msgs::msg::LaserScan,
225 rclcpp_lifecycle::LifecycleNode>> sub;
229 #if RCLCPP_VERSION_GTE(29, 6, 0)
230 sub = std::make_shared<message_filters::Subscriber<sensor_msgs::msg::LaserScan>>(
231 node, topic, custom_qos_profile, sub_opt);
233 #elif RCLCPP_VERSION_GTE(29, 0, 0)
234 sub = std::make_shared<message_filters::Subscriber<sensor_msgs::msg::LaserScan,
235 rclcpp_lifecycle::LifecycleNode>>(
236 std::static_pointer_cast<rclcpp_lifecycle::LifecycleNode>(node),
237 topic, custom_qos_profile, sub_opt);
240 sub = std::make_shared<message_filters::Subscriber<sensor_msgs::msg::LaserScan,
241 rclcpp_lifecycle::LifecycleNode>>(
242 std::static_pointer_cast<rclcpp_lifecycle::LifecycleNode>(node),
243 topic, custom_qos_profile.get_rmw_qos_profile(), sub_opt);
248 auto filter = nav2::create_message_filter<sensor_msgs::msg::LaserScan>(
250 node, tf2::durationFromSec(transform_tolerance));
253 filter->registerCallback(
259 filter->registerCallback(
269 rclcpp::Duration::from_seconds(
270 tf_filter_tolerance));
273 auto sub_opt = nav2::interfaces::createSubscriptionOptions(
274 topic, allow_parameter_qos_overrides_, callback_group_);
277 #if RCLCPP_VERSION_GTE(30, 0, 0)
278 std::shared_ptr<point_cloud_transport::SubscriberFilter> sub;
280 #elif RCLCPP_VERSION_GTE(29, 6, 0)
281 std::shared_ptr<message_filters::Subscriber<sensor_msgs::msg::PointCloud2>> sub;
283 std::shared_ptr<message_filters::Subscriber<sensor_msgs::msg::PointCloud2,
284 rclcpp_lifecycle::LifecycleNode>> sub;
288 #if RCLCPP_VERSION_GTE(30, 0, 0)
289 sub = std::make_shared<point_cloud_transport::SubscriberFilter>(
290 *node, topic, transport_type, custom_qos_profile, sub_opt);
292 #elif RCLCPP_VERSION_GTE(29, 6, 0)
293 sub = std::make_shared<message_filters::Subscriber<sensor_msgs::msg::PointCloud2>>(
294 node, topic, custom_qos_profile, sub_opt);
296 #elif RCLCPP_VERSION_GTE(29, 0, 0)
297 sub = std::make_shared<message_filters::Subscriber<sensor_msgs::msg::PointCloud2,
298 rclcpp_lifecycle::LifecycleNode>>(
299 std::static_pointer_cast<rclcpp_lifecycle::LifecycleNode>(node),
300 topic, custom_qos_profile, sub_opt);
303 sub = std::make_shared<message_filters::Subscriber<sensor_msgs::msg::PointCloud2,
304 rclcpp_lifecycle::LifecycleNode>>(
305 std::static_pointer_cast<rclcpp_lifecycle::LifecycleNode>(node),
306 topic, custom_qos_profile.get_rmw_qos_profile(), sub_opt);
314 "obstacle_layer: inf_is_valid option is not applicable to PointCloud observations.");
317 auto filter = nav2::create_message_filter<sensor_msgs::msg::PointCloud2>(
319 node, tf2::durationFromSec(transform_tolerance));
321 filter->registerCallback(
330 if (sensor_frame !=
"") {
331 std::vector<std::string> target_frames;
333 target_frames.push_back(sensor_frame);
340 const std::vector<rclcpp::Parameter> & )
342 rcl_interfaces::msg::SetParametersResult result;
343 result.successful =
true;
349 const std::vector<rclcpp::Parameter> & parameters)
351 std::lock_guard<Costmap2D::mutex_t> guard(*getMutex());
353 for (
const auto & parameter : parameters) {
354 const auto & param_type = parameter.get_type();
355 const auto & param_name = parameter.get_name();
356 if (param_name.find(name_ +
".") != 0) {
360 if (param_type == ParameterType::PARAMETER_DOUBLE) {
361 if (param_name == name_ +
"." +
"min_obstacle_height" &&
366 }
else if (param_name == name_ +
"." +
"max_obstacle_height" &&
372 }
else if (param_type == ParameterType::PARAMETER_BOOL) {
373 if (param_name == name_ +
"." +
"enabled" && enabled_ != parameter.as_bool()) {
374 enabled_ = parameter.as_bool();
376 }
else if (param_name == name_ +
"." +
"footprint_clearing_enabled") {
377 footprint_clearing_enabled_ = parameter.as_bool();
379 }
else if (param_type == ParameterType::PARAMETER_INTEGER) {
380 if (param_name == name_ +
"." +
"combination_method") {
389 sensor_msgs::msg::LaserScan::ConstSharedPtr message,
390 const std::shared_ptr<ObservationBuffer> & buffer)
393 sensor_msgs::msg::PointCloud2 cloud;
394 cloud.header = message->header;
398 projector_.transformLaserScanToPointCloud(message->header.frame_id, *message, cloud, *tf_);
399 }
catch (tf2::TransformException & ex) {
402 "High fidelity enabled, but TF returned a transform exception to frame %s: %s",
406 }
catch (std::runtime_error & ex) {
409 "transformLaserScanToPointCloud error, it seems the message from laser is malformed."
410 " Ignore this message. what(): %s",
417 buffer->bufferCloud(cloud);
423 sensor_msgs::msg::LaserScan::ConstSharedPtr raw_message,
424 const std::shared_ptr<ObservationBuffer> & buffer)
427 float epsilon = 0.0001;
428 sensor_msgs::msg::LaserScan message = *raw_message;
429 for (
size_t i = 0; i < message.ranges.size(); i++) {
430 float range = message.ranges[i];
431 if (!std::isfinite(range) && range > 0) {
432 message.ranges[i] = message.range_max - epsilon;
437 sensor_msgs::msg::PointCloud2 cloud;
438 cloud.header = message.header;
442 projector_.transformLaserScanToPointCloud(message.header.frame_id, message, cloud, *tf_);
443 }
catch (tf2::TransformException & ex) {
446 "High fidelity enabled, but TF returned a transform exception to frame %s: %s",
449 }
catch (std::runtime_error & ex) {
452 "transformLaserScanToPointCloud error, it seems the message from laser is malformed."
453 " Ignore this message. what(): %s",
460 buffer->bufferCloud(cloud);
466 sensor_msgs::msg::PointCloud2::ConstSharedPtr message,
467 const std::shared_ptr<ObservationBuffer> & buffer)
471 buffer->bufferCloud(*message);
477 double robot_x,
double robot_y,
double robot_yaw,
double * min_x,
478 double * min_y,
double * max_x,
double * max_y)
480 std::lock_guard<Costmap2D::mutex_t> guard(*getMutex());
481 if (rolling_window_) {
487 useExtraBounds(min_x, min_y, max_x, max_y);
490 std::vector<Observation::ConstSharedPtr> observations, clearing_observations;
502 for (
const auto & clearing_observation : clearing_observations) {
507 for (
const auto & observation : observations) {
510 const sensor_msgs::msg::PointCloud2 & cloud = obs.cloud_;
512 const unsigned int max_range_cells =
cellDistance(obs.obstacle_max_range_);
513 const unsigned int min_range_cells =
cellDistance(obs.obstacle_min_range_);
516 if (!
worldToMap(obs.origin_.x, obs.origin_.y, x0, y0)) {
517 RCLCPP_DEBUG(logger_,
"Sensor origin is out of map bounds");
521 sensor_msgs::PointCloud2ConstIterator<float> iter_x(cloud,
"x");
522 sensor_msgs::PointCloud2ConstIterator<float> iter_y(cloud,
"y");
523 sensor_msgs::PointCloud2ConstIterator<float> iter_z(cloud,
"z");
525 for (; iter_x != iter_x.end(); ++iter_x, ++iter_y, ++iter_z) {
526 double px = *iter_x, py = *iter_y, pz = *iter_z;
530 RCLCPP_DEBUG(logger_,
"The point is too low");
536 RCLCPP_DEBUG(logger_,
"The point is too high");
543 RCLCPP_DEBUG(logger_,
"Computing map coords failed");
549 const double wdx = px - obs.origin_.x;
550 const double wdy = py - obs.origin_.y;
551 const double world_dist_sq = wdx * wdx + wdy * wdy;
552 if (world_dist_sq > obs.obstacle_max_range_ * obs.obstacle_max_range_) {
555 if (world_dist_sq < obs.obstacle_min_range_ * obs.obstacle_min_range_) {
562 const int dx =
static_cast<int>(mx) -
static_cast<int>(x0);
563 const int dy =
static_cast<int>(my) -
static_cast<int>(y0);
564 const unsigned int dist =
static_cast<unsigned int>(
565 std::hypot(
static_cast<double>(dx),
static_cast<double>(dy)));
568 if (dist > max_range_cells) {
569 RCLCPP_DEBUG(logger_,
"The point is too far away");
574 if (dist < min_range_cells) {
575 RCLCPP_DEBUG(logger_,
"The point is too close");
579 unsigned int index =
getIndex(mx, my);
580 costmap_[index] = LETHAL_OBSTACLE;
581 touch(px, py, min_x, min_y, max_x, max_y);
585 updateFootprint(robot_x, robot_y, robot_yaw, min_x, min_y, max_x, max_y);
590 double robot_x,
double robot_y,
double robot_yaw,
591 double * min_x,
double * min_y,
595 if (!footprint_clearing_enabled_) {
return;}
598 for (
unsigned int i = 0; i < transformed_footprint_.size(); i++) {
599 touch(transformed_footprint_[i].x, transformed_footprint_[i].y, min_x, min_y, max_x, max_y);
609 std::lock_guard<Costmap2D::mutex_t> guard(*getMutex());
620 if (footprint_clearing_enabled_) {
624 switch (combination_method_) {
626 updateWithOverwrite(master_grid, min_i, min_j, max_i, max_j);
629 updateWithMax(master_grid, min_i, min_j, max_i, max_j);
632 updateWithMaxWithoutUnknownOverwrite(master_grid, min_i, min_j, max_i, max_j);
640 ObstacleLayer::addStaticObservation(
642 bool marking,
bool clearing)
644 const auto observation = Observation::make_shared(std::move(obs));
646 static_marking_observations_.push_back(observation);
649 static_clearing_observations_.push_back(observation);
654 ObstacleLayer::clearStaticObservations(
bool marking,
bool clearing)
657 static_marking_observations_.clear();
660 static_clearing_observations_.clear();
666 std::vector<Observation::ConstSharedPtr> & marking_observations)
const
671 if (marking_buffer) {
672 marking_buffer->lock();
673 marking_buffer->getObservations(marking_observations);
674 current = marking_buffer->isCurrent() && current;
675 marking_buffer->unlock();
678 marking_observations.insert(
679 marking_observations.end(),
680 static_marking_observations_.begin(), static_marking_observations_.end());
686 std::vector<Observation::ConstSharedPtr> & clearing_observations)
const
691 if (clearing_buffer) {
692 clearing_buffer->lock();
693 clearing_buffer->getObservations(clearing_observations);
694 current = clearing_buffer->isCurrent() && current;
695 clearing_buffer->unlock();
698 clearing_observations.insert(
699 clearing_observations.end(),
700 static_clearing_observations_.begin(), static_clearing_observations_.end());
706 const Observation & clearing_observation,
double * min_x,
711 double ox = clearing_observation.origin_.x;
712 double oy = clearing_observation.origin_.y;
713 const sensor_msgs::msg::PointCloud2 & cloud = clearing_observation.cloud_;
720 "Sensor origin at (%.2f, %.2f) is out of map bounds (%.2f, %.2f) to (%.2f, %.2f). "
721 "The costmap cannot raytrace for it.",
723 origin_x_, origin_y_,
729 double origin_x = origin_x_, origin_y = origin_y_;
730 double map_end_x = origin_x + size_x_ * resolution_;
731 double map_end_y = origin_y + size_y_ * resolution_;
734 touch(ox, oy, min_x, min_y, max_x, max_y);
738 sensor_msgs::PointCloud2ConstIterator<float> iter_x(cloud,
"x");
739 sensor_msgs::PointCloud2ConstIterator<float> iter_y(cloud,
"y");
741 for (; iter_x != iter_x.end(); ++iter_x, ++iter_y) {
752 double t = (origin_x - ox) / a;
757 double t = (origin_y - oy) / b;
763 if (wx > map_end_x) {
764 double t = (map_end_x - ox) / a;
765 wx = map_end_x - .001;
768 if (wy > map_end_y) {
769 double t = (map_end_y - oy) / b;
771 wy = map_end_y - .001;
782 unsigned int cell_raytrace_max_range =
cellDistance(clearing_observation.raytrace_max_range_);
783 unsigned int cell_raytrace_min_range =
cellDistance(clearing_observation.raytrace_min_range_);
784 MarkCell marker(costmap_, FREE_SPACE);
786 nav2_util::raytraceLine(
787 marker, x0, y0, x1, y1, size_x_, cell_raytrace_max_range, cell_raytrace_min_range);
790 ox, oy, wx, wy, clearing_observation.raytrace_max_range_,
791 clearing_observation.raytrace_min_range_, min_x, min_y, max_x,
799 auto node = node_.lock();
804 this, std::placeholders::_1));
805 on_set_params_handler_ = node->add_on_set_parameters_callback(
808 this, std::placeholders::_1));
825 auto node = node_.lock();
830 if (on_set_params_handler_ && node) {
831 node->remove_on_set_parameters_callback(on_set_params_handler_.get());
833 on_set_params_handler_.reset();
844 double ox,
double oy,
double wx,
double wy,
double max_range,
double min_range,
845 double * min_x,
double * min_y,
double * max_x,
double * max_y)
847 double dx = wx - ox, dy = wy - oy;
848 double full_distance = hypot(dx, dy);
849 if (full_distance < min_range) {
852 double scale = std::min(1.0, max_range / full_distance);
853 double ex = ox + dx * scale, ey = oy + dy * scale;
854 touch(ex, ey, min_x, min_y, max_x, max_y);
870 if (observation_buffer) {
871 observation_buffer->resetLastUpdated();
A QoS profile for best-effort sensor data with a history of 10 messages.
A 2D costmap provides a mapping between points in the world and their associated "costs".
unsigned int getIndex(unsigned int mx, unsigned int my) const
Given two map coordinates... compute the associated index.
bool worldToMap(double wx, double wy, unsigned int &mx, unsigned int &my) const
Convert from world coordinates to map coordinates.
virtual void updateOrigin(double new_origin_x, double new_origin_y)
Move the origin of the costmap to a new location.... keeping data when it can.
bool setConvexPolygonCost(const std::vector< geometry_msgs::msg::Point > &polygon, unsigned char cost_value)
Sets the cost of a convex polygon to a desired value.
double getSizeInMetersY() const
Accessor for the y size of the costmap in meters.
double getSizeInMetersX() const
Accessor for the x size of the costmap in meters.
virtual void resetMaps()
Resets the costmap and static_map to be unknown space.
unsigned int cellDistance(double world_dist)
Given distance in the world... convert it to cells.
void touch(double x, double y, double *min_x, double *min_y, double *max_x, double *max_y)
virtual void matchSize()
Match the size of the master costmap.
CombinationMethod combination_method_from_int(const int value)
Converts an integer to a CombinationMethod enum and logs on failure.
Abstract class for layered costmap plugin implementations.
std::string joinWithParentNamespace(const std::string &topic)
void setCurrent(bool current)
Set whether the data in the layer is up to date.
bool isCurrent() const
Check to make sure all the data in the layer is up to date. If the layer is not up to date,...
const std::vector< geometry_msgs::msg::Point > & getFootprint() const
Convenience function for layered_costmap_->getFootprint().
bool isRolling()
If this costmap is rolling or not.
Takes in point clouds from sensors, transforms them to the desired frame, and stores them.
Stores an observation in terms of a point cloud and the origin of the source.
Takes in laser and pointcloud data to populate into 2D costmap.
void pointCloud2Callback(sensor_msgs::msg::PointCloud2::ConstSharedPtr message, const std::shared_ptr< nav2_costmap_2d::ObservationBuffer > &buffer)
A callback to handle buffering PointCloud2 messages.
std::vector< std::shared_ptr< nav2_costmap_2d::ObservationBuffer > > marking_buffers_
Used to store observation buffers used for marking obstacles.
virtual void activate()
Activate the layer.
std::vector< std::shared_ptr< tf2_ros::MessageFilterBase > > observation_notifiers_
Used to make sure that transforms are available for each sensor.
std::string global_frame_
The global frame for the costmap.
void updateRaytraceBounds(double ox, double oy, double wx, double wy, double max_range, double min_range, double *min_x, double *min_y, double *max_x, double *max_y)
Process update costmap with raytracing the window bounds.
void laserScanCallback(sensor_msgs::msg::LaserScan::ConstSharedPtr message, const std::shared_ptr< nav2_costmap_2d::ObservationBuffer > &buffer)
A callback to handle buffering LaserScan messages.
bool getMarkingObservations(std::vector< nav2_costmap_2d::Observation::ConstSharedPtr > &marking_observations) const
Get the observations used to mark space.
void resetBuffersLastUpdated()
triggers the update of observations buffer
bool getClearingObservations(std::vector< nav2_costmap_2d::Observation::ConstSharedPtr > &clearing_observations) const
Get the observations used to clear space.
rclcpp::node_interfaces::PostSetParametersCallbackHandle::SharedPtr post_set_params_handler_
Dynamic parameters handler.
std::vector< std::shared_ptr< nav2_costmap_2d::ObservationBuffer > > clearing_buffers_
Used to store observation buffers used for clearing obstacles.
void laserScanValidInfCallback(sensor_msgs::msg::LaserScan::ConstSharedPtr message, const std::shared_ptr< nav2_costmap_2d::ObservationBuffer > &buffer)
A callback to handle buffering LaserScan messages which need filtering to turn Inf values into range_...
std::vector< std::shared_ptr< message_filters::SubscriberBase< rclcpp_lifecycle::LifecycleNode > > > observation_subscribers_
Used for the observation message filters.
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.
rcl_interfaces::msg::SetParametersResult validateParameterUpdatesCallback(const std::vector< rclcpp::Parameter > ¶meters)
Validate incoming parameter updates before applying them. This callback is triggered when one or more...
virtual void deactivate()
Deactivate the layer.
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.
virtual ~ObstacleLayer()
A destructor.
std::vector< std::shared_ptr< nav2_costmap_2d::ObservationBuffer > > observation_buffers_
Used to store observations from various sensors.
virtual void onInitialize()
Initialization process of layer on startup.
double min_obstacle_height_
Max Obstacle Height.
laser_geometry::LaserProjection projector_
Used to project laser scans into point clouds.
double max_obstacle_height_
Max Obstacle Height.
virtual void reset()
Reset this costmap.
virtual void raytraceFreespace(const nav2_costmap_2d::Observation &clearing_observation, double *min_x, double *min_y, double *max_x, double *max_y)
Clear freespace based on one observation.
void updateParametersCallback(const std::vector< rclcpp::Parameter > ¶meters)
Apply parameter updates after validation This callback is executed when parameters have been successf...
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.
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)
@ MaxWithoutUnknownOverwrite