Nav2 Navigation Stack - lyrical  lyrical
ROS 2 Navigation Stack
costmap_subscriber.cpp
1 // Copyright (c) 2019 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 <string>
16 #include <memory>
17 #include <mutex>
18 
19 #include "nav2_costmap_2d/costmap_subscriber.hpp"
20 
21 namespace nav2_costmap_2d
22 {
23 
24 std::shared_ptr<Costmap2D> CostmapSubscriber::getCostmap()
25 {
26  if (!isCostmapReceived()) {
27  throw std::runtime_error("Costmap is not available");
28  }
29  processCurrentCostmapMsg();
30  return costmap_;
31 }
32 
33 void CostmapSubscriber::costmapCallback(const nav2_msgs::msg::Costmap::ConstSharedPtr & msg)
34 {
35  std::lock_guard<std::recursive_mutex> lock(costmap_msg_mutex_);
36  costmap_msg_ = msg;
37  frame_id_ = costmap_msg_->header.frame_id;
38 
39  if (!isCostmapReceived()) {
40  costmap_ = std::make_shared<Costmap2D>(
41  msg->metadata.size_x, msg->metadata.size_y,
42  msg->metadata.resolution, msg->metadata.origin.position.x,
43  msg->metadata.origin.position.y);
44 
45  processCurrentCostmapMsg();
46  }
47 }
48 
50  const nav2_msgs::msg::CostmapUpdate::ConstSharedPtr & update_msg)
51 {
52  if (isCostmapReceived()) {
53  processCurrentCostmapMsg();
54 
55  std::lock_guard<Costmap2D::mutex_t> lock(*(costmap_->getMutex()));
56 
57  auto map_cell_size_x = costmap_->getSizeInCellsX();
58  auto map_call_size_y = costmap_->getSizeInCellsY();
59 
60  if (map_cell_size_x < update_msg->x + update_msg->size_x ||
61  map_call_size_y < update_msg->y + update_msg->size_y)
62  {
63  RCLCPP_WARN(
64  logger_, "Update area outside of original map area. Costmap bounds: %d X %d, "
65  "Update origin: %d, %d bounds: %d X %d", map_cell_size_x, map_call_size_y,
66  update_msg->x, update_msg->y, update_msg->size_x, update_msg->size_y);
67  return;
68  }
69  unsigned char * master_array = costmap_->getCharMap();
70  // copy update msg row-wise
71  for (size_t y = 0; y < update_msg->size_y; ++y) {
72  auto starting_index_of_row_update_in_costmap = (y + update_msg->y) * map_cell_size_x +
73  update_msg->x;
74 
75  std::copy_n(
76  update_msg->data.begin() + (y * update_msg->size_x),
77  update_msg->size_x, &master_array[starting_index_of_row_update_in_costmap]);
78  }
79  } else {
80  RCLCPP_WARN(logger_, "No costmap received.");
81  }
82 }
83 
84 void CostmapSubscriber::processCurrentCostmapMsg()
85 {
86  std::scoped_lock lock(*(costmap_->getMutex()), costmap_msg_mutex_);
87  if (!costmap_msg_) {
88  return;
89  }
90  if (haveCostmapParametersChanged()) {
91  costmap_->resizeMap(
92  costmap_msg_->metadata.size_x, costmap_msg_->metadata.size_y,
93  costmap_msg_->metadata.resolution,
94  costmap_msg_->metadata.origin.position.x,
95  costmap_msg_->metadata.origin.position.y);
96  }
97 
98  unsigned char * master_array = costmap_->getCharMap();
99  std::copy(costmap_msg_->data.begin(), costmap_msg_->data.end(), master_array);
100  costmap_msg_.reset();
101 }
102 
103 bool CostmapSubscriber::haveCostmapParametersChanged()
104 {
105  return hasCostmapSizeChanged() ||
106  hasCostmapResolutionChanged() ||
107  hasCostmapOriginPositionChanged();
108 }
109 
110 bool CostmapSubscriber::hasCostmapSizeChanged()
111 {
112  return costmap_->getSizeInCellsX() != costmap_msg_->metadata.size_x ||
113  costmap_->getSizeInCellsY() != costmap_msg_->metadata.size_y;
114 }
115 
116 bool CostmapSubscriber::hasCostmapResolutionChanged()
117 {
118  return costmap_->getResolution() != costmap_msg_->metadata.resolution;
119 }
120 
121 bool CostmapSubscriber::hasCostmapOriginPositionChanged()
122 {
123  return costmap_->getOriginX() != costmap_msg_->metadata.origin.position.x ||
124  costmap_->getOriginY() != costmap_msg_->metadata.origin.position.y;
125 }
126 
127 } // namespace nav2_costmap_2d
std::shared_ptr< Costmap2D > getCostmap()
Get current costmap.
void costmapCallback(const nav2_msgs::msg::Costmap::ConstSharedPtr &msg)
Callback for the costmap topic.
void costmapUpdateCallback(const nav2_msgs::msg::CostmapUpdate::ConstSharedPtr &update_msg)
Callback for the costmap's update topic.