distance_map.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2021, the neonavigation authors
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <cmath>
31 #include <limits>
32 #include <unordered_map>
33 #include <utility>
34 #include <vector>
35 
36 #include <omp.h>
37 
41 
42 namespace planner_cspace
43 {
44 namespace planner_3d
45 {
48  const Astar::Vec& s_rough)
49 {
50  debug_data_.search_queue_size = open.size();
52 
53  std::vector<Astar::PriorityVec> centers;
54  centers.reserve(num_cost_estim_task_);
55  std::fill(edges_buf_.begin(), edges_buf_.end(), false);
56 
58 
59 #pragma omp parallel
60  {
61  std::vector<Astar::GridmapUpdate> updates;
62  updates.reserve(num_cost_estim_task_ * search_diffs_.size() / omp_get_num_threads());
63  std::vector<size_t> edge_indexes;
64  edge_indexes.reserve(num_cost_estim_task_ * search_diffs_.size() / omp_get_num_threads());
65 
66  const float range_overshoot = p_.euclid_cost[0] * (p_.range + p_.local_range + p_.longcut_range);
67  const float weight_linear = p_.resolution / 100.0;
68 
69  while (true)
70  {
71 #pragma omp barrier
72 #pragma omp single
73  {
74  centers.clear();
75  const float start_cost = g_[s_rough];
76  for (size_t i = 0; i < static_cast<size_t>(num_cost_estim_task_);)
77  {
78  if (open.size() < 1)
79  break;
80  Astar::PriorityVec center(open.top());
81  open.pop();
82  if (center.p_raw_ > g_[center.v_])
83  continue;
84  if (center.p_raw_ - range_overshoot > start_cost)
85  {
86  edges_buf_[center.v_[0] + center.v_[1] * p_.size[0]] = true;
87  continue;
88  }
89  centers.emplace_back(std::move(center));
90  ++i;
91  }
92  } // omp single
93 
94  if (centers.size() == 0)
95  break;
96  updates.clear();
97  edge_indexes.clear();
98 
99 #pragma omp for schedule(static)
100  for (auto it = centers.cbegin(); it < centers.cend(); ++it)
101  {
102  const Astar::Vec p = it->v_;
103 
104  for (const SearchDiffs& ds : search_diffs_)
105  {
106  const Astar::Vec d = ds.d;
107  const Astar::Vec next = p + d;
108 
109  if (static_cast<size_t>(next[0]) >= static_cast<size_t>(p_.size[0]) ||
110  static_cast<size_t>(next[1]) >= static_cast<size_t>(p_.size[1]))
111  {
112  continue;
113  }
114 
115  float cost = ds.euclid_cost;
116 
117  const float gnext = g_[next];
118 
119  if (gnext <= g_[p] + cost)
120  {
121  // Skip as this search task has no chance to find better way.
122  continue;
123  }
124 
125  {
126  float sum = 0, sum_hist = 0;
127  bool collision = false;
128  for (const auto& d : ds.pos)
129  {
130  const Astar::Vec pos = p + d;
131  const char c = cm_rough_[pos];
132  if (c > 99)
133  {
134  collision = true;
135  break;
136  }
137  sum += c;
138  sum_hist += bbf_costmap_->getCost(pos);
139  }
140  if (collision)
141  {
142  edge_indexes.push_back(p[0] + p[1] * p_.size[0]);
143  continue;
144  }
145  cost +=
146  (weight_linear * ds.grid_to_len) *
147  (sum * cc_.weight_costmap_ + sum_hist * cc_.weight_remembered_);
148 
149  if (cost < 0)
150  {
151  cost = 0;
153  }
154  }
155 
156  const float cost_next = it->p_raw_ + cost;
157  if (gnext > cost_next)
158  {
159  updates.emplace_back(p, next, cost_next, cost_next);
160  }
161  }
162  }
163 #pragma omp barrier
164 #pragma omp critical
165  {
166  for (const Astar::GridmapUpdate& u : updates)
167  {
168  if (g_[u.getPos()] > u.getCost())
169  {
170  g_[u.getPos()] = u.getCost();
171  open.push(std::move(u.getPriorityVec()));
172  }
173  }
174  for (const size_t& edge_index : edge_indexes)
175  {
176  edges_buf_[edge_index] = true;
177  }
178  } // omp critical
179  }
180  } // omp parallel
181 }
182 
184  const BlockMemGridmapBase<char, 3, 2>& cm_rough,
185  const CostmapBBF::ConstPtr bbf_costmap)
186  : cm_rough_(cm_rough)
187  , bbf_costmap_(bbf_costmap)
188  , goal_(-1, -1, -1)
189 {
190 }
191 
192 void DistanceMap::setParams(const CostCoeff& cc, const int num_cost_estim_task)
193 {
194  cc_ = cc;
195  num_cost_estim_task_ = num_cost_estim_task;
196 }
197 
198 void DistanceMap::init(const GridAstarModel3D::Ptr model, const Params& p)
199 {
200  if (p.size[0] != p_.size[0] || p.size[1] != p_.size[1])
201  {
202  // Typical open/erase queue size is be approximated by perimeter of the map
203  pq_open_.reserve((p.size[0] + p.size[1]) * 2);
204  pq_erase_.reserve((p.size[0] + p.size[1]) * 2);
205 
206  g_.reset(Astar::Vec(p.size[0], p.size[1], 1));
207  }
208  g_.clear(0);
209 
210  goal_ = Astar::Vec(-1, -1, -1);
211  p_ = p;
212  search_diffs_.clear();
213 
214  const int range_rough = 4;
215  for (Astar::Vec d(-range_rough, 0, 0); d[0] <= range_rough; d[0]++)
216  {
217  for (d[1] = -range_rough; d[1] <= range_rough; d[1]++)
218  {
219  if (d[0] == 0 && d[1] == 0)
220  continue;
221  if (d.sqlen() > range_rough * range_rough)
222  continue;
223 
224  SearchDiffs diffs;
225 
226  const float grid_to_len = d.gridToLenFactor();
227  const int dist = d.len();
228  const float dpx = static_cast<float>(d[0]) / dist;
229  const float dpy = static_cast<float>(d[1]) / dist;
230  Astar::Vecf pos(0, 0, 0);
231  for (int i = 0; i < dist; i++)
232  {
233  Astar::Vec ipos(pos);
234  if (diffs.pos.size() == 0 || diffs.pos.back() != ipos)
235  {
236  diffs.pos.push_back(std::move(ipos));
237  }
238  pos[0] += dpx;
239  pos[1] += dpy;
240  }
241  diffs.grid_to_len = grid_to_len;
242  diffs.d = d;
243  diffs.euclid_cost = model->euclidCostRough(d);
244  search_diffs_.push_back(std::move(diffs));
245  }
246  }
247  edges_buf_.resize(p_.size[0] * p_.size[1], false);
248 }
249 
251  const Astar::Vec& s, const Astar::Vec& e,
252  const Rect& rect)
253 {
254  const Astar::Vec e_rough(e[0], e[1], 0);
255  const Astar::Vec s_rough(s[0], s[1], 0);
256  if (e_rough != goal_)
257  {
258  create(s, e);
259  return;
260  }
261  Astar::Vec p_cost_min;
262  float cost_min = std::numeric_limits<float>::max();
263  for (Astar::Vec p(0, rect.min[1], 0); p[1] <= rect.max[1]; p[1]++)
264  {
265  for (p[0] = rect.min[0]; p[0] <= rect.max[0]; p[0]++)
266  {
267  if (cost_min > g_[p])
268  {
269  p_cost_min = p;
270  cost_min = g_[p];
271  }
272  }
273  }
274  if (cost_min == 0.0)
275  {
276  // Goal is in the updated area
277  create(s, e);
278  return;
279  }
280  pq_open_.clear();
281  pq_erase_.clear();
282 
283  if (s_rough.isExceeded(cm_rough_.size()) || e_rough.isExceeded(cm_rough_.size()))
284  {
285  // Out of the map
286  return;
287  }
288 
289  if (cost_min != std::numeric_limits<float>::max())
290  {
291  pq_erase_.emplace(0.0, 0.0, p_cost_min);
292  }
293 
294  if (g_[s_rough] > cost_min)
295  {
296  pq_erase_.emplace(0.0, 0.0, s_rough);
297  }
298 
299  while (true)
300  {
301  if (pq_erase_.size() < 1)
302  break;
303  const Astar::PriorityVec center(pq_erase_.top());
304  const Astar::Vec p = center.v_;
305  pq_erase_.pop();
306 
307  if (g_[p] == std::numeric_limits<float>::max())
308  continue;
309  g_[p] = std::numeric_limits<float>::max();
310 
311  for (Astar::Vec d(-1, 0, 0); d[0] <= 1; d[0]++)
312  {
313  for (d[1] = -1; d[1] <= 1; d[1]++)
314  {
315  if (!((d[0] == 0) ^ (d[1] == 0)))
316  continue;
317  Astar::Vec next = p + d;
318  next[2] = 0;
319  if ((unsigned int)next[0] >= (unsigned int)p_.size[0] ||
320  (unsigned int)next[1] >= (unsigned int)p_.size[1])
321  continue;
322  const float gn = g_[next];
323  if (gn == std::numeric_limits<float>::max())
324  continue;
325  if (gn < cost_min)
326  {
327  pq_open_.emplace(gn, gn, next);
328  continue;
329  }
330  pq_erase_.emplace(0.0, 0.0, next);
331  edges_buf_[next[0] + next[1] * p_.size[0]] = false;
332  }
333  }
334  }
335 
336  int pos = 0;
337  for (const auto& edge : edges_buf_)
338  {
339  if (edge)
340  {
341  const Astar::Vec v(static_cast<int>(pos % p_.size[0]), static_cast<int>(pos / p_.size[0]), 0);
342  const float p = g_[v];
343  pq_open_.emplace(p, p, v);
344  }
345  ++pos;
346  }
347 
348  if (pq_open_.size() == 0)
349  {
350  pq_open_.emplace(-p_.euclid_cost[0] * 0.5, -p_.euclid_cost[0] * 0.5, e_rough);
351  }
352 
353  fillCostmap(pq_open_, s_rough);
354 }
355 
356 void DistanceMap::create(const Astar::Vec& s, const Astar::Vec& e)
357 {
358  const Astar::Vec e_rough(e[0], e[1], 0);
359  const Astar::Vec s_rough(s[0], s[1], 0);
360  goal_ = e_rough;
361 
362  if (s_rough.isExceeded(cm_rough_.size()) || e_rough.isExceeded(cm_rough_.size()))
363  {
364  // Out of the map
365  return;
366  }
367 
368  pq_open_.clear();
369  pq_erase_.clear();
370  g_.clear(std::numeric_limits<float>::max());
371 
372  g_[e_rough] = -p_.euclid_cost[0] * 0.5; // Decrement to reduce calculation error
373  pq_open_.push(Astar::PriorityVec(g_[e_rough], g_[e_rough], e_rough));
374  fillCostmap(pq_open_, s_rough);
375  g_[e_rough] = 0;
376 }
377 
378 } // namespace planner_3d
379 } // namespace planner_cspace
planner_cspace::planner_3d::CostCoeff
Definition: planner_3d/grid_astar_model.h:51
planner_cspace::planner_3d::DistanceMap::num_cost_estim_task_
int num_cost_estim_task_
Definition: distance_map.h:127
planner_cspace::planner_3d::DistanceMap::SearchDiffs
Definition: distance_map.h:80
planner_cspace::planner_3d::DistanceMap::DebugData::search_queue_cap
size_t search_queue_cap
Definition: distance_map.h:66
planner_cspace::planner_3d::DistanceMap::DebugData::has_negative_cost
bool has_negative_cost
Definition: distance_map.h:67
planner_cspace::planner_3d::DistanceMap::bbf_costmap_
const CostmapBBF::ConstPtr bbf_costmap_
Definition: distance_map.h:129
planner_cspace
Definition: bbf.h:33
planner_cspace::planner_3d::DistanceMap::g_
Astar::Gridmap< float > g_
Definition: distance_map.h:124
planner_cspace::planner_3d::DistanceMap::Rect::max
Astar::Vec max
Definition: distance_map.h:55
planner_cspace::reservable_priority_queue::capacity
size_type capacity() const
Definition: reservable_priority_queue.h:50
planner_cspace::planner_3d::DistanceMap::debug_data_
DebugData debug_data_
Definition: distance_map.h:132
s
XmlRpcServer s
planner_cspace::planner_3d::DistanceMap::update
void update(const Astar::Vec &s, const Astar::Vec &e, const Rect &rect)
Definition: distance_map.cpp:250
planner_cspace::planner_3d::DistanceMap::pq_open_
reservable_priority_queue< Astar::PriorityVec > pq_open_
Definition: distance_map.h:134
planner_cspace::BlockMemGridmapBase::size
virtual const CyclicVecInt< DIM, NONCYCLIC > & size() const =0
planner_cspace::planner_3d::CostmapBBF::ConstPtr
std::shared_ptr< const CostmapBBF > ConstPtr
Definition: costmap_bbf.h:48
planner_cspace::planner_3d::DistanceMap::SearchDiffs::d
Astar::Vec d
Definition: distance_map.h:82
planner_cspace::planner_3d::DistanceMap::Params::size
Astar::Vec size
Definition: distance_map.h:76
planner_cspace::planner_3d::DistanceMap::p_
Params p_
Definition: distance_map.h:125
grid_astar_model.h
planner_cspace::planner_3d::DistanceMap::Rect::min
Astar::Vec min
Definition: distance_map.h:54
planner_cspace::planner_3d::DistanceMap::SearchDiffs::pos
std::vector< Astar::Vec > pos
Definition: distance_map.h:83
planner_cspace::BlockMemGridmapBase< char, 3, 2 >
planner_cspace::planner_3d::DistanceMap::SearchDiffs::grid_to_len
float grid_to_len
Definition: distance_map.h:84
planner_cspace::planner_3d::DistanceMap::cc_
CostCoeff cc_
Definition: distance_map.h:126
planner_cspace::planner_3d::DistanceMap::Params::local_range
int local_range
Definition: distance_map.h:74
planner_cspace::planner_3d::DistanceMap::Params
Definition: distance_map.h:70
planner_cspace::planner_3d::DistanceMap::Params::resolution
float resolution
Definition: distance_map.h:77
d
d
planner_cspace::planner_3d::CostCoeff::weight_remembered_
float weight_remembered_
Definition: planner_3d/grid_astar_model.h:60
distance_map.h
planner_cspace::GridAstar::PriorityVec::p_raw_
float p_raw_
Definition: grid_astar.h:82
planner_cspace::planner_3d::DistanceMap::create
void create(const Astar::Vec &s, const Astar::Vec &e)
Definition: distance_map.cpp:356
grid_astar.h
planner_cspace::planner_3d::DistanceMap::pq_erase_
reservable_priority_queue< Astar::PriorityVec > pq_erase_
Definition: distance_map.h:135
planner_cspace::GridAstar::PriorityVec
Definition: grid_astar.h:78
planner_cspace::planner_3d::DistanceMap::search_diffs_
std::vector< SearchDiffs > search_diffs_
Definition: distance_map.h:131
planner_cspace::planner_3d::DistanceMap::Params::longcut_range
int longcut_range
Definition: distance_map.h:75
planner_cspace::planner_3d::DistanceMap::fillCostmap
void fillCostmap(reservable_priority_queue< Astar::PriorityVec > &open, const Astar::Vec &s_rough)
Definition: distance_map.cpp:46
planner_cspace::GridAstar::PriorityVec::v_
Vec v_
Definition: grid_astar.h:83
planner_cspace::planner_3d::GridAstarModel3D::Ptr
std::shared_ptr< GridAstarModel3D > Ptr
Definition: planner_3d/grid_astar_model.h:76
planner_cspace::planner_3d::CostCoeff::weight_costmap_
float weight_costmap_
Definition: planner_3d/grid_astar_model.h:57
planner_cspace::GridAstar< 3, 2 >::Vec
CyclicVecInt< DIM, NONCYCLIC > Vec
Definition: grid_astar.h:67
planner_cspace::planner_3d::DistanceMap::DebugData::search_queue_size
size_t search_queue_size
Definition: distance_map.h:65
planner_cspace::planner_3d::DistanceMap::init
void init(const GridAstarModel3D::Ptr model, const Params &p)
Definition: distance_map.cpp:198
planner_cspace::planner_3d::DistanceMap::DistanceMap
DistanceMap(const BlockMemGridmapBase< char, 3, 2 > &cm_rough, const CostmapBBF::ConstPtr bbf_costmap)
Definition: distance_map.cpp:183
planner_cspace::planner_3d::DistanceMap::setParams
void setParams(const CostCoeff &cc, const int num_cost_estim_task)
Definition: distance_map.cpp:192
planner_cspace::planner_3d::DistanceMap::Rect
Definition: distance_map.h:52
planner_cspace::planner_3d::DistanceMap::Params::range
int range
Definition: distance_map.h:73
planner_cspace::planner_3d::DistanceMap::goal_
Astar::Vec goal_
Definition: distance_map.h:138
planner_cspace::planner_3d::DistanceMap::edges_buf_
std::vector< bool > edges_buf_
Definition: distance_map.h:136
planner_cspace::reservable_priority_queue
Definition: reservable_priority_queue.h:38
planner_cspace::planner_3d::DistanceMap::SearchDiffs::euclid_cost
float euclid_cost
Definition: distance_map.h:85
planner_cspace::planner_3d::DistanceMap::Params::euclid_cost
Astar::Vecf euclid_cost
Definition: distance_map.h:72
planner_cspace::planner_3d::DistanceMap::cm_rough_
const BlockMemGridmapBase< char, 3, 2 > & cm_rough_
Definition: distance_map.h:128
planner_cspace::CyclicVecBase
Definition: cyclic_vec.h:78


planner_cspace
Author(s): Atsushi Watanabe
autogenerated on Fri May 16 2025 02:15:22