router_node.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 #define POT_HIGH 1.0e10
29 
32 #include <tuw_multi_robot_msgs/Route.h>
33 #include <chrono>
34 #include <boost/functional/hash.hpp>
35 #include <boost/regex.hpp>
36 #include <tf/tf.h>
37 
38 //TODO add Weights from robots...
39 
40 int main ( int argc, char **argv ) {
41 
42  ros::init ( argc, argv, "tuw_multi_robot_router" );
44 
45  ros::Rate r ( 1 );
46 
48 
49  while ( ros::ok() ) {
50  r.sleep();
51  ros::spinOnce();
52  node.monitorExecution();
53  node.updateTimeout ( r.expectedCycleTime().toSec() );
54  }
55 
56  return 0;
57 }
58 
59 
60 namespace multi_robot_router {
61 
63  n_ ( _n ),
64  n_param_ ( "~" ),
65  monitor_enabled_ ( false ),
66  attempts_total_(0),
67  attempts_successful_(0),
68  sum_processing_time_total_(.0),
69  sum_processing_time_successful_(.0){
70  id_ = 0;
71 
72 
73 
74  n_param_.param<bool> ( "single_robot_mode", single_robot_mode_, false );
75 
76  // static subscriptions
77  subMap_ = n_.subscribe ( "map", 1, &Router_Node::mapCallback, this );
78  subVoronoiGraph_ = n_.subscribe ( "segments", 1, &Router_Node::graphCallback, this );
79  subRobotInfo_ = n_.subscribe ( "robot_info" , 10000, &Router_Node::robotInfoCallback, this );
80 
81  if ( single_robot_mode_) {
83  ROS_INFO("Single Robot Mode");
85  } else {
87  ROS_INFO("Multi Robot Mode");
88  subGoalSet_ = n_.subscribe ( "goals" , 1, &Router_Node::goalsCallback, this );
89  }
90 
91  //static publishers
92  pubPlannerStatus_ = n_.advertise<tuw_multi_robot_msgs::RouterStatus> ( "planner_status", 1 );
93 
94  //dynamic reconfigure
95  call_type = boost::bind ( &Router_Node::parametersCallback, this, _1, _2 );
96  param_server.setCallback ( call_type );
97 }
98 
100  for ( const RobotInfoPtr robot: active_robots_ ) {
101  std::map<std::string, double>::iterator it = finished_robots_.find ( robot->robot_name );
102  if ( robot->status == tuw_multi_robot_msgs::RobotInfo::STATUS_DRIVING ) {
103  if ( it != finished_robots_.end() ) {
104  finished_robots_.erase ( it );
105  if ( monitor_enabled_ ) {
106  ROS_INFO ( "%10s started!", robot->robot_name.c_str() );
107  }
108  }
109  } else {
110  if ( it == finished_robots_.end() ) {
111  double duration = (ros::Time::now() - time_first_robot_started_).toSec();
112  finished_robots_[robot->robot_name] = duration;
113  int nr_of_driving_robots = active_robots_.size() - finished_robots_.size();
114  if ( monitor_enabled_ ) {
115  ROS_INFO ( "%10s stopped @ %6.2lf sec, %3i robots left", robot->robot_name.c_str(), duration, nr_of_driving_robots );
116  }
117  }
118  }
119  }
120  if ( finished_robots_.size() == active_robots_.size() ) {
121  if ( monitor_enabled_ ) {
123  ROS_INFO ( "Execution finished after %lf sec!", duration.toSec() );
124  std::stringstream ss;
125  for(std::map<std::string, double>::iterator it = finished_robots_.begin(); it!=finished_robots_.end(); ++it){
126  ss << it->second << ", ";
127  }
128  ROS_INFO ( "Duration by robot: \n [%s]", ss.str().c_str() );
129  }
130  monitor_enabled_ = false;
131  } else {
132  monitor_enabled_ = true;
133  }
134 
135 }
136 
137 void Router_Node::goalCallback ( const geometry_msgs::PoseStamped &msg ) {
138 
139  if ( subscribed_robots_.size() != 1 ) {
140  ROS_WARN ( "No robot subsribed, ou have to publish a tuw_multi_robot_msgs::RobotInfo to let the planer know where your robot is located!");
141  ROS_WARN ( "Use a local behavior controller to publish regual a RobotInfo msg!");
142  return;
143  }
144  tuw_multi_robot_msgs::RobotGoalsArray goalsArray;
145  goalsArray.header = msg.header;
146  goalsArray.robots.resize(1);
147  tuw_multi_robot_msgs::RobotGoals &goals = goalsArray.robots[0];
148  goals.robot_name = subscribed_robots_[0]->robot_name;
149  goals.destinations.resize(1);
150  goals.destinations[0] = msg.pose;
151  goalsCallback ( goalsArray );
152 }
153 
154 void Router_Node::updateTimeout ( const float _secs ) {
155  //Todo update timeouts and clear old messages
156  for ( auto it = subscribed_robots_.begin(); it != subscribed_robots_.end(); it++ ) {
157  ( *it )->updateOnlineStatus ( _secs );
158  }
159 }
160 void Router_Node::parametersCallback ( tuw_multi_robot_router::routerConfig &config, uint32_t level ) {
161  //Important set router before settings
162  uint32_t threads = config.nr_threads;
163  if ( config.router_type == 1 )
165  else
167 
168  if ( config.collision_resolver == 0 ){
170  collisionResolver_ = false;
171  } else if ( config.collision_resolver == 1 ) {
173  collisionResolver_ = true;
174  }else{
176  collisionResolver_ = true;
177  }
178 
179  if ( config.voronoi_graph )
181  else
183 
184  if ( config.goal_mode == 0 )
186  else if ( config.goal_mode == 1 )
188  else
190 
191  routerTimeLimit_s_ = config.router_time_limit_s;
192  topic_timeout_s_ = config.topic_timeout_s;
193 
194  priorityRescheduling_ = config.priority_rescheduling;
195  speedRescheduling_ = config.speed_rescheduling;
196  segmentOptimizations_ = config.path_endpoint_optimization;
197  publish_routing_table_ = config.publish_routing_table;
198 }
199 
200 void Router_Node::mapCallback ( const nav_msgs::OccupancyGrid &_map ) {
201  std::vector<signed char> map = _map.data;
202 
203  Eigen::Vector2d origin;
204  origin[0] = _map.info.origin.position.x;
205  origin[1] = _map.info.origin.position.y;
206 
207  size_t new_hash = getHash ( map, origin, _map.info.resolution );
208 
209  ROS_INFO ( "map %f %f %f", origin[0], origin[1], _map.info.resolution );
210 
211  if ( new_hash != current_map_hash_ ) {
212  mapOrigin_[0] = _map.info.origin.position.x;
213  mapOrigin_[1] = _map.info.origin.position.y;
214  mapResolution_ = _map.info.resolution;
215 
216  cv::Mat m ( _map.info.height, _map.info.width, CV_8SC1, map.data() );
217 
218  m.convertTo ( m, CV_8UC1 );
219  cv::bitwise_not ( m, m );
220 
221  cv::threshold ( m, m, 40, 255, CV_THRESH_BINARY | CV_THRESH_OTSU );
222  cv::distanceTransform ( m, distMap_, CV_DIST_L1, 3 );
223 
224  current_map_hash_ = new_hash;
225  got_map_ = true;
226 
227  ROS_INFO ( "%s: New Map %i %i %lu", n_param_.getNamespace().c_str() , _map.info.width, _map.info.height, current_map_hash_ );
228  }
229 }
230 
231 
232 float Router_Node::calcRadius ( const int shape, const std::vector<float> &shape_variables ) const {
233  tuw_multi_robot_msgs::RobotInfo ri;
234  if ( shape == ri.SHAPE_CIRCLE ) {
235  return shape_variables[0];
236  }
237 
238  return -1;
239 }
240 
241 void Router_Node::robotInfoCallback ( const tuw_multi_robot_msgs::RobotInfo &_robotInfo ) {
242 
243  auto robot = RobotInfo::findObj ( subscribed_robots_, _robotInfo.robot_name );
244  if ( robot == subscribed_robots_.end() ) {
245  // create new entry
246  RobotInfoPtr robot_new = std::make_shared<RobotInfo> ( _robotInfo );
247  robot_new->initTopics ( n_ , !single_robot_mode_);
248  subscribed_robots_.push_back ( robot_new );
249  } else {
250  ( *robot )->updateInfo ( _robotInfo );
251  }
252 
253  robot_radius_max_ = 0;
254  for ( RobotInfoPtr &r: subscribed_robots_ ) {
255  if ( r->radius() > robot_radius_max_ )
256  robot_radius_max_ = r->radius();
257  }
258  if(single_robot_mode_ && (subscribed_robots_.size() > 1)){
259  ROS_WARN("More than one robot subsribed, but the MRRP is in single robot mode");
260  }
261 }
262 
263 void Router_Node::graphCallback ( const tuw_multi_robot_msgs::Graph &msg ) {
264 
265  if (!got_map_) {
266  ROS_INFO("No map received. Waiting...");
267  return;
268  }
269 
270  std::vector<Segment> graph;
271 
272  for ( const tuw_multi_robot_msgs::Vertex &segment : msg.vertices ) {
273  std::vector<Eigen::Vector2d> points;
274 
275  for ( const geometry_msgs::Point &point : segment.path ) {
276  points.emplace_back ( point.x / mapResolution_, point.y / mapResolution_);
277  }
278 
279  std::vector<uint32_t> successors;
280 
281  for ( const auto &succ : segment.successors ) {
282  successors.emplace_back ( succ );
283  }
284 
285  std::vector<uint32_t> predecessors;
286 
287  for ( const auto &pred : segment.predecessors ) {
288  predecessors.emplace_back ( pred );
289  }
290 
291  if ( segment.valid ) {
292  graph.emplace_back ( segment.id, points, successors, predecessors, 2 * robot_radius_max_ / mapResolution_ ); //segment.width);
293  } else {
294  graph.emplace_back ( segment.id, points, successors, predecessors, 0 );
295  }
296  }
297 
298  std::sort ( graph.begin(), graph.end(), sortSegments );
299 
300  size_t hash = getHash ( graph );
301 
302  if ( current_graph_hash_ != hash ) {
303  current_graph_hash_ = hash;
304  graph_ = graph;
305  ROS_INFO ( "%s: Graph %lu", n_param_.getNamespace().c_str() , hash );
306  }
307  got_graph_ = true;
308 }
309 
310 bool Router_Node::preparePlanning ( std::vector<float> &_radius, std::vector<Eigen::Vector3d> &_starts, std::vector<Eigen::Vector3d> &_goals, const tuw_multi_robot_msgs::RobotGoalsArray &goal_msg, std::vector<std::string> &robot_names ) {
311  bool retval = true;
312  active_robots_.clear();
313  _starts.clear();
314  _goals.clear();
315  _radius.clear();
316 
317  for ( int k = 0; k < goal_msg.robots.size(); k++ ) {
318  const tuw_multi_robot_msgs::RobotGoals &route_request = goal_msg.robots[k];
319  RobotInfoPtrIterator active_robot = RobotInfo::findObj ( subscribed_robots_, route_request.robot_name );
320  if ( active_robot == subscribed_robots_.end() ) {
321  ROS_INFO ( "No robot subsribed with the name: %s", route_request.robot_name.c_str() );
322  } else {
323  if ( route_request.destinations.empty() ) {
324  ROS_INFO ( "No robot: %s has not goal defined", route_request.robot_name.c_str() );
325  continue;
326  } else {
327 
328  active_robots_.push_back ( *active_robot );
329 
330  _radius.push_back ( ( *active_robot )->radius() );
331  if ( route_request.destinations.size() > 1 ) {
332  geometry_msgs::Pose p = route_request.destinations[0];
333  _starts.push_back ( Eigen::Vector3d ( p.position.x, p.position.y, getYaw ( p.orientation ) ) );
334  } else {
335  _starts.push_back ( ( *active_robot )->getPose() );
336  }
337 
338  geometry_msgs::Pose p = route_request.destinations.back();
339  _goals.push_back ( Eigen::Vector3d ( p.position.x, p.position.y, getYaw ( p.orientation ) ) );
340  }
341 
342  }
343  }
344  robot_names.resize ( active_robots_.size() );
345  for ( size_t i=0; i < active_robots_.size(); i++ ) {
346  robot_names[i] = active_robots_[i]->robot_name;
347  }
348  return retval;
349 }
350 
351 void Router_Node::goalsCallback ( const tuw_multi_robot_msgs::RobotGoalsArray &_goals ) {
352  //Get robots
353  std::vector<Eigen::Vector3d> starts;
354  std::vector<Eigen::Vector3d> goals;
355  std::vector<float> radius;
356  std::vector<std::string> robot_names;
357 
358 
359 
360  bool preparationSuccessful = preparePlanning ( radius, starts, goals, _goals, robot_names );
361  ROS_INFO ( "%s: Number of active robots %lu", n_param_.getNamespace().c_str(), active_robots_.size() );
362 
363  if ( preparationSuccessful && got_map_ && got_graph_ ) {
364  attempts_total_++;
365  auto t1 = std::chrono::high_resolution_clock::now();
366  preparationSuccessful &= makePlan ( starts, goals, radius, distMap_, mapResolution_, mapOrigin_, graph_, robot_names );
367  auto t2 = std::chrono::high_resolution_clock::now();
368  int duration = std::chrono::duration_cast<std::chrono::milliseconds> ( t2 - t1 ).count();
369  sum_processing_time_total_ += duration;
370  if ( preparationSuccessful ) {
371  int nx = distMap_.cols;
372  int ny = distMap_.rows;
373 
374  double res = mapResolution_;
375  int cx = mapOrigin_[0];
376  int cy = mapOrigin_[1];
377 
378  publish();
381  freshPlan_ = false;
382  } else {
383  publishEmpty();
384  }
385  float rate_success = ((float) attempts_successful_) / (float) attempts_total_;
386  float avr_duration_total = sum_processing_time_total_ / (float) attempts_total_;
387  float avr_duration_successful = sum_processing_time_successful_ / (float) attempts_successful_;
388  ROS_INFO ( "\nSuccess %i, %i = %4.3f, avr %4.0f ms, success: %4.0f ms, %s, %s, %s \n [%4.3f, %4.0f, %4.0f]",
389  attempts_successful_, attempts_total_, rate_success, avr_duration_total, avr_duration_successful,
390  (priorityRescheduling_?"PR= on":"PR= off"), (speedRescheduling_?"SR= on":"SR= off"), (collisionResolver_?"CR= on":"CR= off"),
391  rate_success, avr_duration_total, avr_duration_successful);
392 
393 
394  id_++;
395  } else if ( !got_map_ || !got_graph_ ) {
396  publishEmpty();
397  ROS_INFO ( "%s: Multi Robot Router: No Map or Graph received", n_param_.getNamespace().c_str() );
398  } else {
399  publishEmpty();
400  }
401 }
402 
403 float Router_Node::getYaw ( const geometry_msgs::Quaternion &_rot ) {
404  double roll, pitch, yaw;
405 
406  tf::Quaternion q ( _rot.x, _rot.y, _rot.z, _rot.w );
407  tf::Matrix3x3 ( q ).getRPY ( roll, pitch, yaw );
408  return yaw;
409 }
410 
412  if(publish_routing_table_ == false) return;
413  ROS_INFO ( "%s: No Plan found!!!!, publishing empty plan", n_param_.getNamespace().c_str());
415  finished_robots_.clear();
416  nav_msgs::Path msg_path;
417  tuw_multi_robot_msgs::Route msg_route;
418  msg_path.header.seq = 0;
419  msg_path.header.stamp = time_first_robot_started_;
420  msg_path.header.frame_id = "map";
421  msg_route.header = msg_path.header;
422 
423  for ( RobotInfoPtr &robot: subscribed_robots_ ) {
424  robot->pubPaths_.publish ( msg_path );
425  robot->pubRoute_.publish ( msg_route );
426  }
427 
428  mrrp_status_.id = id_;
429  mrrp_status_.success = 0;
430  mrrp_status_.duration = getDuration_ms();
432 }
433 
435  if(publish_routing_table_ == false) return;
436  ROS_INFO ( "%s: Plan found :-), publishing plan", n_param_.getNamespace().c_str());
438  finished_robots_.clear();
439  nav_msgs::Path msg_path;
440  tuw_multi_robot_msgs::Route msg_route;
441  msg_path.header.seq = 0;
442  msg_path.header.stamp = time_first_robot_started_;
443  msg_path.header.frame_id = "map";
444  msg_route.header = msg_path.header;
445 
446  for ( int i = 0; i < active_robots_.size(); i++ ) {
447  RobotInfoPtr robot = active_robots_[i];
448  const std::vector<Checkpoint> &route = getRoute ( i );
449  msg_path.poses.clear();
450 
451  //Add first point
452  geometry_msgs::PoseStamped pose_1;
453  pose_1.header.seq = 0;
454  pose_1.header.stamp = time_first_robot_started_;
455  pose_1.header.frame_id = "map";
456 
457  Eigen::Vector2d pos ( route[0].start[0] * mapResolution_, route[0].start[1] * mapResolution_ );
458  pose_1.pose.position.x = pos[0] + mapOrigin_[0];
459  pose_1.pose.position.y = pos[1] + mapOrigin_[1];
460 
461  pose_1.pose.orientation.w = 1;
462  msg_path.poses.push_back ( pose_1 );
463 
464  //Add other points
465  for ( const Checkpoint &c : route ) {
466  geometry_msgs::PoseStamped pose;
467  pose.header.seq = 0;
468  pose.header.stamp = time_first_robot_started_;
469  pose.header.frame_id = "map";
470 
471  Eigen::Vector2d pos ( c.end[0] * mapResolution_, c.end[1] * mapResolution_ );
472  pose.pose.position.x = pos[0] + mapOrigin_[0];
473  pose.pose.position.y = pos[1] + mapOrigin_[1];
474 
476  q.setEuler ( 0, 0, c.end[2] );
477 
478  pose.pose.orientation.w = q.w();
479  pose.pose.orientation.x = q.x();
480  pose.pose.orientation.y = q.y();
481  pose.pose.orientation.z = q.z();
482  msg_path.poses.push_back ( pose );
483  }
484 
485  robot->pubPaths_.publish ( msg_path );
486 
487 
488  msg_route.segments.clear();
489 
490  for ( const Checkpoint &cp : route ) {
491  tuw_multi_robot_msgs::RouteSegment seg;
492 
493  Eigen::Vector2d posStart ( cp.start[0] * mapResolution_, cp.start[1] * mapResolution_ );
494  tf::Quaternion qStart;
495  qStart.setEuler ( 0, 0, cp.start[2] );
496 
497  seg.start.position.x = posStart[0] + mapOrigin_[0];
498  seg.start.position.y = posStart[1] + mapOrigin_[1];
499  seg.start.orientation.w = qStart.w();
500  seg.start.orientation.x = qStart.x();
501  seg.start.orientation.y = qStart.y();
502  seg.start.orientation.z = qStart.z();
503 
504  Eigen::Vector2d posEnd ( cp.end[0] * mapResolution_, cp.end[1] * mapResolution_ );
505  tf::Quaternion qEnd;
506  qEnd.setEuler ( 0, 0, cp.end[2] );
507 
508  seg.end.position.x = posEnd[0] + mapOrigin_[0];
509  seg.end.position.y = posEnd[1] + mapOrigin_[1];
510  seg.end.orientation.w = qEnd.w();
511  seg.end.orientation.x = qEnd.x();
512  seg.end.orientation.y = qEnd.y();
513  seg.end.orientation.z = qEnd.z();
514 
515  seg.segment_id = cp.segId;
516  seg.width = graph_[cp.segId].width() * mapResolution_;
517 
518  for ( int j = 0; j < cp.preconditions.size(); j++ ) {
519  tuw_multi_robot_msgs::RoutePrecondition pc;
520  pc.robot_id = active_robots_[cp.preconditions[j].robotId]->robot_name;
521  pc.current_route_segment = cp.preconditions[j].stepCondition;
522  seg.preconditions.push_back ( pc );
523  }
524 
525  msg_route.segments.push_back ( seg );
526  }
527 
528  robot->pubRoute_.publish ( msg_route );
529  }
530 
531  tuw_multi_robot_msgs::RouterStatus ps;
532  ps.id = id_;
533  ps.success = 1;
534  ps.overall_path_length = ( int32_t ) getOverallPathLength();
535  ps.longest_path_length = ( int32_t ) getLongestPathLength();
536  ps.priority_scheduling_attemps = ( int32_t ) getPriorityScheduleAttemps();
537  ps.speed_scheduling_attemps = ( int32_t ) getSpeedScheduleAttemps();
538  ps.duration = ( int32_t ) getDuration_ms();
539 
540  pubPlannerStatus_.publish ( ps );
541 }
542 
543 size_t Router_Node::getHash ( const std::vector<signed char> &_map, const Eigen::Vector2d &_origin, const float &_resolution ) {
544  std::size_t seed = 0;
545 
546  boost::hash_combine ( seed, _origin[0] );
547  boost::hash_combine ( seed, _origin[1] );
548  boost::hash_combine ( seed, _resolution );
549 
550  for ( const signed char &val : _map ) {
551  boost::hash_combine ( seed, val );
552  }
553 
554  return seed;
555 }
556 
557 std::size_t Router_Node::getHash ( const std::vector<Segment> &_graph ) {
558  std::size_t seed = 0;
559 
560  for ( const Segment &seg : _graph ) {
561  boost::hash_combine ( seed, seg.width() );
562  boost::hash_combine ( seed, seg.length() );
563  boost::hash_combine ( seed, seg.getSegmentId() );
564 
565  for ( const int &p : seg.getPredecessors() ) {
566  boost::hash_combine ( seed, p );
567  }
568 
569  for ( const int &s : seg.getSuccessors() ) {
570  boost::hash_combine ( seed, s );
571  }
572 
573  for ( const Eigen::Vector2d &vec : seg.getPoints() ) {
574  boost::hash_combine ( seed, vec[0] );
575  boost::hash_combine ( seed, vec[1] );
576  }
577  }
578 
579  return seed;
580 }
581 
582 
583 
584 
585 } // namespace multi_robot_router
586 
587 
void goalsCallback(const tuw_multi_robot_msgs::RobotGoalsArray &_goals)
static std::vector< std::shared_ptr< RobotInfo > >::iterator findObj(std::vector< std::shared_ptr< RobotInfo > > &data, const std::string &name)
Definition: robot_info.cpp:88
float getYaw(const geometry_msgs::Quaternion &_rot)
dynamic_reconfigure::Server< tuw_multi_robot_router::routerConfig > param_server
Definition: router_node.h:93
void parametersCallback(tuw_multi_robot_router::routerConfig &config, uint32_t level)
int main(int argc, char **argv)
Definition: router_node.cpp:40
ROSCPP_DECL void start()
float calcRadius(const int shape, const std::vector< float > &shape_variables) const
std::vector< RobotInfoPtr > subscribed_robots_
Definition: router_node.h:104
void monitorExecution()
monitors the execution
Definition: router_node.cpp:99
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
XmlRpcServer s
ros::Publisher pubPlannerStatus_
Definition: router_node.h:95
void setPlannerType(routerType _type, uint32_t _nr_threads)
Definition: router.cpp:59
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
Router_Node(ros::NodeHandle &n)
Construct a new Router_Node object.
Definition: router_node.cpp:62
std::vector< std::shared_ptr< RobotInfo > >::iterator RobotInfoPtrIterator
Definition: robot_info.h:124
uint32_t getPriorityScheduleAttemps() const
getter
Definition: router.cpp:479
ros::Subscriber subVoronoiGraph_
Definition: router_node.h:101
#define ROS_WARN(...)
size_t getHash(const std::vector< signed char > &_map, const Eigen::Vector2d &_origin, const float &_resolution)
void mapCallback(const nav_msgs::OccupancyGrid &_map)
void publish()
publishes a RoutingTable
tuw_multi_robot_msgs::RouterStatus mrrp_status_
Definition: router_node.h:91
ros::Subscriber subSingleRobotGoal_
Definition: router_node.h:100
ros::NodeHandle n_
Node handler to the root node.
Definition: router_node.h:79
ros::NodeHandle n_param_
Node handler to the current node.
Definition: router_node.h:80
bool param(const std::string &param_name, T &param_val, const T &default_val) const
const std::vector< Checkpoint > & getRoute(const uint32_t _robot) const
returns the found Routing Table
Definition: router.cpp:459
void publish(const boost::shared_ptr< M > &message) const
void robotInfoCallback(const tuw_multi_robot_msgs::RobotInfo &_robotInfo)
#define ROS_INFO(...)
void graphCallback(const tuw_multi_robot_msgs::Graph &msg)
ROSCPP_DECL bool ok()
void publishEmpty()
publishes an empty RoutingTable
std::map< std::string, double > finished_robots_
robots currently used by the planner
Definition: router_node.h:106
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]
Definition: router.cpp:328
static bool sortSegments(const Segment &i, const Segment &j)
Definition: router_node.h:133
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void setEuler(const tfScalar &yaw, const tfScalar &pitch, const tfScalar &roll)
bool sleep()
const std::string & getNamespace() const
void setCollisionResolutionType(const SegmentExpander::CollisionResolverType _cr)
sets the CollisionResolverType used
Definition: router.cpp:54
dynamic_reconfigure::Server< tuw_multi_robot_router::routerConfig >::CallbackType call_type
Definition: router_node.h:94
bool preparePlanning(std::vector< float > &_radius, std::vector< Eigen::Vector3d > &_starts, std::vector< Eigen::Vector3d > &_goals, const tuw_multi_robot_msgs::RobotGoalsArray &_ros_goals, std::vector< std::string > &robot_names)
void getRPY(tfScalar &roll, tfScalar &pitch, tfScalar &yaw, unsigned int solution_number=1) const
std::vector< Segment > graph_
Definition: router_node.h:116
static Time now()
std::shared_ptr< RobotInfo > RobotInfoPtr
Definition: robot_info.h:123
void goalCallback(const geometry_msgs::PoseStamped &_goal)
float getLongestPathLength() const
getter
Definition: router.cpp:469
float getOverallPathLength() const
getter
Definition: router.cpp:474
uint32_t getSpeedScheduleAttemps() const
getter
Definition: router.cpp:484
ROSCPP_DECL void spinOnce()
std::queue< Index > q
Duration expectedCycleTime() const
std::vector< RobotInfoPtr > active_robots_
robots avaliable
Definition: router_node.h:105
void updateTimeout(const float _secs)
used to update the nodes timeout to latch topics
uint32_t getDuration_ms() const
getter
Definition: router.cpp:464


tuw_multi_robot_router
Author(s): Benjamin Binder
autogenerated on Mon Feb 28 2022 23:57:49