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 "initial_transform_timeout", 60.0);
422 "update_frequency", 5.0);
424 "subscribe_to_stamped_footprint",
false);
428 if (plugin_names_ == default_plugins_) {
429 for (
size_t i = 0; i < default_plugins_.size(); ++i) {
430 nav2::declare_parameter_if_not_declared(
431 node, default_plugins_[i] +
".plugin", rclcpp::ParameterValue(default_types_[i]));
434 plugin_types_.resize(plugin_names_.size());
435 filter_types_.resize(filter_names_.size());
438 for (
size_t i = 0; i < plugin_names_.size(); ++i) {
439 plugin_types_[i] = nav2::get_plugin_type_param(node, plugin_names_[i]);
441 for (
size_t i = 0; i < filter_names_.size(); ++i) {
442 filter_types_[i] = nav2::get_plugin_type_param(node, filter_names_[i]);
446 if (map_publish_frequency_ > 0) {
447 publish_cycle_ = rclcpp::Duration::from_seconds(1 / map_publish_frequency_);
449 publish_cycle_ = rclcpp::Duration(-1s);
455 if (footprint_ !=
"" && footprint_ !=
"[]") {
457 std::vector<geometry_msgs::msg::Point> new_footprint;
464 get_logger(),
"The footprint parameter is invalid: \"%s\", using radius (%lf) instead",
465 footprint_.c_str(), robot_radius_);
471 if (map_width_meters_ <= 0) {
472 throw std::invalid_argument(
473 "You try to set width of map to be negative or zero, "
474 "this isn't allowed, please give a positive value.");
476 if (map_height_meters_ <= 0) {
477 throw std::invalid_argument(
478 "You try to set height of map to be negative or zero, "
479 "this isn't allowed, please give a positive value.");
481 if (resolution_ <= 0.0) {
482 throw std::invalid_argument(
483 "Costmap resolution must be greater than zero.");
486 const double size_x = map_width_meters_ / resolution_;
487 const double size_y = map_height_meters_ / resolution_;
488 const double max_cells = std::numeric_limits<int>::max();
489 if (size_x > max_cells / size_y) {
490 throw std::invalid_argument(
"Costmap cell count exceeds the supported signed index range");
497 if (points.empty()) {
499 get_logger(),
"You try to set an empty footprint"
500 " this isn't allowed, a footprint must contain at least one point.");
503 auto padded = std::make_shared<std::vector<geometry_msgs::msg::Point>>(points);
506 #ifdef __cpp_lib_atomic_shared_ptr
507 unpadded_footprint_.store(std::make_shared<std::vector<geometry_msgs::msg::Point>>(points));
508 padded_footprint_.store(padded);
511 &unpadded_footprint_, std::make_shared<std::vector<geometry_msgs::msg::Point>>(points));
512 std::atomic_store(&padded_footprint_, padded);
514 layered_costmap_->setFootprint(*padded);
519 const geometry_msgs::msg::Polygon & footprint)
527 geometry_msgs::msg::PoseStamped global_pose;
532 double yaw = tf2::getYaw(global_pose.pose.orientation);
533 #ifdef __cpp_lib_atomic_shared_ptr
534 auto padded_footprint = padded_footprint_.load();
536 auto padded_footprint = std::atomic_load(&padded_footprint_);
539 global_pose.pose.position.x, global_pose.pose.position.y, yaw,
540 *padded_footprint, oriented_footprint);
546 RCLCPP_DEBUG(get_logger(),
"mapUpdateLoop frequency: %lf", frequency);
549 if (frequency == 0.0) {
553 RCLCPP_DEBUG(get_logger(),
"Entering loop");
557 while (rclcpp::ok() && !map_update_thread_shutdown_) {
563 std::scoped_lock<std::mutex> lock(_dynamic_parameter_mutex);
571 if (publish_cycle_ > rclcpp::Duration(0s) && layered_costmap_->isInitialized()) {
572 unsigned int x0, y0, xn, yn;
573 layered_costmap_->getBounds(&x0, &xn, &y0, &yn);
574 costmap_publisher_->updateBounds(x0, xn, y0, yn);
576 for (
auto & layer_pub : layer_publishers_) {
577 layer_pub->updateBounds(x0, xn, y0, yn);
580 auto current_time = now();
581 const bool publish_due = last_publish_ + publish_cycle_ < current_time ||
582 current_time < last_publish_;
583 if (publish_due || costmap_publisher_->isRepublishRequested()) {
584 RCLCPP_DEBUG(get_logger(),
"Publish costmap at %s", name_.c_str());
585 costmap_publisher_->publishCostmap();
588 for (
auto & layer_pub : layer_publishers_) {
589 if (publish_due || layer_pub->isRepublishRequested()) {
590 layer_pub->publishCostmap();
596 last_publish_ = current_time;
606 if (r.period() > tf2::durationFromSec(1 / frequency)) {
609 "Costmap2DROS: Map update loop missed its desired rate of %.4fHz... "
610 "the loop actually took %.4f seconds", frequency, r.period());
619 RCLCPP_DEBUG(get_logger(),
"Updating map...");
621 if (!stop_updates_) {
623 geometry_msgs::msg::PoseStamped pose;
625 const double & x = pose.pose.position.x;
626 const double & y = pose.pose.position.y;
627 const double yaw = tf2::getYaw(pose.pose.orientation);
628 layered_costmap_->updateMap(x, y, yaw);
630 auto footprint = std::make_unique<geometry_msgs::msg::PolygonStamped>();
631 footprint->header = pose.header;
632 #ifdef __cpp_lib_atomic_shared_ptr
633 auto padded_footprint = padded_footprint_.load();
635 auto padded_footprint = std::atomic_load(&padded_footprint_);
639 RCLCPP_DEBUG(get_logger(),
"Publishing footprint");
640 footprint_pub_->publish(std::move(footprint));
650 auto waiting_start = now();
652 if (now() - waiting_start > timeout) {
653 throw std::runtime_error(
"Costmap timed out waiting for update");
662 RCLCPP_INFO(get_logger(),
"start");
663 std::vector<std::shared_ptr<Layer>> * plugins = layered_costmap_->getPlugins();
664 std::vector<std::shared_ptr<Layer>> * filters = layered_costmap_->getFilters();
669 for (std::vector<std::shared_ptr<Layer>>::iterator plugin = plugins->begin();
670 plugin != plugins->end();
673 (*plugin)->activate();
675 for (std::vector<std::shared_ptr<Layer>>::iterator filter = filters->begin();
676 filter != filters->end();
679 (*filter)->activate();
683 stop_updates_ =
false;
686 rclcpp::Rate r(20.0);
687 while (rclcpp::ok() && !initialized_) {
688 RCLCPP_DEBUG(get_logger(),
"Sleeping, waiting for initialized_");
696 stop_updates_ =
true;
699 if (layered_costmap_) {
700 std::vector<std::shared_ptr<Layer>> * plugins = layered_costmap_->getPlugins();
701 std::vector<std::shared_ptr<Layer>> * filters = layered_costmap_->getFilters();
704 for (std::vector<std::shared_ptr<Layer>>::iterator plugin = plugins->begin();
705 plugin != plugins->end(); ++plugin)
707 (*plugin)->deactivate();
709 for (std::vector<std::shared_ptr<Layer>>::iterator filter = filters->begin();
710 filter != filters->end(); ++filter)
712 (*filter)->deactivate();
715 initialized_ =
false;
722 stop_updates_ =
true;
723 initialized_ =
false;
729 stop_updates_ =
false;
732 rclcpp::Rate r(100.0);
733 while (!initialized_) {
741 Costmap2D * top = layered_costmap_->getCostmap();
745 std::vector<std::shared_ptr<Layer>> * plugins = layered_costmap_->getPlugins();
746 std::vector<std::shared_ptr<Layer>> * filters = layered_costmap_->getFilters();
747 for (std::vector<std::shared_ptr<Layer>>::iterator plugin = plugins->begin();
748 plugin != plugins->end(); ++plugin)
752 for (std::vector<std::shared_ptr<Layer>>::iterator filter = filters->begin();
753 filter != filters->end(); ++filter)
762 return nav2_util::getCurrentPose(
763 global_pose, *tf_buffer_,
769 const geometry_msgs::msg::PoseStamped & input_pose,
770 geometry_msgs::msg::PoseStamped & transformed_pose)
773 transformed_pose = input_pose;
776 return nav2_util::transformPoseInTargetFrame(
777 input_pose, transformed_pose, *tf_buffer_,
783 const std::vector<rclcpp::Parameter> & parameters)
785 rcl_interfaces::msg::SetParametersResult result;
786 result.successful =
true;
788 for (
const auto & parameter : parameters) {
789 const auto & param_type = parameter.get_type();
790 const auto & param_name = parameter.get_name();
791 if (param_name.find(
'.') != std::string::npos) {
794 if (param_type == ParameterType::PARAMETER_DOUBLE) {
795 if (parameter.as_double() <= 0.0 &&
796 (param_name ==
"resolution" || param_name ==
"publish_frequency"))
799 get_logger(),
"The value of parameter '%s' is incorrectly set to %f, "
800 "it should be >0. Ignoring parameter update.",
801 param_name.c_str(), parameter.as_double());
802 result.successful =
false;
803 }
else if (parameter.as_double() < 0.0 &&
804 (param_name !=
"origin_x" && param_name !=
"origin_y"))
807 get_logger(),
"The value of parameter '%s' is incorrectly set to %f, "
808 "it should be >0. Ignoring parameter update.",
809 param_name.c_str(), parameter.as_double());
810 result.successful =
false;
812 }
else if (param_type == ParameterType::PARAMETER_INTEGER) {
813 if (parameter.as_int() <= 0.0) {
815 get_logger(),
"The value of parameter '%s' is incorrectly set to %ld, "
816 "it should be >0. Ignoring parameter update.",
817 param_name.c_str(), parameter.as_int());
818 result.successful =
false;
820 }
else if (param_type == ParameterType::PARAMETER_STRING && param_name ==
"robot_base_frame") {
823 std::string tf_error;
824 RCLCPP_INFO(get_logger(),
"Checking transform");
825 if (!tf_buffer_->canTransform(
827 tf2::durationFromSec(1.0), &tf_error))
830 get_logger(),
"Timed out waiting for transform from %s to %s"
831 " to become available, tf error: %s",
832 parameter.as_string().c_str(),
global_frame_.c_str(), tf_error.c_str());
834 get_logger(),
"Rejecting robot_base_frame change to %s , leaving it to its original"
836 result.successful =
false;
847 bool resize_map =
false;
848 std::lock_guard<std::mutex> lock_reinit(_dynamic_parameter_mutex);
850 for (
const auto & parameter : parameters) {
851 const auto & param_type = parameter.get_type();
852 const auto & param_name = parameter.get_name();
853 if (param_name.find(
'.') != std::string::npos) {
857 if (param_type == ParameterType::PARAMETER_DOUBLE) {
858 if (param_name ==
"robot_radius") {
859 robot_radius_ = parameter.as_double();
864 }
else if (param_name ==
"footprint_padding") {
865 footprint_padding_ = parameter.as_double();
866 #ifdef __cpp_lib_atomic_shared_ptr
867 auto padded = std::make_shared<std::vector<geometry_msgs::msg::Point>>(
868 *unpadded_footprint_.load());
870 padded_footprint_.store(padded);
872 auto padded = std::make_shared<std::vector<geometry_msgs::msg::Point>>(
873 *std::atomic_load(&unpadded_footprint_));
875 std::atomic_store(&padded_footprint_, padded);
877 layered_costmap_->setFootprint(*padded);
878 }
else if (param_name ==
"transform_tolerance") {
880 }
else if (param_name ==
"publish_frequency") {
881 map_publish_frequency_ = parameter.as_double();
882 publish_cycle_ = rclcpp::Duration::from_seconds(1 / map_publish_frequency_);
883 }
else if (param_name ==
"resolution") {
885 resolution_ = parameter.as_double();
886 }
else if (param_name ==
"origin_x") {
888 origin_x_ = parameter.as_double();
889 }
else if (param_name ==
"origin_y") {
891 origin_y_ = parameter.as_double();
893 }
else if (param_type == ParameterType::PARAMETER_INTEGER) {
894 if (param_name ==
"width") {
896 map_width_meters_ = parameter.as_int();
897 }
else if (param_name ==
"height") {
899 map_height_meters_ = parameter.as_int();
901 }
else if (param_type == ParameterType::PARAMETER_STRING) {
902 if (param_name ==
"footprint") {
903 footprint_ = parameter.as_string();
904 std::vector<geometry_msgs::msg::Point> new_footprint;
908 }
else if (param_name ==
"robot_base_frame") {
914 if (resize_map && !layered_costmap_->isSizeLocked()) {
915 layered_costmap_->resizeMap(
916 (
unsigned int)(map_width_meters_ / resolution_),
917 (
unsigned int)(map_height_meters_ / resolution_), resolution_, origin_x_, origin_y_);
923 const std::shared_ptr<rmw_request_id_t>,
924 const std::shared_ptr<nav2_msgs::srv::GetCosts::Request> request,
925 const std::shared_ptr<nav2_msgs::srv::GetCosts::Response> response)
929 Costmap2D * costmap = layered_costmap_->getCostmap();
930 std::unique_lock<Costmap2D::mutex_t> lock(*(costmap->getMutex()));
931 response->success =
true;
932 for (
const auto & pose : request->poses) {
933 geometry_msgs::msg::PoseStamped pose_transformed;
936 get_logger(),
"Failed to transform, cannot get cost for pose (%.2f, %.2f)",
937 pose.pose.position.x, pose.pose.position.y);
938 response->success =
false;
939 response->costs.push_back(NO_INFORMATION);
942 double yaw = tf2::getYaw(pose_transformed.pose.orientation);
944 if (request->use_footprint) {
945 Footprint footprint = layered_costmap_->getFootprint();
949 get_logger(),
"Received request to get cost at footprint pose (%.2f, %.2f, %.2f)",
950 pose_transformed.pose.position.x, pose_transformed.pose.position.y, yaw);
952 response->costs.push_back(
954 pose_transformed.pose.position.x,
955 pose_transformed.pose.position.y, yaw, footprint));
958 get_logger(),
"Received request to get cost at point (%f, %f)",
959 pose_transformed.pose.position.x,
960 pose_transformed.pose.position.y);
963 pose_transformed.pose.position.x,
964 pose_transformed.pose.position.y, mx, my);
967 response->success =
false;
968 response->costs.push_back(LETHAL_OBSTACLE);
972 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.