00001 #include "ros/ros.h"
00002 #include "ExplorationPlanner.h"
00003 #include <ros/console.h>
00004 #include <ExplorationPlanner.h>
00005 #include <boost/lexical_cast.hpp>
00006 #include <move_base/MoveBaseConfig.h>
00007 #include <move_base_msgs/MoveBaseAction.h>
00008 #include <move_base_msgs/MoveBaseActionFeedback.h>
00009 #include <costmap_2d/costmap_2d_ros.h>
00010 #include <costmap_2d/costmap_2d.h>
00011 #include <costmap_2d/cost_values.h>
00012 #include <costmap_2d/costmap_2d_publisher.h>
00013 #include <costmap_2d/observation.h>
00014 #include <costmap_2d/observation_buffer.h>
00015 #include <tf/transform_listener.h>
00016 #include <std_msgs/String.h>
00017
00018 #include <actionlib/client/simple_action_client.h>
00019 #include <boost/thread.hpp>
00020 #include <boost/thread/mutex.hpp>
00021 #include <iostream>
00022 #include <navfn/navfn_ros.h>
00023
00024 #include <boost/filesystem.hpp>
00025 #include <map_merger/LogMaps.h>
00026
00027
00028
00029
00030
00031
00032
00033 boost::mutex costmap_mutex;
00034
00035
00036 #define OPERATE_ON_GLOBAL_MAP true
00037 #define OPERATE_WITH_GOAL_BACKOFF false
00038
00039 void sleepok(int t, ros::NodeHandle &nh)
00040 {
00041 if (nh.ok())
00042 ros::Duration(1.0).sleep();
00043 }
00044
00045 class Explorer {
00046
00047 public:
00048
00049 Explorer(tf::TransformListener& tf) :
00050 counter(0), rotation_counter(0), nh("~"), exploration_finished(false), number_of_robots(1), accessing_cluster(0), cluster_element_size(0),
00051 cluster_flag(false), cluster_element(-1), cluster_initialize_flag(false), global_iterattions(0), global_iterations_counter(0),
00052 counter_waiting_for_clusters(0), global_costmap_iteration(0), robot_prefix_empty(false), robot_id(0){
00053
00054
00055 nh.param("frontier_selection",frontier_selection,1);
00056 nh.param("local_costmap/width",costmap_width,0);
00057 nh.param("number_unreachable_for_cluster", number_unreachable_frontiers_for_cluster,3);
00058
00059 ROS_INFO("Costmap width: %d", costmap_width);
00060
00061 ROS_INFO("Frontier selection is set to: %d", frontier_selection);
00062
00063 Simulation = false;
00064
00065
00066
00067
00068
00069
00070
00071 srand((unsigned)time(0));
00072
00073
00074
00075
00076
00077 nh.param<std::string>("move_base_frame",move_base_frame,"map");
00078 nh.param<int>("wait_for_planner_result",waitForResult,3);
00079
00080 nh.param<std::string>("robot_prefix",robot_prefix,"");
00081 ROS_INFO("robot prefix: \"%s\"", robot_prefix.c_str());
00082
00083
00084
00085
00086
00087
00088
00089 std::string service = robot_prefix + std::string("/map_merger/logOutput");
00090 mm_log_client = nh.serviceClient<map_merger::LogMaps>(service.c_str());
00091
00092 if(robot_prefix.empty())
00093 {
00094 char hostname_c[1024];
00095 hostname_c[1023] = '\0';
00096 gethostname(hostname_c, 1023);
00097 robot_name = std::string(hostname_c);
00098 ROS_INFO("NO SIMULATION! Robot name: %s", robot_name.c_str());
00099
00100
00101
00102
00103
00104
00105
00106
00107 std::string bob = "bob";
00108 std::string marley = "marley";
00109 std::string turtlebot = "turtlebot";
00110 std::string joy = "joy";
00111 std::string hans = "hans";
00112
00113 if(robot_name.compare(turtlebot) == 0)
00114 robot_id = 0;
00115 if(robot_name.compare(joy) == 0)
00116 robot_id = 1;
00117 if(robot_name.compare(marley) == 0)
00118 robot_id = 2;
00119 if(robot_name.compare(bob) == 0)
00120 robot_id = 3;
00121 if(robot_name.compare(hans) == 0)
00122 robot_id = 4;
00123
00124 robot_prefix_empty = true;
00125 ROS_INFO("Robot name: %s robot_id: %d", robot_name.c_str(), robot_id);
00126 }else
00127 {
00128 robot_name = robot_prefix;
00129 ROS_INFO("Move_base_frame: %s",move_base_frame.c_str());
00130 robot_id = atoi(move_base_frame.substr(7,1).c_str());
00131
00132 ROS_INFO("Robot: %d", robot_id);
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 initLogPath();
00151 csv_file = log_path + std::string("periodical.log");
00152 log_file = log_path + std::string("exploration.log");
00153
00154 ROS_DEBUG("*********************************************");
00155 ROS_INFO("******* Initializing Simple Navigation ******");
00156 ROS_DEBUG(" ");
00157
00158 ROS_DEBUG("Creating global costmap ...");
00159 costmap2d_global = new costmap_2d::Costmap2DROS("global_costmap", tf);
00160 ROS_DEBUG("Global costmap created ... now performing costmap -> pause");
00161 costmap2d_global->pause();
00162 ROS_DEBUG("Pausing performed");
00163
00164 ROS_DEBUG(" ");
00165
00166 if(OPERATE_ON_GLOBAL_MAP == true)
00167 {
00168 costmap2d_local_size = new costmap_2d::Costmap2DROS("local_costmap", tf);
00169 costmap2d_local_size->pause();
00170 ROS_DEBUG("Starting Global costmap ...");
00171 costmap2d_global->start();
00172 costmap2d_local_size->start();
00173
00174 costmap2d_local = costmap2d_global;
00175 }
00176 else
00177 {
00178 ROS_INFO("Creating local costmap ...");
00179 costmap2d_local = new costmap_2d::Costmap2DROS("local_costmap", tf);
00180 ROS_INFO("Local costmap created ... now performing costmap -> pause");
00181 costmap2d_local->pause();
00182 ROS_INFO("Pausing performed");
00183 ROS_INFO("Cost maps created");
00184
00185 ROS_INFO(" ");
00186
00187 ROS_INFO("Starting Global costmap ...");
00188 costmap2d_global->start();
00189 ROS_INFO("Starting Local costmap ... ");
00190 costmap2d_local->start();
00191 ROS_INFO("BOTH COSTMAPS STARTED AND RUNNING ...");
00192 }
00193 ROS_INFO("---------------- COSTMAP DONE ---------------");
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 if (!costmap2d_local->getRobotPose(robotPose)) {
00204 ROS_ERROR("Failed to get RobotPose");
00205 }
00206 visualize_goal_point(robotPose.getOrigin().getX(),
00207 robotPose.getOrigin().getY());
00208
00209
00210 for (int i = 0; i <= 2; i++) {
00211 visualize_home_point();
00212 }
00213
00214 ROS_INFO("---------- SET HOME/ GOAL POINT DONE --------");
00215
00216
00217 exploration = new explorationPlanner::ExplorationPlanner(robot_id, robot_prefix_empty, robot_name);
00218
00219
00220
00221
00222
00223
00224 robot_home_position_x = robotPose.getOrigin().getX();
00225 robot_home_position_y = robotPose.getOrigin().getY();
00226
00227 exploration->next_auction_position_x = robotPose.getOrigin().getX();
00228 exploration->next_auction_position_y = robotPose.getOrigin().getY();
00229
00230 exploration->storeVisitedFrontier(robot_home_position_x,robot_home_position_y, robot_id, robot_name, -1);
00231 exploration->storeFrontier(robot_home_position_x,robot_home_position_y, robot_id, robot_name, -1);
00232
00233 exploration->setRobotConfig(robot_id, robot_home_position_x, robot_home_position_y, move_base_frame);
00234
00235 ROS_INFO(" ");
00236 ROS_INFO("************* INITIALIZING DONE *************");
00237
00238 }
00239
00240
00241 void explore()
00242 {
00243
00244
00245
00246
00247
00248
00249 ROS_DEBUG("Sleeping 5s for costmaps to be updated.");
00250 geometry_msgs::Twist twi;
00251
00252 ros::Publisher twi_publisher = nh.advertise<geometry_msgs::Twist>("/Rosaria/cmd_vel",3);
00253 twi.angular.z = 0.75;
00254 twi_publisher.publish(twi);
00255 ros::Duration(5.0).sleep();
00256 twi_publisher.publish(twi);
00257
00258
00259
00260 time_start = ros::Time::now();
00261
00262
00263 while (exploration_finished == false)
00264 {
00265 Simulation == false;
00266 if(Simulation == false)
00267 {
00268
00269
00270
00271
00272
00273
00274 std::vector<double> final_goal;
00275 std::vector<double> backoffGoal;
00276 std::vector<std::string> robot_str;
00277
00278 bool backoff_sucessfull = false, navigate_to_goal = false;
00279 bool negotiation;
00280 int count = 0;
00281
00282 ROS_INFO("****************** EXPLORE ******************");
00283
00284
00285
00286
00287
00288 costmap_mutex.lock();
00289
00290 exploration->transformToOwnCoordinates_frontiers();
00291 exploration->transformToOwnCoordinates_visited_frontiers();
00292
00293
00294 exploration->initialize_planner("exploration planner", costmap2d_local, costmap2d_global);
00295 exploration->findFrontiers();
00296
00297
00298 exploration->clearVisitedFrontiers();
00299 exploration->clearUnreachableFrontiers();
00300 exploration->clearSeenFrontiers(costmap2d_global);
00301
00302 costmap_mutex.unlock();
00303
00304 exploration->publish_frontier_list();
00305 exploration->publish_visited_frontier_list();
00306
00307 ros::Duration(1).sleep();
00308 exploration->publish_frontier_list();
00309 exploration->publish_visited_frontier_list();
00310
00311
00312
00313
00314 ros::Duration(1).sleep();
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 if(frontier_selection == 2)
00345 {
00346
00347 exploration->sort(1);
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 while(true)
00360 {
00361 goal_determined = exploration->determine_goal(1, &final_goal, count, 0, &robot_str);
00362 if(goal_determined == false)
00363 {
00364 break;
00365 }
00366 else
00367 {
00368
00369 negotiation = true;
00370 if(negotiation == true)
00371 {
00372 break;
00373 }
00374 count++;
00375 }
00376 }
00377 }
00378 else if(frontier_selection == 3)
00379 {
00380 exploration->sort(2);
00381
00382 while(true)
00383 {
00384 goal_determined = exploration->determine_goal(2, &final_goal, count, 0, &robot_str);
00385 if(goal_determined == false)
00386 {
00387 break;
00388 }
00389 else
00390 {
00391
00392 negotiation = true;
00393 if(negotiation == true)
00394 {
00395 break;
00396 }
00397 count++;
00398 }
00399 }
00400 }
00401 else if(frontier_selection == 0)
00402 {
00403 exploration->sort(2);
00404 exploration->sort(3);
00405
00406 while(true)
00407 {
00408 goal_determined = exploration->determine_goal(2, &final_goal, count, 0, &robot_str);
00409 ROS_DEBUG("Goal_determined: %d counter: %d",goal_determined, count);
00410 if(goal_determined == false)
00411 {
00412 break;
00413 }
00414 else
00415 {
00416
00417 negotiation = true;
00418 if(negotiation == true)
00419 {
00420 break;
00421 }
00422 count++;
00423 }
00424 }
00425
00426 }
00427 else if(frontier_selection == 4)
00428 {
00429 while(true)
00430 {
00431 goal_determined = exploration->determine_goal(3, &final_goal, count, 0, &robot_str);
00432 ROS_DEBUG("Goal_determined: %d counter: %d",goal_determined, count);
00433 if(goal_determined == false)
00434 {
00435 break;
00436 }
00437 else
00438 {
00439
00440 negotiation = true;
00441 if(negotiation == true)
00442 {
00443 break;
00444 }
00445 count++;
00446 }
00447 }
00448
00449 }
00450 else if(frontier_selection == 5)
00451 {
00452 if(cluster_initialize_flag == true)
00453 {
00454 exploration->clearVisitedAndSeenFrontiersFromClusters();
00455 }
00456 else
00457 {
00458
00459
00460
00461 if(robot_id == 0)
00462 ros::Duration(10).sleep();
00463
00464 exploration->sort(2);
00465 }
00466
00467 exploration->clusterFrontiers();
00468 exploration->sort(4);
00469 exploration->sort(5);
00470
00471
00472
00473 clusters_available_in_pool.clear();
00474 while(true)
00475 {
00476 final_goal.clear();
00477 goal_determined = exploration->determine_goal(4, &final_goal, count, cluster_element, &robot_str);
00478
00479 if(goal_determined == false)
00480 {
00481 ROS_INFO("Another cluster is not available, no cluster determined");
00482 break;
00483 }
00484 else
00485 {
00486 if(cluster_initialize_flag == false)
00487 {
00488
00489
00490
00491
00492 if(robot_id == 1)
00493 {
00494 ros::Duration(5).sleep();
00495 }
00496
00497 cluster_initialize_flag = true;
00498 }
00499
00500
00501
00502
00503
00504 negotiation = exploration->negotiate_Frontier(final_goal.at(0),final_goal.at(1),final_goal.at(2),final_goal.at(3),final_goal.at(4));
00505
00506 if(negotiation == true)
00507 {
00508 ROS_DEBUG("Negotiation was successful");
00509 cluster_element = final_goal.at(4);
00510 counter_waiting_for_clusters = 0;
00511 break;
00512 }
00513 else
00514 {
00515 cluster_element = final_goal.at(4);
00516 counter_waiting_for_clusters++;
00517 ROS_ERROR("Negotiation was not successful, try next cluster");
00518 }
00519 count++;
00520
00521
00522
00523
00524
00525
00526 clusters_available_in_pool.push_back(1);
00527 }
00528 }
00529
00530 }
00531 else if(frontier_selection == 6)
00532 {
00533 if(cluster_initialize_flag == true)
00534 {
00535 exploration->clearVisitedAndSeenFrontiersFromClusters();
00536 }
00537
00538 exploration->clusterFrontiers();
00539 exploration->sort(6);
00540 exploration->visualizeClustersConsole();
00541
00542 if(cluster_initialize_flag == false)
00543 {
00544 ros::Duration(2).sleep();
00545 }
00546 cluster_initialize_flag = true;
00547
00548 while(true)
00549 {
00550 goal_determined = exploration->determine_goal(4, &final_goal, count, cluster_element, &robot_str);
00551
00552 if(goal_determined == false)
00553 {
00554 break;
00555 }
00556 else
00557 {
00558
00559
00560
00561
00562 negotiation = exploration->negotiate_Frontier(final_goal.at(0),final_goal.at(1),final_goal.at(2),final_goal.at(3),final_goal.at(4));
00563
00564
00565 if(negotiation == true)
00566 {
00567 cluster_element = final_goal.at(4);
00568 break;
00569 }
00570 else
00571 {
00572 cluster_element = int(exploration->clusters.size()*rand()/(RAND_MAX));
00573 ROS_INFO("Random cluster_element: %d from available %lu clusters", cluster_element, exploration->clusters.size());
00574 }
00575 count++;
00576 }
00577 }
00578 }
00579 else if(frontier_selection == 1)
00580 {
00581 costmap_mutex.lock();
00582 if(cluster_initialize_flag == true)
00583 {
00584 exploration->clearVisitedAndSeenFrontiersFromClusters();
00585 }
00586 else
00587 {
00588
00589
00590
00591
00592 exploration->sort(2);
00593 cluster_initialize_flag = true;
00594 }
00595
00596 exploration->clusterFrontiers();
00597 exploration->sort(4);
00598 exploration->sort(5);
00599
00600 costmap_mutex.unlock();
00601
00602 exploration->visualizeClustersConsole();
00603
00604 while(true)
00605 {
00606 final_goal.clear();
00607 robot_str.clear();
00608 goal_determined = exploration->determine_goal(5, &final_goal, 0, cluster_element, &robot_str);
00609
00610 ROS_ERROR("Cluster element: %d", cluster_element);
00611
00612 int cluster_vector_position = -1;
00613
00614 if(cluster_element != -1)
00615 {
00616 if(exploration->clusters.size() > 0)
00617 {
00618 for (int i = 0; i < exploration->clusters.size(); i++)
00619 {
00620 if(exploration->clusters.at(i).id == cluster_element)
00621 {
00622 if(exploration->clusters.at(i).cluster_element.size() > 0)
00623 {
00624 cluster_vector_position = i;
00625 }
00626 break;
00627 }
00628 }
00629 }
00630 }
00631 ROS_ERROR("Cluster vector position: %d", cluster_vector_position);
00632
00633 if(cluster_vector_position >= 0)
00634 {
00635 if(exploration->clusters.at(cluster_vector_position).unreachable_frontier_count >= number_unreachable_frontiers_for_cluster)
00636 {
00637 goal_determined = false;
00638 ROS_ERROR("Cluster inoperateable");
00639 }else
00640 {
00641 ROS_ERROR("Cluster operateable");
00642 }
00643 }
00644
00645 if(goal_determined == false)
00646 {
00647
00648 ROS_INFO("No goal was determined, cluster is empty. Bid for another one");
00649
00650 final_goal.clear();
00651 robot_str.clear();
00652 clusters_available_in_pool.clear();
00653
00654 bool auctioning = exploration->auctioning(&final_goal, &clusters_available_in_pool, &robot_str);
00655 if(auctioning == true)
00656 {
00657 goal_determined = true;
00658 cluster_element = final_goal.at(4);
00659 counter_waiting_for_clusters = 0;
00660 break;
00661 }
00662 else
00663 {
00664 if(exploration->clusters.size() > 0)
00665 {
00666 ROS_INFO("No cluster was selected but other robots are operating ... waiting for new clusters");
00667 counter_waiting_for_clusters++;
00668 break;
00669 }else
00670 {
00671
00672
00673
00674
00675 ROS_ERROR("No goals are available at all");
00676 cluster_element = -1;
00677 break;
00678 }
00679 }
00680 }
00681 else
00682 {
00683 ROS_INFO("Still some goals in current cluster, finish this job first");
00684 break;
00685 }
00686 }
00687
00688 }
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 exploration->visualize_Cluster_Cells();
00700 exploration->visualize_Frontiers();
00701
00702
00703
00704
00705
00706 ROS_INFO("Navigating to Goal");
00707
00708 if(goal_determined == true)
00709 {
00710 if(OPERATE_WITH_GOAL_BACKOFF == true)
00711 {
00712 ROS_DEBUG("Doing smartGoalBackoff");
00713 backoff_sucessfull = exploration->smartGoalBackoff(final_goal.at(0),final_goal.at(1), costmap2d_global, &backoffGoal);
00714 }
00715 else
00716 {
00717 backoff_sucessfull = true;
00718 }
00719 }
00720
00721 if(backoff_sucessfull == true)
00722 {
00723 if(OPERATE_WITH_GOAL_BACKOFF == true)
00724 {
00725 ROS_INFO("Doing navigation to backoff goal");
00726 navigate_to_goal = navigate(backoffGoal);
00727 }else
00728 {
00729 ROS_INFO("Doing navigation to goal");
00730 navigate_to_goal = navigate(final_goal);
00731 }
00732 }
00733 else if(backoff_sucessfull == false && goal_determined == false)
00734 {
00735 navigate_to_goal = navigate(final_goal);
00736 goal_determined = false;
00737 }
00738
00739
00740 if(navigate_to_goal == true && goal_determined == true)
00741 {
00742 exploration->calculate_travel_path(exploration->visited_frontiers.at(exploration->visited_frontiers.size()-1).x_coordinate, exploration->visited_frontiers.at(exploration->visited_frontiers.size()-1).y_coordinate);
00743
00744 ROS_DEBUG("Storeing visited...");
00745 exploration->storeVisitedFrontier(final_goal.at(0),final_goal.at(1),final_goal.at(2),robot_str.at(0),final_goal.at(3));
00746 ROS_DEBUG("Stored Visited frontier");
00747
00748 }
00749 else if(navigate_to_goal == false && goal_determined == true)
00750 {
00751 ROS_DEBUG("Storeing unreachable...");
00752 exploration->storeUnreachableFrontier(final_goal.at(0),final_goal.at(1),final_goal.at(2),robot_str.at(0),final_goal.at(3));
00753 ROS_DEBUG("Stored unreachable frontier");
00754 }
00755
00756
00757
00758
00759
00760
00761
00762 }
00763 else
00764 {
00765 ROS_ERROR("No navigation performed");
00766 }
00767 ROS_DEBUG(" ");
00768 ROS_DEBUG(" ");
00769 }
00770 }
00771
00772 void frontiers()
00773 {
00774 ros::Rate r(5);
00775 while(ros::ok())
00776 {
00777
00778 costmap_mutex.lock();
00779
00780 exploration->clearSeenFrontiers(costmap2d_global);
00781 exploration->clearVisitedFrontiers();
00782 exploration->clearUnreachableFrontiers();
00783
00784 exploration->publish_frontier_list();
00785 exploration->publish_visited_frontier_list();
00786
00787 costmap_mutex.unlock();
00788
00789 r.sleep();
00790 }
00791 }
00792
00793
00794 void map_info()
00795 {
00796 fs_csv.open(csv_file.c_str(), std::fstream::in | std::fstream::app | std::fstream::out);
00797 fs_csv << "#time,exploration_travel_path_global,exploration_travel_path_average,global_map_progress,local_map_progress,number_of_completed_auctions, number_of_uncompleted_auctions, frontier_selection_strategy, costmap_size, unreachable_frontiers" << std::endl;
00798 fs_csv.close();
00799
00800 while(ros::ok() && exploration_finished != true)
00801 {
00802 costmap_mutex.lock();
00803
00804 ros::Duration time = ros::Time::now() - time_start;
00805 double exploration_time = time.toSec();
00806
00807 map_progress.global_freespace = global_costmap_size();
00808 map_progress.local_freespace = local_costmap_size();
00809 map_progress.time = exploration_time;
00810 map_progress_during_exploration.push_back(map_progress);
00811
00812
00813 double exploration_travel_path_global = (double)exploration->exploration_travel_path_global * 0.02;
00814 double exploration_travel_path_average = 0;
00815 if(counter != 0)
00816 {
00817 exploration_travel_path_average = (exploration->exploration_travel_path_global) / counter;
00818 }
00819
00820
00821
00822
00823
00824
00825 fs_csv.open(csv_file.c_str(), std::fstream::in | std::fstream::app | std::fstream::out);
00826
00827 fs_csv << map_progress.time << "," << exploration_travel_path_global << "," << exploration_travel_path_average << "," << map_progress.global_freespace << "," << map_progress.local_freespace << "," << global_iterattions << "," << exploration->number_of_completed_auctions << "," << exploration->number_of_uncompleted_auctions << "," << frontier_selection << "," << costmap_width << "," << exploration->unreachable_frontiers.size() << std::endl;
00828
00829
00830
00831
00832
00833
00834
00835 fs_csv.close();
00836
00837 costmap_mutex.unlock();
00838
00839
00840 map_merger::LogMaps log;
00841 log.request.log = 12;
00842 ROS_DEBUG("Calling map_merger service logOutput");
00843 if(!mm_log_client.call(log))
00844 ROS_WARN("Could not call map_merger service to store log.");
00845 ROS_DEBUG("Finished service call.");
00846
00847 save_progress();
00848
00849 ros::Duration(10.0).sleep();
00850 }
00851 }
00852
00853 int global_costmap_size()
00854 {
00855 occupancy_grid_global = costmap2d_global->getCostmap()->getCharMap();
00856 int num_map_cells_ = costmap2d_global->getCostmap()->getSizeInCellsX() * costmap2d_global->getCostmap()->getSizeInCellsY();
00857 int free = 0;
00858
00859 for (unsigned int i = 0; i < num_map_cells_; i++)
00860 {
00861 if ((int) occupancy_grid_global[i] == costmap_2d::FREE_SPACE)
00862 {
00863 free++;
00864 }
00865 }
00866 return free;
00867 }
00868
00869 int local_costmap_size()
00870 {
00871 if(OPERATE_ON_GLOBAL_MAP == false)
00872 {
00873 occupancy_grid_local = costmap2d_local->getCostmap()->getCharMap();
00874 int num_map_cells_ = costmap2d_local->getCostmap()->getSizeInCellsX() * costmap2d_local->getCostmap()->getSizeInCellsY();
00875 int free = 0;
00876
00877 for (unsigned int i = 0; i < num_map_cells_; i++)
00878 {
00879 if ((int) occupancy_grid_local[i] == costmap_2d::FREE_SPACE)
00880 {
00881 free++;
00882 }
00883 }
00884 return free;
00885 }else
00886 {
00887 occupancy_grid_local = costmap2d_local_size->getCostmap()->getCharMap();
00888 int num_map_cells_ = costmap2d_local_size->getCostmap()->getSizeInCellsX() * costmap2d_local_size->getCostmap()->getSizeInCellsY();
00889 int free = 0;
00890
00891 for (unsigned int i = 0; i < num_map_cells_; i++)
00892 {
00893 if ((int) occupancy_grid_local[i] == costmap_2d::FREE_SPACE)
00894 {
00895 free++;
00896 }
00897 }
00898 return free;
00899 }
00900 }
00901
00902 void initLogPath()
00903 {
00904
00905
00906
00907
00908
00909
00910 nh.param<std::string>("log_path",log_path,"");
00911
00912 std::stringstream robot_number;
00913 robot_number << robot_id;
00914 std::string prefix = "/robot_";
00915 std::string robo_name = prefix.append(robot_number.str());
00916
00917 log_path = log_path.append("/explorer");
00918 log_path = log_path.append(robo_name);
00919 log_path = log_path.append("/");
00920 ROS_INFO("Logging files to %s", log_path.c_str());
00921
00922 boost::filesystem::path boost_log_path(log_path.c_str());
00923 if(!boost::filesystem::exists(boost_log_path))
00924 if(!boost::filesystem::create_directories(boost_log_path))
00925 ROS_ERROR("Cannot create directory %s.", log_path.c_str());
00926
00927 }
00928
00929 void save_progress(bool final=false)
00930 {
00931 ros::Duration ros_time = ros::Time::now() - time_start;
00932
00933 double exploration_time = ros_time.toSec();
00934 int navigation_goals_required = counter;
00935 double exploration_travel_path = (double)exploration->exploration_travel_path_global * 0.02;
00936 double size_global_map = map_progress_during_exploration.at(map_progress_during_exploration.size()-1).global_freespace;
00937
00938 double efficiency_value = (exploration_time) / (number_of_robots * navigation_goals_required);
00939
00940 std::string tmp_log;
00941 if(!final)
00942 {
00943 tmp_log = log_file + std::string(".tmp");
00944 fs.open(tmp_log.c_str(), std::fstream::in | std::fstream::trunc | std::fstream::out);
00945 }
00946 else
00947 {
00948 tmp_log = log_file;
00949 fs.open(tmp_log.c_str(), std::fstream::in | std::fstream::trunc | std::fstream::out);
00950 }
00951
00952
00953
00954
00955
00956 time_t raw_time;
00957 struct tm* timeinfo;
00958 time (&raw_time);
00959 timeinfo = localtime (&raw_time);
00960
00961 fs << "[Exploration]" << std::endl;
00962 fs << "time_file_written = " << asctime(timeinfo);
00963 fs << "start_time = " << time_start << std::endl;
00964 fs << "end_time = " << ros::Time::now() << std::endl;
00965 fs << "exploration_time = " << exploration_time << std::endl;
00966 fs << "required_goals = " << navigation_goals_required << std::endl;
00967 fs << "unreachable_goals = " << exploration->unreachable_frontiers.size() << std::endl;
00968 fs << "travel_path_overall = " << exploration_travel_path << std::endl;
00969 fs << "number_of_completed_auctions = " << exploration->number_of_completed_auctions << std::endl;
00970 fs << "number_of_uncompleted_auctions = " << exploration->number_of_uncompleted_auctions << std::endl;
00971 fs << "frontier_selection_strategy = " << frontier_selection << std::endl;
00972 fs << "costmap_size = " << costmap_width << std::endl;
00973 fs << "global costmap iterations = " << global_costmap_iteration << std::endl;
00974
00975 double param_double;
00976 int param_int;
00977 std::string param;
00978
00979
00980 nh.param<int>("local_costmap/height",param_int,-1);
00981 fs << "explorer_local_costmap_height = " << param_int << std::endl;
00982
00983
00984
00985 nh.param<int>("local_costmap/width",param_int,-1);
00986 fs << "explorer_local_costmap_width = " << param_int << std::endl;
00987
00988 param = robot_prefix + "/move_base/local_costmap/height";
00989 ros::param::get(param,param_double);
00990 fs << "move_base_local_costmap_height = " << param_double << std::endl;
00991
00992 param = robot_prefix + "/move_base/local_costmap/width";
00993 ros::param::get(param,param_double);
00994 fs << "move_base_local_costmap_width = " << param_double << std::endl;
00995
00996 param = robot_prefix + "/move_base/global_costmap/obstacle_layer/raytrace_range";
00997 ros::param::get(param,param_double);
00998 fs << "move_base_raytrace_range = " << param_double << std::endl;
00999
01000 param = robot_prefix + "/move_base/global_costmap/obstacle_layer/obstacle_range";
01001 ros::param::get(param,param_double);
01002 fs << "move_base_obstacle_range = " << param_double << std::endl;
01003
01004
01005 nh.getParam("/global_costmap/obstacle_layer/raytrace_range",param_double);
01006 ros::param::get(param,param_double);
01007 fs << "explorer_raytrace_range = " << param_double << std::endl;
01008
01009
01010
01011 nh.getParam("/global_costmap/obstacle_layer/obstacle_range",param_double);
01012 fs << "explorer_obstacle_range = " << param_double << std::endl;
01013
01014 if(final)
01015 fs << "complete = " << "1" << std::endl;
01016 else
01017 fs << "complete = " << "0" << std::endl;
01018
01019 fs.close();
01020
01021
01022
01023
01024
01025
01026
01027 if(final)
01028 {
01029 map_merger::LogMaps log;
01030 log.request.log = 3;
01031 if(!mm_log_client.call(log))
01032 ROS_WARN("Could not call map_merger service to store log.");
01033 }
01034
01035 }
01036
01037 void exploration_has_finished()
01038 {
01039 ros::Duration ros_time = ros::Time::now() - time_start;
01040
01041 double exploration_time = ros_time.toSec();
01042 int navigation_goals_required = counter;
01043 double exploration_travel_path = (double)exploration->exploration_travel_path_global * 0.02;
01044 double size_global_map = map_progress_during_exploration.at(map_progress_during_exploration.size()-1).global_freespace;
01045 ROS_INFO("overall freespace in the global map: %f", size_global_map);
01046
01047 for(int i = 0; i< map_progress_during_exploration.size(); i++)
01048 {
01049 ROS_INFO("map progress: %f",(map_progress_during_exploration.at(i).global_freespace/size_global_map)*100);
01050 }
01051
01052 ROS_DEBUG("******************************************");
01053 ROS_DEBUG("******************************************");
01054 ROS_DEBUG("TIME: %f sec GOALS: %d PATH: %f COMPLETED AUCTIONS: %d UNCOMPLETED AUCTIONS: %d", exploration_time, navigation_goals_required, exploration_travel_path, exploration->number_of_completed_auctions, exploration->number_of_uncompleted_auctions);
01055 ROS_DEBUG("******************************************");
01056 ROS_DEBUG("******************************************");
01057
01058
01059 double efficiency_value = (exploration_time) / (number_of_robots * navigation_goals_required);
01060
01061
01062
01063
01064
01065 save_progress(true);
01066 ROS_INFO("Wrote file %s\n", log_file.c_str());
01067
01068
01069
01070
01071
01072
01073 map_merger::LogMaps log;
01074 log.request.log = 3;
01075 if(!mm_log_client.call(log))
01076 ROS_WARN("Could not call map_merger service to store log.");
01077
01078
01079
01080 this->indicateSimulationEnd();
01081
01082
01083
01084
01085
01086 }
01087
01088 void indicateSimulationEnd()
01089 {
01091 std::stringstream robot_number;
01092 robot_number << robot_id;
01093
01094 std::string prefix = "/robot_";
01095 std::string status_directory = "/simulation_status";
01096 std::string robo_name = prefix.append(robot_number.str());
01097 std::string file_suffix(".finished");
01098
01099 std::string ros_package_path = ros::package::getPath("multi_robot_analyzer");
01100 std::string status_path = ros_package_path + status_directory;
01101 std::string status_file = status_path + robo_name + file_suffix;
01102
01104 boost::filesystem::path boost_status_path(status_path.c_str());
01105 if(!boost::filesystem::exists(boost_status_path))
01106 if(!boost::filesystem::create_directories(boost_status_path))
01107 ROS_ERROR("Cannot create directory %s.", status_path.c_str());
01108 std::ofstream outfile(status_file.c_str());
01109 outfile.close();
01110 ROS_INFO("Creating file %s to indicate end of exploration.", status_file.c_str());
01111
01112
01113 }
01114
01115
01116 bool iterate_global_costmap(std::vector<double> *global_goal, std::vector<std::string> *robot_str)
01117 {
01118 global_costmap_iteration++;
01119 int counter = 0;
01120 bool exploration_flag;
01121
01122 costmap_mutex.lock();
01123
01124 exploration->transformToOwnCoordinates_frontiers();
01125 exploration->transformToOwnCoordinates_visited_frontiers();
01126
01127
01128 exploration->initialize_planner("exploration planner", costmap2d_global, costmap2d_global);
01129 exploration->findFrontiers();
01130
01131
01132 exploration->clearVisitedFrontiers();
01133 exploration->clearUnreachableFrontiers();
01134 exploration->clearSeenFrontiers(costmap2d_global);
01135
01136 costmap_mutex.unlock();
01137
01138 exploration->visualize_Frontiers();
01139
01140 if(frontier_selection < 5 && frontier_selection != 1)
01141 {
01142 exploration->sort(2);
01143
01144 while(true)
01145 {
01146 exploration_flag = exploration->determine_goal(2, global_goal, counter, -1, robot_str);
01147
01148
01149 if(exploration_flag == false)
01150 {
01151 break;
01152 }
01153 else
01154 {
01155 bool negotiation = true;
01156 negotiation = exploration->negotiate_Frontier(global_goal->at(0),global_goal->at(1),global_goal->at(2),global_goal->at(3), -1);
01157
01158 if(negotiation == true)
01159 {
01160 return true;
01161 break;
01162 }
01163 counter++;
01164 }
01165 }
01166 }else if(frontier_selection == 1 || frontier_selection == 6 || frontier_selection == 5)
01167 {
01168 costmap_mutex.lock();
01169 exploration->clearVisitedAndSeenFrontiersFromClusters();
01170
01171 exploration->clusterFrontiers();
01172
01173 exploration->sort(4);
01174 exploration->sort(5);
01175
01176 costmap_mutex.unlock();
01177
01178
01179
01180 cluster_element = -1;
01181
01182 while(true)
01183 {
01184 std::vector<double> goal_vector;
01185 std::vector<std::string> robot_str_name;
01186 std::vector<int> clusters_used_by_others;
01187
01188 goal_determined = exploration->determine_goal(5, &goal_vector, 0, cluster_element, robot_str);
01189
01190 if(goal_determined == false)
01191 {
01192 ROS_INFO("No goal was determined, cluster is empty. Bid for another one");
01193
01194 goal_vector.clear();
01195 bool auctioning = exploration->auctioning(&goal_vector, &clusters_used_by_others, &robot_str_name);
01196 if(auctioning == true)
01197 {
01198 goal_determined = true;
01199 cluster_element = goal_vector.at(4);
01200
01201 global_goal->push_back(goal_vector.at(0));
01202 global_goal->push_back(goal_vector.at(1));
01203 global_goal->push_back(goal_vector.at(2));
01204 global_goal->push_back(goal_vector.at(3));
01205 global_goal->push_back(goal_vector.at(4));
01206
01207 robot_str->push_back(robot_str_name.at(0));
01208 return true;
01209 }
01210 else
01211 {
01212
01213
01214
01215
01216 ROS_ERROR("No goals are available at all");
01217 cluster_element = -1;
01218 break;
01219 }
01220 }
01221 else
01222 {
01223 ROS_INFO("Still some goals in current cluster, finish this job first");
01224 break;
01225 }
01226 }
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265 exploration->visualize_Cluster_Cells();
01266 }
01267
01268
01269
01270
01271 global_iterattions++;
01272 return false;
01273 }
01274
01275
01276 bool navigate(std::vector<double> goal) {
01277
01278
01279
01280
01281
01282
01283
01284 bool completed_navigation = false;
01285 if (goal_determined == true)
01286 {
01287 visualize_goal_point(goal.at(0), goal.at(1));
01288
01289 counter++;
01290 ROS_INFO("GOAL %d: x: %f y: %f", counter, goal.at(0), goal.at(1));
01291 completed_navigation = move_robot(counter, goal.at(0), goal.at(1));
01292 rotation_counter = 0;
01293 }
01294 else
01295 {
01296 rotation_counter++;
01297
01298 ROS_INFO("In navigation .... cluster_available: %lu counter: %d", exploration->clusters.size(), counter_waiting_for_clusters);
01299
01300 if(exploration->clusters.size() == 0 || counter_waiting_for_clusters > 10)
01301 {
01302 ROS_INFO("Iterating over GLOBAL COSTMAP to find a goal!!!!");
01303 std::vector<double> global_goal;
01304 std::vector<std::string> robot_str;
01305 bool global_costmap_goal = iterate_global_costmap(&global_goal, &robot_str);
01306
01307 if(global_costmap_goal == false)
01308 {
01309
01310
01311
01312 counter++;
01313 ROS_INFO("GOAL %d: BACK TO HOME x: %f y: %f", counter, home_point_x, home_point_y);
01314
01315
01316
01317
01318
01319
01320
01321
01322 exploration_has_finished();
01323 visualize_goal_point(home_point_x, home_point_y);
01324 completed_navigation = false;
01325 for(int i = 0; i< 5; i++)
01326 {
01327 if(completed_navigation == false)
01328 {
01329 completed_navigation = move_robot(counter, home_point_x, home_point_y);
01330 }
01331 else
01332 {
01333 break;
01334 }
01335 }
01336
01337 exploration_finished = true;
01338
01339
01340
01341
01342 }else
01343 {
01344 counter++;
01345 ROS_INFO("GOAL %d: x: %f y: %f", counter, global_goal.at(0), global_goal.at(1));
01346 std::vector<double> backoffGoal;
01347 bool backoff_sucessfull = exploration->smartGoalBackoff(global_goal.at(0),global_goal.at(1), costmap2d_global, &backoffGoal);
01348
01349 if(backoff_sucessfull == true)
01350 {
01351 ROS_DEBUG("doing navigation to back-off goal");
01352 visualize_goal_point(backoffGoal.at(0), backoffGoal.at(1));
01353 completed_navigation = move_robot(counter, backoffGoal.at(0), backoffGoal.at(1));
01354 rotation_counter = 0;
01355 if(completed_navigation == true)
01356 {
01357 exploration->calculate_travel_path(exploration->visited_frontiers.at(exploration->visited_frontiers.size()-1).x_coordinate, exploration->visited_frontiers.at(exploration->visited_frontiers.size()-1).y_coordinate);
01358
01359 ROS_INFO("Storing visited...");
01360 exploration->storeVisitedFrontier(global_goal.at(0),global_goal.at(1),global_goal.at(2),robot_str.at(0), global_goal.at(3));
01361 ROS_INFO("Stored Visited frontier");
01362 }
01363 else
01364 {
01365 ROS_INFO("Storing unreachable...");
01366 exploration->storeUnreachableFrontier(global_goal.at(0),global_goal.at(1),global_goal.at(2),robot_str.at(0), global_goal.at(3));
01367 ROS_INFO("Stored unreachable frontier");
01368 }
01369 }
01370 else if(backoff_sucessfull == false)
01371 {
01372 ROS_ERROR("Navigation to global costmap back-off goal not possible");
01373 ROS_INFO("Storing as unreachable...");
01374 exploration->storeUnreachableFrontier(global_goal.at(0),global_goal.at(1),global_goal.at(2), robot_str.at(0), global_goal.at(3));
01375 ROS_INFO("Stored unreachable frontier");
01376 }
01377 }
01378 }else
01379 {
01380 counter++;
01381 ROS_INFO("GOAL %d: rotation", counter);
01382 completed_navigation = turn_robot(counter);
01383 }
01384 }
01385 return(completed_navigation);
01386 }
01387
01388 void visualize_goal_point(double x, double y) {
01389
01390 goalPoint.header.seq = goal_point_message++;
01391 goalPoint.header.stamp = ros::Time::now();
01392 goalPoint.header.frame_id = move_base_frame;
01393 goalPoint.point.x = x;
01394 goalPoint.point.y = y;
01395
01396 ros::NodeHandle nh_Point("goalPoint");
01397 pub_Point = nh_Point.advertise < geometry_msgs::PointStamped
01398 > ("goalPoint", 100, true);
01399 pub_Point.publish < geometry_msgs::PointStamped > (goalPoint);
01400 }
01401
01402 void visualize_home_point() {
01403
01404 homePoint.header.seq = home_point_message++;
01405 homePoint.header.stamp = ros::Time::now();
01406 homePoint.header.frame_id = move_base_frame;
01407 home_point_x = robotPose.getOrigin().getX();
01408 home_point_y = robotPose.getOrigin().getY();
01409 homePoint.point.x = home_point_x;
01410 homePoint.point.y = home_point_y;
01411
01412 ros::NodeHandle nh("homePoint");
01413 pub_home_Point = nh.advertise < geometry_msgs::PointStamped
01414 > ("homePoint", 100, true);
01415 pub_home_Point.publish < geometry_msgs::PointStamped > (homePoint);
01416
01417 }
01418
01419 bool move_robot(int seq, double position_x, double position_y) {
01420
01421 exploration->next_auction_position_x = position_x;
01422 exploration->next_auction_position_y = position_y;
01423
01424
01425
01426
01427
01428
01429 if (!costmap2d_local->getRobotPose(robotPose)) {
01430 ROS_ERROR("Failed to get RobotPose");
01431 }
01432
01433 actionlib::SimpleActionClient < move_base_msgs::MoveBaseAction
01434 > ac("move_base", true);
01435
01436 while (!ac.waitForServer(ros::Duration(10.0)))
01437 ;
01438
01439 move_base_msgs::MoveBaseGoal goal_msgs;
01440
01441 goal_msgs.target_pose.header.seq = seq;
01442
01443 goal_msgs.target_pose.header.frame_id = move_base_frame;
01444 goal_msgs.target_pose.pose.position.x = position_x;
01445 goal_msgs.target_pose.pose.position.y = position_y;
01446 goal_msgs.target_pose.pose.position.z = 0;
01447 goal_msgs.target_pose.pose.orientation.x = 0;
01448 goal_msgs.target_pose.pose.orientation.y = 0;
01449 goal_msgs.target_pose.pose.orientation.z = 0;
01450 goal_msgs.target_pose.pose.orientation.w = 1;
01451
01452 ac.sendGoal(goal_msgs);
01453
01454
01455 ac.waitForResult(ros::Duration(waitForResult));
01456 while (ac.getState() == actionlib::SimpleClientGoalState::PENDING)
01457 {
01458 ros::Duration(0.5).sleep();
01459 }
01460 ROS_INFO("Not longer PENDING");
01461
01462 while (ac.getState() == actionlib::SimpleClientGoalState::ACTIVE)
01463 {
01464 ros::Duration(0.5).sleep();
01465 }
01466 ROS_INFO("Not longer ACTIVE");
01467
01468 while (ac.getState() != actionlib::SimpleClientGoalState::SUCCEEDED) {
01469 if (ac.getState() == actionlib::SimpleClientGoalState::ABORTED) {
01470 ROS_INFO("ABORTED");
01471
01472 exploration->next_auction_position_x = robotPose.getOrigin().getX();
01473 exploration->next_auction_position_y = robotPose.getOrigin().getY();
01474 return false;
01475 }
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489 }
01490 ROS_INFO("TARGET REACHED");
01491
01492 exploration->next_auction_position_x = robotPose.getOrigin().getX();
01493 exploration->next_auction_position_y = robotPose.getOrigin().getY();
01494 return true;
01495 }
01496
01497 bool turn_robot(int seq) {
01498
01499 double angle = 45;
01500
01501 if (!costmap2d_local->getRobotPose(robotPose)) {
01502 ROS_ERROR("Failed to get RobotPose");
01503 }
01504
01505 actionlib::SimpleActionClient < move_base_msgs::MoveBaseAction
01506 > ac("move_base", true);
01507 while (!ac.waitForServer(ros::Duration(10.0)))
01508 ;
01509
01510 move_base_msgs::MoveBaseGoal goal_msgs;
01511
01512 goal_msgs.target_pose.header.seq = seq;
01513 goal_msgs.target_pose.header.stamp = ros::Time::now();
01514
01515 goal_msgs.target_pose.header.frame_id = move_base_frame;
01516 goal_msgs.target_pose.pose.position.x = robotPose.getOrigin().getX();
01517 goal_msgs.target_pose.pose.position.y = robotPose.getOrigin().getY();
01518 goal_msgs.target_pose.pose.position.z = 0;
01519 goal_msgs.target_pose.pose.orientation.x = 0;
01520 goal_msgs.target_pose.pose.orientation.y = 0;
01521 goal_msgs.target_pose.pose.orientation.z = sin(angle / 2);
01522 goal_msgs.target_pose.pose.orientation.w = cos(angle / 2);
01523
01524 ac.sendGoal(goal_msgs);
01525 ac.waitForResult(ros::Duration(waitForResult));
01526
01527 while (ac.getState() == actionlib::SimpleClientGoalState::PENDING)
01528 {
01529 ros::Duration(0.5).sleep();
01530 }
01531 ROS_INFO("Not longer PENDING");
01532
01533 while (ac.getState() == actionlib::SimpleClientGoalState::ACTIVE)
01534 {
01535 ros::Duration(0.5).sleep();
01536 }
01537 ROS_INFO("Not longer ACTIVE");
01538
01539 while (ac.getState() != actionlib::SimpleClientGoalState::SUCCEEDED) {
01540 if (ac.getState() == actionlib::SimpleClientGoalState::ABORTED) {
01541 ROS_INFO("ABORTED");
01542 return false;
01543 }
01544 }
01545 ROS_INFO("ROTATION ACCOMBLISHED");
01546 return true;
01547 }
01548
01549 void feedbackCallback(
01550 const move_base_msgs::MoveBaseActionFeedback::ConstPtr& msg) {
01551 feedback_value = msg.get()->status.status;
01552 feedback_succeed_value =
01553 msg.get()->feedback.base_position.pose.orientation.w;
01554
01555 }
01556
01557 bool target_reached(void) {
01558
01559 ros::NodeHandle nh_sub_move_base;
01560 sub_move_base = nh_sub_move_base.subscribe("feedback", 1000,
01561 &Explorer::feedbackCallback, this);
01562
01563 while (feedback_value != feedback_succeed_value)
01564 ;
01565
01566 return true;
01567 }
01568
01569 public:
01570
01571 struct map_progress_t
01572 {
01573 double local_freespace;
01574 double global_freespace;
01575 double time;
01576 } map_progress;
01577
01578 ros::Subscriber sub_move_base, sub_obstacle;
01579
01580
01581 costmap_2d::Costmap2DROS* costmap2d_local;
01582 costmap_2d::Costmap2DROS* costmap2d_local_size;
01583 costmap_2d::Costmap2DROS* costmap2d_global;
01584 costmap_2d::Costmap2D costmap;
01585
01586 std::vector<map_progress_t> map_progress_during_exploration;
01587
01588 std::vector<int> clusters_available_in_pool;
01589
01590 int home_position_x, home_position_y;
01591 int robot_id, number_of_robots;
01592 int frontier_selection, costmap_width, global_costmap_iteration, number_unreachable_frontiers_for_cluster;
01593 int counter_waiting_for_clusters;
01594
01595 double robot_home_position_x, robot_home_position_y;
01596 bool Simulation, goal_determined;
01597 bool robot_prefix_empty;
01598 int accessing_cluster, cluster_element_size, cluster_element;
01599 int global_iterattions;
01600 bool cluster_flag, cluster_initialize_flag;
01601 int global_iterations_counter;
01602 int waitForResult;
01603 std::string move_base_frame;
01604 std::string robot_prefix;
01605 std::string robot_name;
01606 const unsigned char* occupancy_grid_global;
01607 const unsigned char* occupancy_grid_local;
01608
01609 std::string csv_file, log_file;
01610 std::string log_path;
01611 std::fstream fs_csv, fs;
01612
01613 private:
01614
01615 ros::Publisher pub_move_base;
01616 ros::Publisher pub_Point;
01617 ros::Publisher pub_home_Point;
01618 ros::Publisher pub_frontiers;
01619
01620 ros::ServiceClient mm_log_client;
01621
01622 ros::NodeHandle nh;
01623 ros::Time time_start;
01624
01625
01626 move_base_msgs::MoveBaseActionGoal action_goal_msg;
01627 move_base_msgs::MoveBaseActionFeedback feedback_msgs;
01628
01629
01630 geometry_msgs::PointStamped goalPoint;
01631 geometry_msgs::PointStamped homePoint;
01632
01633 std::vector<geometry_msgs::PoseStamped> goals;
01634 tf::Stamped<tf::Pose> robotPose;
01635
01636 explorationPlanner::ExplorationPlanner *exploration;
01637
01638 double x_val, y_val, home_point_x, home_point_y;
01639 int seq, feedback_value, feedback_succeed_value, rotation_counter,
01640 home_point_message, goal_point_message;
01641 int counter;
01642 bool pioneer, exploration_finished;
01643 };
01644
01645 int main(int argc, char **argv) {
01646
01647
01648
01649
01650
01651 ros::init(argc, argv, "simple_navigation");
01652
01653
01654
01655 tf::TransformListener tf(ros::Duration(10));
01656 Explorer simple(tf);
01657
01658
01659
01660
01661
01662
01663
01664 boost::thread thr_explore(boost::bind(&Explorer::explore, &simple));
01665
01666
01667
01668
01669
01670 boost::thread thr_map(boost::bind(&Explorer::map_info, &simple));
01671
01672
01673
01674
01675
01676
01677
01678 while (ros::ok()) {
01679
01680 costmap_mutex.lock();
01681 ros::spinOnce();
01682 costmap_mutex.unlock();
01683
01684
01685 ros::Duration(0.1).sleep();
01686 }
01687
01688 thr_explore.interrupt();
01689 thr_map.interrupt();
01690
01691
01692 thr_explore.join();
01693 thr_map.join();
01694
01695
01696 return 0;
01697 }