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_;
513 if (cloud.height == 0 || cloud.width == 0) {
517 const unsigned int max_range_cells =
cellDistance(obs.obstacle_max_range_);
518 const unsigned int min_range_cells =
cellDistance(obs.obstacle_min_range_);
521 if (!
worldToMap(obs.origin_.x, obs.origin_.y, x0, y0)) {
522 RCLCPP_DEBUG(logger_,
"Sensor origin is out of map bounds");
526 sensor_msgs::PointCloud2ConstIterator<float> iter_x(cloud,
"x");
527 sensor_msgs::PointCloud2ConstIterator<float> iter_y(cloud,
"y");
528 sensor_msgs::PointCloud2ConstIterator<float> iter_z(cloud,
"z");
530 for (; iter_x != iter_x.end(); ++iter_x, ++iter_y, ++iter_z) {
531 double px = *iter_x, py = *iter_y, pz = *iter_z;
535 RCLCPP_DEBUG(logger_,
"The point is too low");
541 RCLCPP_DEBUG(logger_,
"The point is too high");
548 RCLCPP_DEBUG(logger_,
"Computing map coords failed");
554 const double wdx = px - obs.origin_.x;
555 const double wdy = py - obs.origin_.y;
556 const double world_dist_sq = wdx * wdx + wdy * wdy;
557 if (world_dist_sq > obs.obstacle_max_range_ * obs.obstacle_max_range_) {
560 if (world_dist_sq < obs.obstacle_min_range_ * obs.obstacle_min_range_) {
567 const int dx =
static_cast<int>(mx) -
static_cast<int>(x0);
568 const int dy =
static_cast<int>(my) -
static_cast<int>(y0);
569 const unsigned int dist =
static_cast<unsigned int>(
570 std::hypot(
static_cast<double>(dx),
static_cast<double>(dy)));
573 if (dist > max_range_cells) {
574 RCLCPP_DEBUG(logger_,
"The point is too far away");
579 if (dist < min_range_cells) {
580 RCLCPP_DEBUG(logger_,
"The point is too close");
584 unsigned int index =
getIndex(mx, my);
585 costmap_[index] = LETHAL_OBSTACLE;
586 touch(px, py, min_x, min_y, max_x, max_y);
590 updateFootprint(robot_x, robot_y, robot_yaw, min_x, min_y, max_x, max_y);
595 double robot_x,
double robot_y,
double robot_yaw,
596 double * min_x,
double * min_y,
600 if (!footprint_clearing_enabled_) {
return;}
603 for (
unsigned int i = 0; i < transformed_footprint_.size(); i++) {
604 touch(transformed_footprint_[i].x, transformed_footprint_[i].y, min_x, min_y, max_x, max_y);
614 std::lock_guard<Costmap2D::mutex_t> guard(*getMutex());
625 if (footprint_clearing_enabled_) {
629 switch (combination_method_) {
631 updateWithOverwrite(master_grid, min_i, min_j, max_i, max_j);
634 updateWithMax(master_grid, min_i, min_j, max_i, max_j);
637 updateWithMaxWithoutUnknownOverwrite(master_grid, min_i, min_j, max_i, max_j);
645 ObstacleLayer::addStaticObservation(
647 bool marking,
bool clearing)
649 const auto observation = Observation::make_shared(std::move(obs));
651 static_marking_observations_.push_back(observation);
654 static_clearing_observations_.push_back(observation);
659 ObstacleLayer::clearStaticObservations(
bool marking,
bool clearing)
662 static_marking_observations_.clear();
665 static_clearing_observations_.clear();
671 std::vector<Observation::ConstSharedPtr> & marking_observations)
const
676 if (marking_buffer) {
677 marking_buffer->lock();
678 marking_buffer->getObservations(marking_observations);
679 current = marking_buffer->isCurrent() && current;
680 marking_buffer->unlock();
683 marking_observations.insert(
684 marking_observations.end(),
685 static_marking_observations_.begin(), static_marking_observations_.end());
691 std::vector<Observation::ConstSharedPtr> & clearing_observations)
const
696 if (clearing_buffer) {
697 clearing_buffer->lock();
698 clearing_buffer->getObservations(clearing_observations);
699 current = clearing_buffer->isCurrent() && current;
700 clearing_buffer->unlock();
703 clearing_observations.insert(
704 clearing_observations.end(),
705 static_clearing_observations_.begin(), static_clearing_observations_.end());
711 const Observation & clearing_observation,
double * min_x,
716 double ox = clearing_observation.origin_.x;
717 double oy = clearing_observation.origin_.y;
718 const sensor_msgs::msg::PointCloud2 & cloud = clearing_observation.cloud_;
725 "Sensor origin at (%.2f, %.2f) is out of map bounds (%.2f, %.2f) to (%.2f, %.2f). "
726 "The costmap cannot raytrace for it.",
728 origin_x_, origin_y_,
734 double origin_x = origin_x_, origin_y = origin_y_;
735 double map_end_x = origin_x + size_x_ * resolution_;
736 double map_end_y = origin_y + size_y_ * resolution_;
739 touch(ox, oy, min_x, min_y, max_x, max_y);
742 if (cloud.height == 0 || cloud.width == 0) {
748 sensor_msgs::PointCloud2ConstIterator<float> iter_x(cloud,
"x");
749 sensor_msgs::PointCloud2ConstIterator<float> iter_y(cloud,
"y");
751 for (; iter_x != iter_x.end(); ++iter_x, ++iter_y) {
762 double t = (origin_x - ox) / a;
767 double t = (origin_y - oy) / b;
773 if (wx > map_end_x) {
774 double t = (map_end_x - ox) / a;
775 wx = map_end_x - .001;
778 if (wy > map_end_y) {
779 double t = (map_end_y - oy) / b;
781 wy = map_end_y - .001;
792 unsigned int cell_raytrace_max_range =
cellDistance(clearing_observation.raytrace_max_range_);
793 unsigned int cell_raytrace_min_range =
cellDistance(clearing_observation.raytrace_min_range_);
794 MarkCell marker(costmap_, FREE_SPACE);
796 nav2_util::raytraceLine(
797 marker, x0, y0, x1, y1, size_x_, cell_raytrace_max_range, cell_raytrace_min_range);
800 ox, oy, wx, wy, clearing_observation.raytrace_max_range_,
801 clearing_observation.raytrace_min_range_, min_x, min_y, max_x,
809 auto node = node_.lock();
814 this, std::placeholders::_1));
815 on_set_params_handler_ = node->add_on_set_parameters_callback(
818 this, std::placeholders::_1));
835 auto node = node_.lock();
840 if (on_set_params_handler_ && node) {
841 node->remove_on_set_parameters_callback(on_set_params_handler_.get());
843 on_set_params_handler_.reset();
854 double ox,
double oy,
double wx,
double wy,
double max_range,
double min_range,
855 double * min_x,
double * min_y,
double * max_x,
double * max_y)
857 double dx = wx - ox, dy = wy - oy;
858 double full_distance = hypot(dx, dy);
859 if (full_distance < min_range) {
862 double scale = std::min(1.0, max_range / full_distance);
863 double ex = ox + dx * scale, ey = oy + dy * scale;
864 touch(ex, ey, min_x, min_y, max_x, max_y);
880 if (observation_buffer) {
881 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