multi_robot_goal_generator_node.cpp
Go to the documentation of this file.
1 #include "ros/ros.h"
2 #include <random>
3 #include "tuw_geometry/utils.h"
5 #include <algorithm>
6 
7 
8 
10  : n_ ( n ),
11  n_param_ ( "~" ) {
12  int nr_of_robots = 0;
13  if ( ! n_param_.getParam ( "nr_of_robots", nr_of_robots ) ) {
14  ROS_ERROR ( "nr_of_robots is not set" );
15  return;
16  }
17 
18  n_param_.param<int> ( "nr_of_avaliable_robots", nr_of_avaliable_robots_, -1 );
19  n_param_.param<std::string> ( "frame_id", frame_id_, "map" );
20  n_param_.param<std::string> ( "robot_name_prefix", robot_name_prefix_, "robot_" );
21  n_param_.param<double> ( "distance_boundary", distance_boundary_, 0.5 );
22  n_param_.param<double> ( "distance_between_robots", distance_between_robots_, 2. );
23  n_param_.param<double> ( "distance_to_map_border", distance_to_map_border_, 0.2 );
24  n_param_.param<int> ( "max_resample", max_resample_, 1000 );
25 
26  updateNrOfRobots ( nr_of_robots );
27  pub_goals_ = n.advertise<tuw_multi_robot_msgs::RobotGoalsArray> ( "goals", 1, true );
28  pub_map_goals_ = n.advertise<nav_msgs::OccupancyGrid> ( "map_goals", 1, true );
29  sub_map_ = n.subscribe ( "map", 1, &RadomGoalGeneratorNode::callback, this );
30 }
31 
32 void RadomGoalGeneratorNode::updateNrOfRobots ( size_t nr_of_robots ) {
33  ROS_INFO ( "nr_of_robots: %i", ( int ) nr_of_robots );
34  ROS_INFO ( "using prefix: %s", robot_name_prefix_.c_str() );
35  robot_goals_array_.robots.clear();
36  if((nr_of_avaliable_robots_ > 0) && (nr_of_avaliable_robots_ < nr_of_robots)){
37  ROS_ERROR( "nr_of_robots must be equal or less then nr_of_avaliable_robots" );
38  return;
39  }
40  robot_goals_array_.robots.resize ( nr_of_robots );
42  ROS_INFO( "nr_of_avaliable_robots < 0 and therefore ignored" );
43  for ( size_t i = 0; i < nr_of_robots; i++ ) {
44  tuw_multi_robot_msgs::RobotGoals &robot_check_points = robot_goals_array_.robots[i];
45  robot_check_points.robot_name = robot_name_prefix_ + std::to_string ( i );
46  }
47  } else {
48  std::set<std::string> avaliable_robots;
49  for ( size_t i = 0; i < nr_of_avaliable_robots_; i++ ) {
50  avaliable_robots.insert(robot_name_prefix_ + std::to_string ( i ));
51  }
52  for ( size_t i = 0; i < nr_of_robots; i++ ) {
53  tuw_multi_robot_msgs::RobotGoals &robot_check_points = robot_goals_array_.robots[i];
54  int offset = rand() % avaliable_robots.size();
55  std::set<std::string>::iterator it = avaliable_robots.begin();
56  std::advance(it,offset);
57  robot_check_points.robot_name = *it;
58  avaliable_robots.erase(it);
59  }
60 
61  }
62 }
63 
64 
65 void RadomGoalGeneratorNode::callback ( const nav_msgs::OccupancyGrid::ConstPtr& msg ) {
66  msg_map_ = msg;
67  publish () ;
68  ros::shutdown();
69 }
70 
72  map_.init ( msg_map_->info, msg_map_->data );
73  msg_map_goals_.header = msg_map_->header;
74  msg_map_goals_.info = msg_map_->info;
75  msg_map_goals_.data.resize ( msg_map_->data.size() );
76  map_goals_.init ( msg_map_goals_.info, msg_map_goals_.data );
77  std::copy ( msg_map_->data.begin(), msg_map_->data.end(), msg_map_goals_.data.begin() );
79  //std::cout << map_.infoHeader() << std::endl;
80  //std::cout << tuw::format(map_.Mw2m()) << std::endl;
81  //std::cout << tuw::format(map_.Mm2w()) << std::endl;
82  std::random_device rd; //Will be used to obtain a seed for the random number engine
83  std::mt19937 gen ( rd() ); //Standard mersenne_twister_engine seeded with rd()
84  std::uniform_real_distribution<> dis_x ( map_.min_x(), map_.max_x() );
85  std::uniform_real_distribution<> dis_y ( map_.min_y(), map_.max_y() );
86  std::uniform_real_distribution<> dis_alpha ( -M_PI, M_PI );
87 
88  int total_retries = 0;
89  int max_retries = 0;
90  for ( tuw_multi_robot_msgs::RobotGoals &robot: robot_goals_array_.robots ) {
91  tuw::Pose2D pw;
92  int retries = 0;
93  bool valid_pose = false;
94  do {
95  pw.set ( dis_x ( gen ), dis_y ( gen ), 0 );
96  if ( map_goals_.isFree ( pw.position() ) ) {
97  if ( ( pw.x() > map_goals_.min_x() + distance_to_map_border_ ) && ( pw.x() < map_goals_.max_x() - distance_to_map_border_ ) && ( pw.y() > map_goals_.min_y() + distance_to_map_border_ ) && ( pw.y() < map_goals_.max_y() - distance_to_map_border_) ) {
98  valid_pose = true;
99  }
100  }
101  retries++;
102  } while ( !valid_pose && ( retries < max_resample_ ) );
103  total_retries += retries;
104  if ( retries < max_resample_ ) {
105  pw.theta() = dis_alpha ( gen );
106  //std::cout << pw << std::endl; //Each call to dis(gen) generates a new random double
107  robot.destinations.resize ( 1 );
108  map_goals_.circle ( pw.position(), distance_between_robots_, map_goals_.SPACE_OCCUPIED, -1 );
109  geometry_msgs::Pose &p = robot.destinations[0];
110  pw.copyToROSPose ( p );
111  } else {
112  ROS_WARN ( "Max retries on finding new free space for goals for robot: %s", robot.robot_name.c_str() );
113  }
114  if ( max_retries < retries ) {
115  max_retries = retries;
116  }
117  }
118 
119 
120  robot_goals_array_.header.frame_id = frame_id_;
121  robot_goals_array_.header.stamp = ros::Time::now();
123 
125  ROS_INFO ( "Goal msg published: %i max retries and %i total retries on finding free space ", max_retries, total_retries );
126 }
127 
128 
129 int main ( int argc, char **argv ) {
130  ros::init ( argc, argv, "RandomGoalGenerator" );
131  ros::NodeHandle n;
132  RadomGoalGeneratorNode node ( n );
133  ros::spin();
134  return 0;
135 }
136 
void publish(const boost::shared_ptr< M > &message) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
double distance_between_robots_
parameter [m]
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
int nr_of_avaliable_robots_
retries/max_resample steps to find a free spot for a goal [m]
void callback(const nav_msgs::OccupancyGrid::ConstPtr &msg)
publishes the motion commands
tuw_multi_robot_msgs::RobotGoalsArray robot_goals_array_
parameter
#define ROS_WARN(...)
nav_msgs::OccupancyGrid msg_map_goals_
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
tuw::GridMap< int8_t > map_goals_
std::string robot_name_prefix_
parameter [m]
void updateNrOfRobots(size_t nr_of_robots)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ROSCPP_DECL void spin()
std::string frame_id_
parameter
bool getParam(const std::string &key, std::string &s) const
static Time now()
ROSCPP_DECL void shutdown()
nav_msgs::OccupancyGrid::ConstPtr msg_map_
double distance_to_map_border_
parameter [m]
double distance_boundary_
parameter count
#define ROS_ERROR(...)
int main(int argc, char **argv)


tuw_multi_robot_goal_generator
Author(s):
autogenerated on Mon Jun 10 2019 15:42:34