MRXT: The Multi-Robot eXploration Tool
Multi-Robot autonomous exploration and mapping simulator.
src/architecture/planner/FSAPlanner.cpp
00001 
00002 #include "FSAPlanner.h"
00003 #include "gridMapInterface.h"
00004 #include <fstream>
00005 #include <math.h>
00006 #include <stdio.h>
00007 #include <list>
00008 #include <vector>
00009 #include <algorithm>
00010 #include <opencv2/opencv.hpp>
00011 #include "pathPlanning.h"
00012 #include "StringTokenizer.h"
00013 
00014 // Para registrar la clase en la factoria
00015 namespace planners{
00016         planner* CreateFSAPlanner(const ConfigFile& conf){
00017                 return new FSAPlanner(conf);
00018         };
00019         const int FSAPLANNER =  1 ;
00020         const bool registered = plannerFactory::Instance().Register(FSAPLANNER, plannerCreator(CreateFSAPlanner));
00021 }
00022 
00023 
00024 using namespace std;
00025 
00026 // constructor
00027 FSAPlanner::FSAPlanner(const ConfigFile& config):       
00028         planner(),
00029         inflate_obstacles(config.read<int>("INFLATE_OBSTACLES")),
00030         integrate_slam(config.read<bool>("INTEGRATE_SLAM")),
00031         escape_allowed(config.read<bool>("ESCAPE_FROM_LOCAL_MINIMA")),
00032         endPlanner(true)
00033 {}
00034 
00035 // destructor
00036 FSAPlanner::~FSAPlanner(){stop();}
00037 
00038 // thread setup
00039 int FSAPlanner::setup(){
00040 //      printf("arranco planificador\n");
00041         prio = 50;
00042         completedPath = true;
00043         return 0;
00044 }
00045 
00046 // thread on stop
00047 void FSAPlanner::onStop(){
00048         if (!endPlanner){
00049                 endPlanner = true;
00050                 closing.lock();
00051                 closing.unlock();
00052         }
00053         printf("[BEHAVIOUR_BASED_PLANNER] [robot %d] Stopped\n", rbase->getNumber());
00054 }
00055 
00056 // thread main code
00057 void FSAPlanner::execute(){
00058         printf("[BEHAVIOUR_BASED_PLANNER] \t\t\t\t BEHAVIOUR_BASED_PLANNER (%d) running\n", rbase->getNumber());
00059         closing.lock();
00060         endPlanner = false;
00061         point goal;
00062         int nextStep=number;
00063 
00064         // initial state
00065         exploring = true;
00066         returning = false;
00067         escapingFromLocalMinimum = false;
00068         returningEscape = false;
00069 
00070         // init logs
00071         FILE* plannerlog=0;
00072         if (logstr){
00073                 char myfilestr[100];
00074                 sprintf(myfilestr,"%splanR%d.log",logstr,number);
00075                 plannerlog = fopen(myfilestr,"w");
00076         }
00077 
00078 //      char mystr[250];
00079 //      if (showPlanner){
00080 //              sprintf(mystr,"plan%d.jpg",number);
00081 //              cvNamedWindow(mystr,0);
00082 //      }
00083 
00084         bool endExploration = false;
00085         while(!endPlanner && !endExploration){
00086                 
00087                 nextStep += 1;
00088 //              printf("[robot %d planner] waiting for step %d\n", number, nextStep);
00089                 mySlam->waitForStep(nextStep);
00090 
00091                 if (nextStep > 20000) endExploration= true;
00092 
00093                 gridMapInterface* omap  = mySlam->getOMap();
00094                 binMap* ppmap                   = mySlam->getPreMap();
00095                 //int numrobots                 = mySlam->getNumRobots();
00096                 point poscell                   = mySlam->getCell(number);
00097 
00098 //              printf("[robot %d] Dispersion: %f\n", number, mySlam->getDisp(number));
00099 
00100 
00101                 // leer mensajes
00102                 string msg;
00103                 int msglen;
00104                 while((msglen=getMessage(msg))){
00105                         //cout << "Message: >> " << msg << endl;
00106                         StringTokenizer st(&msg[0]);
00107                         string messagetype(st.nextToken());
00108                         if (messagetype == "END"){
00109                                 endExploration = true;
00110                                 completedPath = true;
00111                         }
00112                 }
00113                 if (completedPath){
00114                         exploring = true;
00115                         returning = false;
00116                         escapingFromLocalMinimum = false;
00117                         returningEscape = false;
00118                         completedPath = false;
00119                 }
00120                 if (integrate_slam){ 
00121                         if ((exploring || escapingFromLocalMinimum)  && mySlam->getLoc(number)){
00122                                 exploring = false;
00123                                 returning = true;
00124                                 escapingFromLocalMinimum = false;
00125                                 returningEscape = false;
00126                                 path.clear();
00127                         }
00128                         if ((returning || returningEscape) && !mySlam->getLoc(number)){
00129                                 exploring = true;
00130                                 returning = false;
00131                                 escapingFromLocalMinimum = false;
00132                                 returningEscape = false;
00133                                 path.clear();
00134                         }
00135                 }
00136 
00137                 // si hay minimo planificamos
00138                 if (escape_allowed){
00139                         if( (exploring || returning) && reac->localMinimum()){
00140         //                      printf("[FSAPlanner] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Planificando >>>> robot %d\n",number);
00141                 
00142                                 int lenpath;
00143                                 if(exploring){
00144                                         binMap objectives;
00145                                         vector<clusterCell> clusterList;
00146                                         omap->frontiers(objectives);
00147                                         objectives.cluster(clusterList,4);
00148                                         objectives.set(clusterList);
00149                                         lenpath = DijkstraGrid(poscell, objectives, *omap, path, inflate_obstacles);    // path to frontier
00150                                 }
00151                                 else{ // returning 
00152                                         lenpath = DijkstraGrid(poscell, *ppmap, *omap, path, inflate_obstacles);        // path to precise pose
00153                                 }
00154 
00155                                 if (lenpath == 0){
00156         //                              printf("No path found, stopping exploration\n");
00157                                         endExploration = true;
00158                                         completedPath = true;
00159                                         char sms[100];
00160                                         sprintf(sms,"END %d", getDir()); 
00161                                         sendMessage(string(sms),-1);
00162                                 }
00163                                 else{
00164                                         if(exploring){
00165                                                 escapingFromLocalMinimum = true;
00166                                                 returningEscape = false;
00167                                         }
00168                                         else{
00169                                                 escapingFromLocalMinimum = false;
00170                                                 returningEscape = true;
00171                                         }
00172                                         exploring = false;
00173                                         returning = false;
00174                                 }
00175         //                      printf("[FSAPlanner] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Planning end. len = %d >>>> robot %d\n",path.size(), number);
00176                         }
00177                 }
00178 //              if (showPlanner){       // Visualizacion del path
00179 //                      IplImage* im = omap->getMapAsImage();
00180 //                      for (unsigned int i = 0;i < path.size(); i++)
00181 //                              cvCircle(im,cvPoint(path[i].x, omap->getHeight()-1-path[i].y),0,CV_RGB(255,0,0),-1);
00182 //                      cvShowImage(mystr,im);
00183 //                      cvWaitKey(5);
00184 //                      cvReleaseImage(&im);
00185 //              }
00186 
00187 
00188                 // si estamos en planificado quitamos los puntos que hayamos recorrido
00189                 if (escapingFromLocalMinimum || returningEscape){
00190         
00191                         // verificamos que el path sea transitable
00192                         bool obstructedPath = false;
00193                         vector<point>::reverse_iterator riter;
00194                         if(path.size()>1) { 
00195                                 for ( riter = path.rbegin(); riter != path.rend(); riter++ )
00196                                         if (omap->isoccupied(riter->x,riter->y)) { 
00197 //                                              printf("[FSAPlanner] [robot %d] obstructed\n",rbase->getNumber()); 
00198                                                 obstructedPath = true;
00199                                                 break;
00200                                         }
00201                         }
00202 
00203                         // verificar distancia al destino || obstruccion para path completado
00204                         if((sqrt(pow((float)(path.front().x-poscell.x),2) + pow((float)(path.front().y-poscell.y),2)) <= 3.0)  || obstructedPath){
00205 //                              printf("[FSAPlanner] [robot %d] completed\n",rbase->getNumber()); 
00206                                 completedPath = true;
00207                         }
00208                         else { // No hemos llegado al final seguimos avanzando
00209                                 bool found=false;                               
00210 
00211                                 //IplImage* im = (showPlanner)? omap->getMapAsImage() : 0;
00212                                 //if (showPlanner){
00213                                 //      cvCircle(im,cvPoint(poscell.x, omap->getHeight()-1-poscell.y),0,CV_RGB(255,0,0),-1); //posicion rojo    
00214                                 //      for (unsigned int i = 0;i < path.size(); i++)
00215                                 //              cvCircle(im,cvPoint(path[i].x, omap->getHeight()-1-path[i].y),0,CV_RGB(255,0,255),-1); // path magenta
00216                                 //      cvShowImage(mywindowstr,im);
00217                                 //}
00218                                 
00219                                 if(path.size()>=1) {
00220                                         for ( riter = path.rbegin(); riter != path.rend(); riter++ ){
00221                                                 bool visible = true;
00222                                                 int size;
00223                                                 point* line = omap->getLine(poscell.x,poscell.y,riter->x,riter->y,size);
00224                                                 
00225                                                 for (int p = 0; p < size; p++){
00226                                                         if (p > 1 && omap->isoccupied(line[p].x,line[p].y,1)){ 
00227                                                                 visible = false; 
00228                                                                 break;
00229                                                         }
00230                                                 //      else
00231                                                 //              cvCircle(im,cvPoint(line[p].x, omap->getHeight()-1-line[p].y),0,CV_RGB(0,255,0),-1); // visual green
00232                                                 }
00233                                                 //cvShowImage(mywindowstr,im);
00234                                                 //cvWaitKey(2);
00235                                                 delete [] line;
00236                                                 if (visible) { // is visible
00237                                                         goal.x = riter->x;
00238                                                         goal.y = riter->y;
00239                                                         if (found) path.pop_back();
00240                                                         else found = true;
00241                                                         //path.pop_back();
00242                                                         double dist = sqrt(pow(poscell.x-goal.x,2) + pow(poscell.y-goal.y,2));
00243                                                         if ( dist > 1.5/omap->getResolution()) break;
00244                                                 }
00245                                                 else break;
00246                                         }
00247                                 }
00248                                 if(!found){
00249                                         completedPath = true;  // algo falla ninguna celda de la ruta es visible
00250 //                                      printf("[FSAPlanner] [robot %d] no visible cells\n",rbase->getNumber()); 
00251                                 }
00252                                 //if (showPlanner) cvReleaseImage(&im);
00253 
00254                         }
00255 //                      printf("[FSAPlanner] [robot %d] next goal: (%d,%d) - current pos (%d,%d)\n",rbase->getNumber(),goal.x, goal.y, poscell.x,poscell.y);                                            
00256                 }
00257         
00258                 delete omap;
00259                 delete ppmap;
00260 
00261                 //      modificar los enables/goal de la parte reactiva
00262                 if (exploring){
00263 //                      printf("[FSAPlanner] ************************************** [robot %d] Reactive\n",number);
00264                 
00265                         reac->enableAvoidObstacles();
00266                         reac->enableAvoidOtherRobots();
00267                         reac->enableGoToFrontier();
00268 
00269                         reac->disableGoToUnexploredZones();
00270                         reac->disableGoToGoal();
00271                         reac->disableGoToPrecisePoses();
00272                 }
00273                 else if (returning){
00274 //                      printf("[FSAPlanner] ************************************** [robot %d] Returning\n",number);
00275 
00276                         reac->enableAvoidObstacles();
00277                         reac->enableGoToPrecisePoses();
00278 
00279                         reac->disableAvoidOtherRobots();                        
00280                         reac->disableGoToFrontier();
00281                         reac->disableGoToUnexploredZones();
00282                         reac->disableGoToGoal();
00283                 }
00284                 else if (escapingFromLocalMinimum || returningEscape){
00285 //                      printf("[FSAPlanner] ************************************** [robot %d] Escaping from local minimum\n",number);
00286 
00287                         reac->setGoal(goal);
00288 
00289                         reac->enableAvoidObstacles();
00290                         reac->enableGoToGoal();
00291 
00292                         reac->disableAvoidOtherRobots();
00293                         reac->disableGoToFrontier();
00294                         reac->disableGoToUnexploredZones();
00295                         reac->disableGoToPrecisePoses();                        
00296                 }
00297 
00298                 // write logs
00299                 if (logstr){
00300                         fprintf(plannerlog,"%d, %d, %d, %d, %d, %d, %d\n",nextStep, exploring, returning, escapingFromLocalMinimum, returningEscape, poscell.x, poscell.y);
00301                 }
00302         }
00303 
00304 //      if (showPlanner) cvDestroyWindow(mystr);
00305 
00306         //closing logs
00307         if (logstr){
00308                 fclose(plannerlog);
00309         }
00310 
00311 //      printf("[robot %d] stoping robot", number);
00312         reac->disableAll();
00313         reac->stop();
00314 
00315         closing.unlock();
00316         explorationFinished.step();
00317 
00318 }
 All Classes Functions Variables Typedefs