MRXT: The Multi-Robot eXploration Tool
Multi-Robot autonomous exploration and mapping simulator.
|
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 }