multi_robot_router.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 <chrono>
31 #include <iostream>
32 #include <ros/ros.h>
33 
34 namespace multi_robot_router
35 {
36 //TODO Multithreaded
37 
38  MultiRobotRouter::MultiRobotRouter(const uint32_t _nr_robots, const std::vector<uint32_t> &_robotDiameter) : RouteGenerator(), priority_scheduler_(_nr_robots), speed_scheduler_(_nr_robots)
39  {
40  setRobotNr(_nr_robots);
41  robotDiameter_ = _robotDiameter;
43  }
44 
45  MultiRobotRouter::MultiRobotRouter(const uint32_t _nr_robots) : RouteGenerator(), priority_scheduler_(_nr_robots), speed_scheduler_(_nr_robots)
46  {
47  setRobotNr(_nr_robots);
48  std::vector<uint32_t> robotDiameter(_nr_robots, 0);
49  robotDiameter_ = robotDiameter;
51  }
52 
53 
55  {
56  cResType_ = cRes;
57  }
58 
59 
60  void MultiRobotRouter::setRobotNr(const uint32_t _nr_robots)
61  {
62  nr_robots_ = _nr_robots;
63  priority_scheduler_.reset(_nr_robots);
64  }
65 
66  void MultiRobotRouter::setRobotDiameter(const std::vector< uint32_t > &_diameter)
67  {
68  robotDiameter_.clear();
69  robotDiameter_ = _diameter;
70  min_diameter_ = std::numeric_limits<uint32_t>::max();
71 
72  for(const uint32_t d : robotDiameter_)
73  {
74  min_diameter_ = std::min(min_diameter_, d);
75  }
76  }
77 
78  void MultiRobotRouter::resetAttempt(const std::vector< Segment > &_graph)
79  {
83  robotCollisions_.clear();
87  }
88 
90  {
92  }
93 
95  {
97  }
98 
99  bool MultiRobotRouter::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)
100  {
101  std::chrono::time_point<std::chrono::high_resolution_clock> tstart = std::chrono::high_resolution_clock::now();
102 
103  resetAttempt(_graph);
104  route_coordinator_->setStartSegments(_startSegments);
105  route_coordinator_->setGoalSegments(_goalSegments);
106 
107  maxIterationsSingleRobot_ = _graph.size();
108 
111 
112  std::vector<std::vector<RouteVertex>> routeCandidates;
113  routeCandidates.resize(nr_robots_);
114 
115  std::vector<uint32_t> priorityList = priority_scheduler_.getActualSchedule();
116  std::vector<float> speedList = speed_scheduler_.getActualSpeeds();
117  uint32_t firstSchedule = 0;
118  bool found = false;
119  uint32_t lastPlannedRobot;
120  float duration = 0;
121 
122  do
123  {
124  int32_t firstRobot = -1;
125  do
126  {
127  //Find first schedule to replan if speed rescheduling was active
128  //(used for removing from path coordinator)
129  if(firstRobot != -1)
130  {
131  for(uint32_t i = 0; i < priorityList.size(); i++)
132  {
133  if(priorityList[i] == firstRobot)
134  firstSchedule = i;
135  }
136  }
137  found = planPaths(priorityList, speedList, _startSegments, _goalSegments, firstSchedule, routeCandidates, lastPlannedRobot);
138 
140  std::chrono::time_point<std::chrono::high_resolution_clock> tgoal = std::chrono::high_resolution_clock::now();
141  duration = std::chrono::duration_cast<std::chrono::milliseconds>(tgoal - tstart).count();
142  duration /= 1000;
143  }
144  while(useSpeedRescheduler_ && duration < _timeLimit && !found && speed_scheduler_.rescheduleSpeeds(lastPlannedRobot, srr.getRobotCollisions(), speedList, firstRobot) );
145 
147  }
148  while(usePriorityRescheduler_ && duration < _timeLimit && !found && priority_scheduler_.reschedulePriorities(lastPlannedRobot, srr.getRobotCollisions(), priorityList, firstSchedule));
149  routingTable = generatePath(routeCandidates, *route_coordinator_);
150 
151  return found;
152  }
153 
154  bool MultiRobotRouter::planPaths(const std::vector<uint32_t> &_priorityList, const std::vector<float> &_speedList, const std::vector<uint32_t> &_startSegments, const std::vector<uint32_t> &_goalSegments, const uint32_t _firstSchedule, std::vector<std::vector<RouteVertex>> &_routeCandidates, uint32_t &_robot)
155  {
156  bool found = false;
157 
158  //Remove only schedules (robots) which have to be replanned
159  for(uint32_t i = _firstSchedule; i < nr_robots_; i++)
160  {
161  _robot = _priorityList[i];
163  }
164 
165  //Find a plan for each robot with no plan
166  for(uint32_t i = _firstSchedule; i < nr_robots_; i++)
167  {
168  found = false;
169  _robot = _priorityList[i];
170 
171  //route_coordinator_->setActive(_robot);
172 
173  RouteCoordinatorWrapper rcWrapper(_robot, *route_coordinator_);
174  //Worst case scenario: Search whole graph once + n * (move through whole graph to avoid other robot) -> graph.size() * (i+1) iterations
175  if(!srr.getRouteCandidate(_startSegments[_robot], _goalSegments[_robot], rcWrapper, robotDiameter_[_robot], _speedList[_robot], _routeCandidates[_robot], maxIterationsSingleRobot_ * (i + 1)))
176  {
177  //ROS_INFO("Failed Robot");
179  robotCollisions_[_robot].resize(nr_robots_, 0);
180  break;
181  }
182 
184  robotCollisions_[_robot].resize(nr_robots_, 0);
185 
186  if(!route_coordinator_->addRoute(_routeCandidates[_robot], robotDiameter_[_robot], _robot))
187  {
188  ROS_INFO("Failed coordinator");
189  break;
190  }
191 
192  found = true;
193  }
194 
195  return found;
196  }
197 
199  {
200  usePriorityRescheduler_ = _status;
201  }
202 
203  void MultiRobotRouter::setSpeedRescheduling(const bool _status)
204  {
205  useSpeedRescheduler_ = _status;
206  }
207 
208 
209 }
210 
211 
multi_robot_router::SingleRobotRouter::initSearchGraph
void initSearchGraph(const std::vector< Segment > &_graph, const uint32_t minSegmentWidth_=0)
generates the search graph out of the given graph (and optimizes it)
Definition: single_robot_router.cpp:103
multi_robot_router::MultiRobotRouter::useSpeedRescheduler_
bool useSpeedRescheduler_
Definition: multi_robot_router.h:114
multi_robot_router::PriorityScheduler::reset
void reset(const uint32_t _nrRobots)
resets the Priority schedule with an initial priority schedule
Definition: priority_scheduler.cpp:38
multi_robot_router::SingleRobotRouter::setCollisionResolver
void setCollisionResolver(const SegmentExpander::CollisionResolverType cRes)
sets the collisionResolver used
Definition: single_robot_router.cpp:43
multi_robot_router::PriorityScheduler::reschedulePriorities
bool reschedulePriorities(const uint32_t _collidingRobot, std::vector< uint32_t > _collsisions, std::vector< uint32_t > &_newSchedule, uint32_t &_firstRobotToReplan)
rescedules priorities depending on the ound collisions and allready tried schedules
Definition: priority_scheduler.cpp:56
multi_robot_router::MultiRobotRouter::resetAttempt
void resetAttempt(const std::vector< Segment > &_graph)
Definition: multi_robot_router.cpp:78
multi_robot_router::MultiRobotRouter::robotCollisions_
std::vector< std::vector< uint32_t > > robotCollisions_
Definition: multi_robot_router.h:120
multi_robot_router::SpeedScheduler::reset
void reset(const uint32_t _nrRobots)
resets the speed rescheduler (all speeds to max)
Definition: speed_scheduler.cpp:82
ros.h
multi_robot_router::MultiRobotRouter::priorityScheduleAttempts_
uint32_t priorityScheduleAttempts_
Definition: multi_robot_router.h:121
multi_robot_router::MultiRobotRouter::getRoutingTable
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
Definition: multi_robot_router.cpp:99
multi_robot_router::RouteGenerator::generatePath
std::vector< std::vector< Checkpoint > > generatePath(const std::vector< std::vector< RouteVertex >> &_paths, const RouteCoordinator &routeQuerry_) const
generates a final Routing Table containing Segment List and Preconditions to other robots
Definition: route_generator.cpp:33
multi_robot_router::MultiRobotRouter::route_coordinator_
RouteCoordinator * route_coordinator_
Definition: multi_robot_router.h:112
multi_robot_router::SegmentExpander::CollisionResolverType
CollisionResolverType
Definition: segment_expander.h:48
multi_robot_router::MultiRobotRouter::getPriorityScheduleAttempts
virtual const uint32_t getPriorityScheduleAttempts() const
returns the number of attemps to reschedul the priorities taken
Definition: multi_robot_router.cpp:89
multi_robot_router::MultiRobotRouter::srr
SingleRobotRouter srr
Definition: multi_robot_router.h:124
multi_robot_router.h
multi_robot_router::MultiRobotRouter::setPriorityRescheduling
virtual void setPriorityRescheduling(const bool _status)
enables or disables priority rescheduling
Definition: multi_robot_router.cpp:198
multi_robot_router::MultiRobotRouter::setRobotNr
virtual void setRobotNr(const uint32_t _nr_robots)
sets the number of robots used
Definition: multi_robot_router.cpp:60
multi_robot_router::RouteCoordinator::removeRobot
virtual void removeRobot(const uint32_t _robot)=0
removes a Robot from the Routing Table
multi_robot_router::SingleRobotRouter::getRouteCandidate
bool getRouteCandidate(const uint32_t _start, const uint32_t _goal, const RouteCoordinatorWrapper &path_coordinator, const uint32_t _robotDiameter, const float &_robotSpeed, std::vector< RouteVertex > &path, const uint32_t _maxIterations)
calculates a route candidate coordinated with other robots by the given route Coordinated
Definition: single_robot_router.cpp:53
multi_robot_router::MultiRobotRouter::getSpeedScheduleAttempts
virtual const uint32_t getSpeedScheduleAttempts() const
returns the number of attemps to limit the maximum speed of a robot taken
Definition: multi_robot_router.cpp:94
multi_robot_router::MultiRobotRouter::nr_robots_
uint32_t nr_robots_
Definition: multi_robot_router.h:117
multi_robot_router::SpeedScheduler::getActualSpeeds
const std::vector< float > & getActualSpeeds()
returns the computed speed schedule
Definition: speed_scheduler.cpp:35
d
d
multi_robot_router::RouteCoordinator::reset
virtual void reset(const std::vector< Segment > &_graph, const uint32_t _nrRobots)=0
resets the planning session of multiple robots
multi_robot_router::MultiRobotRouter::speedScheduleAttempts_
uint32_t speedScheduleAttempts_
Definition: multi_robot_router.h:122
multi_robot_router::MultiRobotRouter::robotDiameter_
std::vector< uint32_t > robotDiameter_
Definition: multi_robot_router.h:119
multi_robot_router::PriorityScheduler::getActualSchedule
const std::vector< uint32_t > & getActualSchedule() const
returns the currently produced speed schedule
Definition: priority_scheduler.cpp:51
multi_robot_router::MultiRobotRouter::speed_scheduler_
SpeedScheduler speed_scheduler_
Definition: multi_robot_router.h:111
multi_robot_router::MultiRobotRouter::planPaths
bool planPaths(const std::vector< uint32_t > &_priorityList, const std::vector< float > &_speedList, const std::vector< uint32_t > &_startSegments, const std::vector< uint32_t > &_goalSegments, const uint32_t _firstSchedule, std::vector< std::vector< RouteVertex >> &_routeCandidates, uint32_t &_robot)
Definition: multi_robot_router.cpp:154
multi_robot_router::MultiRobotRouter::MultiRobotRouter
MultiRobotRouter(const uint32_t _nr_robots, const std::vector< uint32_t > &_robotDiameter)
constructor
Definition: multi_robot_router.cpp:38
multi_robot_router::MultiRobotRouter::min_diameter_
uint32_t min_diameter_
Definition: multi_robot_router.h:118
multi_robot_router::MultiRobotRouter::maxIterationsSingleRobot_
uint32_t maxIterationsSingleRobot_
Definition: multi_robot_router.h:125
multi_robot_router::MultiRobotRouter::setSpeedRescheduling
virtual void setSpeedRescheduling(const bool _status)
enables or disables speed rescheduling
Definition: multi_robot_router.cpp:203
multi_robot_router::MultiRobotRouter::priority_scheduler_
PriorityScheduler priority_scheduler_
Definition: multi_robot_router.h:110
multi_robot_router::RouteCoordinator::setGoalSegments
virtual bool setGoalSegments(const std::vector< uint32_t > &_goalSegments)=0
updates the goal segments of the planning attempt
multi_robot_router::SingleRobotRouter::getRobotCollisions
const std::vector< uint32_t > & getRobotCollisions() const
returns the found robot collisions while planning
Definition: single_robot_router.cpp:118
multi_robot_router::MultiRobotRouter::setCollisionResolver
virtual void setCollisionResolver(const SegmentExpander::CollisionResolverType cRes)
sets the CollisionResolverType used to resolve occured robot collisions
Definition: multi_robot_router.cpp:54
multi_robot_router::MultiRobotRouter::cResType_
SegmentExpander::CollisionResolverType cResType_
Definition: multi_robot_router.h:123
multi_robot_router::RouteCoordinator::addRoute
virtual bool addRoute(const std::vector< RouteVertex > &_path, const uint32_t _diameterPixel, const uint32_t _robotId)=0
checks if a robot can enter a segment at a specific time
multi_robot_router::MultiRobotRouter::usePriorityRescheduler_
bool usePriorityRescheduler_
Definition: multi_robot_router.h:115
multi_robot_router::RouteGenerator
Definition: route_generator.h:39
multi_robot_router::RouteCoordinator::setStartSegments
virtual bool setStartSegments(const std::vector< uint32_t > &_startSegments)=0
updates the start segments of the planning attempt
ROS_INFO
#define ROS_INFO(...)
multi_robot_router::MultiRobotRouter::rct_
RouteCoordinatorTimed rct_
Definition: multi_robot_router.h:113
multi_robot_router::SpeedScheduler::rescheduleSpeeds
bool rescheduleSpeeds(const uint32_t _collidingRobot, const std::vector< uint32_t > &_collsisions, std::vector< float > &_newSchedule, int32_t &_firstRobotToReplan)
reduces a selected robots maximum speed
Definition: speed_scheduler.cpp:45
multi_robot_router
Definition: avoidance_resolution.h:37
multi_robot_router::RouteCoordinatorWrapper
Definition: route_coordinator.h:122
multi_robot_router::MultiRobotRouter::setRobotDiameter
virtual void setRobotDiameter(const std::vector< uint32_t > &_diameter)
sets the robot diameter for every robot
Definition: multi_robot_router.cpp:66


tuw_multi_robot_router
Author(s): Benjamin Binder
autogenerated on Wed Mar 2 2022 01:10:16