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