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 <sys/stat.h>
00039 #include <sys/types.h>
00040 #include <stdlib.h>
00041 #include <unistd.h>
00042 #include <time.h>
00043 #include <float.h>
00044 #include <fstream>
00045 #include <iostream>
00046 #include <string>
00047
00048 #include <ros/ros.h>
00049 #include <ros/package.h>
00050 #include <move_base_msgs/MoveBaseAction.h>
00051 #include <actionlib/client/simple_action_client.h>
00052 #include <tf/transform_broadcaster.h>
00053 #include <tf/transform_listener.h>
00054 #include <std_msgs/Int16MultiArray.h>
00055 #include <std_msgs/String.h>
00056
00057 using namespace std;
00058
00059 #include "getgraph.h"
00060 #include "message_types.h"
00061 #include "patrolling_sim/GoToStartPosSrv.h"
00062
00063 #define NUM_MAX_ROBOTS 32
00064 #define DEAD_ROBOT_TIME 300.0 // (seconds) time from last goal reached after which a robot is considered dead
00065 #define TIMEOUT_WRITE_RESULTS 180.0 // (seconds) timeout for writing results to file
00066
00067 #define RESOLUTION 1.0 // seconds
00068 #define MAXIDLENESS 500.0 // seconds
00069
00070 #define LOG_MONITOR 0
00071 #define SAVE_HYSTOGRAMS 0
00072 #define EXTENDED_STAGE 0
00073
00074 #define SIMULATE_FOREVER true //WARNING: Set this to false, if you want a finishing condition.
00075 #define TIMEOUT_WRITE_RESULTS_FOREVER 900.0 // timeout for writing results to file when simulating forever
00076
00077 using std::string;
00078 using std::cout;
00079 using std::endl;
00080
00081 typedef unsigned int uint;
00082
00083 ros::Subscriber results_sub;
00084 ros::Publisher results_pub, screenshot_pub;
00085 ros::ServiceServer GotoStartPosMethod;
00086
00087
00088 bool initialize = true;
00089 bool goto_start_pos = false;
00090 uint cnt=0;
00091 uint teamsize;
00092 bool init_robots[NUM_MAX_ROBOTS];
00093 double last_goal_reached[NUM_MAX_ROBOTS];
00094
00095
00096 pthread_mutex_t lock_last_goal_reached;
00097
00098
00099 bool goal_reached = false;
00100
00101 int goal;
00102 double time_zero, last_report_time;
00103 time_t real_time_zero;
00104 double goal_reached_wait,comm_delay,lost_message_rate;
00105 string algorithm, algparams, nav_mod, initial_positions;
00106
00107 const std::string PS_path = ros::package::getPath("patrolling_sim");
00108
00109
00110 #define MAX_DIMENSION 200
00111
00112
00113 double last_visit [MAX_DIMENSION], current_idleness [MAX_DIMENSION], avg_idleness [MAX_DIMENSION], stddev_idleness [MAX_DIMENSION];
00114 double total_0 [MAX_DIMENSION], total_1 [MAX_DIMENSION], total_2[MAX_DIMENSION];
00115 int number_of_visits [MAX_DIMENSION];
00116 size_t dimension;
00117
00118 double worst_avg_idleness, avg_graph_idl, median_graph_idl, stddev_graph_idl, avg_stddev_graph_idl, previous_avg_graph_idl = DBL_MAX;
00119
00120 double min_idleness = 0.0, max_idleness = 0.0;
00121 double gavg, gstddev;
00122 double gT0=0.0, gT1=0.0, gT2=0.0;
00123
00124 uint interference_cnt = 0;
00125 uint complete_patrol = 0;
00126 uint patrol_cnt = 1;
00127
00128
00129
00130 #if SAVE_HYSTOGRAMS
00131 #define hn ((int)(MAXIDLENESS/RESOLUTION)+1)
00132 int hsum;
00133 int hv[hn];
00134 #endif
00135
00136
00137 FILE *idlfile;
00138
00139
00140 FILE *logfile = NULL;
00141
00142 void dolog(const char *str) {
00143 if (logfile) {
00144 fprintf(logfile,"%s\n",str);
00145 fflush(logfile);
00146 }
00147 }
00148
00149 void update_stats(int id_robot, int goal);
00150
00151
00152 double get_last_goal_reached(int k)
00153 {
00154 pthread_mutex_lock(&lock_last_goal_reached);
00155 double r = last_goal_reached[k];
00156 pthread_mutex_unlock(&lock_last_goal_reached);
00157 return r;
00158 }
00159
00160 void set_last_goal_reached(int k, double val)
00161 {
00162 pthread_mutex_lock(&lock_last_goal_reached);
00163 last_goal_reached[k] = val;
00164 pthread_mutex_unlock(&lock_last_goal_reached);
00165 }
00166
00167
00168 void resultsCB(const std_msgs::Int16MultiArray::ConstPtr& msg)
00169 {
00170 dolog("resultsCB - begin");
00171
00172 std::vector<signed short>::const_iterator it = msg->data.begin();
00173
00174 std::vector<int> vresults;
00175
00176 vresults.clear();
00177
00178 for (size_t k=0; k<msg->data.size(); k++) {
00179 vresults.push_back(*it); it++;
00180 }
00181
00182 int id_robot = vresults[0];
00183 int msg_type = vresults[1];
00184
00185 switch(msg_type) {
00186 case INITIALIZE_MSG_TYPE:
00187 {
00188 if (initialize && vresults[2]==1){
00189 if (init_robots[id_robot] == false){
00190 printf("Robot [ID = %d] is Active!\n", id_robot);
00191 init_robots[id_robot] = true;
00192
00193
00194 double current_time = ros::Time::now().toSec();
00195
00196 set_last_goal_reached(id_robot,current_time);
00197
00198 cnt++;
00199 }
00200 if (cnt==teamsize){
00201
00202
00203 while(goto_start_pos){
00204
00205 patrolling_sim::GoToStartPosSrv::Request Req;
00206 Req.teamsize.data = teamsize;
00207 Req.sleep_between_goals.data = 20;
00208 patrolling_sim::GoToStartPosSrv::Response Rep;
00209
00210 ROS_INFO("Sending all robots to starting position.");
00211
00212 if (!ros::service::call("/GotoStartPosSrv", Req, Rep)){
00213 ROS_ERROR("Error invoking /GotoStartPosSrv.");
00214 ROS_ERROR("Sending robots to initial position failed.");
00215 ros::shutdown();
00216 return;
00217
00218 }else{
00219 goto_start_pos = false;
00220 system("rosnode kill GoToStartPos &");
00221 }
00222
00223 }
00224
00225 printf("All Robots GO!\n");
00226 initialize = false;
00227
00228
00229 time_zero = ros::Time::now().toSec();
00230 last_report_time = time_zero;
00231
00232 time (&real_time_zero);
00233 printf("Time zero = %.1f (sim) = %lu (real) \n", time_zero,(long)real_time_zero);
00234
00235 std_msgs::Int16MultiArray msg;
00236 msg.data.clear();
00237 msg.data.push_back(-1);
00238 msg.data.push_back(INITIALIZE_MSG_TYPE);
00239 msg.data.push_back(100);
00240 results_pub.publish(msg);
00241 ros::spinOnce();
00242
00243 }
00244 }
00245
00246
00247 break;
00248 }
00249
00250 case TARGET_REACHED_MSG_TYPE:
00251 {
00252
00253 if (initialize==false){
00254 goal = vresults[2];
00255 ROS_INFO("Robot %d reached Goal %d.\n", id_robot, goal);
00256 fflush(stdout);
00257 goal_reached = true;
00258 update_stats(id_robot, goal);
00259 ros::spinOnce();
00260 }
00261 break;
00262 }
00263
00264 case INTERFERENCE_MSG_TYPE:
00265 {
00266
00267 if (initialize==false){
00268 ROS_INFO("Robot %d sent interference.\n", id_robot);
00269 interference_cnt++;
00270 ros::spinOnce();
00271 }
00272 break;
00273 }
00274 }
00275
00276 dolog("resultsCB - end");
00277
00278 }
00279
00280 void finish_simulation (){
00281 ROS_INFO("Sending stop signal to patrol agents.");
00282 std_msgs::Int16MultiArray msg;
00283 msg.data.clear();
00284 msg.data.push_back(-1);
00285 msg.data.push_back(INITIALIZE_MSG_TYPE);
00286 msg.data.push_back(999);
00287 results_pub.publish(msg);
00288 ros::spinOnce();
00289
00290 #if EXTENDED_STAGE
00291 ROS_INFO("Taking a screenshot of the simulator...");
00292 std_msgs::String ss;
00293 ss.data = "screenshot";
00294 screenshot_pub.publish(ss);
00295 #endif
00296
00297 ros::spinOnce();
00298 }
00299
00300
00301 double Median( double *a, uint dimension )
00302 {
00303 uint table_size = dimension/2;
00304 if(dimension % 2 != 0){
00305 table_size++;
00306 }
00307 if (table_size==0) {table_size = 1;}
00308
00309 double left[table_size], right[table_size], median, *p;
00310 unsigned char nLeft, nRight;
00311
00312
00313 p = a;
00314 median = *p++;
00315 nLeft = nRight = 1;
00316
00317 for(;;)
00318 {
00319
00320 double val = *p++;
00321
00322
00323 if( val < median )
00324 {
00325
00326 unsigned char child = nLeft++, parent = (child - 1) / 2;
00327 while( parent && val > left[parent] )
00328 {
00329 left[child] = left[parent];
00330 child = parent;
00331 parent = (parent - 1) / 2;
00332 }
00333 left[child] = val;
00334
00335
00336 if( nLeft == table_size )
00337 {
00338
00339 for( unsigned char nVal = dimension - (p - a); nVal; --nVal )
00340 {
00341
00342 val = *p++;
00343
00344
00345 if( val < median )
00346 {
00347 child = left[2] > left[1] ? 2 : 1;
00348 if( val >= left[child] )
00349 median = val;
00350 else
00351 {
00352 median = left[child];
00353 parent = child;
00354 child = parent*2 + 1;
00355 while( child < table_size )
00356 {
00357 if( child < table_size-1 && left[child+1] > left[child] )
00358 ++child;
00359 if( val >= left[child] )
00360 break;
00361 left[parent] = left[child];
00362 parent = child;
00363 child = parent*2 + 1;
00364 }
00365 left[parent] = val;
00366 }
00367 }
00368 }
00369 return median;
00370 }
00371 }
00372
00373
00374 else
00375 {
00376
00377 unsigned char child = nRight++, parent = (child - 1) / 2;
00378 while( parent && val < right[parent] )
00379 {
00380 right[child] = right[parent];
00381 child = parent;
00382 parent = (parent - 1) / 2;
00383 }
00384 right[child] = val;
00385
00386
00387 if( nRight == 14 )
00388 {
00389
00390 for( unsigned char nVal = dimension - (p - a); nVal; --nVal )
00391 {
00392
00393 val = *p++;
00394
00395
00396 if( val > median )
00397 {
00398 child = right[2] < right[1] ? 2 : 1;
00399 if( val <= right[child] )
00400 median = val;
00401 else
00402 {
00403 median = right[child];
00404 parent = child;
00405 child = parent*2 + 1;
00406 while( child < table_size )
00407 {
00408 if( child < 13 && right[child+1] < right[child] )
00409 ++child;
00410 if( val <= right[child] )
00411 break;
00412 right[parent] = right[child];
00413 parent = child;
00414 child = parent*2 + 1;
00415 }
00416 right[parent] = val;
00417 }
00418 }
00419 }
00420 return median;
00421 }
00422 }
00423 }
00424 }
00425
00426
00427 uint calculate_patrol_cycle ( int *nr_visits, uint dimension ){
00428 dolog(" calculate_patrol_cycle - begin");
00429 uint result = INT_MAX;
00430 uint imin=0;
00431 for (uint i=0; i<dimension; i++){
00432 if ((uint)nr_visits[i] < result){
00433 result = nr_visits[i]; imin=i;
00434 }
00435 }
00436
00437 dolog(" calculate_patrol_cycle - end");
00438 return result;
00439 }
00440
00441 void scenario_name(char* name, const char* graph_file, const char* teamsize_str)
00442 {
00443 uint i, start_char=0, end_char = strlen(graph_file)-1;
00444
00445 for (i=0; i<strlen(graph_file); i++){
00446 if(graph_file[i]=='/' && i < strlen(graph_file)-1){
00447 start_char = i+1;
00448 }
00449
00450 if(graph_file[i]=='.' && i>0){
00451 end_char = i-1;
00452 break;
00453 }
00454 }
00455
00456 for (i=start_char; i<=end_char; i++){
00457 name [i-start_char] = graph_file [i];
00458 if (i==end_char){
00459 name[i-start_char+1] = '\0';
00460 }
00461 }
00462
00463 strcat(name,"_");
00464 strcat(name,teamsize_str);
00465 }
00466
00467
00468 void write_results (double *avg_idleness, double *stddev_idleness, int *number_of_visits, uint complete_patrol, uint dimension,
00469 double worst_avg_idleness, double avg_graph_idl, double median_graph_idl, double stddev_graph_idl,
00470 double min_idleness, double gavg, double gstddev, double max_idleness,
00471 uint interference_cnt, uint tot_visits, float avg_visits,
00472 const char* graph_file, const char* teamsize_str,
00473 double duration, double real_duration, double comm_delay,
00474 string filename) {
00475
00476 dolog("write_results - begin");
00477
00478 FILE *file;
00479
00480 printf("writing to file %s\n",filename.c_str());
00481
00482
00483 file = fopen (filename.c_str(),"a");
00484
00485
00486 fprintf(file, "\nComplete Patrol Cycles:\t%u\n\n", complete_patrol);
00487 fprintf(file, "Vertex\tAvg Idl\tStdDev Idl\t#Visits\n");
00488 for (uint i=0; i<dimension; i++){
00489 fprintf(file, "%u\t%.1f\t%.1f\t%d\n", i, avg_idleness[i], stddev_idleness[i], number_of_visits[i] );
00490 }
00491
00492 fprintf(file,"\nNode idleness\n");
00493 fprintf(file," worst_avg_idleness (graph) = %.1f\n", worst_avg_idleness);
00494 fprintf(file," avg_idleness (graph) = %.1f\n", avg_graph_idl);
00495 fprintf(file," median_idleness (graph) = %.1f\n", median_graph_idl);
00496 fprintf(file," stddev_idleness (graph) = %.1f\n", stddev_graph_idl);
00497
00498 fprintf(file,"\nGlobal idleness\n");
00499 fprintf(file," min = %.1f\n", min_idleness);
00500 fprintf(file," avg = %.1f\n", gavg);
00501 fprintf(file," stddev = %.1f\n", gstddev);
00502 fprintf(file," max = %.1f\n", max_idleness);
00503
00504 fprintf(file,"\nInterferences\t%u\nInterference rate\t%.2f\nVisits\t%u\nAvg visits per node\t%.1f\nTime Elapsed\t%.1f\nReal Time Elapsed\t%.1f\nComm delay: %.2f\n",
00505 interference_cnt,(float)interference_cnt/duration*60,tot_visits,avg_visits,duration,real_duration,comm_delay);
00506
00507 fprintf(file,"----------------------------------------------------------------------------------------------------------------------------------------------------------------\n\n\n");
00508
00509
00510 fclose(file);
00511
00512 dolog("write_results - end");
00513
00514 }
00515
00516 bool check_dead_robots() {
00517
00518 dolog(" check_dead_robots - begin");
00519
00520 double current_time = ros::Time::now().toSec();
00521 bool r=false;
00522 for (size_t i=0; i<teamsize; i++) {
00523 double l = get_last_goal_reached(i);
00524 double delta = current_time - l;
00525
00526 if (delta>DEAD_ROBOT_TIME*0.75) {
00527 printf("Robot %lu: dead robot - delta = %.1f / %.1f \n",i,delta,DEAD_ROBOT_TIME);
00528 system("play -q beep.wav");
00529 }
00530 if (delta>DEAD_ROBOT_TIME) {
00531
00532 r=true;
00533 break;
00534 }
00535 }
00536
00537 dolog(" check_dead_robots - end");
00538
00539 return r;
00540 }
00541
00542
00543
00544 void update_stats(int id_robot, int goal) {
00545
00546 dolog(" update_stats - begin");
00547
00548
00549
00550 double current_time = ros::Time::now().toSec();
00551
00552 printf("Robot %d reached goal %d (current time: %.2f, alg: %s, nav: %s)\n", id_robot, goal, current_time, algorithm.c_str(), nav_mod.c_str());
00553
00554 double last_visit_temp = current_time - time_zero;
00555 number_of_visits [goal] ++;
00556
00557 set_last_goal_reached(id_robot,current_time);
00558
00559 printf(" nr_of_visits = %d -", number_of_visits [goal]);
00560
00561 if (number_of_visits [goal] == 0) {
00562 avg_idleness [goal] = 0.0; stddev_idleness[goal] = 0.0;
00563 total_0 [goal] = 0.0; total_1 [goal] = 0.0; total_2 [goal] = 0.0;
00564 }
00565 else {
00566
00567 current_idleness [goal] = last_visit_temp - last_visit [goal];
00568
00569 if (current_idleness [goal] > max_idleness)
00570 max_idleness=current_idleness [goal];
00571 if (current_idleness [goal] < min_idleness || min_idleness<0.1)
00572 min_idleness=current_idleness [goal];
00573
00574
00575 gT0++; gT1 += current_idleness[goal]; gT2 += current_idleness[goal]*current_idleness[goal];
00576
00577
00578 total_0 [goal] += 1.0; total_1 [goal] += current_idleness [goal]; total_2 [goal] += current_idleness [goal]*current_idleness [goal];
00579 avg_idleness [goal] = total_1[goal]/total_0[goal];
00580 stddev_idleness[goal] = 1.0/total_0[goal] * sqrt(total_0[goal]*total_2[goal]-total_1[goal]*total_1[goal]);
00581
00582 printf(" idl current = %.2f, ", current_idleness[goal]);
00583 printf(" avg = %.1f, stddev = %.1f,", avg_idleness [goal], stddev_idleness[goal]);
00584 printf(" max = %.1f - interf = %d\n", max_idleness,interference_cnt);
00585
00586
00587 fprintf(idlfile,"%.1f;%d;%d;%.1f;%d\n",current_time,id_robot,goal,current_idleness[goal],interference_cnt);
00588 fflush(idlfile);
00589
00590 #if SAVE_HYSTOGRAMS
00591
00592 int b = (int)(current_idleness[goal]/RESOLUTION);
00593 if (b<hn) {
00594 hv[b]++; hsum++;
00595 }
00596 #endif
00597
00598 }
00599
00600 complete_patrol = calculate_patrol_cycle ( number_of_visits, dimension );
00601 printf(" complete patrol cycles = %d\n", complete_patrol);
00602
00603
00604 size_t hnode; double hidl=0;
00605 for (size_t i=0; i<dimension; i++) {
00606 double cidl = last_visit_temp - last_visit [i];
00607 if (cidl>hidl) {
00608 hidl=cidl; hnode=i;
00609 }
00610 }
00611 printf(" highest current idleness: node %lu idl %.1f\n\n",hnode,hidl);
00612
00613 last_visit [goal] = last_visit_temp;
00614
00615 goal_reached = false;
00616
00617 dolog(" update_stats - end");
00618
00619 }
00620
00621
00622 int main(int argc, char** argv){
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 char teamsize_str[3];
00635 teamsize = atoi(argv[3]);
00636
00637 if ( teamsize >= NUM_MAX_ROBOTS || teamsize <1 ){
00638 ROS_INFO("The Teamsize must be an integer number between 1 and %d", NUM_MAX_ROBOTS);
00639 return 0;
00640 }else{
00641 strcpy (teamsize_str, argv[3]);
00642
00643
00644 }
00645
00646
00647 algorithm = string(argv[2]);
00648 printf("Algorithm: %s\n",algorithm.c_str());
00649
00650 string mapname = string(argv[1]);
00651 string graph_file = "maps/"+mapname+"/"+mapname+".graph";
00652
00653 printf("Graph: %s\n",graph_file.c_str());
00654
00656 chdir(PS_path.c_str());
00657
00658
00659 dimension = GetGraphDimension(graph_file.c_str());
00660 if (dimension>MAX_DIMENSION) {
00661 cout << "ERROR!!! dimension > MAX_DIMENSION (static value) !!!" << endl;
00662 abort();
00663 }
00664 printf("Dimension: %u\n",(uint)dimension);
00665
00666 char hostname[80];
00667
00668 int r = gethostname(hostname,80);
00669 if (r<0)
00670 strcpy(hostname,"default");
00671
00672 printf("Host name: %s\n",hostname);
00673
00674
00675
00676 for (size_t i=0; i<dimension; i++){
00677 number_of_visits[i] = -1;
00678 current_idleness[i] = 0.0;
00679 last_visit[i] = 0.0;
00680 }
00681
00682 for (size_t i=0; i<NUM_MAX_ROBOTS; i++){
00683 init_robots[i] = false;
00684 last_goal_reached[i] = 0.0;
00685 }
00686
00687 bool dead = false;
00688
00689 bool simrun, simabort;
00690
00691
00692 char sname[80];
00693 scenario_name(sname,graph_file.c_str(),teamsize_str);
00694
00695
00696
00697 string path1 = "results";
00698
00699 string path2,path3,path4;
00700
00701 path2 = path1 + "/" + string(sname);
00702 path3 = path2 + "/" + algorithm;
00703 path4 = path3 + "/" + hostname;
00704
00705
00706 struct stat st;
00707
00708 if (stat(path1.c_str(), &st) != 0)
00709 mkdir(path1.c_str(), 0777);
00710 if (stat(path2.c_str(), &st) != 0)
00711 mkdir(path2.c_str(), 0777);
00712 if (stat(path3.c_str(), &st) != 0)
00713 mkdir(path3.c_str(), 0777);
00714 if (stat(path4.c_str(), &st) != 0)
00715 mkdir(path4.c_str(), 0777);
00716
00717 printf("Path experimental results: %s\n",path4.c_str());
00718
00719
00720 time_t rawtime;
00721 struct tm * timeinfo;
00722 char strnow[80];
00723
00724 time (&rawtime);
00725 timeinfo = localtime(&rawtime);
00726 sprintf(strnow,"%d%02d%02d_%02d%02d%02d", timeinfo->tm_year+1900,timeinfo->tm_mon+1,timeinfo->tm_mday,timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);
00727 printf("Date-time of the experiment: %s\n",strnow);
00728
00729
00730
00731 string idlfilename,resultsfilename,resultstimecsvfilename,expname;
00732 expname = path4 + "/" + string(strnow);
00733 idlfilename = expname + "_idleness.csv";
00734 resultsfilename = expname + "_results.txt";
00735 resultstimecsvfilename = expname + "_timeresults.csv";
00736
00737 FILE *fexplist;
00738 fexplist = fopen("experiments.txt", "a");
00739 fprintf(fexplist,"%s\n",expname.c_str());
00740 fclose(fexplist);
00741
00742 idlfile = fopen (idlfilename.c_str(),"a");
00743 fprintf(idlfile,"Time;Robot;Node;Idleness;Interferences\n");
00744
00745 FILE *resultstimecsvfile;
00746 resultstimecsvfile = fopen(resultstimecsvfilename.c_str(), "w");
00747
00748 fprintf(resultstimecsvfile,"Time;Idleness min;Idleness avg;Idleness stddev;Idleness max;Interferences\n");
00749
00750 #if LOG_MONITOR
00751 char logfilename[80];
00752 sprintf(logfilename,"monitor_%s.log",strnow);
00753 logfile = fopen(logfilename, "w");
00754 #endif
00755
00756 dolog("Monitor node starting");
00757 dolog(expname.c_str());
00758
00759 #if SAVE_HYSTOGRAMS
00760
00761 for (int k=0; k<hn; k++) hv[k]=0;
00762 hsum=0;
00763 #endif
00764
00765
00766 ros::init(argc, argv, "monitor");
00767 ros::NodeHandle nh;
00768
00769
00770 results_sub = nh.subscribe("results", 100, resultsCB);
00771
00772
00773 results_pub = nh.advertise<std_msgs::Int16MultiArray>("results", 100);
00774
00775 #if EXTENDED_STAGE
00776 screenshot_pub = nh.advertise<std_msgs::String>("/stageGUIRequest", 100);
00777 #endif
00778
00779 double duration = 0.0, real_duration = 0.0;
00780
00781 ros::Rate loop_rate(30);
00782
00783 nh.setParam("/simulation_running", "true");
00784 nh.setParam("/simulation_abort", "false");
00785
00786 if(ros::service::exists("/GotoStartPosSrv", false)){
00787 goto_start_pos = true;
00788 ROS_INFO("/GotoStartPosSrv is advertised. Robots will be sent to starting positions.");
00789 }else{
00790 ROS_WARN("/GotoStartPosSrv does not exist. Assuming robots are already at starting positions.");
00791 }
00792
00793 double current_time = ros::Time::now().toSec();
00794
00795
00796 if (! ros::param::get("/goal_reached_wait", goal_reached_wait)) {
00797 goal_reached_wait = 0.0;
00798 ROS_WARN("Cannot read parameter /goal_reached_wait. Using default value 0.0!");
00799 }
00800
00801 if (! ros::param::get("/communication_delay", comm_delay)) {
00802 comm_delay = 0.0;
00803 ROS_WARN("Cannot read parameter /communication_delay. Using default value 0.0!");
00804 }
00805
00806 if (! ros::param::get("/lost_message_rate", lost_message_rate)) {
00807 lost_message_rate = 0.0;
00808 ROS_WARN("Cannot read parameter /lost_message_rate. Using default value 0.0!");
00809 }
00810
00811 if (! ros::param::get("/initial_positions", initial_positions)) {
00812 initial_positions = "default";
00813 ROS_WARN("Cannot read parameter /initial_positions. Using default value '%s'!", initial_positions.c_str());
00814 }
00815
00816 if (! ros::param::get("/navigation_module", nav_mod)) {
00817 ROS_WARN("Cannot read parameter /navigation_module. Using default value 'ros'!");
00818 nav_mod = "ros";
00819 }
00820
00821
00822
00823 pthread_mutex_init(&lock_last_goal_reached, NULL);
00824
00825
00826
00827 while( ros::ok() ){
00828
00829 dolog("main loop - begin");
00830
00831 if (!initialize){
00832
00833
00834 double report_time = ros::Time::now().toSec();
00835
00836
00837
00838
00839 bool timeout_write_results;
00840
00841 #if SIMULATE_FOREVER
00842 timeout_write_results = (report_time - last_report_time > TIMEOUT_WRITE_RESULTS_FOREVER);
00843 #else
00844 timeout_write_results = (report_time - last_report_time > TIMEOUT_WRITE_RESULTS);
00845 #endif
00846
00847 if ((patrol_cnt == complete_patrol) || timeout_write_results){
00848
00849 dolog("main loop - write results begin");
00850
00851 if (complete_patrol==1) {
00852 ros::param::get("/algorithm_params", algparams);
00853 if (! ros::param::get("/goal_reached_wait", goal_reached_wait))
00854 goal_reached_wait = 0.0;
00855 }
00856
00857
00858
00859 previous_avg_graph_idl = avg_graph_idl;
00860
00861 printf("******************************************\n");
00862 printf("Patrol completed [%d]. Write to File!\n",complete_patrol);
00863
00864 worst_avg_idleness = 0.0;
00865 avg_graph_idl = 0.0;
00866 stddev_graph_idl = 0.0;
00867 avg_stddev_graph_idl = 0.0;
00868
00869
00870 double T0=0.0,T1=0.0,T2=0.0,S1=0.0;
00871 for (size_t i=0; i<dimension; i++){
00872 T0++; T1+=avg_idleness[i]; T2+=avg_idleness[i]*avg_idleness[i];
00873 S1+=stddev_idleness[i];
00874 if ( avg_idleness[i] > worst_avg_idleness ){
00875 worst_avg_idleness = avg_idleness[i];
00876 }
00877 }
00878
00879 avg_graph_idl = T1/T0;
00880 stddev_graph_idl = 1.0/T0 * sqrt(T0*T2-T1*T1);
00881 avg_stddev_graph_idl = S1/T0;
00882
00883 gavg = gT1/gT0;
00884 gstddev = 1.0/gT0 * sqrt(gT0*gT2-gT1*gT1);
00885
00886 uint i,tot_visits=0;
00887 for (size_t i=0; i<dimension; i++){
00888 tot_visits += number_of_visits[i];
00889 }
00890 float avg_visits = (float)tot_visits/dimension;
00891
00892 duration = report_time-time_zero;
00893 time_t real_now; time (&real_now);
00894 real_duration = (double)real_now - (double)real_time_zero;
00895
00896 printf("Node idleness\n");
00897 printf(" worst_avg_idleness (graph) = %.2f\n", worst_avg_idleness);
00898 printf(" avg_idleness (graph) = %.2f\n", avg_graph_idl);
00899 median_graph_idl = Median (avg_idleness, dimension);
00900 printf(" median_idleness (graph) = %.2f\n", median_graph_idl);
00901 printf(" stddev_idleness (graph) = %.2f\n", stddev_graph_idl);
00902
00903 printf("Global idleness\n");
00904 printf(" min = %.1f\n", min_idleness);
00905 printf(" avg = %.1f\n", gavg);
00906 printf(" stddev = %.1f\n", gstddev);
00907 printf(" max = %.1f\n", max_idleness);
00908
00909 printf("\nInterferences\t%u\nInterference rate\t%.2f\nVisits\t%u\nAvg visits per node\t%.1f\nTime Elapsed\t%.1f\nReal Time Elapsed\t%.1f\n",
00910 interference_cnt,(float)interference_cnt/duration*60,tot_visits,avg_visits,duration,real_duration);
00911
00912 if (timeout_write_results)
00913 last_report_time = report_time;
00914 else
00915 patrol_cnt++;
00916
00917
00918 double tolerance = 0.025 * avg_graph_idl;
00919 printf ("diff avg_idleness = %.1f\n",fabs(previous_avg_graph_idl - avg_graph_idl));
00920 printf ("tolerance = %.1f\n",tolerance);
00921
00922
00923 if (!timeout_write_results)
00924 write_results (avg_idleness, stddev_idleness, number_of_visits, complete_patrol, dimension,
00925 worst_avg_idleness, avg_graph_idl, median_graph_idl, stddev_graph_idl,
00926 min_idleness, gavg, gstddev, max_idleness,
00927 interference_cnt, tot_visits, avg_visits,
00928 graph_file.c_str(), teamsize_str, duration, real_duration, comm_delay,
00929 resultsfilename);
00930 else {
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940 fprintf(resultstimecsvfile,"%.1f;%.1f;%.1f;%.1f;%.1f;%d\n",
00941 duration,min_idleness,gavg,gstddev,max_idleness,interference_cnt);
00942 fflush(resultstimecsvfile);
00943
00944 }
00945
00946 dolog("main loop - write results begin");
00947
00948 }
00949
00950
00951 dolog(" check - begin");
00952
00953
00954 #if SIMULATE_FOREVER == false
00955 dead = check_dead_robots();
00956
00957 simrun=true; simabort=false;
00958 std::string psimrun, psimabort; bool bsimabort;
00959 if (nh.getParam("/simulation_running", psimrun))
00960 if (psimrun=="false")
00961 simrun = false;
00962 if (nh.getParam("/simulation_abort", psimabort))
00963 if (psimabort=="true")
00964 simabort = true;
00965 if (nh.getParam("/simulation_abort", bsimabort))
00966 simabort = bsimabort;
00967
00968 if ( (dead) || (!simrun) || (simabort) ) {
00969 printf ("Simulation is Over\n");
00970 nh.setParam("/simulation_running", false);
00971 finish_simulation ();
00972 ros::spinOnce();
00973 break;
00974 }
00975 #endif
00976
00977 dolog(" check - end");
00978
00979 }
00980
00981 current_time = ros::Time::now().toSec();
00982 ros::spinOnce();
00983 loop_rate.sleep();
00984
00985 dolog("main loop - end");
00986
00987 }
00988
00989 ros::shutdown();
00990
00991 fclose(idlfile);
00992 fclose(resultstimecsvfile);
00993
00994
00995
00996
00997 duration = current_time-time_zero;
00998 time_t real_now; time (&real_now);
00999 real_duration = (double)real_now - (double)real_time_zero;
01000
01001 uint tot_visits=0;
01002 for (size_t i=0; i<dimension; i++){
01003 tot_visits += number_of_visits[i];
01004 }
01005 float avg_visits = (float)tot_visits/dimension;
01006
01007
01008
01009 string infofilename;
01010 infofilename = expname + "_info.csv";
01011
01012 FILE *infofile;
01013 infofile = fopen (infofilename.c_str(),"w");
01014 fprintf(infofile,"%s;%s;%s;%.1f;%.2f;%s;%s;%s;%s;%s;%.1f;%.1f;%d;%s;%.1f;%.1f;%.1f;%.1f;%.2f;%d;%.1f;%d\n",
01015 mapname.c_str(),teamsize_str,initial_positions.c_str(),goal_reached_wait,comm_delay,nav_mod.c_str(),
01016 algorithm.c_str(), algparams.c_str(),hostname,
01017 strnow,duration,real_duration,interference_cnt,(dead?"FAIL":(simabort?"ABORT":"TIMEOUT")),
01018 min_idleness, gavg, gstddev, max_idleness, (float)interference_cnt/duration*60,
01019 tot_visits, avg_visits, complete_patrol
01020 );
01021
01022 fclose(infofile);
01023 cout << "Info file " << infofilename << " saved." << endl;
01024
01025
01026 #if SAVE_HYSTOGRAMS
01027
01028 string hfilename,chfilename;
01029 hfilename = expname + ".hist";
01030 chfilename = expname + ".chist";
01031
01032 cout << "Histogram output files: " << hfilename << endl;
01033 std::ofstream of1; of1.open(hfilename.c_str());
01034 std::ofstream of2; of2.open(chfilename.c_str());
01035 double c=0;
01036 for (int k=0; k<hn; k++) {
01037 of1 << k*RESOLUTION << " " << (double)hv[k]/hsum << endl;
01038 c += (double)hv[k]/hsum;
01039 of2 << k*RESOLUTION << " " << c << endl;
01040 }
01041 of1.close(); of2.close();
01042 #endif
01043
01044 printf("Monitor closed.\n");
01045
01046 dolog("Monitor closed");
01047
01048 #if EXTENDED_STAGE
01049 sleep(5);
01050 char cmd[80];
01051 sprintf(cmd, "mv ~/.ros/stage-000003.png %s/%s_stage.png", path4.c_str(),strnow);
01052 system(cmd);
01053 printf("%s\n",cmd);
01054 printf("Screenshot image copied.\n");
01055 sleep(3);
01056 dolog("Snapshots done");
01057 #endif
01058
01059 }
01060