GBS.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 *
00003 * Software License Agreement (BSD License)
00004 *
00005 *  Copyright (c) 2011, ISR University of Coimbra.
00006 *  All rights reserved.
00007 *
00008 *  Redistribution and use in source and binary forms, with or without
00009 *  modification, are permitted provided that the following conditions
00010 *  are met:
00011 *
00012 *   * Redistributions of source code must retain the above copyright
00013 *     notice, this list of conditions and the following disclaimer.
00014 *   * Redistributions in binary form must reproduce the above
00015 *     copyright notice, this list of conditions and the following
00016 *     disclaimer in the documentation and/or other materials provided
00017 *     with the distribution.
00018 *   * Neither the name of the ISR University of Coimbra nor the names of its
00019 *     contributors may be used to endorse or promote products derived
00020 *     from this software without specific prior written permission.
00021 *
00022 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033 *  POSSIBILITY OF SUCH DAMAGE.
00034 *
00035 * Author: David Portugal, 2011
00036 *********************************************************************/
00037 
00038 #include <ros/ros.h>
00039 #include <move_base_msgs/MoveBaseAction.h>
00040 #include <actionlib/client/simple_action_client.h>
00041 #include <tf/transform_broadcaster.h>
00042 #include <nav_msgs/Odometry.h>
00043 
00044 #include "getgraph.h"
00045 #include "algorithms.h"
00046 
00047 #define NUM_MAX_ROBOTS 32
00048 
00049 typedef unsigned int uint;
00050 typedef actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction> MoveBaseClient;
00051 
00052 bool ResendGoal; //Send the same goal again (if goal failed...)
00053 bool interference;
00054 bool goal_complete;
00055 bool initialize = true;
00056 bool end_simulation = false;
00057 int next_vertex = -1;
00058 uint backUpCounter;
00059 
00060 //To calculate robot's state:
00061 bool arrived = false;
00062 uint vertex_arrived;
00063 int robot_arrived;
00064 
00065 int TEAMSIZE;
00066 int ID_ROBOT;
00067 
00068 double xPos[NUM_MAX_ROBOTS]; //tabelas de posições (atençao ao index pro caso de 1 so robot)
00069 double yPos[NUM_MAX_ROBOTS]; //tabelas de posições (atençao ao index pro caso de 1 so robot)
00070 
00071 ros::Subscriber odom_sub;
00072 ros::Publisher odom_pub;
00073 ros::Subscriber results_sub;
00074 ros::Publisher results_pub;
00075 ros::Publisher cmd_vel_pub;
00076 
00077 void send_goal_result (uint vertex){
00078   /*
00079   string frame_id       //robot ID
00080     float64 x           //Goal (X=vertex,0,0)  
00081 */      
00082         printf("Send Vertex %u [Goal] to Results: Robot %d\n",vertex,ID_ROBOT); 
00083         
00084         geometry_msgs::PointStamped msg;        
00085         char id_robot_str[3];
00086         sprintf(id_robot_str, "%d", ID_ROBOT);  //integer to array
00087                 
00088         msg.header.frame_id = id_robot_str;
00089         msg.point.x = float (vertex);
00090         msg.point.y = 0.0; 
00091         msg.point.z = 0.0;
00092 
00093         results_pub.publish(msg);
00094         ros::spinOnce();
00095 }
00096 
00097 void backup(){
00098         
00099         while (backUpCounter<=100){
00100         
00101         if(backUpCounter==0){
00102                 ROS_INFO("The wall is too close! I need to do some backing up...");
00103                 // Move the robot back...
00104                 geometry_msgs::Twist cmd_vel;
00105                 cmd_vel.linear.x = -0.1;
00106                 cmd_vel.angular.z = 0.0;
00107                 cmd_vel_pub.publish(cmd_vel);
00108         }
00109                         
00110         if(backUpCounter==40){
00111                 // Turn the robot around...
00112                 geometry_msgs::Twist cmd_vel;
00113                 cmd_vel.linear.x = 0.0;
00114                 cmd_vel.angular.z = 0.5;
00115                 cmd_vel_pub.publish(cmd_vel);
00116         }
00117                         
00118         if(backUpCounter==100){
00119                 // Stop the robot...
00120                 geometry_msgs::Twist cmd_vel;
00121                 cmd_vel.linear.x = 0.0;
00122                 cmd_vel.angular.z = 0.0;
00123                 cmd_vel_pub.publish(cmd_vel);
00124                         
00125                 ROS_INFO("Done backing up, now on with my life!");              
00126         }
00127 
00128         backUpCounter++;
00129         }
00130         
00131 }
00132 
00133 void goalDoneCallback(const actionlib::SimpleClientGoalState &state, const move_base_msgs::MoveBaseResultConstPtr &result){ //goal terminado (completo ou cancelado)
00134 //      ROS_INFO("Goal is complete (suceeded, aborted or cancelled).");
00135         // If the goal succeeded send a new one!
00136         //if(state.state_ == actionlib::SimpleClientGoalState::SUCCEEDED) sendNewGoal = true;
00137         // If it was aborted time to back up!
00138         //if(state.state_ == actionlib::SimpleClientGoalState::ABORTED) needToBackUp = true;    
00139         
00140         if(state.state_ == actionlib::SimpleClientGoalState::SUCCEEDED){
00141                 ROS_INFO("SUCCESS");
00142                 goal_complete = true;
00143                 send_goal_result (next_vertex);
00144                 
00145         }else{
00146                 ROS_INFO("CANCELLED or ABORTED...BACKUP & Resend Goal!");       //tentar voltar a enviar goal..
00147                 backUpCounter = 0;
00148                 backup();
00149                 ResendGoal = true;
00150         }
00151 }
00152 
00153 void goalActiveCallback(){      //enquanto o robot esta a andar para o goal...
00154         goal_complete = false;
00155 //      ROS_INFO("Goal is active.");
00156 }
00157 
00158 void odomCB(const nav_msgs::Odometry::ConstPtr& msg) { //colocar propria posicao na tabela
00159         
00160 //      printf("Colocar Propria posição na tabela, ID_ROBOT = %d\n",ID_ROBOT);
00161         int idx = ID_ROBOT;
00162         
00163         if (ID_ROBOT<=-1){
00164                 idx = 0;
00165         }
00166         
00167         xPos[idx]=msg->pose.pose.position.x;
00168         yPos[idx]=msg->pose.pose.position.y;
00169         
00170 //      printf("Posicao colocada em Pos[%d]\n",idx);
00171 }
00172 
00173 void positionsCB(const nav_msgs::Odometry::ConstPtr& msg) {     //construir tabelas de posições
00174         
00175 //     printf("Construir tabela de posicoes (receber posicoes), ID_ROBOT = %d\n",ID_ROBOT);    
00176         
00177     char id[20]; //identificador do robot q enviou a msg d posição...
00178     strcpy( id, msg->header.frame_id.c_str() );
00179     //int stamp = msg->header.seq;
00180 //     printf("robot q mandou msg = %s\n", id);
00181     
00182     // Build Positions Table
00183     
00184     if (ID_ROBOT>-1){
00185         //verify id "XX" of robot: (string: "robot_XX/odom")
00186         
00187         char str_idx[4];
00188         uint i;
00189         
00190         for (i=6; i<10; i++){
00191                 if (id[i]=='/'){
00192                         str_idx[i-6] = '\0';
00193                         break;
00194                 }else{
00195                         str_idx[i-6] = id[i];
00196                 }
00197         }
00198         
00199         int idx = atoi (str_idx);
00200 //      printf("id robot q mandou msg = %d\n",idx);
00201         
00202         if (idx >= TEAMSIZE && TEAMSIZE <= NUM_MAX_ROBOTS){
00203                 //update teamsize:
00204                 TEAMSIZE = idx+1;
00205         }
00206         
00207         if (ID_ROBOT != idx){  //Ignore own positions   
00208                 xPos[idx]=msg->pose.pose.position.x;
00209                 yPos[idx]=msg->pose.pose.position.y;            
00210         }       
00211 //      printf ("Position Table:\n frame.id = %s\n id_robot = %d\n xPos[%d] = %f\n yPos[%d] = %f\n\n", id, idx, idx, xPos[idx], idx, yPos[idx] );           
00212     }
00213 }
00214 
00215 void resultsCB(const geometry_msgs::PointStamped::ConstPtr& msg) {
00216         
00217         if(initialize){ //em espera que o monitor a desbloquei e passe initialize para false
00218                 
00219 //              printf("Is it the monitor? frame_id = %s (%f,%f,%f)\n",msg->header.frame_id.c_str(),msg->point.x,msg->point.y,msg->point.z);
00220                 
00221                 if (msg->header.frame_id == "monitor"){
00222                         printf("Let's Patrol!\n");
00223                         initialize = false;
00224                 }
00225                 
00226         }else {
00227           
00228                 if (msg->header.frame_id == "monitor" && msg->point.x == 1.0 && msg->point.y == 1.0 && msg->point.z == 1.0){
00229                         printf("The simulation is over. Let's leave\n");
00230                         end_simulation = true;
00231                 
00232                   
00233                 }else if (msg->header.frame_id != "monitor")    {       //Robot reached Goal (including itself!!!)
00234                 
00235                   double interf = msg->point.y;
00236                   double init = msg->point.z;
00237                   
00238                   robot_arrived = atoi( msg->header.frame_id.c_str() ); 
00239                   vertex_arrived = (int)msg->point.x;
00240                         
00241                     if (interf == 0.0 && init == 0.0){                
00242                       if (robot_arrived != ID_ROBOT){   //ignorar msgs do proprio robô:
00243                         arrived = true;                                       
00244                         //printf("Robot %d reached Goal %d.\n", robot_arrived, vertex_arrived);
00245                       }
00246                     }
00247                 }
00248         }
00249 }
00250 
00251 void initialize_node (){
00252   /*
00253   string frame_id       //robot ID
00254     float64 z           //initialization (0,0,Z=ID)  
00255 */      
00256         printf("Initialize Node: Robot %d\n",ID_ROBOT); 
00257         ros::Rate loop_rate(1); //1 segundo
00258         
00259         geometry_msgs::PointStamped msg;        
00260         
00261         char id_robot_str[3];
00262         sprintf(id_robot_str, "%d", ID_ROBOT);  //integer to array
00263                 
00264         msg.header.frame_id = id_robot_str;
00265         msg.point.x = 0.0;
00266         msg.point.y = 0.0; 
00267         msg.point.z = (float) ID_ROBOT; //Z = ID
00268         
00269         int count = 0;
00270         while (count<2){
00271                 results_pub.publish(msg);
00272                 ros::spinOnce();
00273                 //printf("publiquei msg.\n");
00274                 loop_rate.sleep();
00275                 count++;
00276         }       
00277 }
00278 
00279 void send_interference(){
00280   /*
00281   string frame_id       //robot ID
00282     float64 y           //Interference (0,Y=1,0)  
00283 */      
00284         printf("Send Interference: Robot %d\n",ID_ROBOT);       
00285         //ros::Rate loop_rate(1); //1 segundo
00286         
00287         geometry_msgs::PointStamped msg;        
00288         char id_robot_str[3];
00289         sprintf(id_robot_str, "%d", ID_ROBOT);  //integer to array
00290                 
00291         msg.header.frame_id = id_robot_str;
00292         msg.point.x = 0.0;
00293         msg.point.y = 1.0; 
00294         msg.point.z = 0.0;
00295 
00296         results_pub.publish(msg);
00297         ros::spinOnce();
00298 }
00299 
00300 bool check_interference (void){ //verificar se os robots estao proximos
00301         
00302         int i;
00303         double dist_quad;
00304         
00305         /* Poderei usar TEAMSIZE para afinar */
00306         for (i=0; i<ID_ROBOT; i++){     //percorrer vizinhos (assim asseguro q cada interferencia é so encontrada 1 vez)
00307                 
00308                 dist_quad = (xPos[i] - xPos[ID_ROBOT])*(xPos[i] - xPos[ID_ROBOT]) + (yPos[i] - yPos[ID_ROBOT])*(yPos[i] - yPos[ID_ROBOT]);
00309                 
00310                 if (dist_quad <= /*sqrt*/4){    //robots are 2 meter or less apart
00311 //                      ROS_INFO("Feedback: Robots are very close. INTERFERENCE! Dist_Quad = %f", dist_quad);
00312                         interference = true;
00313                         return interference;
00314                 }               
00315         }
00316         
00317         interference = false;
00318         return interference;
00319         
00320 }
00321 
00322 void goalFeedbackCallback(const move_base_msgs::MoveBaseFeedbackConstPtr &feedback){    //publicar posições
00323 
00324 //      printf("ID_ROBOT = %d [feedback callback]\n", ID_ROBOT);
00325         
00326         //Publish Position to common node:
00327         nav_msgs::Odometry msg; 
00328         
00329         int idx = ID_ROBOT;
00330                 
00331         if (ID_ROBOT <= -1){
00332                 msg.header.frame_id = "odom";    //identificador do robot q publicou
00333                 idx = 0;
00334         }else{
00335                 char string[20];
00336                 strcpy (string,"robot_"); 
00337                 char id[3];
00338                 itoa(ID_ROBOT, id, 10);  
00339                 strcat(string,id);
00340                 strcat(string,"/odom"); //string = "robot_X/odom"       
00341                 //strcpy( msg.header.frame_id, string );
00342                 msg.header.frame_id = string;
00343         }
00344         
00345         msg.pose.pose.position.x = xPos[idx]; //send odometry.x
00346         msg.pose.pose.position.y = yPos[idx]; //send odometry.y
00347         
00348         odom_pub.publish(msg);
00349         ros::spinOnce();
00350         
00351         //ROS_INFO("[POSITION PUBLISHED]: ID = %s, X = %f, Y = %f", msg.header.frame_id.c_str(), xPos[idx], yPos[idx]);
00352 //      printf("ID_ROBOT = %d\n", ID_ROBOT);
00353 //      printf("TEAMSIZE = %d\n", TEAMSIZE);    
00354         check_interference();   
00355 }
00356 
00357 
00358 int main(int argc, char** argv){        //pass the .graph file to open
00359   /*
00360   argc=3
00361   argv[0]=/.../patrolling_sim/bin/GBS
00362   argv[1]=__name:=XXXXXX
00363   argv[2]=maps/1r-5-map.graph
00364   argv[3]=ID_ROBOT
00365   argv[4]=NUMBER_OF_ROBOTS      //this is only necessary to automatically define G2
00366   */
00367   
00368   
00369   //More than One robot (ID between 0 and 99)
00370   if ( atoi(argv[3])>NUM_MAX_ROBOTS || atoi(argv[3])<-1 ){
00371     ROS_INFO("The Robot's ID must be an integer number between 0 an 99"); //max 100 robots 
00372     return 0;
00373   }else{
00374     ID_ROBOT = atoi(argv[3]); 
00375     //printf("ID_ROBOT = %d\n",ID_ROBOT); //-1 in the case there is only 1 robot.
00376   }
00377 
00378   uint i = strlen( argv[2] );
00379   char graph_file[i];
00380   strcpy (graph_file,argv[2]);
00381   
00382   //Check Graph Dimension:
00383   uint dimension = GetGraphDimension(graph_file);
00384   
00385   //Create Structure to save the Graph Info;
00386   vertex vertex_web[dimension];
00387   
00388   //Get the Graph info from the Graph File
00389   GetGraphInfo(vertex_web, dimension, graph_file);
00390   
00391   
00392   
00394   double G1 = 0.1;
00395   
00396   int NUMBER_OF_ROBOTS = atoi(argv[4]);
00397  
00398   //default:
00399   double G2 = 100.0;
00400   double edge_min = 1.0;
00401   
00402   if ( strcmp (graph_file,"maps/grid/grid.graph") == 0 ){  
00403     if (NUMBER_OF_ROBOTS == 1){G2 = 20.54;}
00404     if (NUMBER_OF_ROBOTS == 2){G2 = 17.70;}
00405     if (NUMBER_OF_ROBOTS == 4){G2 = 11.15;}
00406     if (NUMBER_OF_ROBOTS == 6){G2 = 10.71;}
00407     if (NUMBER_OF_ROBOTS == 8){G2 = 10.29;}
00408     if (NUMBER_OF_ROBOTS == 12){G2 = 9.13;}
00409     
00410   }else if (strcmp (graph_file,"maps/example/example.graph") == 0 ) {
00411     if (NUMBER_OF_ROBOTS == 1){G2 = 220.0;}
00412     if (NUMBER_OF_ROBOTS == 2){G2 = 180.5;}
00413     if (NUMBER_OF_ROBOTS == 4){G2 = 159.3;}
00414     if (NUMBER_OF_ROBOTS == 6){G2 = 137.15;}
00415     if (NUMBER_OF_ROBOTS == 8 || NUMBER_OF_ROBOTS == 12){G2 = 126.1;}
00416     edge_min = 20.0;
00417     
00418   }else if (strcmp (graph_file,"maps/cumberland/cumberland.graph") == 0) {
00419     if (NUMBER_OF_ROBOTS == 1){G2 = 152.0;}
00420     if (NUMBER_OF_ROBOTS == 2){G2 = 100.4;}
00421     if (NUMBER_OF_ROBOTS == 4){G2 = 80.74;}
00422     if (NUMBER_OF_ROBOTS == 6){G2 = 77.0;}
00423     if (NUMBER_OF_ROBOTS == 8 || NUMBER_OF_ROBOTS == 12){G2 = 63.5;}    
00424     edge_min = 50.0;
00425     
00426   }
00427   
00428   printf("G1 = %f, G2 = %f\n", G1, G2);
00429   
00430   
00431    
00432   /* Define Starting Vertex/Position (Launch File Parameters) */
00433 
00434   ros::init(argc, argv, "c_reactive");
00435   ros::NodeHandle nh;
00436   double initial_x, initial_y;
00437   
00438   XmlRpc::XmlRpcValue list;
00439   nh.getParam("initial_pos", list);
00440   ROS_ASSERT(list.getType() == XmlRpc::XmlRpcValue::TypeArray);
00441   
00442   int value = ID_ROBOT;
00443   if (value == -1){value = 0;}
00444   
00445   ROS_ASSERT(list[2*value].getType() == XmlRpc::XmlRpcValue::TypeDouble);
00446   initial_x = static_cast<double>(list[2*value]);
00447   
00448   ROS_ASSERT(list[2*value+1].getType() == XmlRpc::XmlRpcValue::TypeDouble);
00449   initial_y = static_cast<double>(list[2*value+1]);
00450  
00451 //   printf("initial position: x = %f, y = %f\n", initial_x, initial_y);
00452   uint current_vertex = IdentifyVertex(vertex_web, dimension, initial_x, initial_y);
00453 //   printf("initial vertex = %d\n\n",current_vertex);  
00454   
00455   
00456    //Publicar dados de "odom" para nó de posições
00457   odom_pub = nh.advertise<nav_msgs::Odometry>("positions", 1); //only concerned about the most recent
00458         
00459   //Subscrever posições de outros robots
00460   odom_sub = nh.subscribe("positions", 10, positionsCB);  
00461   
00462   char string[20];
00463   char string2[20];
00464   
00465   if(ID_ROBOT==-1){ 
00466     strcpy (string,"odom"); //string = "odom"
00467     strcpy (string2,"cmd_vel"); //string = "cmd_vel"
00468     TEAMSIZE = 1;
00469   }else{ 
00470     strcpy (string,"robot_");
00471     strcpy (string2,"robot_"); 
00472     char id[3];
00473     itoa(ID_ROBOT, id, 10);  
00474     strcat(string,id);
00475     strcat(string2,id);
00476     strcat(string,"/odom"); //string = "robot_X/odom" 
00477     strcat(string2,"/cmd_vel"); //string = "robot_X/cmd_vel"
00478     TEAMSIZE = ID_ROBOT + 1;
00479   }       
00480   
00481 //   printf("string de publicação da odometria: %s\n",string);
00482 
00483    //Cmd_vel to backup:
00484    cmd_vel_pub  = nh.advertise<geometry_msgs::Twist>(string2, 1);
00485    
00486   //Subscrever para obter dados de "odom" do robot corrente
00487   ros::Subscriber sub;
00488   sub = nh.subscribe(string, 1, odomCB); //size of the buffer = 1 (?)
00489   ros::spinOnce();    
00490     
00491   
00492   /* Define Goal */  
00493   
00494   if(ID_ROBOT==-1){ 
00495     strcpy (string,"move_base"); //string = "move_base
00496   }else{ 
00497     strcpy (string,"robot_"); 
00498     char id[3];
00499     itoa(ID_ROBOT, id, 10);  
00500     strcat(string,id);
00501     strcat(string,"/move_base"); //string = "robot_X/move_base"  
00502   }
00503   
00504   //printf("string = %s\n",string);
00505   MoveBaseClient ac(string, true); 
00506   
00507   //wait for the action server to come up
00508   while(!ac.waitForServer(ros::Duration(5.0))){
00509      ROS_INFO("Waiting for the move_base action server to come up");
00510   }  
00511 
00512   //Define Goal:
00513   move_base_msgs::MoveBaseGoal goal;
00514   
00515   //Publicar dados para "results"
00516   results_pub = nh.advertise<geometry_msgs::PointStamped>("results", 1); //only concerned about the most recent
00517   results_sub = nh.subscribe("results", 10, resultsCB); //Subscrever "results" vindo dos robots
00518   
00519   initialize_node(); //dizer q está vivo
00520   ros::Rate loop_rate(1); //1 segundo
00521   
00522   /* Wait until all nodes are ready.. */
00523   while(initialize){
00524         ros::spinOnce();
00525         loop_rate.sleep();
00526   }
00527   
00528   /* Run Algorithm */
00529    
00530   double instantaneous_idleness [dimension];
00531   double last_visit [dimension];
00532   for(i=0;i<dimension;i++){ 
00533     instantaneous_idleness[i]= 0.0; 
00534     last_visit[i]= 0.0; 
00535     
00536     if(i==current_vertex){
00537       last_visit[i]= 0.1; //Avoids getting back at the initial vertex
00538     }
00539   }
00540   
00541   interference = false;
00542   ResendGoal = false;
00543   goal_complete = true;
00544   
00545   double now;
00546   
00547   
00548   while(1){
00549           
00550     if(goal_complete){
00551             
00552             if(next_vertex>-1){
00553                 //Update Idleness Table:
00554                 now = ros::Time::now().toSec();
00555                         
00556                 for(i=0; i<dimension; i++){
00557                         if (i == next_vertex){
00558                                 last_visit[i] = now;    
00559                         }       
00560                         instantaneous_idleness[i]= now - last_visit[i];           
00561                 } 
00562                 
00563                 current_vertex = next_vertex;           
00564         
00565                         
00566                 //Show Idleness Table:
00567         /*      for (i=0; i<dimension; i++){
00568                         printf("idleness[%u] = %f\n",i,instantaneous_idleness[i]);      
00569                 } */
00570             }
00571     
00572         //devolver proximo vertex tendo em conta apenas as idlenesses;
00573         next_vertex = (int) greedy_bayesian_strategy(current_vertex, vertex_web, instantaneous_idleness, G1, G2, edge_min);
00574         //printf("Move Robot to Vertex %d (%f,%f)\n", next_vertex, vertex_web[next_vertex].x, vertex_web[next_vertex].y);
00575         
00576         //Send the goal to the robot (Global Map)
00577         geometry_msgs::Quaternion angle_quat = tf::createQuaternionMsgFromYaw(0.0);
00578         goal.target_pose.header.frame_id = "map"; 
00579         goal.target_pose.header.stamp = ros::Time::now();    
00580         goal.target_pose.pose.position.x = vertex_web[next_vertex].x;
00581         goal.target_pose.pose.position.y = vertex_web[next_vertex].y;  
00582         goal.target_pose.pose.orientation = angle_quat;
00583         ROS_INFO("Sending goal - Vertex %d (%f,%f)\n", next_vertex, vertex_web[next_vertex].x, vertex_web[next_vertex].y);
00584         ac.sendGoal(goal, boost::bind(&goalDoneCallback, _1, _2), boost::bind(&goalActiveCallback), boost::bind(&goalFeedbackCallback, _1));
00585         //ac.waitForResult();   
00586         
00587         goal_complete = false;
00588     
00589     }else{
00590         if (interference){
00591                                                 
00592                 // Stop the robot..                     
00593                 ROS_INFO("Interference detected!\n");   
00594                 send_interference();
00595 
00596                 //get own "odom" positions...
00597                 ros::spinOnce();                
00598                                         
00599                 //Waiting until conflict is solved...
00600                 while(interference){
00601                         interference = check_interference();
00602                         if (goal_complete || ResendGoal){
00603                                 interference = false;
00604                         }
00605                 }
00606                         // se saiu é pq interference = false                   
00607         }           
00608             
00609         if(ResendGoal){
00610                 //Send the goal to the robot (Global Map)
00611                 geometry_msgs::Quaternion angle_quat = tf::createQuaternionMsgFromYaw(0.0);         
00612                 goal.target_pose.header.frame_id = "map"; 
00613                 goal.target_pose.header.stamp = ros::Time::now();    
00614                 goal.target_pose.pose.position.x = vertex_web[next_vertex].x;
00615                 goal.target_pose.pose.position.y = vertex_web[next_vertex].y;  
00616                 goal.target_pose.pose.orientation = angle_quat; //alpha -> orientação  (queria optimizar este parametro -> através da direcção do vizinho!)
00617                 ROS_INFO("Sending goal - Vertex %d (%f,%f)\n", next_vertex, vertex_web[next_vertex].x, vertex_web[next_vertex].y);
00618 //              printf("ID_ROBOT = %d\n", ID_ROBOT);
00619                 ac.sendGoal(goal, boost::bind(&goalDoneCallback, _1, _2), boost::bind(&goalActiveCallback), boost::bind(&goalFeedbackCallback, _1));
00620                 ResendGoal = false; //para nao voltar a entrar (envia goal so uma vez)
00621         }
00622         
00623         if (arrived && NUMBER_OF_ROBOTS>1){     //a different robot arrived at a vertex: update idleness table and keep track of last vertices positions of other robots.
00624 
00625           //printf("Robot %d reached Goal %d.\n", robot_arrived, vertex_arrived);    
00626 
00627           //Update Idleness Table:
00628           now = ros::Time::now().toSec();
00629                           
00630           for(i=0; i<dimension; i++){
00631                   if (i == vertex_arrived){
00632                             //actualizar last_visit[dimension]
00633                           last_visit[vertex_arrived] = now;     
00634                   }                     
00635                   //actualizar instantaneous_idleness[dimension]
00636                   instantaneous_idleness[i]= now - last_visit[i];           
00637           } 
00638 
00639           
00640                           
00641           //Show Idleness Table:                
00642 //         for (i=0; i<dimension; i++){
00643 //                printf("idleness[%u] = %f\n",i,instantaneous_idleness[i]);      
00644 //        } 
00645           
00646           arrived = false;
00647         }
00648         
00649         if(end_simulation){
00650               return 0;
00651         }       
00652         
00653     }
00654   }
00655   
00656   return 0; 
00657 }


patrolling_sim
Author(s): David Portugal
autogenerated on Mon Jan 6 2014 11:26:29