39 #include "nav2_costmap_2d/costmap_2d_ros.hpp"
50 #include "nav2_costmap_2d/layered_costmap.hpp"
51 #include "nav2_util/execution_timer.hpp"
52 #include "nav2_ros_common/node_utils.hpp"
53 #include "nav2_ros_common/rate.hpp"
54 #include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
55 #include "nav2_ros_common/tf2_factories.hpp"
56 #include "nav2_util/robot_utils.hpp"
57 #include "rcl_interfaces/msg/set_parameters_result.hpp"
59 using namespace std::chrono_literals;
60 using std::placeholders::_1;
61 using rcl_interfaces::msg::ParameterType;
65 Costmap2DROS::Costmap2DROS(
const rclcpp::NodeOptions & options)
66 : nav2::LifecycleNode(
"costmap",
"", options),
68 default_plugins_{
"static_layer",
"obstacle_layer",
"inflation_layer"},
70 "nav2_costmap_2d::StaticLayer",
71 "nav2_costmap_2d::ObstacleLayer",
72 "nav2_costmap_2d::InflationLayer"}
79 const std::string & name,
80 const std::string & parent_namespace,
81 const bool & use_sim_time,
82 const rclcpp::NodeOptions & parent_options)
84 std::vector<std::string> new_arguments = parent_options.arguments();
85 bool use_intra_process_comms = parent_options.use_intra_process_comms();
86 nav2::replaceOrAddArgument(
87 new_arguments,
"-r",
"__ns",
88 "__ns:=" + nav2::add_namespaces(parent_namespace, name));
89 nav2::replaceOrAddArgument(new_arguments,
"-r",
"__node", name +
":" +
"__node:=" + name);
90 nav2::replaceOrAddArgument(
91 new_arguments,
"-p",
"use_sim_time",
92 "use_sim_time:=" + std::string(use_sim_time ?
"true" :
"false"));
93 return rclcpp::NodeOptions().use_intra_process_comms(use_intra_process_comms).arguments(
98 const std::string & name,
99 const std::string & parent_namespace,
100 const bool & use_sim_time,
101 const rclcpp::NodeOptions & options)
102 : nav2::LifecycleNode(name,
"",
106 default_plugins_{
"static_layer",
"obstacle_layer",
"inflation_layer"},
108 "nav2_costmap_2d::StaticLayer",
109 "nav2_costmap_2d::ObstacleLayer",
110 "nav2_costmap_2d::InflationLayer"}
117 RCLCPP_INFO(get_logger(),
"Creating Costmap");
118 declare_parameter(
"lethal_cost_threshold", rclcpp::ParameterValue(100));
119 declare_parameter(
"trinary_costmap", rclcpp::ParameterValue(
true));
120 declare_parameter(
"unknown_cost_value", rclcpp::ParameterValue(
static_cast<unsigned char>(0xff)));
121 declare_parameter(
"inscribed_obstacle_cost_value", rclcpp::ParameterValue(99));
122 declare_parameter(
"use_maximum", rclcpp::ParameterValue(
false));
132 RCLCPP_INFO(get_logger(),
"Configuring");
135 }
catch (
const std::exception & e) {
137 get_logger(),
"Failed to configure costmap! %s.", e.what());
138 return nav2::CallbackReturn::FAILURE;
141 callback_group_ = create_callback_group(
142 rclcpp::CallbackGroupType::MutuallyExclusive,
false);
145 layered_costmap_ = std::make_unique<LayeredCostmap>(
148 if (!layered_costmap_->isSizeLocked()) {
149 layered_costmap_->resizeMap(
150 (
unsigned int)(map_width_meters_ / resolution_),
151 (
unsigned int)(map_height_meters_ / resolution_), resolution_, origin_x_, origin_y_);
155 tf_buffer_ = nav2::create_transform_buffer(
this, callback_group_);
156 tf_listener_ = nav2::create_transform_listener(*tf_buffer_);
159 for (
unsigned int i = 0; i < plugin_names_.size(); ++i) {
160 RCLCPP_INFO(get_logger(),
"Using plugin \"%s\"", plugin_names_[i].c_str());
162 std::shared_ptr<Layer> plugin = plugin_loader_.createSharedInstance(plugin_types_[i]);
164 layered_costmap_->addPlugin(plugin);
168 layered_costmap_.get(), plugin_names_[i], tf_buffer_.get(),
170 }
catch (
const std::exception & e) {
172 get_logger(),
"Failed to initialize costmap plugin %s! %s.",
173 plugin_names_[i].c_str(), e.what());
174 return nav2::CallbackReturn::FAILURE;
177 RCLCPP_INFO(get_logger(),
"Initialized plugin \"%s\"", plugin_names_[i].c_str());
180 for (
unsigned int i = 0; i < filter_names_.size(); ++i) {
181 RCLCPP_INFO(get_logger(),
"Using costmap filter \"%s\"", filter_names_[i].c_str());
183 std::shared_ptr<Layer> filter = plugin_loader_.createSharedInstance(filter_types_[i]);
185 layered_costmap_->addFilter(filter);
188 layered_costmap_.get(), filter_names_[i], tf_buffer_.get(),
191 RCLCPP_INFO(get_logger(),
"Initialized costmap filter \"%s\"", filter_names_[i].c_str());
196 footprint_stamped_sub_ = create_subscription<geometry_msgs::msg::PolygonStamped>(
197 "footprint", [
this](
const geometry_msgs::msg::PolygonStamped::ConstSharedPtr & footprint)
200 footprint_sub_ = create_subscription<geometry_msgs::msg::Polygon>(
201 "footprint", [
this](
const geometry_msgs::msg::Polygon::ConstSharedPtr & footprint)
205 footprint_pub_ = create_publisher<geometry_msgs::msg::PolygonStamped>(
206 "published_footprint");
208 costmap_publisher_ = std::make_unique<Costmap2DPublisher>(
211 "costmap", always_send_full_costmap_,
map_vis_z_);
213 auto layers = layered_costmap_->getPlugins();
215 for (
auto & layer : *layers) {
216 auto costmap_layer = std::dynamic_pointer_cast<CostmapLayer>(layer);
217 if (costmap_layer !=
nullptr) {
218 layer_publishers_.emplace_back(
219 std::make_unique<Costmap2DPublisher>(
222 layer->getName(), always_send_full_costmap_,
map_vis_z_)
231 std::vector<geometry_msgs::msg::Point> new_footprint;
237 get_cost_service_ = create_service<nav2_msgs::srv::GetCosts>(
238 std::string(
"get_cost_") + get_name(),
241 std::placeholders::_3));
244 clear_costmap_service_ = std::make_unique<ClearCostmapService>(
shared_from_this(), *
this);
246 executor_ = std::make_shared<rclcpp::executors::SingleThreadedExecutor>();
247 executor_->add_callback_group(callback_group_, get_node_base_interface());
248 executor_thread_ = std::make_unique<nav2::NodeThread>(executor_);
249 return nav2::CallbackReturn::SUCCESS;
255 RCLCPP_INFO(get_logger(),
"Activating");
260 std::string tf_error;
262 RCLCPP_INFO(get_logger(),
"Checking transform");
264 const auto initial_transform_timeout = rclcpp::Duration::from_seconds(
266 const auto initial_transform_timeout_point = now() + initial_transform_timeout;
267 while (rclcpp::ok() &&
268 !tf_buffer_->canTransform(
272 get_logger(),
"Timed out waiting for transform from %s to %s"
273 " to become available, tf error: %s",
277 if (now() > initial_transform_timeout_point) {
280 "Failed to activate %s because "
281 "transform from %s to %s did not become available before timeout",
284 return nav2::CallbackReturn::FAILURE;
294 footprint_pub_->on_activate();
295 costmap_publisher_->on_activate();
297 for (
auto & layer_pub : layer_publishers_) {
298 layer_pub->on_activate();
303 stop_updates_ =
false;
304 map_update_thread_shutdown_ =
false;
311 post_set_params_handler_ = this->add_post_set_parameters_callback(
314 this, std::placeholders::_1));
315 on_set_params_handler = this->add_on_set_parameters_callback(
318 return nav2::CallbackReturn::SUCCESS;
324 RCLCPP_INFO(get_logger(),
"Deactivating");
326 remove_post_set_parameters_callback(post_set_params_handler_.get());
327 post_set_params_handler_.reset();
328 remove_on_set_parameters_callback(on_set_params_handler.get());
329 on_set_params_handler.reset();
334 map_update_thread_shutdown_ =
true;
340 footprint_pub_->on_deactivate();
341 costmap_publisher_->on_deactivate();
343 for (
auto & layer_pub : layer_publishers_) {
344 layer_pub->on_deactivate();
347 return nav2::CallbackReturn::SUCCESS;
353 RCLCPP_INFO(get_logger(),
"Cleaning up");
354 executor_thread_.reset();
355 get_cost_service_.reset();
356 costmap_publisher_.reset();
357 clear_costmap_service_.reset();
359 layer_publishers_.clear();
361 layered_costmap_.reset();
363 tf_listener_.reset();
366 footprint_sub_.reset();
367 footprint_pub_.reset();
369 return nav2::CallbackReturn::SUCCESS;
375 RCLCPP_INFO(get_logger(),
"Shutting down");
376 return nav2::CallbackReturn::SUCCESS;
382 RCLCPP_DEBUG(get_logger(),
" getParameters");
386 "always_send_full_costmap",
false);
390 "footprint", std::string(
"[]"));
392 "global_frame", std::string(
"map"));
402 "plugins", default_plugins_);
404 "filters", std::vector<std::string>());
406 "publish_frequency", 1.0);
410 "robot_base_frame", std::string(
"base_link"));
412 "robot_radius", 0.1);
414 "rolling_window",
false);
416 "track_unknown_space",
false);
418 "transform_tolerance", 0.3);
420 "transform_staleness_threshold", 0.0);
422 "initial_transform_timeout", 60.0);
424 "update_frequency", 5.0);
426 "subscribe_to_stamped_footprint",
false);
430 if (plugin_names_ == default_plugins_) {
431 for (
size_t i = 0; i < default_plugins_.size(); ++i) {
432 nav2::declare_parameter_if_not_declared(
433 node, default_plugins_[i] +
".plugin", rclcpp::ParameterValue(default_types_[i]));
436 plugin_types_.resize(plugin_names_.size());
437 filter_types_.resize(filter_names_.size());
440 for (
size_t i = 0; i < plugin_names_.size(); ++i) {
441 plugin_types_[i] = nav2::get_plugin_type_param(node, plugin_names_[i]);
443 for (
size_t i = 0; i < filter_names_.size(); ++i) {
444 filter_types_[i] = nav2::get_plugin_type_param(node, filter_names_[i]);
448 if (map_publish_frequency_ > 0) {
449 publish_cycle_ = rclcpp::Duration::from_seconds(1 / map_publish_frequency_);
451 publish_cycle_ = rclcpp::Duration(-1s);
457 if (footprint_ !=
"" && footprint_ !=
"[]") {
459 std::vector<geometry_msgs::msg::Point> new_footprint;
466 get_logger(),
"The footprint parameter is invalid: \"%s\", using radius (%lf) instead",
467 footprint_.c_str(), robot_radius_);
473 if (map_width_meters_ <= 0) {
474 throw std::invalid_argument(
475 "You try to set width of map to be negative or zero, "
476 "this isn't allowed, please give a positive value.");
478 if (map_height_meters_ <= 0) {
479 throw std::invalid_argument(
480 "You try to set height of map to be negative or zero, "
481 "this isn't allowed, please give a positive value.");
483 if (resolution_ <= 0.0) {
484 throw std::invalid_argument(
485 "Costmap resolution must be greater than zero.");
488 const double size_x = map_width_meters_ / resolution_;
489 const double size_y = map_height_meters_ / resolution_;
490 const double max_cells = std::numeric_limits<int>::max();
491 if (size_x > max_cells / size_y) {
492 throw std::invalid_argument(
"Costmap cell count exceeds the supported signed index range");
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 auto padded = std::make_shared<std::vector<geometry_msgs::msg::Point>>(points);
508 #ifdef __cpp_lib_atomic_shared_ptr
509 unpadded_footprint_.store(std::make_shared<std::vector<geometry_msgs::msg::Point>>(points));
510 padded_footprint_.store(padded);
513 &unpadded_footprint_, std::make_shared<std::vector<geometry_msgs::msg::Point>>(points));
514 std::atomic_store(&padded_footprint_, padded);
516 layered_costmap_->setFootprint(*padded);
521 const geometry_msgs::msg::Polygon & footprint)
529 geometry_msgs::msg::PoseStamped global_pose;
534 double yaw = tf2::getYaw(global_pose.pose.orientation);
535 #ifdef __cpp_lib_atomic_shared_ptr
536 auto padded_footprint = padded_footprint_.load();
538 auto padded_footprint = std::atomic_load(&padded_footprint_);
541 global_pose.pose.position.x, global_pose.pose.position.y, yaw,
542 *padded_footprint, oriented_footprint);
548 RCLCPP_DEBUG(get_logger(),
"mapUpdateLoop frequency: %lf", frequency);
551 if (frequency == 0.0) {
555 RCLCPP_DEBUG(get_logger(),
"Entering loop");
559 while (rclcpp::ok() && !map_update_thread_shutdown_) {
565 std::scoped_lock<std::mutex> lock(_dynamic_parameter_mutex);
573 if (publish_cycle_ > rclcpp::Duration(0s) && layered_costmap_->isInitialized()) {
574 unsigned int x0, y0, xn, yn;
575 layered_costmap_->getBounds(&x0, &xn, &y0, &yn);
576 costmap_publisher_->updateBounds(x0, xn, y0, yn);
578 for (
auto & layer_pub : layer_publishers_) {
579 layer_pub->updateBounds(x0, xn, y0, yn);
582 auto current_time = now();
583 const bool publish_due = last_publish_ + publish_cycle_ < current_time ||
584 current_time < last_publish_;
585 if (publish_due || costmap_publisher_->isRepublishRequested()) {
586 RCLCPP_DEBUG(get_logger(),
"Publish costmap at %s", name_.c_str());
587 costmap_publisher_->publishCostmap();
590 for (
auto & layer_pub : layer_publishers_) {
591 if (publish_due || layer_pub->isRepublishRequested()) {
592 layer_pub->publishCostmap();
598 last_publish_ = current_time;
608 if (r.period() > tf2::durationFromSec(1 / frequency)) {
611 "Costmap2DROS: Map update loop missed its desired rate of %.4fHz... "
612 "the loop actually took %.4f seconds", frequency, r.period());
621 RCLCPP_DEBUG(get_logger(),
"Updating map...");
623 if (!stop_updates_) {
625 geometry_msgs::msg::PoseStamped pose;
627 const double & x = pose.pose.position.x;
628 const double & y = pose.pose.position.y;
629 const double yaw = tf2::getYaw(pose.pose.orientation);
630 layered_costmap_->updateMap(x, y, yaw);
632 auto footprint = std::make_unique<geometry_msgs::msg::PolygonStamped>();
633 footprint->header = pose.header;
634 #ifdef __cpp_lib_atomic_shared_ptr
635 auto padded_footprint = padded_footprint_.load();
637 auto padded_footprint = std::atomic_load(&padded_footprint_);
641 RCLCPP_DEBUG(get_logger(),
"Publishing footprint");
642 footprint_pub_->publish(std::move(footprint));
652 auto waiting_start = now();
654 if (now() - waiting_start > timeout) {
655 throw std::runtime_error(
"Costmap timed out waiting for update");
664 RCLCPP_INFO(get_logger(),
"start");
665 std::vector<std::shared_ptr<Layer>> * plugins = layered_costmap_->getPlugins();
666 std::vector<std::shared_ptr<Layer>> * filters = layered_costmap_->getFilters();
671 for (std::vector<std::shared_ptr<Layer>>::iterator plugin = plugins->begin();
672 plugin != plugins->end();
675 (*plugin)->activate();
677 for (std::vector<std::shared_ptr<Layer>>::iterator filter = filters->begin();
678 filter != filters->end();
681 (*filter)->activate();
685 stop_updates_ =
false;
688 rclcpp::Rate r(20.0);
689 while (rclcpp::ok() && !initialized_) {
690 RCLCPP_DEBUG(get_logger(),
"Sleeping, waiting for initialized_");
698 stop_updates_ =
true;
701 if (layered_costmap_) {
702 std::vector<std::shared_ptr<Layer>> * plugins = layered_costmap_->getPlugins();
703 std::vector<std::shared_ptr<Layer>> * filters = layered_costmap_->getFilters();
706 for (std::vector<std::shared_ptr<Layer>>::iterator plugin = plugins->begin();
707 plugin != plugins->end(); ++plugin)
709 (*plugin)->deactivate();
711 for (std::vector<std::shared_ptr<Layer>>::iterator filter = filters->begin();
712 filter != filters->end(); ++filter)
714 (*filter)->deactivate();
717 initialized_ =
false;
724 stop_updates_ =
true;
725 initialized_ =
false;
731 stop_updates_ =
false;
734 rclcpp::Rate r(100.0);
735 while (!initialized_) {
743 Costmap2D * top = layered_costmap_->getCostmap();
747 std::vector<std::shared_ptr<Layer>> * plugins = layered_costmap_->getPlugins();
748 std::vector<std::shared_ptr<Layer>> * filters = layered_costmap_->getFilters();
749 for (std::vector<std::shared_ptr<Layer>>::iterator plugin = plugins->begin();
750 plugin != plugins->end(); ++plugin)
754 for (std::vector<std::shared_ptr<Layer>>::iterator filter = filters->begin();
755 filter != filters->end(); ++filter)
764 if (!nav2_util::getFreshPose(
775 const geometry_msgs::msg::PoseStamped & input_pose,
776 geometry_msgs::msg::PoseStamped & transformed_pose)
779 transformed_pose = input_pose;
782 return nav2_util::transformPoseInTargetFrame(
783 input_pose, transformed_pose, *tf_buffer_,
789 const std::vector<rclcpp::Parameter> & parameters)
791 rcl_interfaces::msg::SetParametersResult result;
792 result.successful =
true;
794 for (
const auto & parameter : parameters) {
795 const auto & param_type = parameter.get_type();
796 const auto & param_name = parameter.get_name();
797 if (param_name.find(
'.') != std::string::npos) {
800 if (param_type == ParameterType::PARAMETER_DOUBLE) {
801 if (parameter.as_double() <= 0.0 &&
802 (param_name ==
"resolution" || param_name ==
"publish_frequency"))
805 get_logger(),
"The value of parameter '%s' is incorrectly set to %f, "
806 "it should be >0. Ignoring parameter update.",
807 param_name.c_str(), parameter.as_double());
808 result.successful =
false;
809 }
else if (parameter.as_double() < 0.0 &&
810 (param_name !=
"origin_x" && param_name !=
"origin_y"))
813 get_logger(),
"The value of parameter '%s' is incorrectly set to %f, "
814 "it should be >0. Ignoring parameter update.",
815 param_name.c_str(), parameter.as_double());
816 result.successful =
false;
818 }
else if (param_type == ParameterType::PARAMETER_INTEGER) {
819 if (parameter.as_int() <= 0.0) {
821 get_logger(),
"The value of parameter '%s' is incorrectly set to %ld, "
822 "it should be >0. Ignoring parameter update.",
823 param_name.c_str(), parameter.as_int());
824 result.successful =
false;
826 }
else if (param_type == ParameterType::PARAMETER_STRING && param_name ==
"robot_base_frame") {
829 std::string tf_error;
830 RCLCPP_INFO(get_logger(),
"Checking transform");
831 if (!tf_buffer_->canTransform(
833 tf2::durationFromSec(1.0), &tf_error))
836 get_logger(),
"Timed out waiting for transform from %s to %s"
837 " to become available, tf error: %s",
838 parameter.as_string().c_str(),
global_frame_.c_str(), tf_error.c_str());
840 get_logger(),
"Rejecting robot_base_frame change to %s , leaving it to its original"
842 result.successful =
false;
853 bool resize_map =
false;
854 std::lock_guard<std::mutex> lock_reinit(_dynamic_parameter_mutex);
856 for (
const auto & parameter : parameters) {
857 const auto & param_type = parameter.get_type();
858 const auto & param_name = parameter.get_name();
859 if (param_name.find(
'.') != std::string::npos) {
863 if (param_type == ParameterType::PARAMETER_DOUBLE) {
864 if (param_name ==
"robot_radius") {
865 robot_radius_ = parameter.as_double();
870 }
else if (param_name ==
"footprint_padding") {
871 footprint_padding_ = parameter.as_double();
872 #ifdef __cpp_lib_atomic_shared_ptr
873 auto padded = std::make_shared<std::vector<geometry_msgs::msg::Point>>(
874 *unpadded_footprint_.load());
876 padded_footprint_.store(padded);
878 auto padded = std::make_shared<std::vector<geometry_msgs::msg::Point>>(
879 *std::atomic_load(&unpadded_footprint_));
881 std::atomic_store(&padded_footprint_, padded);
883 layered_costmap_->setFootprint(*padded);
884 }
else if (param_name ==
"transform_tolerance") {
886 }
else if (param_name ==
"transform_staleness_threshold") {
888 }
else if (param_name ==
"publish_frequency") {
889 map_publish_frequency_ = parameter.as_double();
890 publish_cycle_ = rclcpp::Duration::from_seconds(1 / map_publish_frequency_);
891 }
else if (param_name ==
"resolution") {
893 resolution_ = parameter.as_double();
894 }
else if (param_name ==
"origin_x") {
896 origin_x_ = parameter.as_double();
897 }
else if (param_name ==
"origin_y") {
899 origin_y_ = parameter.as_double();
901 }
else if (param_type == ParameterType::PARAMETER_INTEGER) {
902 if (param_name ==
"width") {
904 map_width_meters_ = parameter.as_int();
905 }
else if (param_name ==
"height") {
907 map_height_meters_ = parameter.as_int();
909 }
else if (param_type == ParameterType::PARAMETER_STRING) {
910 if (param_name ==
"footprint") {
911 footprint_ = parameter.as_string();
912 std::vector<geometry_msgs::msg::Point> new_footprint;
916 }
else if (param_name ==
"robot_base_frame") {
922 if (resize_map && !layered_costmap_->isSizeLocked()) {
923 layered_costmap_->resizeMap(
924 (
unsigned int)(map_width_meters_ / resolution_),
925 (
unsigned int)(map_height_meters_ / resolution_), resolution_, origin_x_, origin_y_);
931 const std::shared_ptr<rmw_request_id_t>,
932 const std::shared_ptr<nav2_msgs::srv::GetCosts::Request> request,
933 const std::shared_ptr<nav2_msgs::srv::GetCosts::Response> response)
937 Costmap2D * costmap = layered_costmap_->getCostmap();
938 std::unique_lock<Costmap2D::mutex_t> lock(*(costmap->getMutex()));
939 response->success =
true;
940 for (
const auto & pose : request->poses) {
941 geometry_msgs::msg::PoseStamped pose_transformed;
944 get_logger(),
"Failed to transform, cannot get cost for pose (%.2f, %.2f)",
945 pose.pose.position.x, pose.pose.position.y);
946 response->success =
false;
947 response->costs.push_back(NO_INFORMATION);
950 double yaw = tf2::getYaw(pose_transformed.pose.orientation);
952 if (request->use_footprint) {
953 Footprint footprint = layered_costmap_->getFootprint();
957 get_logger(),
"Received request to get cost at footprint pose (%.2f, %.2f, %.2f)",
958 pose_transformed.pose.position.x, pose_transformed.pose.position.y, yaw);
960 response->costs.push_back(
962 pose_transformed.pose.position.x,
963 pose_transformed.pose.position.y, yaw, footprint));
966 get_logger(),
"Received request to get cost at point (%f, %f)",
967 pose_transformed.pose.position.x,
968 pose_transformed.pose.position.y);
971 pose_transformed.pose.position.x,
972 pose_transformed.pose.position.y, mx, my);
975 response->success =
false;
976 response->costs.push_back(LETHAL_OBSTACLE);
980 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.
double transform_staleness_threshold_
Maximum robot pose TF age; 0 disables the check.
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.