00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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 <geometry_msgs/PointStamped.h>
00043 #include <float.h>
00044
00045 #include "getgraph.h"
00046
00047 #define NUM_MAX_ROBOTS 32
00048
00049 typedef unsigned int uint;
00050
00051 ros::Subscriber results_sub;
00052 ros::Publisher results_pub;
00053
00054
00055 bool initialize = true;
00056 uint count=0;
00057 uint teamsize;
00058 bool init_robots[NUM_MAX_ROBOTS];
00059
00060
00061 bool interference = false;
00062 bool goal_reached = false;
00063 int goal;
00064 double time_zero;
00065
00066 void resultsCB(const geometry_msgs::PointStamped::ConstPtr& msg) {
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 int id_robot_int;
00079
00080 if (initialize){
00081
00082 double id_robot_dbl = msg->point.z;
00083 id_robot_int = (int) id_robot_dbl;
00084
00085
00086
00087 if (id_robot_int == -1){id_robot_int = 0;}
00088 if (init_robots[id_robot_int] == false){
00089 printf("Robot [ID = %d] is Active!\n",id_robot_int);
00090 init_robots[id_robot_int] = true;
00091 count++;
00092 }
00093
00094 if (count==teamsize){
00095 printf("All Robots GO!\n");
00096 initialize = false;
00097
00098
00099 time_zero = ros::Time::now().toSec();
00100
00101
00102 geometry_msgs::PointStamped msg;
00103 msg.header.frame_id = "monitor";
00104 msg.point.x = 0.0;
00105 msg.point.y = 0.0;
00106 msg.point.z = 0.0;
00107 results_pub.publish(msg);
00108 ros::spinOnce();
00109 }
00110
00111 }else{
00112
00113 double vertex = msg->point.x;
00114 double interf = msg->point.y;
00115 double init = msg->point.z;
00116
00117 if (msg->header.frame_id != "monitor"){
00118
00119
00120 id_robot_int = atoi( msg->header.frame_id.c_str() );
00121
00122 if (interf == 0.0 && init == 0.0){
00123 goal = (int) vertex;
00124 printf("Robot %d reached Goal %d.\n", id_robot_int, goal);
00125 goal_reached = true;
00126 }
00127 if (interf == 1.0 ){
00128
00129 interference = true;
00130 }
00131
00132 }
00133 }
00134 }
00135
00136 void finish_simulation (){
00137 geometry_msgs::PointStamped msg;
00138 msg.header.frame_id = "monitor";
00139 msg.point.x = 1.0;
00140 msg.point.y = 1.0;
00141 msg.point.z = 1.0;
00142 results_pub.publish(msg);
00143 ros::spinOnce();
00144 }
00145
00146
00147 double Median( double *a, uint dimension )
00148 {
00149 uint table_size = dimension/2;
00150 if(dimension % 2 != 0){
00151 table_size++;
00152 }
00153 if (table_size==0) {table_size = 1;}
00154
00155 double left[table_size], right[table_size], median, *p;
00156 unsigned char nLeft, nRight;
00157
00158
00159 p = a;
00160 median = *p++;
00161 nLeft = nRight = 1;
00162
00163 for(;;)
00164 {
00165
00166 double val = *p++;
00167
00168
00169 if( val < median )
00170 {
00171
00172 unsigned char child = nLeft++, parent = (child - 1) / 2;
00173 while( parent && val > left[parent] )
00174 {
00175 left[child] = left[parent];
00176 child = parent;
00177 parent = (parent - 1) / 2;
00178 }
00179 left[child] = val;
00180
00181
00182 if( nLeft == table_size )
00183 {
00184
00185 for( unsigned char nVal = dimension - (p - a); nVal; --nVal )
00186 {
00187
00188 val = *p++;
00189
00190
00191 if( val < median )
00192 {
00193 child = left[2] > left[1] ? 2 : 1;
00194 if( val >= left[child] )
00195 median = val;
00196 else
00197 {
00198 median = left[child];
00199 parent = child;
00200 child = parent*2 + 1;
00201 while( child < table_size )
00202 {
00203 if( child < table_size-1 && left[child+1] > left[child] )
00204 ++child;
00205 if( val >= left[child] )
00206 break;
00207 left[parent] = left[child];
00208 parent = child;
00209 child = parent*2 + 1;
00210 }
00211 left[parent] = val;
00212 }
00213 }
00214 }
00215 return median;
00216 }
00217 }
00218
00219
00220 else
00221 {
00222
00223 unsigned char child = nRight++, parent = (child - 1) / 2;
00224 while( parent && val < right[parent] )
00225 {
00226 right[child] = right[parent];
00227 child = parent;
00228 parent = (parent - 1) / 2;
00229 }
00230 right[child] = val;
00231
00232
00233 if( nRight == 14 )
00234 {
00235
00236 for( unsigned char nVal = dimension - (p - a); nVal; --nVal )
00237 {
00238
00239 val = *p++;
00240
00241
00242 if( val > median )
00243 {
00244 child = right[2] < right[1] ? 2 : 1;
00245 if( val <= right[child] )
00246 median = val;
00247 else
00248 {
00249 median = right[child];
00250 parent = child;
00251 child = parent*2 + 1;
00252 while( child < table_size )
00253 {
00254 if( child < 13 && right[child+1] < right[child] )
00255 ++child;
00256 if( val <= right[child] )
00257 break;
00258 right[parent] = right[child];
00259 parent = child;
00260 child = parent*2 + 1;
00261 }
00262 right[parent] = val;
00263 }
00264 }
00265 }
00266 return median;
00267 }
00268 }
00269 }
00270 }
00271
00272
00273 uint calculate_patrol_cycle ( uint *nr_visits, uint dimension ){
00274 uint result = INT_MAX;
00275
00276 for (uint i=0; i<dimension; i++){
00277 if (nr_visits[i] < result){
00278 result = nr_visits[i];
00279 }
00280 }
00281 return result;
00282 }
00283
00284
00285 void write_results (double *avg_idleness, uint *number_of_visits, uint complete_patrol, uint dimension, double worst_idleness, double avg_graph_idl, double median_graph_idl, uint interference_count, char* graph_file, char* algorithm, char* teamsize_str, double timevalue){
00286 FILE *file;
00287
00288 char name[30];
00289 uint i, start_char=0, end_char = strlen(graph_file)-1;
00290
00291 for (i=0; i<strlen(graph_file); i++){
00292 if(graph_file[i]=='/' && i < strlen(graph_file)-1){
00293 start_char = i+1;
00294 }
00295
00296 if(graph_file[i]=='.' && i>0){
00297 end_char = i-1;
00298 break;
00299 }
00300 }
00301
00302 for (i=start_char; i<=end_char; i++){
00303 name [i-start_char] = graph_file [i];
00304 if (i==end_char){
00305 name[i-start_char+1] = '\0';
00306 }
00307 }
00308
00309 strcat(name,"_");
00310 strcat(name,algorithm);
00311 strcat(name,"_");
00312 strcat(name,teamsize_str);
00313 strcat(name,".xls");
00314
00315 char file_path[40];
00316 strcpy(file_path,"results/");
00317 strcat(file_path,name);
00318
00319 printf("FILE: %s\n", file_path);
00320 file = fopen (file_path,"a");
00321
00322
00323 fprintf(file, "\nComplete Patrol Cycles:\t%u\n\n", complete_patrol);
00324 fprintf(file, "Vertex\tAvg Idl\t#Visits\n");
00325
00326 for (i=0; i<dimension; i++){
00327 fprintf(file, "%u\t%f\t%u\n", i, avg_idleness[i], number_of_visits[i] );
00328 }
00329
00330 fprintf(file,"\nWorst Idl\t%f\nAvg Graph Idl\t%f\nMedian Graph Idl\t%f\nInterferences\t%u\nTime Elapsed\t%f\n",worst_idleness,avg_graph_idl,median_graph_idl,interference_count,timevalue);
00331 fprintf(file,"----------------------------------------------------------------------------------------------------------------------------------------------------------------\n\n\n");
00332 fclose(file);
00333 }
00334
00335
00336 int main(int argc, char** argv){
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 char teamsize_str[3];
00349 teamsize = atoi(argv[3]);
00350
00351 if ( teamsize >= NUM_MAX_ROBOTS || teamsize <1 ){
00352 ROS_INFO("The Teamsize must be an integer number between 1 and %d", NUM_MAX_ROBOTS);
00353 return 0;
00354 }else{
00355 strcpy (teamsize_str, argv[3]);
00356
00357
00358 }
00359
00360 uint i = strlen( argv[2] );
00361 char algorithm[i];
00362 strcpy (algorithm,argv[2]);
00363 printf("Algorithm: %s\n",algorithm);
00364
00365 i = strlen( argv[1] );
00366 char graph_file[i];
00367 strcpy (graph_file,argv[1]);
00368 printf("Graph: %s\n",graph_file);
00369
00370
00371 uint dimension = GetGraphDimension(graph_file);
00372 printf("Dimension: %u\n",dimension);
00373
00374
00375 double last_visit [dimension], current_idleness [dimension], avg_idleness [dimension];
00376 uint number_of_visits [dimension];
00377
00378 double worst_idleness, avg_graph_idl, median_graph_idl, previous_avg_graph_idl = DBL_MAX;
00379 uint interference_count = 0;
00380 uint complete_patrol = 0;
00381 uint patrol_count = 1;
00382
00383 for (i=0; i<dimension; i++){
00384 number_of_visits[i] = 0;
00385 current_idleness[i] = 0.0;
00386 last_visit[i] = 0.0;
00387 }
00388
00389 for (i=0; i<NUM_MAX_ROBOTS; i++){
00390 init_robots[i] = false;
00391 }
00392
00393
00394 ros::init(argc, argv, "monitor");
00395 ros::NodeHandle nh;
00396
00397
00398 results_sub = nh.subscribe("results", 10, resultsCB);
00399
00400
00401 results_pub = nh.advertise<geometry_msgs::PointStamped>("results", 1);
00402
00403 ros::Rate loop_rate(100);
00404
00405 while( ros::ok() ){
00406
00407 if (!initialize){
00408
00409 if (interference){
00410 interference_count++;
00411 interference = false;
00412 }
00413
00414 if (goal_reached){
00415
00416
00417
00418 double last_visit_temp = ros::Time::now().toSec() - time_zero; ;
00419 number_of_visits [goal] ++;
00420
00421
00422
00423 current_idleness [goal] = last_visit_temp - last_visit [goal];
00424
00425
00426 if (number_of_visits [goal] <= 1){
00427 avg_idleness [goal] = current_idleness [goal];
00428
00429 }else{
00430 avg_idleness [goal] = ( avg_idleness [goal] * (double) (number_of_visits [goal] - 1) + current_idleness [goal] ) / ( (double) number_of_visits [goal] );
00431 }
00432
00433
00434 last_visit [goal] = last_visit_temp;
00435
00436
00437 complete_patrol = calculate_patrol_cycle ( number_of_visits, dimension );
00438
00439 goal_reached = false;
00440 }
00441
00442 if (patrol_count == complete_patrol){
00443
00444 previous_avg_graph_idl = avg_graph_idl;
00445
00446 printf("Patrol completed [%d]. Write to File!\n",complete_patrol);
00447 worst_idleness = 0.0;
00448 avg_graph_idl = 0.0;
00449
00450 for (i=0; i<dimension; i++){
00451
00452 if ( avg_idleness[i] > worst_idleness ){
00453 worst_idleness = avg_idleness[i];
00454 }
00455
00456 avg_graph_idl += avg_idleness[i];
00457
00458 }
00459
00460 printf("worst_idleness (graph) = %f\n", worst_idleness);
00461 avg_graph_idl = avg_graph_idl / (double) dimension;
00462 printf("avg_idleness (graph) = %f\n", avg_graph_idl);
00463 median_graph_idl = Median (avg_idleness, dimension);
00464 printf("median_idleness (graph) = %f\n", median_graph_idl);
00465 printf("interference = %d\n\n", interference_count);
00466
00467 patrol_count++;
00468
00469 double tolerance = 0.025 * avg_graph_idl;
00470 printf ("tolerance = %f\n",tolerance);
00471
00472
00473 write_results (avg_idleness, number_of_visits, complete_patrol, dimension, worst_idleness, avg_graph_idl, median_graph_idl, interference_count, graph_file, algorithm, teamsize_str,ros::Time::now().toSec()-time_zero);
00474
00475 if (abs (previous_avg_graph_idl - avg_graph_idl) <= tolerance) {
00476 printf ("Simulation is Over\n");
00477 finish_simulation ();
00478 return 0;
00479 }
00480
00481 }
00482 }
00483
00484 ros::spinOnce();
00485 loop_rate.sleep();
00486 }
00487
00488 }