MRXT: The Multi-Robot eXploration Tool
Multi-Robot autonomous exploration and mapping simulator.
src/architecture/planner/IGPlanner.cpp
00001 
00002 #include "IGPlanner.h"
00003 #include "gridMapInterface.h"
00004 #include <fstream>
00005 #include <math.h>
00006 #include <stdio.h>
00007 #include <list>
00008 #include <vector>
00009 #include <opencv2/opencv.hpp>
00010 #include "StringTokenizer.h"
00011 
00012 // Para registrar la clase en la factoria
00013 namespace planners{
00014         planner* CreateInformationGainPlanner(const ConfigFile& conf){
00015                 return new InformationGainPlanner(conf);
00016         };
00017         const int IGPLANNER = 3 ;
00018         const bool registered = plannerFactory::Instance().Register(IGPLANNER, plannerCreator(CreateInformationGainPlanner));
00019 }
00020 
00021 
00022 using namespace std;
00023 
00024 // Constructor
00025 InformationGainPlanner::InformationGainPlanner(const ConfigFile& config):
00026         planner(),
00027         endPlanner(true),
00028         replanning_period(config.read<float>("REPLANNING_PERIOD")),
00029         inflate_obstacles(config.read<int>("INFLATE_OBSTACLES")),
00030         utility_radius(config.read<float>("UTILITY_RADIUS")),
00031         utility_weight(config.read<float>("UTILITY_WEIGHT")),
00032         cost_weight(config.read<float>("COST_WEIGHT"))
00033 {}
00034 
00035 // Destructor
00036 InformationGainPlanner::~InformationGainPlanner(){stop();}
00037 
00038 // thread Setup
00039 int InformationGainPlanner::setup(){
00040 
00041 //      printf("arranco planificador\n");
00042         completedPath = true;
00043         prio = 50;
00044         return 0;
00045 }
00046 
00047 // thread on stop
00048 void InformationGainPlanner::onStop(){
00049         if (!endPlanner){
00050                 endPlanner = true;
00051                 closing.lock();
00052                 closing.unlock();
00053         }
00054         printf("[CU-PLANNER] [robot %d] Stopped\n", rbase->getNumber());
00055 }
00056 
00057 // thread main execution
00058 void InformationGainPlanner::execute(){
00059         printf("[CU-PLANNER] \t\t\t\t\t\t COST-UTILITY PLANNER (%d) running\n", rbase->getNumber());
00060         closing.lock();
00061         endPlanner = false;
00062         point goal;     
00063         int nextStep=number;
00064         
00065         FILE* plannerlog=0;
00066         if (logstr){
00067                 char myfilestr[100];
00068                 sprintf(myfilestr,"%splanR%d.log",logstr,number);       
00069                 plannerlog = fopen(myfilestr,"w");
00070         }
00071 
00072 //      char mywindowstr[250];
00073 //      if (showPlanner){
00074 //              sprintf(mywindowstr,"plan%d.jpg",number);
00075 //              cvNamedWindow(mywindowstr,0);
00076 //      }
00077 //      
00078         bool endExploration = false;
00079         int nextPlanning=0;
00080         while(!endPlanner && !endExploration){
00081                 
00082                 // esperamos a SLAM
00083                 nextStep=mySlam->getStep()+1;
00084                 //printf("[CU-PLANNER] [robot %d planner] waiting for step %d\n", number, nextStep);
00085                 mySlam->waitForStep(nextStep);
00086 
00087                 if (nextStep > 20000) endExploration = true;
00088 
00089                 // tomamos los datos
00090                 gridMapInterface* omap          = mySlam->getOMap();
00091                 binMap* ppmap                   = mySlam->getPreMap();
00092                 //int numrobots                 = mySlam->getNumRobots();
00093                 point poscell                   = mySlam->getCell(number);
00094                 pose robotpos                   = mySlam->getPos(number);
00095                 
00096                 // celda con orientacion
00097 //              ocell ori;
00098 //              ori.x = poscell.x;
00099 //              ori.y = poscell.y;
00100 //              float ang = robotpos.th;
00101 //              ori.th = int(floor(ang/(PI/4)+0.5));
00102 //              if (ori.th > 7) ori.th -=8;
00103 //              if (ori.th < 0) ori.th +=8;
00104 
00105                 IplImage* im = (showPlanner)? omap->getMapAsImage():0;
00106 
00107                 // leer mensajes
00108                 string msg;
00109                 int msglen;
00110                 while((msglen=getMessage(msg))){
00111                         //cout << "Message: >> " << msg << endl;
00112                         StringTokenizer st(&msg[0]);
00113                         string messagetype(st.nextToken());
00114                         if (messagetype == "END"){
00115                                 endExploration = true;
00116                                 completedPath = true;
00117                         }
00118                 }
00119 
00120                 bool obstructedPath;
00121 
00122                 // si hemos llegado al ultimo destino planificamos
00123                 if(completedPath == true  || nextStep == nextPlanning){
00124                         nextPlanning = nextStep + (int)floor(replanning_period/mySlam->getSampleTime()+0.5);
00125                         completedPath = false;
00126 //                      printf("[IGPLANNER] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLANNING >>>> robot %d\n",number);
00127                         // mapa de fronteras
00128                         binMap objectives;
00129                         vector<clusterCell> clusterList;
00130                         omap->frontiers(objectives);
00131                         objectives.cluster(clusterList,2*inflate_obstacles);
00132                         objectives.set(clusterList);
00133                         //objectives.showMap("FRONTERAS");
00134                         
00135                         // mapa de costes
00136                         vector<point> targets;
00137                         vector<point>::iterator targetIter;
00138 //                      printf("[IGPLANNER] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Creating COST MAP !!!!!!!!!!!\n");
00139                         costMapSimple* cm = createCostMap(poscell,objectives,*omap,targets,inflate_obstacles);
00140 //                      printf("[IGPLANNER] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> COSTMAP Created !!!!!!!!!!!!!\n");
00141                         
00142 //                      printf("[IGPLANNER] Número de objetivos: %d\n",(int)targets.size());
00143                         
00144                         // elegir destino
00145                         point dest = poscell;
00146                         float maxVal =  -9999999999999.9f;
00147                         int util_cells = ((int)floor(utility_radius/omap->getResolution()+0.5));
00148                         float maxutility =  util_cells*util_cells*PI;
00149                         float maxcost = cm->getMaxCost();
00150                         for (targetIter = targets.begin(); targetIter!= targets.end(); targetIter++){
00151                                 if (targetIter->x!=poscell.x && targetIter->y != poscell.y){
00152                                         binMap esz;
00153                                         omap->esz(targetIter->x,targetIter->y,esz,0,util_cells);
00154                                         float utilvalue = utility(*omap,esz);
00155                                         float cost = cm->getCost(targetIter->x,targetIter->y);
00156                                         float value = utility_weight*utilvalue/maxutility - cost_weight*cost/maxcost;
00157                                         //printf("(%d,%d) value = %f, utility = %f, cost= %f \n",targetIter->x,targetIter->y,value,utilvalue, cost);
00158                                         if (value > maxVal){
00159                                                 maxVal = value;
00160                                                 dest = *targetIter;
00161                                         }
00162                                 }
00163                         }
00164                         
00165                         // recuperar el path
00166                         //printf("origen  (%d,%d,%d)\n",ori.x,ori.y,ori.th);
00167                         //printf("destino (%d,%d,%d)\n",dest.x,dest.y,dest.th);
00168                         cm->getPath(dest,path);
00169                         delete cm;
00170                         
00171                         if (targets.size()==0){
00172 //                              printf("[IGPLANNER] No path to frontiers, stopping exploration\n");
00173                                 endExploration = true;
00174                                 completedPath = true;
00175                                 char sms[100];
00176                                 sprintf(sms,"END %d", getDir()); 
00177                                 sendMessage(string(sms),-1);
00178                         }
00179 //                      printf("[IGPLANNER] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLANNING END >>>> robot %d\n",number);
00180                 }
00181 
00182                 // Seguimos con la ruta
00183                 else {
00184         
00185                         // verificamos que el path sea transitable
00186                         bool obstructedPath = false;
00187                         vector<point>::reverse_iterator riter;
00188                         if(path.size()>1) { 
00189                                 for ( riter = path.rbegin(); riter != path.rend(); riter++ )
00190                                         if (omap->isoccupied(riter->x,riter->y)) { 
00191 //                                              printf("[IGPLANNER] [robot %d] obstructed\n",rbase->getNumber()); 
00192                                                 obstructedPath = true;
00193                                                 break;
00194                                         }
00195                         }
00196                         // verificar distancia al destino || obstruccion para path completado
00197                         if((sqrt(pow((float)(path.front().x-poscell.x),2) + pow((float)(path.front().y-poscell.y),2)) <= 3.0)  || obstructedPath){
00198 //                              printf("[IGPLANNER] [robot %d] completed\n",rbase->getNumber()); 
00199                                 completedPath = true;
00200                         }
00201                         else { // No hemos llegado al final seguimos avanzando
00202                                 bool found=false;                               
00203 
00204                                 //IplImage* im = (showPlanner)? omap->getMapAsImage() : 0;
00205                                 //if (showPlanner){
00206                                 //      cvCircle(im,cvPoint(poscell.x, omap->getHeight()-1-poscell.y),0,CV_RGB(255,0,0),-1); //posicion rojo    
00207                                 //      for (unsigned int i = 0;i < path.size(); i++)
00208                                 //              cvCircle(im,cvPoint(path[i].x, omap->getHeight()-1-path[i].y),0,CV_RGB(255,0,255),-1); // path magenta
00209                                 //      cvShowImage(mywindowstr,im);
00210                                 //}
00211                                 
00212                                 if(path.size()>=1) {
00213                                         for ( riter = path.rbegin(); riter != path.rend(); riter++ ){
00214                                                 bool visible = true;
00215                                                 int size;
00216                                                 point* line = omap->getLine(poscell.x,poscell.y,riter->x,riter->y,size);
00217                                                 
00218                                                 for (int p = 0; p < size; p++){
00219                                                         if (p > 1 && omap->isoccupied(line[p].x,line[p].y,1)){ 
00220                                                                 visible = false; 
00221                                                                 break;
00222                                                         }
00223                                                 //      else
00224                                                 //              cvCircle(im,cvPoint(line[p].x, omap->getHeight()-1-line[p].y),0,CV_RGB(0,255,0),-1); // visual green
00225                                                 }
00226                                                 //cvShowImage(mywindowstr,im);
00227                                                 //cvWaitKey(2);
00228                                                 delete [] line;
00229                                                 if (visible) { // is visible
00230                                                         goal.x = riter->x;
00231                                                         goal.y = riter->y;
00232                                                         if (found) path.pop_back();
00233                                                         else found = true;
00234                                                         //path.pop_back();
00235                                                         double dist = sqrt(pow(poscell.x-goal.x,2) + pow(poscell.y-goal.y,2));
00236                                                         if ( dist > 1.5/omap->getResolution()) break;
00237                                                 }
00238                                                 else break;
00239                                         }
00240                                 }
00241                                 if(!found){
00242                                         completedPath = true;  // algo falla ninguna celda de la ruta es visible
00243 //                                      printf("[IGPLANNER] [robot %d] no visible cells\n",rbase->getNumber()); 
00244                                 }
00245                                 //if (showPlanner) cvReleaseImage(&im);
00246 
00247                         }
00248 //                      printf("[IGPLANNER] [robot %d] next goal: (%d,%d) - current pos (%d,%d)\n",rbase->getNumber(),goal.x, goal.y, ori.x,ori.y);                                             
00249                 }
00250 
00251 
00252                 // visualizacion
00253 //              if (showPlanner){
00254 //                      cvCircle(im,cvPoint(poscell.x, omap->getHeight()-1-poscell.y),0,CV_RGB(255,0,0),-1); //posicion rojo
00255 //                      cvCircle(im,cvPoint(poscell.x+avancex[ori.th], omap->getHeight()-1-poscell.y-avancey[ori.th]),0,CV_RGB(0,0,255),-1); // orientacion azul
00256 //                      for (unsigned int i = 0;i < path.size(); i++)
00257 //                              cvCircle(im,cvPoint(path[i].x, omap->getHeight()-1-path[i].y),0,CV_RGB(255,0,255),-1); // path magenta
00258 //                      cvShowImage(mywindowstr,im);
00259 //                      cvWaitKey(5);
00260 //                      cvReleaseImage(&im);
00261 //              }
00262                 
00263                 if (omap) delete omap;
00264                 if (ppmap) delete ppmap;
00265 
00266                 //      modificar los enables/goal de la parte reactiva
00267                 if (completedPath)      reac->disableAll();                             // paramos el robot hasta planificar de nuevo
00268                 else{
00269 //                      printf("************************************** [robot %d] Following Path\n",number);
00270 
00271                         reac->setGoal(goal);
00272                         reac->enableGoToGoal();
00273                         reac->enableAvoidObstacles();                                   
00274                         reac->disableAvoidOtherRobots();
00275                         reac->disableGoToFrontier();
00276                         reac->disableGoToUnexploredZones();
00277                         reac->disableGoToPrecisePoses();        
00278                 }
00279 
00280                 // write logs
00281                 if (logstr)     fprintf(plannerlog,"%d, %d, %d, %d\n", nextStep, completedPath, poscell.x, poscell.y);
00282         }
00283 
00284 //      if (showPlanner) cvDestroyWindow(mywindowstr);
00285 
00286         //closing logs
00287         if (logstr)     fclose(plannerlog);
00288 
00289 //      printf("[robot %d] stoping robot", number);
00290         reac->disableAll();
00291         reac->stop();
00292 
00293         closing.unlock();
00294         explorationFinished.step();
00295 }
00296 
00297 
00298 int InformationGainPlanner::utility(const gridMapInterface& omap, const binMap& esz){
00299         int value=0;    
00300         for (int i = esz.getRoi().x ; i < esz.getRoi().x + esz.getRoi().width ; i++){
00301                 for (int j = esz.getRoi().y ; j < esz.getRoi().y + esz.getRoi().height ; j++){   // for each cell
00302                         if (esz.get(i,j) && omap.isunknown(i,j)){
00303                                 value++;
00304                         }
00305                 }
00306         }
00307         return value;
00308 }
 All Classes Functions Variables Typedefs