31 #include <unordered_set> 50 std::vector<uint32_t> robotRadius(
robot_nr_, 0);
83 bool Router::preprocessEndpoints(
const std::vector<float> &_radius,
const float &resolution,
const Eigen::Vector2d &origin,
const std::vector<Segment> &_graph)
85 for (uint32_t i = 0; i <
goals_.size(); i++)
91 float radius = _radius[i];
94 if ( d_start < radius / 2)
100 if (d_goal < radius / 2)
110 bool Router::processEndpointsExpander(
const cv::Mat &_map,
const std::vector<Segment> &_graph,
const Eigen::Vector2d &_realStart,
const Eigen::Vector2d &_realGoal, Eigen::Vector2d &_voronoiStart, Eigen::Vector2d &_voronoiGoal, uint32_t &_segmentStart, uint32_t &_segmentGoal,
const uint32_t _diameter,
const uint32_t _index)
const 113 int32_t segIdStart = -1;
114 int32_t segIdGoal = -1;
117 uint32_t size_x = _map.cols;
118 uint32_t size_y = _map.rows;
127 if (segIdStart != -1 && segIdGoal != -1)
129 _voronoiStart = (_graph[segIdStart].getStart() + _graph[segIdStart].getEnd()) / 2;
130 _voronoiGoal = (_graph[segIdGoal].getStart() + _graph[segIdGoal].getEnd()) / 2;
139 std::map<uint32_t, Eigen::Vector2d> points;
141 for (
const Segment &seg : _graph)
143 std::pair<uint32_t, Eigen::Vector2d> p(seg.getSegmentId(), (seg.getStart() + seg.getEnd()) / 2);
148 std::vector<float> potential;
149 potential.resize(size_x * size_y);
150 float *p = &potential[0];
153 _expander.
findGoalOnMap(_realStart, size_x * size_y, p, points, 0, _voronoiStart, segIdStart, _diameter / 2);
155 std::vector<float> potential2;
156 potential2.resize(size_x * size_y);
157 float *p2 = &potential2[0];
158 _expander.
findGoalOnMap(_realGoal, size_x * size_y, p2, points, 0, _voronoiGoal, segIdGoal, _diameter / 2);
161 if (segIdStart == -1)
163 ROS_INFO(
"Multi Robot Router: Start of robot %i \"%s\" was not found", _index,
robot_names_[_index].c_str());
169 ROS_INFO(
"Multi Robot Router: Goal of robot %i \"%s\" was not found", _index,
robot_names_[_index].c_str());
173 _segmentStart = segIdStart;
174 _segmentGoal = segIdGoal;
177 if (!
resolveSegment(_graph, _segmentStart, _realStart, _diameter, _segmentStart))
179 ROS_INFO(
"Multi Robot Router: Start of robot %i \"%s\" is not valid", _index,
robot_names_[_index].c_str());
183 if (!
resolveSegment(_graph, _segmentGoal, _realGoal, _diameter, _segmentGoal))
185 ROS_INFO(
"Multi Robot Router: Goal of robot %i \"%s\" is not valid", _index,
robot_names_[_index].c_str());
192 bool Router::calculateStartPoints(
const std::vector<float> &_radius,
const cv::Mat &_map,
const float &resolution,
const Eigen::Vector2d &origin,
const std::vector<Segment> &_graph)
197 std::vector<std::thread> t;
200 std::vector<uint32_t> result;
203 for (uint32_t i = 0; i <
goals_.size(); i++)
205 uint32_t &res = result[i];
212 uint32_t diam = 2 * ((float)_radius[i]) / resolution;
215 [
this, &res, _map, _graph, realS, realG, &voronS, &voronG, &segS, &segG, diam, i]() {
223 for (uint32_t i = 0; i <
goals_.size(); i++)
228 for (uint32_t i = 0; i <
goals_.size(); i++)
239 float minDist = FLT_MAX;
240 int32_t segment = -1;
243 for (uint32_t i = 0; i < _graph.size(); i++)
247 if (d < minDist && d <= _graph[i].width())
260 Eigen::Vector2d pa = _s.
getStart() - _p;
266 return std::sqrt(pa.dot(pa));
268 Eigen::Vector2d bp = _p - _s.
getEnd();
271 if (n.dot(bp) > 0.0f)
272 return std::sqrt(bp.dot(bp));
275 Eigen::Vector2d e = pa - n * (c / n.dot(n));
277 return std::sqrt(e.dot(e));
280 bool Router::resolveSegment(
const std::vector<Segment> &_graph,
const uint32_t &_segId,
const Eigen::Vector2d &_originPoint,
const float &_diameter, uint32_t &_foundSeg)
const 282 const Segment seg = _graph[_segId];
288 std::vector<uint32_t> neighbours;
295 float dist = std::numeric_limits<float>::max();
298 for (
const uint32_t &neighbour : neighbours)
300 float ds_x = _originPoint[0] - _graph[neighbour].getStart()[0];
301 float ds_y = _originPoint[1] - _graph[neighbour].getStart()[1];
302 float de_x = _originPoint[0] - _graph[neighbour].getEnd()[0];
303 float de_y = _originPoint[1] - _graph[neighbour].getEnd()[1];
304 float d = (std::sqrt(ds_x * ds_x + ds_y * ds_y) + std::sqrt(de_x * de_x + de_y * de_y)) / 2;
306 if (d < dist && _diameter <= _graph[neighbour].width())
308 _foundSeg = neighbour;
315 if (_diameter <= _graph[_foundSeg].width())
318 else if (_diameter <= seg.
width())
328 bool Router::makePlan(
const std::vector<Eigen::Vector3d> &_starts,
const std::vector<Eigen::Vector3d> &_goals,
const std::vector<float> &_radius,
const cv::Mat &_map,
const float &_resolution,
const Eigen::Vector2d &_origin,
const std::vector<Segment> &_graph,
const std::vector<std::string> &_robot_names)
331 auto t1 = std::chrono::high_resolution_clock::now();
332 std::clock_t startcputime = std::clock();
334 if (_goals.size() != _starts.size() || _goals.size() != _radius.size())
336 ROS_INFO(
"Multi Robot Router: Wrong nr of goals, starts or radii %lu %lu %lu", _starts.size(),
goals_.size(), _radius.size());
337 auto t2 = std::chrono::high_resolution_clock::now();
338 duration_ = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
346 ROS_INFO(
"=========================================================");
353 ROS_INFO(
"Multi Robot Router: Failed to find Endpoints !!!");
354 auto t2 = std::chrono::high_resolution_clock::now();
355 duration_ = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
360 std::vector<uint32_t> diameter;
362 for (
int i = 0; i < _radius.size(); i++)
364 diameter.push_back(2 * ((
float)_radius[i]) / _resolution);
374 ROS_INFO(
"Multi Robot Router: Failed to find Routing Table !!!");
375 auto t2 = std::chrono::high_resolution_clock::now();
376 duration_ = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
391 float lengthPath = 0;
395 Eigen::Vector3d vec = (seg.end - seg.start);
396 float lengthVertex = std::sqrt(vec[0] * vec[0] + vec[1] * vec[1]);
398 lengthPath += lengthVertex;
407 auto t2 = std::chrono::high_resolution_clock::now();
408 duration_ = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
int32_t getSegment(const std::vector< Segment > &_graph, const Eigen::Vector2d &_pose) const
std::vector< Eigen::Vector2d > realStart_
float getOverallPathLength() const
getter
bool preprocessEndpoints(const std::vector< float > &_radius, const float &resolution, const Eigen::Vector2d &origin, const std::vector< Segment > &_graph)
MultiRobotRouterThreadedSrr mrrTs_
virtual const uint32_t getPriorityScheduleAttempts() const
returns the number of attemps to reschedul the priorities taken
void setPlannerType(routerType _type, uint32_t _nr_threads)
std::vector< Eigen::Vector2d > realGoals_
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
std::vector< Eigen::Vector2d > voronoiGoals_
void resize(const uint32_t _nr_robots)
resizes the planner to a different nr of _nr_robots
virtual void setSpeedRescheduling(const bool _status)
enables or disables speed rescheduling
float getDistanceToObstacle(const Eigen::Vector2d &vec)
returns the distance to the closest obstacle for a point
virtual void setCollisionResolver(const SegmentExpander::CollisionResolverType cRes)
sets the CollisionResolverType used to resolve occured robot collisions
void initialize(const cv::Mat &_map)
initializes the point expander with a distance map
PointExpander pointExpander_
with the robot id one can access the robot name
virtual void setRobotDiameter(const std::vector< uint32_t > &_diameter)
sets the robot diameter for every robot
const std::vector< Checkpoint > & getRoute(const uint32_t _robot) const
returns the found Routing Table
float getLongestPathLength() const
getter
const Eigen::Vector2d & getEnd() const
void optimizePaths(const std::vector< Segment > &_graph)
bool processEndpointsExpander(const cv::Mat &_map, const std::vector< Segment > &_graph, const Eigen::Vector2d &_realStart, const Eigen::Vector2d &_realGoal, Eigen::Vector2d &_voronoiStart, Eigen::Vector2d &_voronoiGoal, uint32_t &_segmentStart, uint32_t &_segmentGoal, const uint32_t _diameter, const uint32_t _index) const
bool makePlan(const std::vector< Eigen::Vector3d > &_starts, const std::vector< Eigen::Vector3d > &_goals, const std::vector< float > &_radius, const cv::Mat &_map, const float &_resolution, const Eigen::Vector2d &_origin, const std::vector< Segment > &_graph, const std::vector< std::string > &_robot_names)
generates the plan from (Vertex[odom robotPose] to Vertex[_goals]
bool resolveSegment(const std::vector< Segment > &_graph, const uint32_t &_segId, const Eigen::Vector2d &_originPoint, const float &_radius, uint32_t &_foundSeg) const
virtual bool getRoutingTable(const std::vector< Segment > &_graph, const std::vector< uint32_t > &_startSegments, const std::vector< uint32_t > &_goalSegments, std::vector< std::vector< Checkpoint >> &_routingTable, const float &_timeLimit)
computes the routing table according to the given start and goal _goalSegments
const std::vector< uint32_t > & getSuccessors() const
uint32_t getPriorityScheduleAttemps() const
getter
std::vector< Eigen::Vector2d > voronoiStart_
std::vector< Eigen::Vector3d > starts_
const Eigen::Vector2d & getStart() const
virtual void setPriorityRescheduling(const bool _status)
enables or disables priority rescheduling
float distanceToSegment(const Segment &_s, const Eigen::Vector2d &_p) const
void setCollisionResolutionType(const SegmentExpander::CollisionResolverType _cr)
sets the CollisionResolverType used
virtual const uint32_t getSpeedScheduleAttempts() const
returns the number of attemps to limit the maximum speed of a robot taken
std::vector< uint32_t > goalSegments_
std::vector< uint32_t > startSegments_
const std::vector< uint32_t > & getPredecessors() const
bool priorityRescheduling_
uint32_t getSpeedScheduleAttemps() const
getter
std::vector< std::vector< Checkpoint > > routingTable_
std::vector< std::string > robot_names_
std::vector< Eigen::Vector3d > goals_
uint32_t getDuration_ms() const
getter
bool calculateStartPoints(const std::vector< float > &_radius, const cv::Mat &_map, const float &resolution, const Eigen::Vector2d &origin, const std::vector< Segment > &_graph)
bool segmentOptimizations_
MultiRobotRouter * multiRobotRouter_
void postprocessRoutingTable()
virtual void setRobotNr(const uint32_t _nr_robots)
sets the number of robots used