Nav2 Navigation Stack - lyrical  lyrical
ROS 2 Navigation Stack
costmap_2d_ros.hpp
1 /*********************************************************************
2  *
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2008, 2013, Willow Garage, Inc.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of Willow Garage, Inc. nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * Author: Eitan Marder-Eppstein
36  * David V. Lu!!
37  *********************************************************************/
38 #ifndef NAV2_COSTMAP_2D__COSTMAP_2D_ROS_HPP_
39 #define NAV2_COSTMAP_2D__COSTMAP_2D_ROS_HPP_
40 
41 #include <atomic>
42 #include <memory>
43 #include <string>
44 #include <vector>
45 
46 #include "geometry_msgs/msg/polygon.hpp"
47 #include "geometry_msgs/msg/polygon_stamped.hpp"
48 #include "nav2_costmap_2d/costmap_2d_publisher.hpp"
49 #include "nav2_costmap_2d/footprint.hpp"
50 #include "nav2_costmap_2d/footprint_collision_checker.hpp"
51 #include "nav2_costmap_2d/clear_costmap_service.hpp"
52 #include "nav2_costmap_2d/layered_costmap.hpp"
53 #include "nav2_costmap_2d/layer.hpp"
54 #include "nav2_ros_common/lifecycle_node.hpp"
55 #include "nav2_msgs/srv/get_costs.hpp"
56 #include "pluginlib/class_loader.hpp"
57 #include "tf2/convert.hpp"
58 #include "tf2/LinearMath/Transform.hpp"
59 #include "nav2_ros_common/tf2_factories.hpp"
60 #include "tf2/time.hpp"
61 #include "tf2/transform_datatypes.hpp"
62 #include "nav2_ros_common/service_server.hpp"
63 
64 #pragma GCC diagnostic push
65 #pragma GCC diagnostic ignored "-Wpedantic"
66 #include "tf2/utils.hpp"
67 #pragma GCC diagnostic pop
68 
69 namespace nav2_costmap_2d
70 {
71 
76 {
77 public:
82  explicit Costmap2DROS(const rclcpp::NodeOptions & options = rclcpp::NodeOptions());
83 
90  explicit Costmap2DROS(
91  const std::string & name,
92  const std::string & parent_namespace = "/",
93  const bool & use_sim_time = false,
94  const rclcpp::NodeOptions & options = rclcpp::NodeOptions());
95 
99  void init();
100 
104  ~Costmap2DROS();
105 
109  nav2::CallbackReturn on_configure(const rclcpp_lifecycle::State & state) override;
110 
114  nav2::CallbackReturn on_activate(const rclcpp_lifecycle::State & state) override;
115 
119  nav2::CallbackReturn on_deactivate(const rclcpp_lifecycle::State & state) override;
120 
124  nav2::CallbackReturn on_cleanup(const rclcpp_lifecycle::State & state) override;
125 
129  nav2::CallbackReturn on_shutdown(const rclcpp_lifecycle::State & state) override;
130 
136  void on_rcl_preshutdown() override
137  {
139  // Transitioning handled by parent node
140  return;
141  }
142 
143  // Else, if this is an independent node, this node needs to handle itself.
144  RCLCPP_INFO(
145  get_logger(), "Running Nav2 LifecycleNode rcl preshutdown (%s)",
146  this->get_name());
147 
148  runCleanups();
149 
150  destroyBond();
151  }
152 
158  void start();
159 
163  void stop();
164 
168  void pause();
169 
173  void resume();
174 
178  void updateMap();
179 
183  void resetLayers();
184 
186  bool isCurrent()
187  {
188  return layered_costmap_->isCurrent();
189  }
190 
196  void waitUntilCurrent(const rclcpp::Duration & timeout);
197 
203  bool getRobotPose(geometry_msgs::msg::PoseStamped & global_pose);
204 
212  const geometry_msgs::msg::PoseStamped & input_pose,
213  geometry_msgs::msg::PoseStamped & transformed_pose);
214 
216  std::string getName() const
217  {
218  return name_;
219  }
220 
222  double getTransformTolerance() const
223  {
224  return transform_tolerance_;
225  }
226 
233  {
234  return layered_costmap_->getCostmap();
235  }
236 
241  std::string getGlobalFrameID()
242  {
243  return global_frame_;
244  }
245 
250  std::string getBaseFrameID()
251  {
252  return robot_base_frame_;
253  }
254 
259  {
260  return layered_costmap_.get();
261  }
262 
264  geometry_msgs::msg::Polygon getRobotFootprintPolygon()
265  {
266 #ifdef __cpp_lib_atomic_shared_ptr
267  return nav2_costmap_2d::toPolygon(*padded_footprint_.load());
268 #else
269  return nav2_costmap_2d::toPolygon(*std::atomic_load(&padded_footprint_));
270 #endif
271  }
272 
281  std::vector<geometry_msgs::msg::Point> getRobotFootprint()
282  {
283 #ifdef __cpp_lib_atomic_shared_ptr
284  return *padded_footprint_.load();
285 #else
286  return *std::atomic_load(&padded_footprint_);
287 #endif
288  }
289 
297  std::vector<geometry_msgs::msg::Point> getUnpaddedRobotFootprint()
298  {
299 #ifdef __cpp_lib_atomic_shared_ptr
300  return *unpadded_footprint_.load();
301 #else
302  return *std::atomic_load(&unpadded_footprint_);
303 #endif
304  }
305 
310  void getOrientedFootprint(std::vector<geometry_msgs::msg::Point> & oriented_footprint);
311 
322  void setRobotFootprint(const std::vector<geometry_msgs::msg::Point> & points);
323 
334  void setRobotFootprintPolygon(const geometry_msgs::msg::Polygon & footprint);
335 
336  nav2::TransformBuffer::SharedPtr getTfBuffer() {return tf_buffer_;}
337 
344  bool getUseRadius() {return use_radius_;}
345 
352  double getRobotRadius() {return robot_radius_;}
353 
358  void getCostsCallback(
359  const std::shared_ptr<rmw_request_id_t>,
360  const std::shared_ptr<nav2_msgs::srv::GetCosts::Request> request,
361  const std::shared_ptr<nav2_msgs::srv::GetCosts::Response> response);
362 
363 protected:
364  // Publishers and subscribers
365  nav2::Publisher<geometry_msgs::msg::PolygonStamped>::SharedPtr
366  footprint_pub_;
367  std::unique_ptr<Costmap2DPublisher> costmap_publisher_;
368 
369  std::vector<std::unique_ptr<Costmap2DPublisher>> layer_publishers_;
370 
371  nav2::Subscription<geometry_msgs::msg::Polygon>::SharedPtr footprint_sub_;
372  nav2::Subscription<geometry_msgs::msg::PolygonStamped>::SharedPtr footprint_stamped_sub_;
373  nav2::Subscription<rcl_interfaces::msg::ParameterEvent>::SharedPtr parameter_sub_;
374 
375  // Dedicated callback group and executor for tf timer_interface and message filter
376  rclcpp::CallbackGroup::SharedPtr callback_group_;
377  rclcpp::executors::SingleThreadedExecutor::SharedPtr executor_;
378  std::unique_ptr<nav2::NodeThread> executor_thread_;
379 
380  // Transform listener
381  nav2::TransformBuffer::SharedPtr tf_buffer_;
382  nav2::TransformListener::SharedPtr tf_listener_;
383 
384  std::unique_ptr<LayeredCostmap> layered_costmap_{nullptr};
385  std::string name_;
386 
390  void mapUpdateLoop(double frequency);
391  std::atomic<bool> map_update_thread_shutdown_{false}; // [AI generated]
392  std::atomic<bool> stop_updates_{false};
393  std::atomic<bool> initialized_{false};
394  std::atomic<bool> stopped_{true};
395  std::mutex _dynamic_parameter_mutex;
396  std::unique_ptr<std::thread> map_update_thread_;
397  rclcpp::Time last_publish_{0, 0, RCL_ROS_TIME};
398  rclcpp::Duration publish_cycle_{1, 0};
399  pluginlib::ClassLoader<Layer> plugin_loader_{"nav2_costmap_2d", "nav2_costmap_2d::Layer"};
400 
404  void getParameters();
405  bool always_send_full_costmap_{false};
406  std::string footprint_;
407  float footprint_padding_{0};
408  std::string global_frame_;
409  int map_height_meters_{0};
410  double map_publish_frequency_{0};
411  double map_update_frequency_{0};
412  int map_width_meters_{0};
413  double origin_x_{0};
414  double origin_y_{0};
415  std::vector<std::string> default_plugins_;
416  std::vector<std::string> default_types_;
417  std::vector<std::string> plugin_names_;
418  std::vector<std::string> plugin_types_;
419  std::vector<std::string> filter_names_;
420  std::vector<std::string> filter_types_;
421  double resolution_{0};
422  std::string robot_base_frame_;
423  double robot_radius_;
424  bool rolling_window_{false};
425  bool track_unknown_space_{false};
428  double map_vis_z_{0};
431 
433 
434  // Derived parameters
435  bool use_radius_{false};
436 #ifdef __cpp_lib_atomic_shared_ptr
437  std::atomic<std::shared_ptr<std::vector<geometry_msgs::msg::Point>>> unpadded_footprint_{
438  std::make_shared<std::vector<geometry_msgs::msg::Point>>()};
439  std::atomic<std::shared_ptr<std::vector<geometry_msgs::msg::Point>>> padded_footprint_{
440  std::make_shared<std::vector<geometry_msgs::msg::Point>>()};
441 #else
442  std::shared_ptr<std::vector<geometry_msgs::msg::Point>> unpadded_footprint_{
443  std::make_shared<std::vector<geometry_msgs::msg::Point>>()};
444  std::shared_ptr<std::vector<geometry_msgs::msg::Point>> padded_footprint_{
445  std::make_shared<std::vector<geometry_msgs::msg::Point>>()};
446 #endif
447 
448  // Services
449  nav2::ServiceServer<nav2_msgs::srv::GetCosts>::SharedPtr get_cost_service_;
450  std::unique_ptr<ClearCostmapService> clear_costmap_service_;
451 
452  // Dynamic parameters handler
453  PostSetParametersCallbackHandle::SharedPtr post_set_params_handler_;
454  OnSetParametersCallbackHandle::SharedPtr on_set_params_handler;
455 
464  rcl_interfaces::msg::SetParametersResult validateParameterUpdatesCallback(
465  const std::vector<rclcpp::Parameter> & parameters);
466 
473  void updateParametersCallback(const std::vector<rclcpp::Parameter> & parameters);
474 };
475 
476 // free functions
477 
482 rclcpp::NodeOptions getChildNodeOptions(
483  const std::string & name,
484  const std::string & parent_namespace,
485  const bool & use_sim_time,
486  const rclcpp::NodeOptions & parent_options);
487 
488 } // namespace nav2_costmap_2d
489 
490 #endif // NAV2_COSTMAP_2D__COSTMAP_2D_ROS_HPP_
A lifecycle node wrapper to enable common Nav2 needs such as manipulating parameters.
void destroyBond()
Destroy bond connection to lifecycle manager.
A ROS wrapper for a 2D Costmap. Handles subscribing to topics that provide observations about obstacl...
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.
geometry_msgs::msg::Polygon getRobotFootprintPolygon()
Returns the current padded footprint as a geometry_msgs::msg::Polygon.
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.
bool getUseRadius()
Get the costmap's use_radius_ parameter, corresponding to whether the footprint for the robot is a ci...
nav2::CallbackReturn on_deactivate(const rclcpp_lifecycle::State &state) override
Deactivate node.
std::string getName() const
Returns costmap name.
rcl_interfaces::msg::SetParametersResult validateParameterUpdatesCallback(const std::vector< rclcpp::Parameter > &parameters)
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.
double transform_tolerance_
The timeout before transform errors.
bool rolling_window_
Whether to use a rolling window version of the costmap.
LayeredCostmap * getLayeredCostmap()
Get the layered costmap object used in the node.
void on_rcl_preshutdown() override
as a child-LifecycleNode : Costmap2DROS may be launched by another Lifecycle Node as a composed modul...
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.
std::string getBaseFrameID()
Returns the local frame of the costmap.
std::vector< geometry_msgs::msg::Point > getRobotFootprint()
Return the current footprint of the robot as a vector of points.
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.
std::string getGlobalFrameID()
Returns the global frame of 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 > &parameters)
Apply parameter updates after validation This callback is executed when parameters have been successf...
double getTransformTolerance() const
Returns the delay in transform (tf) data that is tolerable in seconds.
double getRobotRadius()
Get the costmap's robot_radius_ parameter, corresponding to raidus of the robot footprint when it is ...
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.
Costmap2D * getCostmap()
Return a pointer to the "master" costmap which receives updates from all the layers.
void init()
Common initialization for constructors.
std::vector< geometry_msgs::msg::Point > getUnpaddedRobotFootprint()
Return the current unpadded footprint of the robot as a vector of points.
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".
Definition: costmap_2d.hpp:69
Instantiates different layer plugins and aggregates them into one score.
geometry_msgs::msg::Polygon toPolygon(const std::vector< geometry_msgs::msg::Point > &pts)
Convert vector of Points to Polygon msg.
Definition: footprint.cpp:92
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,...