39 #include "nav2_costmap_2d/costmap_2d_ros.hpp"
49 #include "nav2_costmap_2d/layered_costmap.hpp"
50 #include "nav2_util/execution_timer.hpp"
51 #include "nav2_ros_common/node_utils.hpp"
52 #include "nav2_ros_common/rate.hpp"
53 #include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
54 #include "nav2_ros_common/tf2_factories.hpp"
55 #include "nav2_util/robot_utils.hpp"
56 #include "rcl_interfaces/msg/set_parameters_result.hpp"
58 using namespace std::chrono_literals;
59 using std::placeholders::_1;
60 using rcl_interfaces::msg::ParameterType;
64 Costmap2DROS::Costmap2DROS(
const rclcpp::NodeOptions & options)
65 : nav2::LifecycleNode(
"costmap",
"", options),
67 default_plugins_{
"static_layer",
"obstacle_layer",
"inflation_layer"},
69 "nav2_costmap_2d::StaticLayer",
70 "nav2_costmap_2d::ObstacleLayer",
71 "nav2_costmap_2d::InflationLayer"}
78 const std::string & name,
79 const std::string & parent_namespace,
80 const bool & use_sim_time,
81 const rclcpp::NodeOptions & parent_options)
83 std::vector<std::string> new_arguments = parent_options.arguments();
84 bool use_intra_process_comms = parent_options.use_intra_process_comms();
85 nav2::replaceOrAddArgument(
86 new_arguments,
"-r",
"__ns",
87 "__ns:=" + nav2::add_namespaces(parent_namespace, name));
88 nav2::replaceOrAddArgument(new_arguments,
"-r",
"__node", name +
":" +
"__node:=" + name);
89 nav2::replaceOrAddArgument(
90 new_arguments,
"-p",
"use_sim_time",
91 "use_sim_time:=" + std::string(use_sim_time ?
"true" :
"false"));
92 return rclcpp::NodeOptions().use_intra_process_comms(use_intra_process_comms).arguments(
97 const std::string & name,
98 const std::string & parent_namespace,
99 const bool & use_sim_time,
100 const rclcpp::NodeOptions & options)
101 : nav2::LifecycleNode(name,
"",
105 default_plugins_{
"static_layer",
"obstacle_layer",
"inflation_layer"},
107 "nav2_costmap_2d::StaticLayer",
108 "nav2_costmap_2d::ObstacleLayer",
109 "nav2_costmap_2d::InflationLayer"}
116 RCLCPP_INFO(get_logger(),
"Creating Costmap");
117 declare_parameter(
"lethal_cost_threshold", rclcpp::ParameterValue(100));
118 declare_parameter(
"trinary_costmap", rclcpp::ParameterValue(
true));
119 declare_parameter(
"unknown_cost_value", rclcpp::ParameterValue(
static_cast<unsigned char>(0xff)));
120 declare_parameter(
"inscribed_obstacle_cost_value", rclcpp::ParameterValue(99));
121 declare_parameter(
"use_maximum", rclcpp::ParameterValue(
false));
131 RCLCPP_INFO(get_logger(),
"Configuring");
134 }
catch (
const std::exception & e) {
136 get_logger(),
"Failed to configure costmap! %s.", e.what());
137 return nav2::CallbackReturn::FAILURE;
140 callback_group_ = create_callback_group(
141 rclcpp::CallbackGroupType::MutuallyExclusive,
false);
144 layered_costmap_ = std::make_unique<LayeredCostmap>(
147 if (!layered_costmap_->isSizeLocked()) {
148 layered_costmap_->resizeMap(
149 (
unsigned int)(map_width_meters_ / resolution_),
150 (
unsigned int)(map_height_meters_ / resolution_), resolution_, origin_x_, origin_y_);
154 tf_buffer_ = nav2::create_transform_buffer(
this, callback_group_);
155 tf_listener_ = nav2::create_transform_listener(*tf_buffer_);
158 for (
unsigned int i = 0; i < plugin_names_.size(); ++i) {
159 RCLCPP_INFO(get_logger(),
"Using plugin \"%s\"", plugin_names_[i].c_str());
161 std::shared_ptr<Layer> plugin = plugin_loader_.createSharedInstance(plugin_types_[i]);
164 std::unique_lock<Costmap2D::mutex_t> lock(*(layered_costmap_->getCostmap()->getMutex()));
166 layered_costmap_->addPlugin(plugin);
170 layered_costmap_.get(), plugin_names_[i], tf_buffer_.get(),
172 }
catch (
const std::exception & e) {
174 get_logger(),
"Failed to initialize costmap plugin %s! %s.",
175 plugin_names_[i].c_str(), e.what());
176 return nav2::CallbackReturn::FAILURE;
181 RCLCPP_INFO(get_logger(),
"Initialized plugin \"%s\"", plugin_names_[i].c_str());
184 for (
unsigned int i = 0; i < filter_names_.size(); ++i) {
185 RCLCPP_INFO(get_logger(),
"Using costmap filter \"%s\"", filter_names_[i].c_str());
187 std::shared_ptr<Layer> filter = plugin_loader_.createSharedInstance(filter_types_[i]);
190 std::unique_lock<Costmap2D::mutex_t> lock(*(layered_costmap_->getCostmap()->getMutex()));
192 layered_costmap_->addFilter(filter);
195 layered_costmap_.get(), filter_names_[i], tf_buffer_.get(),
200 RCLCPP_INFO(get_logger(),
"Initialized costmap filter \"%s\"", filter_names_[i].c_str());
205 footprint_stamped_sub_ = create_subscription<geometry_msgs::msg::PolygonStamped>(
206 "footprint", [
this](
const geometry_msgs::msg::PolygonStamped::ConstSharedPtr & footprint)
209 footprint_sub_ = create_subscription<geometry_msgs::msg::Polygon>(
210 "footprint", [
this](
const geometry_msgs::msg::Polygon::ConstSharedPtr & footprint)
214 footprint_pub_ = create_publisher<geometry_msgs::msg::PolygonStamped>(
215 "published_footprint");
217 costmap_publisher_ = std::make_unique<Costmap2DPublisher>(
220 "costmap", always_send_full_costmap_,
map_vis_z_);
222 auto layers = layered_costmap_->getPlugins();
224 for (
auto & layer : *layers) {
225 auto costmap_layer = std::dynamic_pointer_cast<CostmapLayer>(layer);
226 if (costmap_layer !=
nullptr) {
227 layer_publishers_.emplace_back(
228 std::make_unique<Costmap2DPublisher>(
231 layer->getName(), always_send_full_costmap_,
map_vis_z_)
240 std::vector<geometry_msgs::msg::Point> new_footprint;
246 get_cost_service_ = create_service<nav2_msgs::srv::GetCosts>(
247 std::string(
"get_cost_") + get_name(),
250 std::placeholders::_3));
253 clear_costmap_service_ = std::make_unique<ClearCostmapService>(
shared_from_this(), *
this);
255 executor_ = std::make_shared<rclcpp::executors::SingleThreadedExecutor>();
256 executor_->add_callback_group(callback_group_, get_node_base_interface());
257 executor_thread_ = std::make_unique<nav2::NodeThread>(executor_);
258 return nav2::CallbackReturn::SUCCESS;
264 RCLCPP_INFO(get_logger(),
"Activating");
269 std::string tf_error;
271 RCLCPP_INFO(get_logger(),
"Checking transform");
273 const auto initial_transform_timeout = rclcpp::Duration::from_seconds(
275 const auto initial_transform_timeout_point = now() + initial_transform_timeout;
276 while (rclcpp::ok() &&
277 !tf_buffer_->canTransform(
281 get_logger(),
"Timed out waiting for transform from %s to %s"
282 " to become available, tf error: %s",
286 if (now() > initial_transform_timeout_point) {
289 "Failed to activate %s because "
290 "transform from %s to %s did not become available before timeout",
293 return nav2::CallbackReturn::FAILURE;
303 footprint_pub_->on_activate();
304 costmap_publisher_->on_activate();
306 for (
auto & layer_pub : layer_publishers_) {
307 layer_pub->on_activate();
312 stop_updates_ =
false;
313 map_update_thread_shutdown_ =
false;
320 post_set_params_handler_ = this->add_post_set_parameters_callback(
323 this, std::placeholders::_1));
324 on_set_params_handler = this->add_on_set_parameters_callback(
327 return nav2::CallbackReturn::SUCCESS;
333 RCLCPP_INFO(get_logger(),
"Deactivating");
335 remove_post_set_parameters_callback(post_set_params_handler_.get());
336 post_set_params_handler_.reset();
337 remove_on_set_parameters_callback(on_set_params_handler.get());
338 on_set_params_handler.reset();
343 map_update_thread_shutdown_ =
true;
349 footprint_pub_->on_deactivate();
350 costmap_publisher_->on_deactivate();
352 for (
auto & layer_pub : layer_publishers_) {
353 layer_pub->on_deactivate();
356 return nav2::CallbackReturn::SUCCESS;
362 RCLCPP_INFO(get_logger(),
"Cleaning up");
363 executor_thread_.reset();
364 get_cost_service_.reset();
365 costmap_publisher_.reset();
366 clear_costmap_service_.reset();
368 layer_publishers_.clear();
370 layered_costmap_.reset();
372 tf_listener_.reset();
375 footprint_sub_.reset();
376 footprint_pub_.reset();
378 return nav2::CallbackReturn::SUCCESS;
384 RCLCPP_INFO(get_logger(),
"Shutting down");
385 return nav2::CallbackReturn::SUCCESS;
391 RCLCPP_DEBUG(get_logger(),
" getParameters");
395 "always_send_full_costmap",
false);
399 "footprint", std::string(
"[]"));
401 "global_frame", std::string(
"map"));
411 "plugins", default_plugins_);
413 "filters", std::vector<std::string>());
415 "publish_frequency", 1.0);
419 "robot_base_frame", std::string(
"base_link"));
421 "robot_radius", 0.1);
423 "rolling_window",
false);
425 "track_unknown_space",
false);
427 "transform_tolerance", 0.3);
429 "initial_transform_timeout", 60.0);
431 "update_frequency", 5.0);
433 "subscribe_to_stamped_footprint",
false);
437 if (plugin_names_ == default_plugins_) {
438 for (
size_t i = 0; i < default_plugins_.size(); ++i) {
439 nav2::declare_parameter_if_not_declared(
440 node, default_plugins_[i] +
".plugin", rclcpp::ParameterValue(default_types_[i]));
443 plugin_types_.resize(plugin_names_.size());
444 filter_types_.resize(filter_names_.size());
447 for (
size_t i = 0; i < plugin_names_.size(); ++i) {
448 plugin_types_[i] = nav2::get_plugin_type_param(node, plugin_names_[i]);
450 for (
size_t i = 0; i < filter_names_.size(); ++i) {
451 filter_types_[i] = nav2::get_plugin_type_param(node, filter_names_[i]);
455 if (map_publish_frequency_ > 0) {
456 publish_cycle_ = rclcpp::Duration::from_seconds(1 / map_publish_frequency_);
458 publish_cycle_ = rclcpp::Duration(-1s);
464 if (footprint_ !=
"" && footprint_ !=
"[]") {
466 std::vector<geometry_msgs::msg::Point> new_footprint;
473 get_logger(),
"The footprint parameter is invalid: \"%s\", using radius (%lf) instead",
474 footprint_.c_str(), robot_radius_);
480 if (map_width_meters_ <= 0) {
482 get_logger(),
"You try to set width of map to be negative or zero,"
483 " this isn't allowed, please give a positive value.");
485 if (map_height_meters_ <= 0) {
487 get_logger(),
"You try to set height of map to be negative or zero,"
488 " this isn't allowed, please give a positive value.");
490 if (resolution_ <= 0.0 || !std::isfinite(resolution_)) {
491 throw std::invalid_argument(
492 "Costmap resolution must be a positive finite value.");
499 if (points.empty()) {
501 get_logger(),
"You try to set an empty footprint"
502 " this isn't allowed, a footprint must contain at least one point.");
505 unpadded_footprint_ = points;
506 padded_footprint_ = points;
508 layered_costmap_->setFootprint(padded_footprint_);
513 const geometry_msgs::msg::Polygon & footprint)
521 geometry_msgs::msg::PoseStamped global_pose;
526 double yaw = tf2::getYaw(global_pose.pose.orientation);
528 global_pose.pose.position.x, global_pose.pose.position.y, yaw,
529 padded_footprint_, oriented_footprint);
535 RCLCPP_DEBUG(get_logger(),
"mapUpdateLoop frequency: %lf", frequency);
538 if (frequency == 0.0) {
542 RCLCPP_DEBUG(get_logger(),
"Entering loop");
546 while (rclcpp::ok() && !map_update_thread_shutdown_) {
552 std::scoped_lock<std::mutex> lock(_dynamic_parameter_mutex);
560 if (publish_cycle_ > rclcpp::Duration(0s) && layered_costmap_->isInitialized()) {
561 unsigned int x0, y0, xn, yn;
562 layered_costmap_->getBounds(&x0, &xn, &y0, &yn);
563 costmap_publisher_->updateBounds(x0, xn, y0, yn);
565 for (
auto & layer_pub : layer_publishers_) {
566 layer_pub->updateBounds(x0, xn, y0, yn);
569 auto current_time = now();
570 if ((last_publish_ + publish_cycle_ < current_time) ||
574 RCLCPP_DEBUG(get_logger(),
"Publish costmap at %s", name_.c_str());
575 costmap_publisher_->publishCostmap();
577 for (
auto & layer_pub : layer_publishers_) {
578 layer_pub->publishCostmap();
581 last_publish_ = current_time;
591 if (r.period() > tf2::durationFromSec(1 / frequency)) {
594 "Costmap2DROS: Map update loop missed its desired rate of %.4fHz... "
595 "the loop actually took %.4f seconds", frequency, r.period());
604 RCLCPP_DEBUG(get_logger(),
"Updating map...");
606 if (!stop_updates_) {
608 geometry_msgs::msg::PoseStamped pose;
610 const double & x = pose.pose.position.x;
611 const double & y = pose.pose.position.y;
612 const double yaw = tf2::getYaw(pose.pose.orientation);
613 layered_costmap_->updateMap(x, y, yaw);
615 auto footprint = std::make_unique<geometry_msgs::msg::PolygonStamped>();
616 footprint->header = pose.header;
619 RCLCPP_DEBUG(get_logger(),
"Publishing footprint");
620 footprint_pub_->publish(std::move(footprint));
630 auto waiting_start = now();
632 if (now() - waiting_start > timeout) {
633 throw std::runtime_error(
"Costmap timed out waiting for update");
642 RCLCPP_INFO(get_logger(),
"start");
643 std::vector<std::shared_ptr<Layer>> * plugins = layered_costmap_->getPlugins();
644 std::vector<std::shared_ptr<Layer>> * filters = layered_costmap_->getFilters();
649 for (std::vector<std::shared_ptr<Layer>>::iterator plugin = plugins->begin();
650 plugin != plugins->end();
653 (*plugin)->activate();
655 for (std::vector<std::shared_ptr<Layer>>::iterator filter = filters->begin();
656 filter != filters->end();
659 (*filter)->activate();
663 stop_updates_ =
false;
666 rclcpp::Rate r(20.0);
667 while (rclcpp::ok() && !initialized_) {
668 RCLCPP_DEBUG(get_logger(),
"Sleeping, waiting for initialized_");
676 stop_updates_ =
true;
679 if (layered_costmap_) {
680 std::vector<std::shared_ptr<Layer>> * plugins = layered_costmap_->getPlugins();
681 std::vector<std::shared_ptr<Layer>> * filters = layered_costmap_->getFilters();
684 for (std::vector<std::shared_ptr<Layer>>::iterator plugin = plugins->begin();
685 plugin != plugins->end(); ++plugin)
687 (*plugin)->deactivate();
689 for (std::vector<std::shared_ptr<Layer>>::iterator filter = filters->begin();
690 filter != filters->end(); ++filter)
692 (*filter)->deactivate();
695 initialized_ =
false;
702 stop_updates_ =
true;
703 initialized_ =
false;
709 stop_updates_ =
false;
712 rclcpp::Rate r(100.0);
713 while (!initialized_) {
721 Costmap2D * top = layered_costmap_->getCostmap();
725 std::vector<std::shared_ptr<Layer>> * plugins = layered_costmap_->getPlugins();
726 std::vector<std::shared_ptr<Layer>> * filters = layered_costmap_->getFilters();
727 for (std::vector<std::shared_ptr<Layer>>::iterator plugin = plugins->begin();
728 plugin != plugins->end(); ++plugin)
732 for (std::vector<std::shared_ptr<Layer>>::iterator filter = filters->begin();
733 filter != filters->end(); ++filter)
742 return nav2_util::getCurrentPose(
743 global_pose, *tf_buffer_,
749 const geometry_msgs::msg::PoseStamped & input_pose,
750 geometry_msgs::msg::PoseStamped & transformed_pose)
753 transformed_pose = input_pose;
756 return nav2_util::transformPoseInTargetFrame(
757 input_pose, transformed_pose, *tf_buffer_,
763 const std::vector<rclcpp::Parameter> & parameters)
765 rcl_interfaces::msg::SetParametersResult result;
766 result.successful =
true;
767 for (
const auto & parameter : parameters) {
768 const auto & param_type = parameter.get_type();
769 const auto & param_name = parameter.get_name();
770 if (param_name.find(
'.') != std::string::npos) {
773 if (param_type == ParameterType::PARAMETER_DOUBLE) {
774 if (parameter.as_double() <= 0.0 &&
775 (param_name ==
"resolution" || param_name ==
"publish_frequency"))
778 get_logger(),
"The value of parameter '%s' is incorrectly set to %f, "
779 "it should be >0. Ignoring parameter update.",
780 param_name.c_str(), parameter.as_double());
781 result.successful =
false;
782 }
else if (parameter.as_double() < 0.0 &&
783 (param_name !=
"origin_x" && param_name !=
"origin_y"))
786 get_logger(),
"The value of parameter '%s' is incorrectly set to %f, "
787 "it should be >0. Ignoring parameter update.",
788 param_name.c_str(), parameter.as_double());
789 result.successful =
false;
791 }
else if (param_type == ParameterType::PARAMETER_INTEGER) {
792 if (parameter.as_int() <= 0.0) {
794 get_logger(),
"The value of parameter '%s' is incorrectly set to %ld, "
795 "it should be >0. Ignoring parameter update.",
796 param_name.c_str(), parameter.as_int());
797 result.successful =
false;
799 }
else if (param_type == ParameterType::PARAMETER_STRING && param_name ==
"robot_base_frame") {
802 std::string tf_error;
803 RCLCPP_INFO(get_logger(),
"Checking transform");
804 if (!tf_buffer_->canTransform(
806 tf2::durationFromSec(1.0), &tf_error))
809 get_logger(),
"Timed out waiting for transform from %s to %s"
810 " to become available, tf error: %s",
811 parameter.as_string().c_str(),
global_frame_.c_str(), tf_error.c_str());
813 get_logger(),
"Rejecting robot_base_frame change to %s , leaving it to its original"
815 result.successful =
false;
825 bool resize_map =
false;
826 std::lock_guard<std::mutex> lock_reinit(_dynamic_parameter_mutex);
828 for (
const auto & parameter : parameters) {
829 const auto & param_type = parameter.get_type();
830 const auto & param_name = parameter.get_name();
831 if (param_name.find(
'.') != std::string::npos) {
835 if (param_type == ParameterType::PARAMETER_DOUBLE) {
836 if (param_name ==
"robot_radius") {
837 robot_radius_ = parameter.as_double();
842 }
else if (param_name ==
"footprint_padding") {
843 footprint_padding_ = parameter.as_double();
844 padded_footprint_ = unpadded_footprint_;
846 layered_costmap_->setFootprint(padded_footprint_);
847 }
else if (param_name ==
"transform_tolerance") {
849 }
else if (param_name ==
"publish_frequency") {
850 map_publish_frequency_ = parameter.as_double();
851 publish_cycle_ = rclcpp::Duration::from_seconds(1 / map_publish_frequency_);
852 }
else if (param_name ==
"resolution") {
854 resolution_ = parameter.as_double();
855 }
else if (param_name ==
"origin_x") {
857 origin_x_ = parameter.as_double();
858 }
else if (param_name ==
"origin_y") {
860 origin_y_ = parameter.as_double();
862 }
else if (param_type == ParameterType::PARAMETER_INTEGER) {
863 if (param_name ==
"width") {
865 map_width_meters_ = parameter.as_int();
866 }
else if (param_name ==
"height") {
868 map_height_meters_ = parameter.as_int();
870 }
else if (param_type == ParameterType::PARAMETER_STRING) {
871 if (param_name ==
"footprint") {
872 footprint_ = parameter.as_string();
873 std::vector<geometry_msgs::msg::Point> new_footprint;
877 }
else if (param_name ==
"robot_base_frame") {
883 if (resize_map && !layered_costmap_->isSizeLocked()) {
884 layered_costmap_->resizeMap(
885 (
unsigned int)(map_width_meters_ / resolution_),
886 (
unsigned int)(map_height_meters_ / resolution_), resolution_, origin_x_, origin_y_);
892 const std::shared_ptr<rmw_request_id_t>,
893 const std::shared_ptr<nav2_msgs::srv::GetCosts::Request> request,
894 const std::shared_ptr<nav2_msgs::srv::GetCosts::Response> response)
898 Costmap2D * costmap = layered_costmap_->getCostmap();
899 std::unique_lock<Costmap2D::mutex_t> lock(*(costmap->getMutex()));
900 response->success =
true;
901 for (
const auto & pose : request->poses) {
902 geometry_msgs::msg::PoseStamped pose_transformed;
905 get_logger(),
"Failed to transform, cannot get cost for pose (%.2f, %.2f)",
906 pose.pose.position.x, pose.pose.position.y);
907 response->success =
false;
908 response->costs.push_back(NO_INFORMATION);
911 double yaw = tf2::getYaw(pose_transformed.pose.orientation);
913 if (request->use_footprint) {
914 Footprint footprint = layered_costmap_->getFootprint();
918 get_logger(),
"Received request to get cost at footprint pose (%.2f, %.2f, %.2f)",
919 pose_transformed.pose.position.x, pose_transformed.pose.position.y, yaw);
921 response->costs.push_back(
923 pose_transformed.pose.position.x,
924 pose_transformed.pose.position.y, yaw, footprint));
927 get_logger(),
"Received request to get cost at point (%f, %f)",
928 pose_transformed.pose.position.x,
929 pose_transformed.pose.position.y);
932 pose_transformed.pose.position.x,
933 pose_transformed.pose.position.y, mx, my);
936 response->success =
false;
937 response->costs.push_back(LETHAL_OBSTACLE);
941 response->costs.push_back(
static_cast<float>(costmap->
getCost(mx, my)));
nav2::LifecycleNode::SharedPtr shared_from_this()
Get a shared pointer of this.
ParameterT declare_or_get_parameter(const std::string ¶meter_name, const ParameterDescriptor ¶meter_descriptor=ParameterDescriptor())
Declares or gets a parameter with specified type (not value). If the parameter is already declared,...
A sim-time-aware rate for Nav2 loops.
Costmap2DROS(const rclcpp::NodeOptions &options=rclcpp::NodeOptions())
Constructor for the wrapper.
nav2::CallbackReturn on_cleanup(const rclcpp_lifecycle::State &state) override
Cleanup node.
void mapUpdateLoop(double frequency)
Function on timer for costmap update.
void getOrientedFootprint(std::vector< geometry_msgs::msg::Point > &oriented_footprint)
Build the oriented footprint of the robot at the robot's current pose.
bool getRobotPose(geometry_msgs::msg::PoseStamped &global_pose)
Get the pose of the robot in the global frame of the costmap.
void getParameters()
Get parameters for node.
void pause()
Stops the costmap from updating, but sensor data still comes in over the wire.
void getCostsCallback(const std::shared_ptr< rmw_request_id_t >, const std::shared_ptr< nav2_msgs::srv::GetCosts::Request > request, const std::shared_ptr< nav2_msgs::srv::GetCosts::Response > response)
Get the cost at a point in costmap.
nav2::CallbackReturn on_configure(const rclcpp_lifecycle::State &state) override
Configure node.
nav2::CallbackReturn on_deactivate(const rclcpp_lifecycle::State &state) override
Deactivate node.
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...
nav2::CallbackReturn on_activate(const rclcpp_lifecycle::State &state) override
Activate node.
~Costmap2DROS()
A destructor.
double transform_tolerance_
The timeout before transform errors.
bool rolling_window_
Whether to use a rolling window version of the costmap.
void resume()
Resumes costmap updates.
double initial_transform_timeout_
The timeout before activation of the node errors.
void updateMap()
Update the map with the layered costmap / plugins.
void setRobotFootprint(const std::vector< geometry_msgs::msg::Point > &points)
Set the footprint of the robot to be the given set of points, padded by footprint_padding.
void resetLayers()
Reset each individual layer.
bool transformPoseToGlobalFrame(const geometry_msgs::msg::PoseStamped &input_pose, geometry_msgs::msg::PoseStamped &transformed_pose)
Transform the input_pose in the global frame of the costmap.
std::string global_frame_
The global frame for the costmap.
void start()
Subscribes to sensor topics if necessary and starts costmap updates, can be called to restart the cos...
void stop()
Stops costmap updates and unsubscribes from sensor topics.
std::string robot_base_frame_
The frame_id of the robot base.
bool subscribe_to_stamped_footprint_
If true, the footprint subscriber expects a PolygonStamped msg.
bool isCurrent()
Same as getLayeredCostmap()->isCurrent().
void updateParametersCallback(const std::vector< rclcpp::Parameter > ¶meters)
Apply parameter updates after validation This callback is executed when parameters have been successf...
void waitUntilCurrent(const rclcpp::Duration &timeout)
Wait for the costmap to become current after updates or parameter changes.
void setRobotFootprintPolygon(const geometry_msgs::msg::Polygon &footprint)
Set the footprint of the robot to be the given polygon, padded by footprint_padding.
std::unique_ptr< std::thread > map_update_thread_
A thread for updating the map.
void init()
Common initialization for constructors.
bool is_lifecycle_follower_
whether is a child-LifecycleNode or an independent node
nav2::CallbackReturn on_shutdown(const rclcpp_lifecycle::State &state) override
shutdown node
A 2D costmap provides a mapping between points in the world and their associated "costs".
void resetMap(unsigned int x0, unsigned int y0, unsigned int xn, unsigned int yn)
Reset the costmap in bounds.
unsigned char getCost(unsigned int mx, unsigned int my) const
Get the cost of a cell in the costmap.
bool worldToMap(double wx, double wy, unsigned int &mx, unsigned int &my) const
Convert from world coordinates to map coordinates.
unsigned int getSizeInCellsX() const
Accessor for the x size of the costmap in cells.
unsigned int getSizeInCellsY() const
Accessor for the y size of the costmap in cells.
Measures execution time of code between calls to start and end.
void start()
Call just prior to code you want to measure.
double elapsed_time_in_seconds()
Extract the measured time as a floating point number of seconds.
void end()
Call just after the code you want to measure.
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)
bool makeFootprintFromString(const std::string &footprint_string, std::vector< geometry_msgs::msg::Point > &footprint)
Make the footprint from the given string.
void padFootprint(std::vector< geometry_msgs::msg::Point > &footprint, double padding)
Adds the specified amount of padding to the footprint (in place)
rclcpp::NodeOptions getChildNodeOptions(const std::string &name, const std::string &parent_namespace, const bool &use_sim_time, const rclcpp::NodeOptions &parent_options)
Given the node options of a parent node, expands of replaces the fields for the node name,...
std::vector< geometry_msgs::msg::Point > makeFootprintFromRadius(double radius)
Create a circular footprint from a given radius.
std::vector< geometry_msgs::msg::Point > toPointVector(const geometry_msgs::msg::Polygon &polygon)
Convert Polygon msg to vector of Points.