point_expander.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017, <copyright holder> <email>
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  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the <organization> nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY <copyright holder> <email> ''AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL <copyright holder> <email> BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
30 #include <opencv2/core/mat.hpp>
31 #include <ros/ros.h>
32 
33 namespace multi_robot_router
34 {
35 void PointExpander::initialize(const cv::Mat &_map)
36 {
37  nx_ = _map.cols;
38  ny_ = _map.rows;
39  ns_ = nx_ * ny_;
40 
41  distance_field_ = _map.clone();
42 }
43 
44 void PointExpander::addPotentialExpansionCandidate(PointExpander::Index _current, int32_t _next_x, int32_t _next_y, float *_potential, uint32_t _distToObstacle)
45 {
46  float potentialPrev = _potential[_current.i];
47  Index next = _current.offsetDist(_next_x, _next_y, nx_, ny_);
48 
49  //Check Boundries
50  if (next.i < 0 || next.i > ns_)
51  return;
52 
53  //Dont update allready found potentials
54  if (_potential[next.i] < POT_HIGH)
55  return;
56 
57  if (((float *)distance_field_.data)[next.i] < _distToObstacle)
58  return;
59 
60  float dist = 0;
61  float pot = potentialPrev + neutral_cost_;
62  float weight = pot; //Dijkstra
63 
64  _potential[next.i] = pot;
65 
66  queue_.push(Index(next.i, weight, dist, pot));
67 }
68 
69 PointExpander::Index PointExpander::findGoal(const PointExpander::Index &_start, const uint32_t &_cycles, float *_potential, const std::map<uint32_t, Index> &_goals, const uint32_t &_optimizationSteps, int32_t &segIdx, const uint32_t &_radius)
70 {
71  std::fill(_potential, _potential + ns_, POT_HIGH);
72  uint32_t cycle = 0;
73 
74  uint32_t _noGoalPoses = _optimizationSteps + 1;
75 
76  Index current(_start.i, 0, 0, 0);
77  _potential[current.i] = 0;
78 
79  //clear the queue
80  clearpq(queue_);
81  queue_.push(current);
82 
83  Index currentGoal(-1, -1, -1, -1);
84  segIdx = -1;
85 
86  while (!queue_.empty() && _noGoalPoses > 0 && cycle < _cycles)
87  {
88  if (queue_.empty())
89  return Index(-1, -1, -1, -1);
90 
91  current = queue_.top();
92  queue_.pop();
93 
94  int32_t segmentIndex = -1;
95 
96  if (isGoal(current, _goals, segmentIndex))
97  {
98  if (currentGoal.i == -1)
99  {
100  currentGoal = current;
101  segIdx = segmentIndex;
102  }
103  else
104  {
105  if (_potential[current.i] < _potential[currentGoal.i] + current.distance(currentGoal, nx_))
106  {
107  currentGoal = current;
108  segIdx = segmentIndex;
109  }
110  }
111 
112  _noGoalPoses--;
113 
114  if (_noGoalPoses == 0)
115  return currentGoal;
116  }
117 
118  addPotentialExpansionCandidate(current, 1, 0, _potential, _radius);
119  addPotentialExpansionCandidate(current, 0, 1, _potential, _radius);
120  addPotentialExpansionCandidate(current, -1, 0, _potential, _radius);
121  addPotentialExpansionCandidate(current, 0, -1, _potential, _radius);
122 
123  cycle++;
124  }
125 
126  if (cycle >= _cycles)
127  return Index(-1, -1, -1, -1);
128  else
129  return _start;
130 }
131 
132 bool PointExpander::isGoal(Index _p, const std::map<uint32_t, Index> &_goals, int32_t &segIdx)
133 {
134  segIdx = -1;
135 
136  for (const std::pair<uint32_t, Index> &g : _goals)
137  {
138  if (_p.i == g.second.i)
139  {
140  segIdx = g.first;
141  return true;
142  }
143  }
144 
145  return false;
146 }
147 
148 bool PointExpander::findGoalOnMap(const Eigen::Vector2d &_start, const uint32_t &_cycles, float *_potential, const std::map<uint32_t, Eigen::Vector2d> &_goals, const uint32_t &_optimizationSteps, Eigen::Vector2d &_foundPoint, int32_t &_segIdx, const uint32_t &_radius)
149 {
150  Index startPoint((int32_t)_start[0], (int32_t)_start[1], nx_, 0, 0, 0);
151 
152  if (startPoint.i < 0)
153  return false;
154 
155  Index foundPoint(-1, -1, -1, -1);
156 
157  std::map<uint32_t, Index> goals;
158 
159  for (const std::pair<int, Eigen::Vector2d> &g : _goals)
160  {
161  Index idx((int32_t)g.second[0], (int32_t)g.second[1], nx_, 0, 0, 0);
162  std::pair<uint32_t, Index> i(g.first, idx);
163  goals.insert(i);
164  }
165 
166  foundPoint = findGoal(startPoint, _cycles, _potential, goals, _optimizationSteps, _segIdx, _radius);
167  _foundPoint[0] = ((int32_t)foundPoint.getX(nx_));
168  _foundPoint[1] = ((int32_t)foundPoint.getY(nx_));
169 
170  return (foundPoint.i >= 0);
171 }
172 
173 float PointExpander::getDistanceToObstacle(const Eigen::Vector2d &_pt)
174 {
175  Index point((int32_t)_pt[0], (int32_t)_pt[1], nx_, 0, 0, 0);
176  return ((float *)distance_field_.data)[point.i];
177 }
178 } // namespace multi_robot_router
void addPotentialExpansionCandidate(Index _current, int32_t _next_x, int32_t _next_y, float *_potential, uint32_t _distToObstacle)
bool findGoalOnMap(const Eigen::Vector2d &_start, const uint32_t &_cycles, float *_potential, const std::map< uint32_t, Eigen::Vector2d > &_goals, const uint32_t &_optimizationSteps, Eigen::Vector2d &_foundPoint, int32_t &_segIdx, const uint32_t &_radius)
searches the first occurence of a point in the goals_ list and returns the index
float getDistanceToObstacle(const Eigen::Vector2d &vec)
returns the distance to the closest obstacle for a point
void clearpq(std::priority_queue< T, S, C > &q)
void initialize(const cv::Mat &_map)
initializes the point expander with a distance map
Index findGoal(const Index &_start, const uint32_t &_cycles, float *_potential, const std::map< uint32_t, Index > &_goals, const uint32_t &_optimizationSteps, int32_t &segIdx, const uint32_t &_radius)
std::priority_queue< Index, std::vector< Index >, greater1 > queue_
Index offsetDist(int dist_x, int dist_y, int nx, int ny)
bool isGoal(Index _p, const std::map< uint32_t, Index > &_goals, int32_t &segIdx)
#define POT_HIGH


tuw_multi_robot_router
Author(s): Benjamin Binder
autogenerated on Mon Jun 10 2019 15:42:49