52 for(
int i = 0; i <
ns_; i++)
54 distance_field[i] = ((
float*)_distField.data)[i];
55 voronoi_graph[i] = ((int8_t*)_voronoiPath.data)[i];
56 global_map[i] = ((int8_t*)_map.data)[i];
64 for(uint32_t i = 0; i < _segments.size(); i++)
66 if(!_segments[i].getOptStart())
71 if(!_segments[i].getOptEnd())
78 for(uint32_t i = 0; i < _segments.size(); i++)
80 if((_segments[i].getStart() - _segments[i].getEnd()).norm() == 0)
90 for(uint32_t i = 0; i < _segments.size(); i++)
94 if((_segments[i].getStart() - _segments[i].getEnd()).norm() < _maxPixelsEndSegment && (_segments[i].getPredecessors().size() == 0 || _segments[i].getSuccessors().size() == 0))
105 for(uint32_t pd : _segments[_id].getPredecessors())
107 _segments[pd].cleanNeighbors(_id);
109 for(uint32_t sc : _segments[_id].getSuccessors())
111 _segments[sc].cleanNeighbors(_id);
113 _segments.erase(_segments.begin() + _id);
115 for(uint32_t j = 0; j < _segments.size(); j++)
117 _segments[j].decreaseNeighborIdAbove(_id);
124 std::vector<Segment *> connectedSegmnetsStart;
125 std::vector<Segment *> connectedSegmnetsEnd;
129 for(uint32_t i = startIndex; i < _segments.size(); i++)
131 if(!_segments[i].getOptStart())
133 if((_segments[i].getStart() - pt).norm() < maxPixels)
135 connectedSegmnetsStart.push_back(&_segments[i]);
136 _segments[i].setStart(pt);
137 _segments[i].getOptStart() =
true;
141 if(!_segments[i].getOptEnd())
143 if((_segments[i].getEnd() - pt).norm() < maxPixels)
145 connectedSegmnetsEnd.push_back(&_segments[i]);
146 _segments[i].setEnd(pt);
147 _segments[i].getOptEnd() =
true;
153 for(uint32_t i = 0; i < connectedSegmnetsStart.size(); i++)
155 for(uint32_t j = 0; j < connectedSegmnetsStart.size(); j++)
159 if(!(*connectedSegmnetsStart[i]).containsPredecessor((*connectedSegmnetsStart[j]).getId()))
161 (*connectedSegmnetsStart[i]).addPredecessor((*connectedSegmnetsStart[j]).getId());
166 for(uint32_t j = 0; j < connectedSegmnetsEnd.size(); j++)
168 if(!(*connectedSegmnetsStart[i]).containsPredecessor((*connectedSegmnetsEnd[j]).getId()))
170 (*connectedSegmnetsStart[i]).addPredecessor((*connectedSegmnetsEnd[j]).getId());
175 for(uint32_t i = 0; i < connectedSegmnetsEnd.size(); i++)
177 for(uint32_t j = 0; j < connectedSegmnetsStart.size(); j++)
179 if(!(*connectedSegmnetsEnd[i]).containsSuccessor((*connectedSegmnetsStart[j]).getId()))
181 (*connectedSegmnetsEnd[i]).addSuccessor((*connectedSegmnetsStart[j]).getId());
185 for(uint32_t j = 0; j < connectedSegmnetsEnd.size(); j++)
189 if(!(*connectedSegmnetsEnd[i]).containsSuccessor((*connectedSegmnetsEnd[j]).getId()))
191 (*connectedSegmnetsEnd[i]).addSuccessor((*connectedSegmnetsEnd[j]).getId());
201 std::vector<tuw_graph::Segment> segments;
203 if(_path.size() > 1 && _path.size() <= _minimum_length)
206 Segment seg(_path, 2 * min_seg_width);
207 segments.push_back(seg);
209 else if(_path.size() > 1 && _path.size() > _minimum_length)
211 uint32_t nr_segments = _path.size() / _minimum_length;
212 float real_length = std::ceil((
float)_path.size() / (float)nr_segments);
214 for(uint32_t i = 0; i < nr_segments; i++)
217 std::vector<Eigen::Vector2d> map_path_segment;
218 for(uint32_t j = std::max<int>(0, i * real_length); j <= (i + 1) * real_length && j < _path.size(); j++)
220 map_path_segment.push_back( {_path[j][0], _path[j][1]});
224 Segment newSegment(std::vector<Eigen::Vector2d>(map_path_segment), 2 * min_seg_width);
227 segments.push_back(newSegment);
230 segments[segments.size() - 2].addSuccessor(segments[segments.size() - 1].getId());
231 segments[segments.size() - 1].addPredecessor(segments[segments.size() - 2].getId());
241 std::vector< Segment >
Segment_Expander::getGraph(
const std::vector<std::vector<Eigen::Vector2d>> &_endPoints,
float *_potential,
const float _min_length,
float _optimizePixelsCrossing,
const float _optimizePixelsEndSegments)
246 _optimizePixelsCrossing = std::max<float>(_min_length/10, _optimizePixelsCrossing);
249 std::shared_ptr<std::vector< Segment >> segments = std::make_shared<std::vector<Segment>>();
250 std::vector< std::vector< Eigen::Vector2d > > endPoints = _endPoints;
253 std::vector<Crossing> crossings_;
254 for(uint32_t i = 0; i < endPoints.size(); i++)
256 Crossing c(std::vector< Eigen::Vector2d > (endPoints[i]));
258 crossings_.push_back(c);
262 while(endPoints.size() > 0)
264 std::vector<Eigen::Vector2d> startCrossing = endPoints.back();
265 if(startCrossing.size() > 0)
267 Eigen::Vector2d startPoint = startCrossing.back();
270 for(
const Eigen::Vector2d &cVec : startCrossing)
272 Index idx(cVec[0], cVec[1],
nx_, 0, 0, 0);
273 _potential[idx.
i] = 0;
276 Index start(startPoint[0], startPoint[1],
nx_, 0, 0, 0);
278 std::vector<Eigen::Vector2d> path =
getPath(start, _potential, endPoints);
280 std::vector< Segment > pathSegments =
splitPath(path, _min_length);
281 segments->insert(segments->end(), pathSegments.begin(), pathSegments.end());
286 endPoints.pop_back();
300 optimizeSegments((*segments), _optimizePixelsCrossing, _optimizePixelsEndSegments);
307 if(_path.size() == 0)
310 Index p1(_path[0][0], _path[0][1],
nx_, 0, 0, 0);
313 for(
const Eigen::Vector2d &point : _path)
315 Index p(point[0], point[1],
nx_, 0, 0, 0);
316 minimum_path_space = std::min<float>(
distance_field_[p.
i], minimum_path_space);
319 return minimum_path_space;
325 std::vector<std::vector< Eigen::Vector2d > > endpoints;
327 std::fill(_potential, _potential +
ns_, -1);
329 for(
int i = 0; i <
ns_; i++)
332 if(_potential[i] >= 0)
342 endpoints.push_back(crossing);
347 return std::vector<std::vector< Eigen::Vector2d > >(endpoints);
356 if(_point.
i < 0 || _point.
i >
ns_)
376 const std::vector<std::vector<Eigen::Vector2d>> &_endpoints)
378 std::vector< Eigen::Vector2d > points;
384 Index current(_start.
i, _potential[_start.
i], 0, _potential[_start.
i]);
391 while(!(
queue_.empty()) && (cycle < cycles))
402 if(current.
i != _start.
i &&
isEndpoint(current, _endpoints))
405 Eigen::Vector2d point;
426 float dx = points.front()[0] - points.back()[0];
427 float dy = points.front()[1] - points.back()[1];
430 if(!
findEdgeSegments_ || points.size() <= 3 || std::sqrt(dx * dx + dy * dy) <= 3)
441 std::vector<Eigen::Vector2d> points;
447 Index current(_start.
i, _potential[_start.
i], 0, _potential[_start.
i]);
454 while(!(
queue_.empty()) && (cycle < cycles))
464 if(current.
i != _start.
i &&
isEndpoint(current, _endpoints))
467 Eigen::Vector2d point;
500 std::vector< Eigen::Vector2d > points;
506 Index current(_start.
i, _potential[_start.
i], 0, _potential[_start.
i]);
513 while(!(
queue_.empty()) && (cycle < cycles))
523 Eigen::Vector2d point;
526 points.push_back(point);
527 _potential[current.
i] = -2;
550 float potentialPrev = potential[current.
i];
553 if(next.
i < 0 || next.
i >
ns_)
557 if(potential[next.
i] >= 0)
568 float pot = potentialPrev + 1;
572 potential[next.
i] = pot;
583 uint32_t neighbours[8] =
603 uint32_t num_neighbours = neighbours[0] + neighbours[1] + neighbours[2] + neighbours[3] + neighbours[4] + neighbours[5] + neighbours[6] + neighbours[7];
605 if(neighbours[0] && neighbours[1] && !neighbours[2])
608 if(!neighbours[0] && neighbours[1] && neighbours[2])
611 if(neighbours[2] && neighbours[3] && !neighbours[4])
614 if(!neighbours[2] && neighbours[3] && neighbours[4])
618 if(neighbours[4] && neighbours[5] && !neighbours[6])
621 if(!neighbours[4] && neighbours[5] && neighbours[6])
625 if(neighbours[6] && neighbours[7] && !neighbours[0])
628 if(!neighbours[6] && neighbours[7] && neighbours[0])
631 return num_neighbours;
637 for(uint32_t j = 0; j < _endpoints.size(); j++)
639 if(_endpoints[j].size() > 0)
641 for(uint32_t i = 0; i < _endpoints[j].size(); i++)
643 if((
int)(_endpoints[j][i][0]) == _current.
getX(
nx_) && (int)(_endpoints[j][i][1]) == _current.
getY(
nx_))
645 _endpoints[j].erase(_endpoints[j].begin() + i);
647 if(_endpoints[j].size() == 0)
649 _endpoints.erase(_endpoints.begin() + j);
656 _endpoints.erase(_endpoints.begin() + j);
664 for(
auto it_crossing = _endpoints.begin(); it_crossing != _endpoints.end(); it_crossing++)
666 for(
auto it = it_crossing->begin(); it != it_crossing->end(); it++)
669 if((*it)[0] == _current.
getX(
nx_) && (*it)[1] == _current.
getY(
nx_))
void addExpansionCandidate(const Index ¤t, const Index &next, float *potential)
void optimizeSegments(std::vector< Segment > &_segments, float _maxPixelsCrossing, float _maxPixelsEndSeg)
static void resetId()
resets the id counter (which is used to generate uinique ids)
std::unique_ptr< float[]> distance_field_
std::priority_queue< Index, std::vector< Index >, greater1 > queue_
std::unique_ptr< int8_t[]> voronoi_graph_
std::vector< Eigen::Vector2d > getPath(const Index &start, float *_potential, const std::vector< std::vector< Eigen::Vector2d >> &_endpoints)
std::vector< Eigen::Vector2d > expandCrossing(const Index &i, float *_potential)
void Initialize(cv::Mat &_map, cv::Mat &_distField, cv::Mat &_voronoiPath)
initializes the expander by setting the voronoi path map and distancefield
Index offsetDist(int dist_x, int dist_y, int nx, int ny) const
std::vector< std::vector< Eigen::Vector2d > > calcEndpoints(float *_potential)
looks for crossings and saves all segment endpoints of it
Eigen::Vector2d expandSegment(Index start, float *_potential, const std::vector< std::vector< Eigen::Vector2d >> &_endpoints)
void optimizeSegmentsAroundPoint(std::vector< Segment > &_segments, const Eigen::Vector2d &pt, float maxPixels, int startIndex)
float getMinSegmentWidth(const std::vector< Eigen::Vector2d > &_path)
void removeSegmentFromList(const uint32_t _id, std::vector< Segment > &_segments)
void removeEndpoint(const Index &_current, std::vector< std::vector< Eigen::Vector2d >> &_endpoints)
bool checkSegmentPoint(const Index &_point)
void setSegmentReference(const std::shared_ptr< std::vector< Segment >> &segs)
saves the reference to the vector containing all segments to have access to them to alter other segme...
std::vector< Segment > getGraph(const std::vector< std::vector< Eigen::Vector2d >> &_endPoints, float *_potential, const float _min_length, float _optimizePixelsCrossing, const float _optimizePixelsEndSegments)
returns a list of segments, which represent the found search graph
const std::vector< tuw_graph::Segment > splitPath(const std::vector< Eigen::Vector2d > &_path, const float _minimum_length)
void clearpq(std::priority_queue< T, S, C > &q)
uint32_t nrOfNeighbours(uint32_t i) const
bool isEndpoint(Index &_current, const std::vector< std::vector< Eigen::Vector2d >> &_endpoints)
std::unique_ptr< int8_t[]> global_map_