MRXT: The Multi-Robot eXploration Tool
Multi-Robot autonomous exploration and mapping simulator.
src/architecture/planner/auxiliar/pathPlanning.cpp
00001 
00002 #include "pathPlanning.h"
00003 #include <math.h>
00004 
00005 using namespace std;
00006 
00007 int AStarGrid(const point& rcell, const point& target, const gridMapInterface& omap, std::vector<point>& path, bool trackUnknown){
00008 
00009         point last;
00010         point* p;
00011 
00012         long int mincost, newcost;
00013         int ci, cj, i;
00014         bool stop = false;
00015 
00016         // costmap
00017         int len = omap.getWidth()*omap.getHeight();
00018         int mapstep = omap.getWidth();
00019         costCellH* costmap = new costCellH[len]();
00020         // clean cost map
00021         for (i=0; i < len; i++){
00022                 costmap[i].open = false;
00023                 costmap[i].closed = false;
00024         }
00025 
00026         // lists
00027         vector<point> openlist;
00028         vector<point> closedlist;
00029         vector<point>::iterator iter;
00030         vector<point>::iterator pointer;
00031         openlist.reserve(len);
00032         closedlist.reserve(len);
00033         path.reserve(omap.getWidth()+omap.getHeight());
00034 
00035         point next = rcell;
00036         int idxnext = next.y*mapstep+next.x;
00037 
00038         // mapa de costes inicial
00039         //binMap obs;
00040         //omap.occupiedCells(obs,2); 
00041 
00042         //1) Add the starting square (or node) to the open list.
00043         openlist.push_back(next);
00044 
00045         costmap[idxnext].parent = 0;
00046         costmap[idxnext].G = 0;
00047         costmap[next.y*mapstep+next.x].H = VHMOV * (abs(target.x-next.x)+abs(target.y-next.y)); // Heruristic cost
00048         costmap[idxnext].F = costmap[idxnext].G + costmap[idxnext].H;
00049         costmap[idxnext].open = true;
00050 
00051         // 2) Repeat the following:
00052         do{
00053                 mincost = LONG_MAX;
00054                 // a) Look for the lowest F cost square on the open list. We refer to this as the current square.
00055                 for ( iter = openlist.begin( ); iter != openlist.end( ); iter++ ){
00056                         int idxit = iter->y*mapstep+iter->x;
00057                         if (mincost > costmap[idxit].F){
00058                                 mincost = costmap[idxit].F;
00059                                 pointer = iter;
00060                         }
00061                 }
00062 
00063                 // b) Switch it to the closed list.
00064                 memcpy(&last, &(*pointer), sizeof(point));
00065                 closedlist.push_back(last);
00066                 openlist.erase(pointer);
00067                 int idxlast = last.y*mapstep+last.x;
00068                 costmap[idxlast].closed = true;
00069                 costmap[idxlast].open = false;
00070 
00071                 // c) For each of the 8 squares adjacent to this current square
00072                 for (ci=last.x-1; ci<= last.x+1; ci++){
00073                         if (ci<0 || ci >=  omap.getWidth()) continue;
00074                         for (cj=last.y-1; cj<= last.y+1; cj++){
00075                                 if (cj<0 || cj >=  omap.getHeight()) continue;
00076                                 if (ci!=last.x || cj!=last.y){
00077                                         idxnext = cj*mapstep+ci;
00078                                         //*If it is not walkable or if it is on the closed list, ignore it. Otherwise do the following. 
00079                                         if( ( omap.isfree(ci,cj) || (trackUnknown && !omap.isoccupied(ci,cj)) ) && costmap[idxnext].closed==false){
00080                                                 //*If it isn't on the open list, add it to the open list. Make the current square the parent of this square. Record the F, G, and H costs of the square. 
00081                                                 if (costmap[idxnext].open==false){
00082 //                                                      cout << " closed" << endl;
00083                                                         next.x = ci;
00084                                                         next.y = cj;
00085                                                         openlist.push_back(next);
00086                                                         costmap[idxnext].parent = &closedlist.back();
00087                                                         
00088                                                         // G = lastcost + movement cost + penalize occupation probability
00089                                                         if (fabs((float)(last.x-ci))+fabs((float)(last.y-cj))>1){       // diagonal
00090                                                                 costmap[idxnext].G = costmap[idxlast].G + DMOV + COSTOCC*omap.getValue(next.x,next.y,3); 
00091                                                         }
00092                                                         else{                                                   // horizontal
00093                                                                 costmap[idxnext].G = costmap[idxlast].G + VHMOV + COSTOCC*omap.getValue(next.x,next.y,3);
00094                                                         }
00095                                                         costmap[idxnext].H = VHMOV * (abs(target.x-next.x)+abs(target.y-next.y)); // Heruristic cost
00096                                                         costmap[idxnext].F = costmap[idxnext].G + costmap[idxnext].H;
00097                                                         costmap[idxnext].open = true;
00098                                                 }
00099                                                 // If it is on the open list already, check to see if this path to that square is better, using G cost as the measure. 
00100                                                 // A lower G cost means that this is a better path. If so, change the parent of the square to the current square, 
00101                                                 // and recalculate the G and F scores of the square. If you are keeping your open list sorted by F score, you may need
00102                                                 // to resort the list to account for the change.
00103                                                 else{
00104                                                         // newcost
00105                                                         if (fabs((float)(last.x-ci))+fabs((float)(last.y-cj))>1){ // diagonal
00106                                                                 newcost = costmap[idxlast].G + DMOV + COSTOCC*omap.getValue(ci,cj,3); 
00107                                                         }
00108                                                         else{                                                                   // horizontal
00109                                                                 newcost = costmap[idxlast].G + VHMOV + COSTOCC*omap.getValue(ci,cj,3);
00110                                                         }
00111 
00112                                                         // if this new path is shorter...
00113                                                         if(costmap[idxnext].G > newcost){
00114                                                                 costmap[idxnext].G = newcost;
00115                                                                 costmap[idxnext].F = costmap[idxnext].G + costmap[idxnext].H;
00116                                                                 costmap[idxnext].parent = &closedlist.back();
00117                                                         }
00118                                                 }
00119                                         }
00120                                 }
00121                         }  // cj
00122                 } //ci
00123 
00124                 //  d) Stop when you:
00125                 //    * Add the target square to the closed list, in which case the path has been found (see note below), or
00126                 //    * Fail to find the target square, and the open list is empty. In this case, there is no path.   
00127                 if (last.x == target.x && last.y == target.y){
00128                         stop = true;
00129                 }
00130 
00131         } while(!openlist.empty() && stop==false);
00132         //3) Save the path. Working backwards from the target square, go from each square to its parent square until you reach the starting square. That is your path. 
00133         path.clear();
00134 
00135         int sizePath = 0;
00136         if (stop){
00137                 p = &closedlist.back();
00138                 point np;
00139                 while (p!=0){
00140                         np.x = p->x;
00141                         np.y = p->y;
00142                         path.push_back(np);
00143                         p = (point*) costmap[np.y*mapstep+np.x].parent;
00144                 };
00145                 sizePath = path.size();
00146         }
00147 
00148         delete[] costmap;
00149         return sizePath;
00150 };
00151 
00152 int DijkstraGrid(const point& rcell, const binMap& objectives, const gridMapInterface& omap, std::vector<point>& path, int inflaterad){
00153 
00154         point last;
00155         point* p;
00156 
00157         long int mincost, newcost;
00158         int ci, cj, i;
00159         bool stop = false;
00160 
00161         // costmap
00162         int len = omap.getWidth()*omap.getHeight();
00163         int mapstep = omap.getWidth();
00164         costCell* costmap = new costCell[len]();
00165         // clean cost map
00166         for (i=0; i < len; i++){
00167                 costmap[i].open = false;
00168                 costmap[i].closed = false;
00169         }
00170 
00171         // lists
00172         vector<point> openlist;
00173         vector<point> closedlist;
00174         vector<point>::iterator iter;
00175         vector<point>::iterator pointer;
00176         openlist.reserve(len);
00177         closedlist.reserve(len);
00178         path.reserve(omap.getWidth()+omap.getHeight());
00179 
00180         point next = rcell;
00181         int idxnext = next.y*mapstep+next.x;
00182 
00183         // mapa de costes inicial
00184         //binMap obs;
00185         //omap.occupiedCells(obs,2); 
00186 
00187         //1) Add the starting square (or node) to the open list.
00188         openlist.push_back(next);
00189 
00190         costmap[idxnext].parent = 0;
00191         costmap[idxnext].C = 0;
00192         costmap[idxnext].open = true;
00193 
00194         // 2) Repeat the following:
00195         do{
00196                 mincost = LONG_MAX;
00197                 // a) Look for the lowest F cost square on the open list. We refer to this as the current square.
00198                 for ( iter = openlist.begin( ); iter != openlist.end( ); iter++ ){
00199                         int idxit = iter->y*mapstep+iter->x;
00200                         if (mincost > costmap[idxit].C){
00201                                 mincost = costmap[idxit].C;
00202                                 pointer = iter;
00203                         }
00204                 }
00205 
00206                 // b) Switch it to the closed list.
00207                 memcpy(&last, &(*pointer), sizeof(point));
00208                 closedlist.push_back(last);
00209                 openlist.erase(pointer);
00210                 int idxlast = last.y*mapstep+last.x;
00211                 costmap[idxlast].closed = true;
00212                 costmap[idxlast].open = false;
00213 
00214                 // c) For each of the 8 squares adjacent to this current square
00215                 for (ci=last.x-1; ci<= last.x+1; ci++){
00216                         for (cj=last.y-1; cj<= last.y+1; cj++){
00217                                 if (ci!=last.x || cj!=last.y){
00218                                         idxnext = cj*mapstep+ci;
00219                                         //*If it is not walkable or if it is on the closed list, ignore it. Otherwise do the following. 
00220                                         if( (omap.isfree(ci,cj)) && (costmap[idxnext].closed==false)){
00221                                                 //*If it isn't on the open list, add it to the open list. Make the current square the parent of this square. Record the F, G, and H costs of the square. 
00222                                                 if (costmap[idxnext].open==false){
00223                                                                 next.x = ci;
00224                                                                 next.y = cj;
00225                                                                 openlist.push_back(next);
00226                                                                 costmap[idxnext].parent = &closedlist.back();
00227                                                                 costmap[idxnext].C = costmap[idxlast].C + omap.getValue(next.x,next.y,inflaterad)*COSTOCC + ( ((abs(last.x-next.x)+abs(last.y-next.y))>1)? DMOV: VHMOV);
00228                                                                 /*
00229                                                                 // C = lastcost + movement cost + penalize occupation probability
00230                                                                 if (fabs((float)(last.x-ci))+fabs((float)(last.y-cj))>1){       // diagonal
00231                                                                         costmap[idxnext].C = costmap[idxlast].C + DMOV + COSTOCC*omap.getValue(next.x,next.y,3); 
00232                                                                 }
00233                                                                 else{                                                                                                           // horizontal
00234                                                                         costmap[idxnext].C = costmap[idxlast].C + VHMOV + COSTOCC*omap.getValue(next.x,next.y,3);
00235                                                                 }*/
00236                                                                 costmap[idxnext].open = true;
00237 
00238 
00239                                                 }
00240                                                 // If it is on the open list already, check to see if this path to that square is better, using G cost as the measure. 
00241                                                 // A lower G cost means that this is a better path. If so, change the parent of the square to the current square, 
00242                                                 // and recalculate the G and F scores of the square. If you are keeping your open list sorted by F score, you may need
00243                                                 // to resort the list to account for the change.
00244                                                 else{
00245                                                         // newcost
00246                                                         newcost = costmap[idxlast].C + omap.getValue(next.x,next.y,inflaterad)*COSTOCC + ( ((abs(last.x-next.x)+abs(last.y-next.y))>1)? DMOV: VHMOV);
00247                                                         /*if (fabs((float)(last.x-ci))+fabs((float)(last.y-cj))>1){ // diagonal
00248                                                                 newcost = costmap[idxlast].C + DMOV + COSTOCC*omap.getValue(ci,cj,3); 
00249                                                         }
00250                                                         else{                                                                   // horizontal
00251                                                                 newcost = costmap[idxlast].C + VHMOV + COSTOCC*omap.getValue(ci,cj,3);
00252                                                         }*/
00253 
00254                                                         // if this new path is shorter...
00255                                                         if(costmap[idxnext].C > newcost){
00256                                                                 costmap[idxnext].C = newcost;
00257                                                                 costmap[idxnext].parent = &closedlist.back();
00258                                                         }
00259                                                 }
00260                                         }
00261                                 }
00262                         }  // cj
00263                 } //ci
00264 
00265                 //  d) Stop when you:
00266                 //    * Add the target square to the closed list, in which case the path has been found (see note below), or
00267                 //    * Fail to find the target square, and the open list is empty. In this case, there is no path.   
00268 
00269                 if( objectives.get(last.x,last.y)){ // if cell is a frontier
00270                         stop = true;
00271                 }
00272 
00273         } while(!openlist.empty() && stop==false);
00274         //3) Save the path. Working backwards from the target square, go from each square to its parent square until you reach the starting square. That is your path. 
00275         path.clear();
00276 
00277         int sizePath = 0;
00278         if (stop){
00279                 p = &closedlist.back();
00280                 point np;
00281                 while (p!=0){
00282                         np.x = p->x;
00283                         np.y = p->y;
00284                         path.push_back(np);
00285                         p = (point*) costmap[np.y*mapstep+np.x].parent;
00286                 };
00287                 sizePath = path.size();
00288         }
00289 
00290         delete[] costmap;
00291         return sizePath;
00292 };
00293 
00294 //int DijkstraGridWithHeading(const ocell& rcell, const binMap& objectives, const gridMapInterface& omap, std::vector<ocell>& resultpath){
00295 //      
00296 //      ocell last;
00297 //      long int mincost, newcost;
00298 //      int i;
00299 //      bool stop = false;
00300 //      
00301 //      // costmap
00302 //      int len = omap.getWidth()*omap.getHeight()*8;
00303 //      int ystep = omap.getWidth()*8;
00304 //      costCell* costmap = new costCell[len]();
00305 //      for (i=0; i < len; i++){                // clean cost map
00306 //              costmap[i].open = false;
00307 //              costmap[i].closed = false;
00308 //      }
00309 //      
00310 //      // mapa de obstaculos
00311 //      //binMap obs;
00312 //      //omap.occupiedCells(obs,2); 
00313 //      //obs.showMap("OBSTACLES");
00314 
00315 //      // lists
00316 //      vector<ocell> openlist;
00317 //      openlist.reserve(len);
00318 //      vector<ocell> closedlist;
00319 //      closedlist.reserve(len);
00320 //      
00321 //      vector<ocell>::iterator pointer;
00322 //      vector<ocell>::iterator iter;
00323 //      
00324 //      resultpath.reserve(4*(omap.getWidth()+omap.getHeight()));
00325 //      
00326 //      //1) Add the starting square (or node) to the open list.
00327 //      ocell next = rcell;
00328 //      int idxnext = next.y*ystep+next.x*8+next.th;
00329 //      costmap[idxnext].parent = 0;
00330 //      costmap[idxnext].C = 0;
00331 //      costmap[idxnext].open = true;
00332 //      openlist.push_back(next);
00333 
00334 //      // 2) Repeat the following:
00335 //      do{
00336 //              mincost = 99999999;
00337 //              // a) Look for the lowest C cost square on the open list. We refer to this as the current square.
00338 //              for ( iter = openlist.begin(); iter != openlist.end(); iter++ ){
00339 //                      int cost = costmap[iter->y*ystep+iter->x*8+iter->th].C;
00340 //                      if (mincost > cost ){
00341 //                              mincost = cost;
00342 //                              pointer = iter;
00343 //                      }
00344 //              }
00345 //              
00346 //              // b) Switch it to the closed list.
00347 //              last = *pointer;
00348 //              closedlist.push_back(last);
00349 //              openlist.erase(pointer);
00350 //              int idxlast = last.y*ystep+last.x*8+last.th;
00351 //              costmap[idxlast].closed = true;
00352 //              costmap[idxlast].open = false;
00353 //              
00354 //              // c) For each of the oriented cells accesible from the current square
00355 //              for (i = -1 ; i < 2; i++){
00356 //                      next.th = last.th + i;
00357 //                      if (next.th > 7) next.th -= 8;
00358 //                      else if (next.th < 0) next.th += 8;
00359 //                      next.x = last.x + avancex[next.th]; 
00360 //                      next.y = last.y + avancey[next.th];
00361 //                      idxnext = next.y*ystep+next.x*8+next.th;
00362 //                      
00363 //                      //*If it is not walkable or if it is on the closed list, ignore it. Otherwise do the following. 
00364 //                      if( omap.isfree(next.x,next.y) && (!costmap[idxnext].closed)){
00365 //                              //*If it isn't on the open list, add it to the open list. Make the current square the parent of this square.
00366 //                              if (!costmap[idxnext].open){
00367 //                                      openlist.push_back(next);
00368 //                                      costmap[idxnext].parent = &closedlist.back();
00369 //                                      costmap[idxnext].C = costmap[idxlast].C + omap.getValue(next.x,next.y,3)*COSTOCC + ( ((abs(last.x-next.x)+abs(last.y-next.y))>1)? DMOV: VHMOV);
00370 //                                      costmap[idxnext].open = true;
00371 //                              }
00372 //                              // If it is on the open list already, check to see if this path to that square is better.
00373 //                              else{
00374 //                                      // newcost
00375 //                                      newcost = costmap[idxlast].C + omap.getValue(next.x,next.y,3)*COSTOCC + (( (abs(last.x-next.x)+abs(last.y-next.y))>1)? DMOV : VHMOV);
00376 
00377 //                                      // if this new path is shorter...
00378 //                                      if(costmap[idxnext].C > newcost){
00379 //                                              costmap[idxnext].C = newcost;
00380 //                                              costmap[idxnext].parent = &closedlist.back();
00381 //                                      }
00382 //                              }
00383 //                              //printf("l = %d, c = %d ", costmap[idxlast].C,costmap[idxnext].C);
00384 //                      }
00385 //              }
00386 
00387 //              //  d) Stop when you:
00388 //              //    * Add the target square to the closed list, in which case the path has been found (see note below), or
00389 //              //    * Fail to find the target square, and the open list is empty. In this case, there is no path.   
00390 //              if( objectives.get(last.x,last.y) && costmap[idxlast].C > 100) // if cell is a frontier
00391 //                      stop = true;
00392 
00393 //      } while(!openlist.empty() && !stop);
00394 
00395 //      //3) Save the path. Working backwards from the target square, go from each square to its parent square until you reach the starting square. That is your path. 
00396 //      resultpath.clear();
00397 //      int sizePath = 0;
00398 
00399 //      ocell* p;
00400 //      if (stop){
00401 //              if (closedlist.size()>0){
00402 //                      p = &closedlist.back();
00403 //                      while (p!=0){
00404 //                              resultpath.push_back(*p);
00405 //                              idxnext = p->y*ystep+p->x*8+p->th;
00406 //                              p = (ocell*)costmap[idxnext].parent;
00407 //                      }
00408 //              }
00409 //              sizePath = resultpath.size();
00410 //      }
00411 //      else if (closedlist.size()==1){
00412 //              printf("no hay camino, media vuelta\n");
00413 //              next.th=rcell.th+4;
00414 //              if (next.th > 7) next.th -= 8;
00415 //              else if (next.th < 0) next.th += 8; 
00416 //              next.x = last.x + avancex[next.th]; 
00417 //              next.y = last.y + avancey[next.th];
00418 //              resultpath.push_back(next);
00419 //              sizePath = resultpath.size();
00420 //      }
00421 //      printf("size path=%d\n",sizePath);
00422 //      delete[] costmap;
00423 //      return sizePath;
00424 //};
00425 
00426 //costMap* createPolicy(const ocell& target, const gridMapInterface& omap){
00427 
00428 //      ocell last;
00429 //      long int mincost, newcost;
00430 //      int i;
00431 //      bool stop = false;
00432 //      
00433 //      // costmap
00434 //      int len = omap.getWidth()*omap.getHeight()*8;
00435 //      int ystep = omap.getWidth()*8;
00436 //      costCell* costmap = new costCell[len]();
00437 //      for (i=0; i < len; i++){                // clean cost map
00438 //              costmap[i].open = false;
00439 //              costmap[i].closed = false;
00440 //      }
00441 //      
00442 //      // mapa de obstaculos
00443 //      binMap obs;
00444 //      omap.occupiedCells(obs,2); 
00445 //      //obs.showMap("OBSTACLES");
00446 
00447 //      // lists
00448 //      vector<ocell> openlist;
00449 //      openlist.reserve(len);
00450 //      vector<ocell>* closedlist = new vector<ocell>();
00451 //      closedlist->reserve(len);
00452 
00453 //      //vector<point> targets;
00454 //      //int numtargets = objectives.getPositives(targets);
00455 
00456 //      vector<ocell>::iterator pointer;
00457 //      vector<ocell>::iterator iter;
00458 //      //vector<point>::iterator targetiter;
00459 //      
00460 //      //1) Add the starting square (or node) to the open list.
00461 //      ocell next = target;
00462 //      int idxnext = next.y*ystep+next.x*8+next.th;
00463 //      costmap[idxnext].parent = 0;
00464 //      costmap[idxnext].C = 0;
00465 //      costmap[idxnext].open = true;
00466 //      openlist.push_back(next);
00467 
00468 //      // 2) Repeat the following:
00469 //      long maxcost = 0;
00470 //      do{
00471 //              mincost = 99999999;
00472 //              // a) Look for the lowest C cost square on the open list. We refer to this as the current square.
00473 //              for ( iter = openlist.begin(); iter != openlist.end(); iter++ ){
00474 //                      int cost = costmap[iter->y*ystep+iter->x*8+iter->th].C;
00475 //                      if (mincost > cost ){
00476 //                              mincost = cost;
00477 //                              pointer = iter;
00478 //                      }
00479 //              }
00480 //              
00481 //              // b) Switch it to the closed list.
00482 //              last = *pointer;
00483 //              closedlist->push_back(last);
00484 //              openlist.erase(pointer);
00485 //              int idxlast = last.y*ystep+last.x*8+last.th;
00486 //              costmap[idxlast].closed = true;
00487 //              costmap[idxlast].open = false;
00488 //              
00489 //              // c) For each of the oriented cells accesible from the current square
00490 //              for (i = -4 ; i <= 3; i++){
00491 //                      next.th = last.th;// + i;
00492 //                      if (next.th > 7) next.th -= 8;
00493 //                      else if (next.th < 0) next.th += 8;
00494 //                      next.x = last.x + avancex[next.th]; 
00495 //                      next.y = last.y + avancey[next.th];
00496 //                      idxnext = next.y*ystep+next.x*8+next.th;
00497 //                      
00498 //                      // If it is not walkable or if it is on the closed list, ignore it. Otherwise do the following. 
00499 //                      if( omap.isfree(next.x,next.y) && (!costmap[idxnext].closed)){
00500 //                              // If it isn't on the open list, add it to the open list. Make the current square the parent of this square.
00501 //                              if (!costmap[idxnext].open){
00502 //                                      openlist.push_back(next);
00503 //                                      costmap[idxnext].parent = &closedlist->back();
00504 //                                      costmap[idxnext].C = costmap[idxlast].C + omap.getValue(next.x,next.y,3)*COSTOCC + obs.get(next.x,next.y)*COSTOBS+ ( ((abs(last.x-next.x)+abs(last.y-next.y))>1)? DMOV: VHMOV);
00505 //                                      costmap[idxnext].open = true;
00506 //                              }
00507 //                              // If it is on the open list already, check to see if this path to that square is better.
00508 //                              else{
00509 //                                      // newcost
00510 //                                      newcost = costmap[idxlast].C + omap.getValue(next.x,next.y,3)*COSTOCC + + obs.get(next.x,next.y)*COSTOBS+(( (abs(last.x-next.x)+abs(last.y-next.y))>1)? DMOV : VHMOV);
00511 
00512 //                                      // if this new path is shorter...
00513 //                                      if(costmap[idxnext].C > newcost){
00514 //                                              costmap[idxnext].C = newcost;
00515 //                                              costmap[idxnext].parent = &closedlist->back();
00516 //                                      }
00517 //                              }
00518 //                              //printf("l = %d, c = %d ", costmap[idxlast].C,costmap[idxnext].C);
00519 //                      }
00520 //              }
00521 
00522 //              //  d) Stop when you:
00523 //              //    * Add the target square to the closed list, in which case the path has been found (see note below), or
00524 //              //    * Fail to find the target square, and the open list is empty. In this case, there is no path.
00525 //      } while(!openlist.empty());
00526 
00527 //      costMap* result = new costMap(costmap,ystep,8,closedlist,maxcost);
00528 
00529 //      return result;
00530 //}
00531 
00532 // costMap* createCostMapOri(const ocell& origin, const binMap& objectives, const gridMapInterface& omap, vector<ocell>& reachable){
00533 
00534 //      ocell last;
00535 //      long int mincost, newcost;
00536 //      int i;
00537 //      bool stop = false;
00538 //      
00539 //      // costmap
00540 //      int len = omap.getWidth()*omap.getHeight()*8;
00541 //      int ystep = omap.getWidth()*8;
00542 //      costCell* costmap = new costCell[len]();
00543 //      for (i=0; i < len; i++){                // clean cost map
00544 //              costmap[i].open = false;
00545 //              costmap[i].closed = false;
00546 //      }
00547 //      
00548 //      // mapa de obstaculos
00549 //      //binMap obs;
00550 //      //omap.occupiedCells(obs,2); 
00551 //      //obs.showMap("OBSTACLES");
00552 
00553 //      // lists
00554 //      vector<ocell> openlist;
00555 //      openlist.reserve(len);
00556 //      vector<ocell>* closedlist = new vector<ocell>();
00557 //      closedlist->reserve(len);
00558 //      vector<point> targets;
00559 //      int numtargets = objectives.getPositives(targets);
00560 
00561 //      vector<ocell>::iterator pointer;
00562 //      vector<ocell>::iterator iter;
00563 //      vector<point>::iterator targetiter;
00564 //      
00565 //      //1) Add the starting square (or node) to the open list.
00566 //      ocell next = origin;
00567 //      int idxnext = next.y*ystep+next.x*8+next.th;
00568 //      costmap[idxnext].parent = 0;
00569 //      costmap[idxnext].C = 0;
00570 //      costmap[idxnext].open = true;
00571 //      openlist.push_back(next);
00572 
00573 //      // 2) Repeat the following:
00574 //      long maxcost = 0;
00575 //      do{
00576 //              mincost = 99999999;
00577 //              // a) Look for the lowest C cost square on the open list. We refer to this as the current square.
00578 //              for ( iter = openlist.begin(); iter != openlist.end(); iter++ ){
00579 //                      int cost = costmap[iter->y*ystep+iter->x*8+iter->th].C;
00580 //                      if (mincost > cost ){
00581 //                              mincost = cost;
00582 //                              pointer = iter;
00583 //                      }
00584 //              }
00585 //              
00586 //              // b) Switch it to the closed list.
00587 //              last = *pointer;
00588 //              closedlist->push_back(last);
00589 //              openlist.erase(pointer);
00590 //              int idxlast = last.y*ystep+last.x*8+last.th;
00591 //              costmap[idxlast].closed = true;
00592 //              costmap[idxlast].open = false;
00593 //              
00594 //              // c) For each of the oriented cells accesible from the current square
00595 //              for (i = -4 ; i <= 3; i++){
00596 ////            for (i = -1 ; i < 2; i++){
00597 //                      next.th = last.th + i;
00598 //                      if (next.th > 7) next.th -= 8;
00599 //                      else if (next.th < 0) next.th += 8;
00600 //                      next.x = last.x + avancex[next.th]; 
00601 //                      next.y = last.y + avancey[next.th];
00602 //                      idxnext = next.y*ystep+next.x*8+next.th;
00603 //                      
00604 //                      // If it is not walkable or if it is on the closed list, ignore it. Otherwise do the following. 
00605 //                      if( omap.isfree(next.x,next.y) && (!costmap[idxnext].closed)){
00606 //                              // If it isn't on the open list, add it to the open list. Make the current square the parent of this square.
00607 //                              if (!costmap[idxnext].open){
00608 //                                      openlist.push_back(next);
00609 //                                      costmap[idxnext].parent = &closedlist->back();
00610 //                                      costmap[idxnext].C = costmap[idxlast].C + omap.getValue(next.x,next.y,3)*COSTOCC + ( ((abs(last.x-next.x)+abs(last.y-next.y))>1)? DMOV: VHMOV);
00611 //                                      costmap[idxnext].open = true;
00612 //                              }
00613 //                              // If it is on the open list already, check to see if this path to that square is better.
00614 //                              else{
00615 //                                      // newcost
00616 //                                      newcost = costmap[idxlast].C + omap.getValue(next.x,next.y,3)*COSTOCC + (( (abs(last.x-next.x)+abs(last.y-next.y))>1)? DMOV : VHMOV);
00617 
00618 //                                      // if this new path is shorter...
00619 //                                      if(costmap[idxnext].C > newcost){
00620 //                                              costmap[idxnext].C = newcost;
00621 //                                              costmap[idxnext].parent = &closedlist->back();
00622 //                                      }
00623 //                              }
00624 //                              //printf("l = %d, c = %d ", costmap[idxlast].C,costmap[idxnext].C);
00625 //                      }
00626 //              }
00627 
00628 //              //  d) Stop when you:
00629 //              //    * Add the target square to the closed list, in which case the path has been found (see note below), or
00630 //              //    * Fail to find the target square, and the open list is empty. In this case, there is no path.
00631 //              if( objectives.get(last.x,last.y)){ // if cell is a frontier
00632 //                      for ( targetiter = targets.begin(); targetiter != targets.end(); targetiter++ ){
00633 //                              if (targetiter->x == last.x && targetiter->y == last.y){
00634 //                                      reachable.push_back(last);
00635 //                                      targets.erase(targetiter);
00636 //                                      numtargets--;
00637 //                                      if (!numtargets) stop = true;
00638 //                                      if (maxcost < costmap[idxlast].C) maxcost = costmap[idxlast].C;
00639 //                                      break;
00640 //                              }
00641 //                      }
00642 //              }
00643 //      } while(!openlist.empty() && !stop);
00644 
00645 //      costMap* result = new costMap(costmap,ystep,8,closedlist,maxcost);
00646 
00647 //      return result;
00648 //}
00649 
00650 
00651 costMapSimple* createCostMap(const point& origin, const binMap& objectives, const gridMapInterface& omap, vector<point>& reachable, int inflaterad){
00652 
00653         point last;
00654         long int mincost, newcost;
00655         int i;
00656         bool stop = false;
00657         
00658         // costmap
00659         int len = omap.getWidth()*omap.getHeight();
00660         int ystep = omap.getWidth();
00661         costCell* costmap = new costCell[len]();
00662         for (i=0; i < len; i++){                // clean cost map
00663                 costmap[i].open = false;
00664                 costmap[i].closed = false;
00665         }
00666         
00667         // mapa de obstaculos
00668         //binMap obs;
00669         //omap.occupiedCells(obs,2); 
00670         //obs.showMap("OBSTACLES");
00671 
00672         // lists
00673         vector<point> openlist;
00674         openlist.reserve(len);
00675         vector<point>* closedlist = new vector<point>();
00676         closedlist->reserve(len);
00677         vector<point> targets;
00678         int numtargets = objectives.getPositives(targets);
00679 
00680         vector<point>::iterator pointer;
00681         vector<point>::iterator iter;
00682         vector<point>::iterator targetiter;
00683         
00684         //1) Add the starting square (or node) to the open list.
00685         point next = origin;
00686         int idxnext = next.y*ystep+next.x;
00687         costmap[idxnext].parent = 0;
00688         costmap[idxnext].C = 0;
00689         costmap[idxnext].open = true;
00690         openlist.push_back(next);
00691 
00692         // 2) Repeat the following:
00693         long maxcost = 0;
00694         do{
00695                 mincost = 99999999;
00696                 // a) Look for the lowest C cost square on the open list. We refer to this as the current square.
00697                 for ( iter = openlist.begin(); iter != openlist.end(); iter++ ){
00698                         int cost = costmap[iter->y*ystep+iter->x].C;
00699                         if (mincost > cost ){
00700                                 mincost = cost;
00701                                 pointer = iter;
00702                         }
00703                 }
00704                 
00705                 // b) Switch it to the closed list.
00706                 last = *pointer;
00707                 closedlist->push_back(last);
00708                 openlist.erase(pointer);
00709                 int idxlast = last.y*ystep+last.x;
00710                 costmap[idxlast].closed = true;
00711                 costmap[idxlast].open = false;
00712                 
00713                 // c) For each of the 8 squares adjacent to this current square
00714                 for (next.x=last.x-1; next.x<= last.x+1; next.x++){
00715                         for (next.y=last.y-1; next.y<= last.y+1; next.y++){
00716                                 if (next.x!=last.x || next.y!=last.y){
00717                                         idxnext = next.y*ystep+next.x;
00718         
00719                                         // If it is not walkable or if it is on the closed list, ignore it. Otherwise do the following. 
00720                                         if( omap.isfree(next.x,next.y) && (!costmap[idxnext].closed)){
00721                                                 // If it isn't on the open list, add it to the open list. Make the current square the parent of this square.
00722                                                 if (!costmap[idxnext].open){
00723                                                         openlist.push_back(next);
00724                                                         costmap[idxnext].parent = &closedlist->back();
00725                                                         costmap[idxnext].C = costmap[idxlast].C + omap.getValue(next.x,next.y,inflaterad)*COSTOCC + ( ((abs(last.x-next.x)+abs(last.y-next.y))>1)? DMOV: VHMOV);
00726                                                         costmap[idxnext].open = true;
00727                                                 }
00728                                                 // If it is on the open list already, check to see if this path to that square is better.
00729                                                 else{
00730                                                         // newcost
00731                                                         newcost = costmap[idxlast].C + omap.getValue(next.x,next.y,inflaterad)*COSTOCC + (( (abs(last.x-next.x)+abs(last.y-next.y))>1)? DMOV : VHMOV);
00732 
00733                                                         // if this new path is shorter...
00734                                                         if(costmap[idxnext].C > newcost){
00735                                                                 costmap[idxnext].C = newcost;
00736                                                                 costmap[idxnext].parent = &closedlist->back();
00737                                                         }
00738                                                 }
00739                                         }
00740                                 }
00741                         }
00742                 }
00743 
00744                 //  d) Stop when you:
00745                 //    * Add the target square to the closed list, in which case the path has been found (see note below), or
00746                 //    * Fail to find the target square, and the open list is empty. In this case, there is no path.
00747                 if( objectives.get(last.x,last.y)){ // if cell is a frontier
00748                         //printf("target found [%d, %d]\n",last.x,last.y);
00749                         for ( targetiter = targets.begin(); targetiter != targets.end(); targetiter++ ){
00750                                 if (targetiter->x == last.x && targetiter->y == last.y){
00751                                         reachable.push_back(last);
00752                                         targets.erase(targetiter);
00753                                         numtargets--;
00754                                         if (!numtargets) stop = true;
00755                                         if (maxcost < costmap[idxlast].C) maxcost = costmap[idxlast].C;
00756                                         break;
00757                                 }
00758                         }
00759                 }
00760         } while(!openlist.empty() && !stop);
00761         costMapSimple* result = new costMapSimple(costmap,ystep,closedlist,maxcost);
00762 
00763         return result;
00764 }
 All Classes Functions Variables Typedefs