Nav2 Navigation Stack - kilted  kilted
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 static_cast<double>(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  oriented_footprint.reserve(footprint.size());
136  geometry_msgs::msg::Point new_pt;
137  for (unsigned int i = 0; i < footprint.size(); ++i) {
138  new_pt.x = x + (footprint[i].x * cos_th - footprint[i].y * sin_th);
139  new_pt.y = y + (footprint[i].x * sin_th + footprint[i].y * cos_th);
140  oriented_footprint.push_back(new_pt);
141  }
142 
143  return footprintCost(oriented_footprint);
144 }
145 
146 // declare our valid template parameters
149 
150 } // namespace nav2_costmap_2d
Checker for collision with a footprint on a costmap.
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 footprintCostAtPose(double x, double y, double theta, const Footprint &footprint)
Find the footprint cost a a post with an unoriented footprint.
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.