Nav2 Navigation Stack - kilted  kilted
ROS 2 Navigation Stack
clear_costmap_service.cpp
1 // Copyright (c) 2018 Intel Corporation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <vector>
16 #include <string>
17 #include <algorithm>
18 #include <memory>
19 
20 #include "nav2_costmap_2d/clear_costmap_service.hpp"
21 #include "nav2_costmap_2d/costmap_2d_ros.hpp"
22 
23 namespace nav2_costmap_2d
24 {
25 
26 using std::vector;
27 using std::string;
28 using std::shared_ptr;
29 using std::any_of;
30 using ClearExceptRegion = nav2_msgs::srv::ClearCostmapExceptRegion;
31 using ClearAroundRobot = nav2_msgs::srv::ClearCostmapAroundRobot;
32 using ClearEntirely = nav2_msgs::srv::ClearEntireCostmap;
33 
35  const nav2_util::LifecycleNode::WeakPtr & parent,
36  Costmap2DROS & costmap)
37 : costmap_(costmap)
38 {
39  auto node = parent.lock();
40  logger_ = node->get_logger();
41  reset_value_ = costmap_.getCostmap()->getDefaultValue();
42 
43  clear_except_service_ = std::make_shared<nav2_util::ServiceServer<ClearExceptRegion,
44  std::shared_ptr<rclcpp_lifecycle::LifecycleNode>>>(
45  std::string("clear_except_") + costmap_.getName(),
46  node,
47  std::bind(
48  &ClearCostmapService::clearExceptRegionCallback, this,
49  std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
50 
51  clear_around_service_ = std::make_shared<nav2_util::ServiceServer<ClearAroundRobot,
52  std::shared_ptr<rclcpp_lifecycle::LifecycleNode>>>(
53  std::string("clear_around_") + costmap_.getName(),
54  node,
55  std::bind(
56  &ClearCostmapService::clearAroundRobotCallback, this,
57  std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
58 
59  clear_entire_service_ = std::make_shared<nav2_util::ServiceServer<ClearEntirely,
60  std::shared_ptr<rclcpp_lifecycle::LifecycleNode>>>(
61  std::string("clear_entirely_") + costmap_.getName(),
62  node,
63  std::bind(
64  &ClearCostmapService::clearEntireCallback, this,
65  std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
66 }
67 
69 {
70  // make sure services shutdown.
71  clear_except_service_.reset();
72  clear_around_service_.reset();
73  clear_entire_service_.reset();
74 }
75 
76 void ClearCostmapService::clearExceptRegionCallback(
77  const shared_ptr<rmw_request_id_t>/*request_header*/,
78  const shared_ptr<ClearExceptRegion::Request> request,
79  const shared_ptr<ClearExceptRegion::Response>/*response*/)
80 {
81  RCLCPP_INFO(
82  logger_, "%s",
83  ("Received request to clear except a region the " + costmap_.getName()).c_str());
84 
85  clearRegion(request->reset_distance, true);
86 }
87 
88 void ClearCostmapService::clearAroundRobotCallback(
89  const shared_ptr<rmw_request_id_t>/*request_header*/,
90  const shared_ptr<ClearAroundRobot::Request> request,
91  const shared_ptr<ClearAroundRobot::Response>/*response*/)
92 {
93  clearRegion(request->reset_distance, false);
94 }
95 
96 void ClearCostmapService::clearEntireCallback(
97  const std::shared_ptr<rmw_request_id_t>/*request_header*/,
98  const std::shared_ptr<ClearEntirely::Request>/*request*/,
99  const std::shared_ptr<ClearEntirely::Response>/*response*/)
100 {
101  RCLCPP_INFO(
102  logger_, "%s",
103  ("Received request to clear entirely the " + costmap_.getName()).c_str());
104 
105  clearEntirely();
106 }
107 
108 void ClearCostmapService::clearRegion(const double reset_distance, bool invert)
109 {
110  double x, y;
111 
112  if (!getPosition(x, y)) {
113  RCLCPP_ERROR(
114  logger_, "%s",
115  "Cannot clear map because robot pose cannot be retrieved.");
116  return;
117  }
118 
119  auto layers = costmap_.getLayeredCostmap()->getPlugins();
120 
121  for (auto & layer : *layers) {
122  if (layer->isClearable()) {
123  auto costmap_layer = std::static_pointer_cast<CostmapLayer>(layer);
124  clearLayerRegion(costmap_layer, x, y, reset_distance, invert);
125  }
126  }
127 
128  // AlexeyMerzlyakov: No need to clear layer region for costmap filters
129  // as they are always supposed to be not clearable.
130 }
131 
132 void ClearCostmapService::clearLayerRegion(
133  shared_ptr<CostmapLayer> & costmap, double pose_x, double pose_y, double reset_distance,
134  bool invert)
135 {
136  std::unique_lock<Costmap2D::mutex_t> lock(*(costmap->getMutex()));
137 
138  double start_point_x = pose_x - reset_distance / 2;
139  double start_point_y = pose_y - reset_distance / 2;
140  double end_point_x = start_point_x + reset_distance;
141  double end_point_y = start_point_y + reset_distance;
142 
143  int start_x, start_y, end_x, end_y;
144  costmap->worldToMapNoBounds(start_point_x, start_point_y, start_x, start_y);
145  costmap->worldToMapNoBounds(end_point_x, end_point_y, end_x, end_y);
146 
147  costmap->clearArea(start_x, start_y, end_x, end_y, invert);
148 
149  double ox = costmap->getOriginX(), oy = costmap->getOriginY();
150  double width = costmap->getSizeInMetersX(), height = costmap->getSizeInMetersY();
151  costmap->addExtraBounds(ox, oy, ox + width, oy + height);
152 }
153 
155 {
156  std::unique_lock<Costmap2D::mutex_t> lock(*(costmap_.getCostmap()->getMutex()));
157  costmap_.resetLayers();
158 }
159 
160 bool ClearCostmapService::getPosition(double & x, double & y) const
161 {
162  geometry_msgs::msg::PoseStamped pose;
163  if (!costmap_.getRobotPose(pose)) {
164  return false;
165  }
166 
167  x = pose.pose.position.x;
168  y = pose.pose.position.y;
169 
170  return true;
171 }
172 
173 } // namespace nav2_costmap_2d
ClearCostmapService()=delete
A constructor.
void clearRegion(double reset_distance, bool invert)
Clears the region outside of a user-specified area reverting to the static map.
A ROS wrapper for a 2D Costmap. Handles subscribing to topics that provide observations about obstacl...
bool getRobotPose(geometry_msgs::msg::PoseStamped &global_pose)
Get the pose of the robot in the global frame of the costmap.
std::string getName() const
Returns costmap name.
LayeredCostmap * getLayeredCostmap()
Get the layered costmap object used in the node.
void resetLayers()
Reset each individual layer.
Costmap2D * getCostmap()
Return a pointer to the "master" costmap which receives updates from all the layers.
unsigned char getDefaultValue()
Get the default background value of the costmap.
Definition: costmap_2d.hpp:309
std::vector< std::shared_ptr< Layer > > * getPlugins()
Get the vector of pointers to the costmap plugins.
A simple wrapper on ROS2 services server.