Nav2 Navigation Stack - humble  humble
ROS 2 Navigation Stack
footprint_collision_checker.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 // Modified by: Shivang Patel (shivaang14@gmail.com)
16 
17 #include <memory>
18 #include <string>
19 #include <vector>
20 #include <algorithm>
21 
22 #include "nav2_costmap_2d/footprint_collision_checker.hpp"
23 
24 #include "nav2_costmap_2d/cost_values.hpp"
25 #include "nav2_costmap_2d/exceptions.hpp"
26 #include "nav2_costmap_2d/footprint.hpp"
27 #include "nav2_util/line_iterator.hpp"
28 
29 using namespace std::chrono_literals;
30 
31 namespace nav2_costmap_2d
32 {
33 
34 template<typename CostmapT>
36 : costmap_(nullptr)
37 {
38 }
39 
40 template<typename CostmapT>
42  CostmapT costmap)
43 : costmap_(costmap)
44 {
45 }
46 
47 template<typename CostmapT>
48 double FootprintCollisionChecker<CostmapT>::footprintCost(const Footprint footprint)
49 {
50  // now we really have to lay down the footprint in the costmap_ grid
51  unsigned int x0, x1, y0, y1;
52  double footprint_cost = 0.0;
53 
54  // get the cell coord of the first point
55  if (!worldToMap(footprint[0].x, footprint[0].y, x0, y0)) {
56  return static_cast<double>(LETHAL_OBSTACLE);
57  }
58 
59  // cache the start to eliminate a worldToMap call
60  unsigned int xstart = x0;
61  unsigned int ystart = y0;
62 
63  // we need to rasterize each line in the footprint
64  for (unsigned int i = 0; i < footprint.size() - 1; ++i) {
65  // get the cell coord of the second point
66  if (!worldToMap(footprint[i + 1].x, footprint[i + 1].y, x1, y1)) {
67  return static_cast<double>(LETHAL_OBSTACLE);
68  }
69 
70  footprint_cost = std::max(lineCost(x0, x1, y0, y1), footprint_cost);
71 
72  // the second point is next iteration's first point
73  x0 = x1;
74  y0 = y1;
75 
76  // if in collision, no need to continue
77  if (footprint_cost == static_cast<double>(LETHAL_OBSTACLE)) {
78  return footprint_cost;
79  }
80  }
81 
82  // we also need to connect the first point in the footprint to the last point
83  // the last iteration's x1, y1 are the last footprint point's coordinates
84  return std::max(lineCost(xstart, x1, ystart, y1), footprint_cost);
85 }
86 
87 template<typename CostmapT>
88 double FootprintCollisionChecker<CostmapT>::lineCost(int x0, int x1, int y0, int y1) const
89 {
90  double line_cost = 0.0;
91  double point_cost = -1.0;
92 
93  for (nav2_util::LineIterator line(x0, y0, x1, y1); line.isValid(); line.advance()) {
94  point_cost = pointCost(line.getX(), line.getY()); // Score the current point
95 
96  // if in collision, no need to continue
97  if (point_cost == static_cast<double>(LETHAL_OBSTACLE)) {
98  return point_cost;
99  }
100 
101  if (line_cost < point_cost) {
102  line_cost = point_cost;
103  }
104  }
105 
106  return line_cost;
107 }
108 
109 template<typename CostmapT>
111  double wx, double wy, unsigned int & mx, unsigned int & my)
112 {
113  return costmap_->worldToMap(wx, wy, mx, my);
114 }
115 
116 template<typename CostmapT>
118 {
119  return costmap_->getCost(x, y);
120 }
121 
122 template<typename CostmapT>
124 {
125  costmap_ = costmap;
126 }
127 
128 template<typename CostmapT>
130  double x, double y, double theta, const Footprint footprint)
131 {
132  double cos_th = cos(theta);
133  double sin_th = sin(theta);
134  Footprint oriented_footprint;
135  for (unsigned int i = 0; i < footprint.size(); ++i) {
136  geometry_msgs::msg::Point new_pt;
137  new_pt.x = x + (footprint[i].x * cos_th - footprint[i].y * sin_th);
138  new_pt.y = y + (footprint[i].x * sin_th + footprint[i].y * cos_th);
139  oriented_footprint.push_back(new_pt);
140  }
141 
142  return footprintCost(oriented_footprint);
143 }
144 
145 // declare our valid template parameters
148 
149 } // namespace nav2_costmap_2d
Checker for collision with a footprint on a costmap.
double footprintCostAtPose(double x, double y, double theta, const Footprint footprint)
Find the footprint cost a a post with an unoriented footprint.
double lineCost(int x0, int x1, int y0, int y1) const
Get the cost for a line segment.
bool worldToMap(double wx, double wy, unsigned int &mx, unsigned int &my)
Get the map coordinates from a world point.
double footprintCost(const Footprint footprint)
Find the footprint cost in oriented footprint.
void setCostmap(CostmapT costmap)
Set the current costmap object to use for collision detection.
double pointCost(int x, int y) const
Get the cost of a point.
An iterator implementing Bresenham Ray-Tracing.
bool isValid() const
If the iterator is valid.