Nav2 Navigation Stack - kilted  kilted
ROS 2 Navigation Stack
costmap_queue.cpp
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2017, Locus Robotics
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 #include "costmap_queue/costmap_queue.hpp"
35 #include <algorithm>
36 #include <cmath>
37 #include <vector>
38 
39 using std::hypot;
40 
41 namespace costmap_queue
42 {
43 
45 : MapBasedQueue(), costmap_(costmap), max_distance_(-1), manhattan_(manhattan),
46  cached_max_distance_(-1)
47 {
48  reset();
49 }
50 
52 {
53  unsigned int size_x = costmap_.getSizeInCellsX(), size_y = costmap_.getSizeInCellsY();
54  if (seen_.size() != size_x * size_y) {
55  seen_.resize(size_x * size_y);
56  }
57  std::fill(seen_.begin(), seen_.end(), false);
58  computeCache();
60 }
61 
62 void CostmapQueue::enqueueCell(unsigned int x, unsigned int y)
63 {
64  unsigned int index = costmap_.getIndex(x, y);
65  enqueueCell(index, x, y, x, y);
66 }
67 
69  unsigned int index, unsigned int cur_x, unsigned int cur_y,
70  unsigned int src_x, unsigned int src_y)
71 {
72  if (seen_[index]) {return;}
73 
74  // we compute our distance table one cell further than the inflation radius
75  // dictates so we can make the check below
76  double distance = distanceLookup(cur_x, cur_y, src_x, src_y);
77  CellData data(distance, index, cur_x, cur_y, src_x, src_y);
78  if (validCellToQueue(data)) {
79  seen_[index] = true;
80  enqueue(distance, data);
81  }
82 }
83 
85 {
86  // get the highest priority cell and pop it off the priority queue
87  CellData current_cell = front();
88  pop();
89 
90  unsigned int index = current_cell.index_;
91  unsigned int mx = current_cell.x_;
92  unsigned int my = current_cell.y_;
93  unsigned int sx = current_cell.src_x_;
94  unsigned int sy = current_cell.src_y_;
95 
96  // attempt to put the neighbors of the current cell onto the queue
97  unsigned int size_x = costmap_.getSizeInCellsX();
98  if (mx > 0) {
99  enqueueCell(index - 1, mx - 1, my, sx, sy);
100  }
101  if (my > 0) {
102  enqueueCell(index - size_x, mx, my - 1, sx, sy);
103  }
104  if (mx < size_x - 1) {
105  enqueueCell(index + 1, mx + 1, my, sx, sy);
106  }
107  if (my < costmap_.getSizeInCellsY() - 1) {
108  enqueueCell(index + size_x, mx, my + 1, sx, sy);
109  }
110 
111  return current_cell;
112 }
113 
115 {
116  if (max_distance_ == -1) {
117  max_distance_ = std::max(costmap_.getSizeInCellsX(), costmap_.getSizeInCellsY());
118  }
119  if (max_distance_ == cached_max_distance_) {return;}
120  cached_distances_.clear();
121 
122  cached_distances_.resize(max_distance_ + 2);
123 
124  for (unsigned int i = 0; i < cached_distances_.size(); ++i) {
125  cached_distances_[i].resize(max_distance_ + 2);
126  for (unsigned int j = 0; j < cached_distances_[i].size(); ++j) {
127  if (manhattan_) {
128  cached_distances_[i][j] = i + j;
129  } else {
130  cached_distances_[i][j] = hypot(i, j);
131  }
132  }
133  }
134  cached_max_distance_ = max_distance_;
135 }
136 
137 } // namespace costmap_queue
Storage for cell information used during queue expansion.
double distanceLookup(const unsigned int cur_x, const unsigned int cur_y, const unsigned int src_x, const unsigned int src_y)
Lookup pre-computed distances.
void enqueueCell(unsigned int x, unsigned int y)
Add a cell the queue.
CellData getNextCell()
Get the next cell to examine, and enqueue its neighbors as needed.
void reset() override
Clear the queue.
void computeCache()
Compute the cached distances.
CostmapQueue(nav2_costmap_2d::Costmap2D &costmap, bool manhattan=false)
constructor
virtual bool validCellToQueue(const CellData &)
Check to see if we should add this cell to the queue. Always true unless overridden.
Templatized interface for a priority queue.
virtual void reset()
Clear the queue.
CellData & front()
Return the item at the front of the queue.
void enqueue(const double priority, CellData item)
Add a new item to the queue with a set priority.
void pop()
Remove (and destroy) the item at the front of the queue.
A 2D costmap provides a mapping between points in the world and their associated "costs".
Definition: costmap_2d.hpp:69
unsigned int getIndex(unsigned int mx, unsigned int my) const
Given two map coordinates... compute the associated index.
Definition: costmap_2d.hpp:231
unsigned int getSizeInCellsX() const
Accessor for the x size of the costmap in cells.
Definition: costmap_2d.cpp:546
unsigned int getSizeInCellsY() const
Accessor for the y size of the costmap in cells.
Definition: costmap_2d.cpp:551