2Dgridsearch.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, Maxim Likhachev
00003  * All rights reserved.
00004  * 
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  * 
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the University of Pennsylvania nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  * 
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 #include <iostream>
00030 using namespace std;
00031 
00032 #include "../sbpl/headers.h"
00033 
00034 
00035 
00036 
00037 //---------------------initialization and destruction routines--------------------------------------------------------
00038 SBPL2DGridSearch::SBPL2DGridSearch(int width_x, int height_y, float cellsize_m)
00039 {
00040         iteration_ = 0;
00041     searchStates2D_ = NULL;
00042 
00043     width_ = width_x;
00044     height_ = height_y;
00045         cellSize_m_ = cellsize_m;
00046     
00047     startX_ = -1;
00048     startY_ = -1;
00049         goalX_ = -1;
00050         goalY_ = -1;
00051 
00052         largestcomputedoptf_ = 0;
00053 
00054         //compute dx, dy, dxintersects and dyintersects arrays
00055         computedxy();
00056 
00057         term_condition_usedlast = SBPL_2DGRIDSEARCH_TERM_CONDITION_ALLCELLS;
00058 
00059         //allocate memory
00060         OPEN2D_ = new CIntHeap(width_x*height_y);
00061         if(!createSearchStates2D())
00062         {
00063                 SBPL_ERROR("ERROR: failed to create searchstatespace2D\n");
00064                 throw new SBPL_Exception();
00065         }
00066         
00067         //by default, OPEN is implemented as heap
00068         OPEN2DBLIST_ = NULL;
00069         OPENtype_ = SBPL_2DGRIDSEARCH_OPENTYPE_HEAP;
00070 
00071 }
00072 
00073 bool SBPL2DGridSearch::setOPENdatastructure(SBPL_2DGRIDSEARCH_OPENTYPE OPENtype)
00074 {
00075         OPENtype_ = OPENtype;
00076 
00077         switch(OPENtype_)
00078         {
00079         case SBPL_2DGRIDSEARCH_OPENTYPE_HEAP:
00080                 //this is the default, nothing else needs to be done
00081                 break;
00082         case SBPL_2DGRIDSEARCH_OPENTYPE_SLIDINGBUCKETS:
00083                 SBPL_PRINTF("setting OPEN2D data structure to sliding buckets\n");
00084                 if(OPEN2DBLIST_ == NULL)
00085                 {
00086                         //create sliding buckets
00087                         //compute max distance for edge
00088                         int maxdistance = 0;
00089                         for(int dind = 0; dind  < SBPL_2DGRIDSEARCH_NUMOF2DDIRS; dind++)
00090                         {
00091                                 maxdistance = __max(maxdistance, dxy_distance_mm_[dind]);
00092                         }
00093                         int bucketsize = __max(1000, this->width_ + this->height_);
00094                         int numofbuckets =      255*maxdistance; 
00095                         SBPL_PRINTF("creating sliding bucket-based OPEN2D %d buckets, each bucket of size %d ...", numofbuckets, bucketsize);
00096                         OPEN2DBLIST_ = new CSlidingBucket(numofbuckets, bucketsize); 
00097                         SBPL_PRINTF("done\n");
00098                 }
00099                 //delete other data structures
00100                 if(OPEN2D_ != NULL){
00101                         OPEN2D_->makeemptyheap();
00102                         delete OPEN2D_;
00103                         OPEN2D_ = NULL;
00104                 }
00105 
00106                 break;
00107         default:
00108                 SBPL_ERROR("ERROR: unknown data structure type = %d for OPEN2D\n", OPENtype_);
00109                 throw new SBPL_Exception();
00110         };
00111 
00112         return true;
00113 }
00114 
00115     
00116 bool SBPL2DGridSearch::createSearchStates2D(void)
00117 {
00118         int x,y;
00119 
00120     if(searchStates2D_ != NULL){
00121         SBPL_ERROR("ERROR: We already have a non-NULL search states array\n");
00122         return false;
00123     }
00124     
00125     searchStates2D_ = new SBPL_2DGridSearchState* [width_];
00126     for(x = 0; x < width_; x++)
00127     {
00128         searchStates2D_[x] = new SBPL_2DGridSearchState[height_];
00129         for(y = 0; y < height_; y++)
00130         {
00131                         searchStates2D_[x][y].iterationaccessed = iteration_;
00132                 searchStates2D_[x][y].x = x;
00133                 searchStates2D_[x][y].y = y;
00134                         initializeSearchState2D(&searchStates2D_[x][y]);
00135         }
00136     }
00137     return true;
00138 }
00139 
00140 inline void SBPL2DGridSearch::initializeSearchState2D(SBPL_2DGridSearchState* state2D)
00141 {
00142         state2D->g = INFINITECOST;
00143         state2D->heapindex = 0;
00144         state2D->iterationaccessed = iteration_;
00145 }
00146 
00147 
00148 void SBPL2DGridSearch::destroy()
00149 {
00150 
00151         // destroy the OPEN list:
00152     if(OPEN2D_ != NULL){
00153         OPEN2D_->makeemptyheap();
00154         delete OPEN2D_;
00155         OPEN2D_ = NULL;
00156     }
00157 
00158     // destroy the 2D states:
00159     if(searchStates2D_ != NULL){
00160             for(int x = 0; x < width_; x++)
00161                 {
00162                         delete [] searchStates2D_[x];
00163                 }
00164                 delete [] searchStates2D_;
00165         searchStates2D_ = NULL;
00166     }
00167 
00168         if(OPEN2DBLIST_ != NULL)
00169         {
00170                 delete OPEN2DBLIST_;
00171                 OPEN2DBLIST_ = NULL;
00172         }
00173 }
00174 
00175 
00176 void SBPL2DGridSearch::computedxy()
00177 {
00178 
00179         //initialize some constants for 2D search
00180         dx_[0] = 1; dy_[0] = 1; dx0intersects_[0] = -1; dy0intersects_[0] = -1; 
00181         dx_[1] = 1; dy_[1] = 0; dx0intersects_[1] = -1; dy0intersects_[1] = -1;
00182         dx_[2] = 1; dy_[2] = -1;        dx0intersects_[2] = -1; dy0intersects_[2] = -1;
00183         dx_[3] = 0; dy_[3] = 1; dx0intersects_[3] = -1; dy0intersects_[3] = -1;
00184         dx_[4] = 0; dy_[4] = -1;        dx0intersects_[4] = -1; dy0intersects_[4] = -1;
00185         dx_[5] = -1; dy_[5] = 1;        dx0intersects_[5] = -1; dy0intersects_[5] = -1;
00186         dx_[6] = -1; dy_[6] = 0;        dx0intersects_[6] = -1; dy0intersects_[6] = -1;
00187         dx_[7] = -1; dy_[7] = -1;       dx0intersects_[7] = -1; dy0intersects_[7] = -1;
00188 
00189     //Note: these actions have to be starting at 8 and through 15, since they 
00190     //get multiplied correspondingly in Dijkstra's search based on index
00191 #if SBPL_2DGRIDSEARCH_NUMOF2DDIRS == 16
00192     dx_[8] = 2; dy_[8] = 1;     dx0intersects_[8] = 1; dy0intersects_[8] = 0; dx1intersects_[8] = 1; dy1intersects_[8] = 1;
00193         dx_[9] = 1; dy_[9] = 2; dx0intersects_[9] = 0; dy0intersects_[9] = 1; dx1intersects_[9] = 1; dy1intersects_[9] = 1;
00194         dx_[10] = -1; dy_[10] = 2;      dx0intersects_[10] = 0; dy0intersects_[10] = 1; dx1intersects_[10] = -1; dy1intersects_[10] = 1;
00195         dx_[11] = -2; dy_[11] = 1;      dx0intersects_[11] = -1; dy0intersects_[11] = 0; dx1intersects_[11] = -1; dy1intersects_[11] = 1;
00196         dx_[12] = -2; dy_[12] = -1;     dx0intersects_[12] = -1; dy0intersects_[12] = 0; dx1intersects_[12] = -1; dy1intersects_[12] = -1;
00197         dx_[13] = -1; dy_[13] = -2;     dx0intersects_[13] = 0; dy0intersects_[13] = -1; dx1intersects_[13] = -1; dy1intersects_[13] = -1;
00198         dx_[14] = 1; dy_[14] = -2;      dx0intersects_[14] = 0; dy0intersects_[14] = -1; dx1intersects_[14] = 1; dy1intersects_[14] = -1;
00199         dx_[15] = 2; dy_[15] = -1; dx0intersects_[15] = 1; dy0intersects_[15] = 0; dx1intersects_[15] = 1; dy1intersects_[15] = -1;
00200 #endif          
00201 
00202         //compute distances
00203         for(int dind = 0; dind  < SBPL_2DGRIDSEARCH_NUMOF2DDIRS; dind++)
00204         {
00205 
00206                 if(dx_[dind] != 0 && dy_[dind] != 0){
00207             if(dind <= 7)
00208                 dxy_distance_mm_[dind] = (int)(cellSize_m_*1414);       //the cost of a diagonal move in millimeters
00209             else
00210                 dxy_distance_mm_[dind] = (int)(cellSize_m_*2236);       //the cost of a move to 1,2 or 2,1 or so on in millimeters
00211                 }
00212                 else
00213                         dxy_distance_mm_[dind] = (int)(cellSize_m_*1000);       //the cost of a horizontal move in millimeters
00214         }
00215 }
00216 
00217 //--------------------------------------------------------------------------------------------------------------------
00218 
00219 
00220 //-----------------------------------------debugging functions--------------------------------------------------------------
00221 void SBPL2DGridSearch::printvalues()
00222 {
00223 
00224 
00225 
00226 }
00227 //--------------------------------------------------------------------------------------------------------------------
00228 
00229 
00230 //-----------------------------------------main functions--------------------------------------------------------------
00231 bool SBPL2DGridSearch::search(unsigned char** Grid2D, unsigned char obsthresh, int startx_c, int starty_c, int goalx_c, int goaly_c,  
00232                                                           SBPL_2DGRIDSEARCH_TERM_CONDITION termination_condition)
00233 {
00234 
00235         switch(OPENtype_)
00236         {
00237         case SBPL_2DGRIDSEARCH_OPENTYPE_HEAP:
00238                 return SBPL2DGridSearch::search_withheap(Grid2D, obsthresh, startx_c, starty_c, goalx_c, goaly_c,  
00239                                                           termination_condition);
00240                 break;
00241         case SBPL_2DGRIDSEARCH_OPENTYPE_SLIDINGBUCKETS:
00242                 return SBPL2DGridSearch::search_withslidingbuckets(Grid2D, obsthresh, startx_c, starty_c, goalx_c, goaly_c, termination_condition);
00243                 break;
00244         default:
00245                 SBPL_ERROR("ERROR: unknown data structure type = %d for OPEN2D\n", OPENtype_);
00246                 throw new SBPL_Exception();
00247         };
00248         return false;
00249 }
00250 
00251 
00252 
00253 bool SBPL2DGridSearch::search_withheap(unsigned char** Grid2D, unsigned char obsthresh, int startx_c, int starty_c, int goalx_c, int goaly_c,  
00254                                                           SBPL_2DGRIDSEARCH_TERM_CONDITION termination_condition)
00255 {
00256 
00257     SBPL_2DGridSearchState *searchExpState = NULL;
00258     SBPL_2DGridSearchState *searchPredState = NULL;
00259     int numofExpands = 0;
00260         int key;
00261 
00262     //get the current time
00263         clock_t starttime = clock();
00264         
00265         //closed = 0
00266         iteration_++;
00267 
00268         //init start and goal coordinates
00269         startX_ = startx_c;
00270         startY_ = starty_c;
00271     goalX_ = goalx_c;
00272         goalY_ = goaly_c;
00273 
00274         //clear the heap
00275         OPEN2D_->makeemptyheap();
00276 
00277         //set the term. condition
00278         term_condition_usedlast = termination_condition;
00279 
00280     //check the validity of start/goal
00281     if(!withinMap(startx_c, starty_c) || !withinMap(goalx_c, goaly_c))
00282         {
00283                 SBPL_ERROR("ERROR: grid2Dsearch is called on invalid start (%d %d) or goal(%d %d)\n", startx_c, starty_c, goalx_c, goaly_c);
00284                 return false;
00285         }
00286 
00287     // initialize the start and goal states
00288     searchExpState = &searchStates2D_[startX_][startY_]; 
00289     initializeSearchState2D(searchExpState);
00290     initializeSearchState2D(&searchStates2D_[goalx_c][goaly_c]);
00291     SBPL_2DGridSearchState* search2DGoalState = &searchStates2D_[goalx_c][goaly_c];
00292 
00293         //seed the search
00294         searchExpState->g = 0;
00295         key = searchExpState->g;
00296         if(termination_condition == SBPL_2DGRIDSEARCH_TERM_CONDITION_OPTPATHFOUND)
00297                 key = key + SBPL_2DGRIDSEARCH_HEUR2D(startX_,startY_); //use h-values only if we are NOT computing all state values     
00298         
00299         OPEN2D_->insertheap(searchExpState, key);
00300     
00301 
00302         //set the termination condition
00303         float term_factor = 0.0;
00304         switch(termination_condition)
00305         {
00306         case SBPL_2DGRIDSEARCH_TERM_CONDITION_OPTPATHFOUND:
00307                 term_factor = 1;
00308                 break;
00309         case SBPL_2DGRIDSEARCH_TERM_CONDITION_20PERCENTOVEROPTPATH:
00310                 term_factor = (float)(1.0/1.2);
00311                 break;
00312         case SBPL_2DGRIDSEARCH_TERM_CONDITION_TWOTIMESOPTPATH:
00313                 term_factor = 0.5;
00314                 break;
00315         case SBPL_2DGRIDSEARCH_TERM_CONDITION_THREETIMESOPTPATH:
00316                 term_factor = (float)(1.0/3.0);
00317                 break;
00318         case SBPL_2DGRIDSEARCH_TERM_CONDITION_ALLCELLS:
00319                 term_factor = 0.0;
00320                 break;
00321         default:
00322                 SBPL_ERROR("ERROR: incorrect termination factor for grid2Dsearch\n");
00323                 term_factor = 0.0;
00324         };
00325         
00326         char *pbClosed = (char*)calloc(1, width_*height_);
00327 
00328     //the main repetition of expansions
00329     while(!OPEN2D_->emptyheap() &&  __min(INFINITECOST, search2DGoalState->g) > term_factor*OPEN2D_->getminkeyheap())
00330     {
00331         //get the next state for expansion
00332         searchExpState = (SBPL_2DGridSearchState*)OPEN2D_->deleteminheap();
00333         numofExpands++;
00334 
00335                 int exp_x = searchExpState->x;
00336                 int exp_y = searchExpState->y;
00337 
00338                 //close the state
00339                 pbClosed[exp_x + width_*exp_y] = 1;
00340 
00341         //iterate over successors
00342                 int expcost = Grid2D[exp_x][exp_y];
00343                 for(int dir = 0; dir < SBPL_2DGRIDSEARCH_NUMOF2DDIRS; dir++)
00344                 {
00345                         int newx = exp_x + dx_[dir];
00346                         int newy = exp_y + dy_[dir];            
00347                                                 
00348                         //make sure it is inside the map and has no obstacle
00349                         if(!withinMap(newx, newy))
00350                                 continue;
00351 
00352                         if(pbClosed[newx + width_*newy] == 1)
00353                                 continue;
00354 
00355                         //compute the cost 
00356             int mapcost = __max(Grid2D[newx][newy], expcost);
00357 
00358 #if SBPL_2DGRIDSEARCH_NUMOF2DDIRS > 8
00359             if(dir > 7){
00360                 //check two more cells through which the action goes
00361                 mapcost = __max(mapcost, Grid2D[exp_x + dx0intersects_[dir]][exp_y + dy0intersects_[dir]]); 
00362                 mapcost = __max(mapcost, Grid2D[exp_x + dx1intersects_[dir]][exp_y + dy1intersects_[dir]]); 
00363             }
00364 #endif
00365 
00366                         if(mapcost >= obsthresh) //obstacle encountered
00367                                 continue; 
00368                         int cost = (mapcost+1)*dxy_distance_mm_[dir];
00369 
00370                         //get the predecessor
00371                         searchPredState = &searchStates2D_[newx][newy];                 
00372 
00373                         //update predecessor if necessary
00374            if(searchPredState->iterationaccessed != iteration_ || searchPredState->g > cost + searchExpState->g) 
00375            {
00376                                 searchPredState->iterationaccessed = iteration_;
00377                                 searchPredState->g = __min(INFINITECOST, cost + searchExpState->g); 
00378                 key = searchPredState->g; 
00379                                 if(termination_condition == SBPL_2DGRIDSEARCH_TERM_CONDITION_OPTPATHFOUND)
00380                                         key = key + SBPL_2DGRIDSEARCH_HEUR2D(searchPredState->x, searchPredState->y); //use h-values only if we are NOT computing all state values
00381                                 
00382                                 if(searchPredState->heapindex == 0)
00383                                         OPEN2D_->insertheap(searchPredState, key);
00384                                 else
00385                                         OPEN2D_->updateheap(searchPredState, key);
00386 
00387                         }
00388         } //over successors
00389     }//while
00390 
00391         //set lower bounds for the remaining states
00392     if(!OPEN2D_->emptyheap()) 
00393                 largestcomputedoptf_ = OPEN2D_->getminkeyheap();
00394         else
00395                 largestcomputedoptf_ = INFINITECOST;
00396 
00397 
00398         delete [] pbClosed;
00399 
00400     SBPL_PRINTF("# of expands during 2dgridsearch=%d time=%d msecs 2Dsolcost_inmm=%d largestoptfval=%d (start=%d %d goal=%d %d)\n", 
00401                 numofExpands, (int)(((clock()-starttime)/(double)CLOCKS_PER_SEC)*1000), searchStates2D_[goalx_c][goaly_c].g, largestcomputedoptf_,
00402                         startx_c, starty_c, goalx_c, goaly_c);
00403 
00404         return false;
00405 }
00406 
00407 
00408 //experimental version
00409 //have only one copy of a state in the list, but the order of expansions is BFS with possible re-expansions. Thus the order can be maintained by FIFO queue implemented
00410 //by list (requires though the implementation of the lastelement in the list)
00411 bool SBPL2DGridSearch::search_exp(unsigned char** Grid2D, unsigned char obsthresh, int startx_c, int starty_c, int goalx_c, int goaly_c)
00412 {
00413 
00414     SBPL_2DGridSearchState *searchExpState = NULL;
00415     SBPL_2DGridSearchState *searchPredState = NULL;
00416     int numofExpands = 0;
00417         CList OPEN2DLIST;
00418 
00419     //get the current time
00420         clock_t starttime = clock();
00421         
00422         //closed = 0
00423         iteration_++;
00424 
00425         //init start and goal coordinates
00426         startX_ = startx_c;
00427         startY_ = starty_c;
00428     goalX_ = goalx_c;
00429         goalY_ = goaly_c;
00430 
00431     //check the validity of start/goal
00432     if(!withinMap(startx_c, starty_c) || !withinMap(goalx_c, goaly_c))
00433         {
00434                 SBPL_ERROR("ERROR: grid2Dsearch is called on invalid start (%d %d) or goal(%d %d)\n", startx_c, starty_c, goalx_c, goaly_c);
00435                 return false;
00436         }
00437 
00438     // initialize the start and goal states
00439     searchExpState = &searchStates2D_[startX_][startY_];
00440     initializeSearchState2D(searchExpState);
00441         //no initialization for the goal state - it will reset iteration_ variable
00442 
00443         //seed the search
00444         searchExpState->g = 0;
00445         searchExpState->listelem[SBPL_2DSEARCH_OPEN_LIST_ID] = NULL;
00446         OPEN2DLIST.insertinfront(searchExpState, SBPL_2DSEARCH_OPEN_LIST_ID);
00447     
00448     //the main repetition of expansions
00449     while(!OPEN2DLIST.empty())
00450     {
00451         //get the next state for expansion
00452         searchExpState = (SBPL_2DGridSearchState*)OPEN2DLIST.getlast();
00453                 OPEN2DLIST.remove(searchExpState, SBPL_2DSEARCH_OPEN_LIST_ID);
00454         numofExpands++;
00455 
00456                 int exp_x = searchExpState->x;
00457                 int exp_y = searchExpState->y;
00458 
00459         //iterate over successors
00460                 for(int dir = 0; dir < SBPL_2DGRIDSEARCH_NUMOF2DDIRS; dir++)
00461                 {
00462                         int newx = exp_x + dx_[dir];
00463                         int newy = exp_y + dy_[dir];            
00464                                                 
00465                         //make sure it is inside the map and has no obstacle
00466                         if(!withinMap(newx, newy))
00467                                 continue;
00468 
00469                         //compute the cost 
00470             int mapcost = __max(Grid2D[newx][newy], Grid2D[exp_x][exp_y]);
00471 
00472 #if SBPL_2DGRIDSEARCH_NUMOF2DDIRS > 8
00473             if(dir > 7){
00474                 //check two more cells through which the action goes
00475                 mapcost = __max(mapcost, Grid2D[exp_x + dx0intersects_[dir]][exp_y + dy0intersects_[dir]]); 
00476                 mapcost = __max(mapcost, Grid2D[exp_x + dx1intersects_[dir]][exp_y + dy1intersects_[dir]]); 
00477             }
00478 #endif
00479 
00480                         if(mapcost >= obsthresh) //obstacle encountered
00481                                 continue; 
00482                         int cost = (mapcost+1)*dxy_distance_mm_[dir];
00483 
00484                         //get the predecessor
00485                         searchPredState = &searchStates2D_[newx][newy];                 
00486 
00487                         //clear the list
00488                         if(searchPredState->iterationaccessed != iteration_)
00489                                 searchPredState->listelem[SBPL_2DSEARCH_OPEN_LIST_ID] = NULL;
00490 
00491                         //update predecessor if necessary
00492            if(searchPredState->iterationaccessed != iteration_ || searchPredState->g > cost + searchExpState->g)
00493            {
00494                                 searchPredState->iterationaccessed = iteration_;
00495                                 searchPredState->g = __min(INFINITECOST, cost + searchExpState->g); 
00496 
00497                                 if(searchPredState->g >= INFINITECOST)
00498                                 {
00499                                         SBPL_ERROR("ERROR: infinite g\n");
00500                                         throw new SBPL_Exception();
00501                                 }
00502 
00503                                 //put it into the list if not there already
00504                                 if(searchPredState->listelem[SBPL_2DSEARCH_OPEN_LIST_ID] == NULL)
00505                                         OPEN2DLIST.insertinfront(searchPredState, SBPL_2DSEARCH_OPEN_LIST_ID);
00506                                 //otherwise, the state remains where it is but it now has a new g-value                         
00507                         }
00508         } //over successors
00509     }//while
00510 
00511         //set lower bounds for the remaining states - none left since we exhausted the whole list
00512         largestcomputedoptf_ = INFINITECOST;
00513 
00514 
00515     SBPL_PRINTF("# of expands during 2dgridsearch=%d time=%d msecs 2Dsolcost_inmm=%d largestoptfval=%d (start=%d %d goal=%d %d)\n", 
00516                 numofExpands, (int)(((clock()-starttime)/(double)CLOCKS_PER_SEC)*1000), searchStates2D_[goalx_c][goaly_c].g, largestcomputedoptf_,
00517                         startx_c, starty_c, goalx_c, goaly_c);
00518 
00519         return false;
00520 }
00521 
00522 
00523 //experimental version
00524 //OPEN list is implemented as a bucket list
00525 bool SBPL2DGridSearch::search_withbuckets(unsigned char** Grid2D, unsigned char obsthresh, int startx_c, int starty_c, int goalx_c, int goaly_c)
00526 {
00527 
00528     SBPL_2DGridSearchState *searchExpState = NULL;
00529     SBPL_2DGridSearchState *searchPredState = NULL;
00530     int numofExpands = 0;
00531 
00532     //get the current time
00533         clock_t starttime = clock();
00534         
00535         //int max_bucketed_priority = obsthresh*10*__max(this->width_, this->height_);
00536         int max_bucketed_priority = (int)(0.1*obsthresh*dxy_distance_mm_[0]*__max(this->width_, this->height_));
00537         SBPL_PRINTF("bucket-based OPEN2D has up to %d bucketed priorities, the rest will be unsorted\n", max_bucketed_priority);
00538         CBucket OPEN2DBLIST(0, max_bucketed_priority); 
00539 
00540     SBPL_PRINTF("OPEN2D allocation time=%d msecs\n", (int)(((clock()-starttime)/(double)CLOCKS_PER_SEC)*1000));
00541 
00542         //closed = 0
00543         iteration_++;
00544 
00545         //init start and goal coordinates
00546         startX_ = startx_c;
00547         startY_ = starty_c;
00548     goalX_ = goalx_c;
00549         goalY_ = goaly_c;
00550 
00551     //check the validity of start/goal
00552     if(!withinMap(startx_c, starty_c) || !withinMap(goalx_c, goaly_c))
00553         {
00554                 SBPL_ERROR("ERROR: grid2Dsearch is called on invalid start (%d %d) or goal(%d %d)\n", startx_c, starty_c, goalx_c, goaly_c);
00555                 return false;
00556         }
00557 
00558     // initialize the start and goal states
00559     searchExpState = &searchStates2D_[startX_][startY_];
00560     initializeSearchState2D(searchExpState);
00561         //no initialization for the goal state - it will reset iteration_ variable
00562 
00563         //seed the search
00564         searchExpState->g = 0;
00565         searchExpState->heapindex = -1;
00566         OPEN2DBLIST.insert(searchExpState, searchExpState->g);  
00567     
00568     //the main repetition of expansions
00569     while(!OPEN2DBLIST.empty())
00570     {
00571         //get the next state for expansion
00572         searchExpState = (SBPL_2DGridSearchState*)OPEN2DBLIST.popminelement();
00573         numofExpands++;
00574 
00575                 int exp_x = searchExpState->x;
00576                 int exp_y = searchExpState->y;
00577 
00578         //iterate over successors
00579                 for(int dir = 0; dir < SBPL_2DGRIDSEARCH_NUMOF2DDIRS; dir++)
00580                 {
00581                         int newx = exp_x + dx_[dir];
00582                         int newy = exp_y + dy_[dir];            
00583                                                 
00584                         //make sure it is inside the map and has no obstacle
00585                         if(!withinMap(newx, newy))
00586                                 continue;
00587 
00588                         //compute the cost 
00589             int mapcost = __max(Grid2D[newx][newy], Grid2D[exp_x][exp_y]);
00590 
00591 #if SBPL_2DGRIDSEARCH_NUMOF2DDIRS > 8
00592             if(dir > 7){
00593                 //check two more cells through which the action goes
00594                 mapcost = __max(mapcost, Grid2D[exp_x + dx0intersects_[dir]][exp_y + dy0intersects_[dir]]); 
00595                 mapcost = __max(mapcost, Grid2D[exp_x + dx1intersects_[dir]][exp_y + dy1intersects_[dir]]); 
00596             }
00597 #endif
00598 
00599                         if(mapcost >= obsthresh) //obstacle encountered
00600                                 continue; 
00601                         int cost = (mapcost+1)*dxy_distance_mm_[dir];
00602 
00603                         //get the predecessor
00604                         searchPredState = &searchStates2D_[newx][newy];                 
00605 
00606                         //clear the element from OPEN
00607                         if(searchPredState->iterationaccessed != iteration_)
00608                                 searchPredState->heapindex = -1;
00609 
00610                         //update predecessor if necessary
00611            if(searchPredState->iterationaccessed != iteration_ || searchPredState->g > cost + searchExpState->g)
00612            {
00613                                 int oldstatepriority = searchPredState->g;
00614                                 searchPredState->iterationaccessed = iteration_;
00615                                 searchPredState->g = __min(INFINITECOST, cost + searchExpState->g); 
00616 
00617                                 if(searchPredState->g >= INFINITECOST)
00618                                 {
00619                                         SBPL_ERROR("ERROR: infinite g\n");
00620                                         throw new SBPL_Exception();
00621                                 }
00622 
00623                                 //put it into the list if not there already
00624                                 if(searchPredState->heapindex != -1)
00625                                         OPEN2DBLIST.remove(searchPredState, oldstatepriority);
00626                                 OPEN2DBLIST.insert(searchPredState, searchPredState->g);
00627                         }
00628         } //over successors
00629     }//while
00630 
00631         //set lower bounds for the remaining states
00632     if(!OPEN2DBLIST.empty()) 
00633                 largestcomputedoptf_ = OPEN2DBLIST.getminpriority();
00634         else
00635                 largestcomputedoptf_ = INFINITECOST;
00636 
00637 
00638 
00639     SBPL_PRINTF("# of expands during 2dgridsearch=%d time=%d msecs 2Dsolcost_inmm=%d largestoptfval=%d bucketassortedarraymaxsize=%d (start=%d %d goal=%d %d)\n", 
00640                 numofExpands, (int)(((clock()-starttime)/(double)CLOCKS_PER_SEC)*1000), searchStates2D_[goalx_c][goaly_c].g, largestcomputedoptf_,
00641                         OPEN2DBLIST.maxassortedpriorityVsize,
00642                         startx_c, starty_c, goalx_c, goaly_c);
00643 
00644         return false;
00645 }
00646 
00647 
00648 //experimental version
00649 //OPEN list is implemented as a sliding bucket list
00650 bool SBPL2DGridSearch::search_withslidingbuckets(unsigned char** Grid2D, unsigned char obsthresh, int startx_c, int starty_c, int goalx_c, int goaly_c,
00651                                                                                                  SBPL_2DGRIDSEARCH_TERM_CONDITION termination_condition)
00652 {
00653 
00654     SBPL_2DGridSearchState *searchExpState = NULL;
00655     SBPL_2DGridSearchState *searchPredState = NULL;
00656     int numofExpands = 0;
00657 
00658 #if DEBUG
00659 #ifndef ROS
00660   const char* 2dgriddebug = "2dgriddebug.txt";
00661 #endif
00662         FILE* f2Dsearch = SBPL_FOPEN(2dgriddebug, "w");
00663 #endif
00664         
00665         //closed = 0
00666         iteration_++;
00667 
00668         //init start and goal coordinates
00669         startX_ = startx_c;
00670         startY_ = starty_c;
00671     goalX_ = goalx_c;
00672         goalY_ = goaly_c;
00673 
00674     //check the validity of start/goal
00675     if(!withinMap(startx_c, starty_c) || !withinMap(goalx_c, goaly_c))
00676         {
00677                 SBPL_ERROR("ERROR: grid2Dsearch is called on invalid start (%d %d) or goal(%d %d)\n", startx_c, starty_c, goalx_c, goaly_c);
00678 #if DEBUG
00679     SBPL_FCLOSE(f2Dsearch);
00680 #endif
00681                 return false;
00682         }
00683 
00684         //reset OPEN
00685         OPEN2DBLIST_->reset();  
00686 
00687         //set the term. condition
00688         term_condition_usedlast = termination_condition;
00689 
00690     // initialize the start and goal states
00691     searchExpState = &searchStates2D_[startX_][startY_];
00692     initializeSearchState2D(searchExpState);
00693     initializeSearchState2D(&searchStates2D_[goalx_c][goaly_c]);
00694     SBPL_2DGridSearchState* search2DGoalState = &searchStates2D_[goalx_c][goaly_c];
00695 
00696         //seed the search
00697         searchExpState->g = 0;
00698         OPEN2DBLIST_->insert(searchExpState, searchExpState->g);        
00699 
00700         //set the termination condition
00701         float term_factor = 0.0;
00702         switch(termination_condition)
00703         {
00704         case SBPL_2DGRIDSEARCH_TERM_CONDITION_OPTPATHFOUND:
00705                 term_factor = 1;
00706                 break;
00707         case SBPL_2DGRIDSEARCH_TERM_CONDITION_20PERCENTOVEROPTPATH:
00708                 term_factor = (float)(1.0/1.2);
00709                 break;
00710         case SBPL_2DGRIDSEARCH_TERM_CONDITION_TWOTIMESOPTPATH:
00711                 term_factor = 0.5;
00712                 break;
00713         case SBPL_2DGRIDSEARCH_TERM_CONDITION_THREETIMESOPTPATH:
00714                 term_factor = (float)(1.0/3.0);
00715                 break;
00716         case SBPL_2DGRIDSEARCH_TERM_CONDITION_ALLCELLS:
00717                 term_factor = 0.0;
00718                 break;
00719         default:
00720                 SBPL_ERROR("ERROR: incorrect termination factor for grid2Dsearch\n");
00721                 term_factor = 0.0;
00722         };
00723         
00724     //get the current time
00725         clock_t starttime = clock();
00726 
00727 
00728         char *pbClosed = (char*)calloc(1, width_*height_);   
00729 
00730     //the main repetition of expansions
00731         SBPL_PRINTF("2D search with sliding buckets and term_factor=%.3f\n", term_factor);
00732         int prevg = 0;
00733     while(!OPEN2DBLIST_->empty() && search2DGoalState->g > term_factor*OPEN2DBLIST_->getminkey())
00734     {
00735 
00736 #if DEBUG
00737                 SBPL_FPRINTF(f2Dsearch, "currentminelement_priority before pop=%d\n",  OPEN2DBLIST_->getminkey());
00738 #endif
00739 
00740         //get the next state for expansion
00741         searchExpState = (SBPL_2DGridSearchState*)OPEN2DBLIST_->popminelement();
00742 
00743                 if(searchExpState->g > OPEN2DBLIST_->getminkey()){
00744                         SBPL_ERROR("ERROR: g=%d for state %d %d but minpriority=%d (prevg=%d)\n", searchExpState->g, 
00745                                 searchExpState->x, searchExpState->y, OPEN2DBLIST_->getminkey(), prevg);
00746                 }
00747                 prevg = searchExpState->g;
00748 
00749                 int exp_x = searchExpState->x;
00750                 int exp_y = searchExpState->y;
00751 
00752                 //close the state if it wasn't yet
00753                 if(pbClosed[exp_x + width_*exp_y] == 1)
00754                         continue;
00755                 pbClosed[exp_x + width_*exp_y] = 1;
00756 
00757 #if DEBUG
00758                 SBPL_FPRINTF(f2Dsearch, "expanding state <%d %d> with g=%d (currentminelement_priority=%d, currentfirstbucket_bindex=%d, currentfirstbucket_priority=%d)\n", 
00759                         searchExpState->x, searchExpState->y, searchExpState->g, OPEN2DBLIST_->getminkey(), 
00760                         OPEN2DBLIST_->currentfirstbucket_bindex, OPEN2DBLIST_->currentfirstbucket_priority);
00761 #endif
00762 
00763                 //expand
00764         numofExpands++;
00765 
00766         //iterate over successors
00767                 int expcost = Grid2D[exp_x][exp_y];
00768                 for(int dir = 0; dir < SBPL_2DGRIDSEARCH_NUMOF2DDIRS; dir++)
00769                 {
00770                         int newx = exp_x + dx_[dir];
00771                         int newy = exp_y + dy_[dir];            
00772                                                 
00773                         //make sure it is inside the map and has no obstacle
00774                         if(!withinMap(newx, newy))
00775                                 continue;
00776 
00777                         if(pbClosed[newx + width_*newy] == 1)
00778                                 continue;
00779 
00780                         //compute the cost 
00781             int mapcost = __max(Grid2D[newx][newy], expcost);
00782 
00783 #if SBPL_2DGRIDSEARCH_NUMOF2DDIRS > 8
00784             if(dir > 7){
00785                 //check two more cells through which the action goes
00786                 mapcost = __max(mapcost, Grid2D[exp_x + dx0intersects_[dir]][exp_y + dy0intersects_[dir]]); 
00787                 mapcost = __max(mapcost, Grid2D[exp_x + dx1intersects_[dir]][exp_y + dy1intersects_[dir]]); 
00788             }
00789 #endif
00790 
00791                         if(mapcost >= obsthresh) //obstacle encountered
00792                                 continue; 
00793                         int cost = (mapcost+1)*dxy_distance_mm_[dir];
00794 
00795                         //get the predecessor
00796                         searchPredState = &searchStates2D_[newx][newy];                 
00797 
00798                         //update predecessor if necessary
00799            if(searchPredState->iterationaccessed != iteration_ || searchPredState->g > cost + searchExpState->g)
00800            {
00801                                 searchPredState->iterationaccessed = iteration_;
00802                                 searchPredState->g = __min(INFINITECOST, cost + searchExpState->g); 
00803 
00804 #if DEBUG
00805                                 SBPL_FPRINTF(f2Dsearch, "inserting state <%d %d> with g=%d\n", searchPredState->x, searchPredState->y, searchPredState->g);
00806 #endif
00807 
00808                                 //put it into the list
00809                                 OPEN2DBLIST_->insert(searchPredState, searchPredState->g);
00810                         }
00811         } //over successors
00812     }//while
00813 
00814         //set lower bounds for the remaining states
00815     if(!OPEN2DBLIST_->empty()) 
00816                 largestcomputedoptf_ = ((SBPL_2DGridSearchState*)OPEN2DBLIST_->getminelement())->g;
00817         else
00818                 largestcomputedoptf_ = INFINITECOST;
00819 
00820         delete [] pbClosed;
00821 
00822 
00823     SBPL_PRINTF("# of expands during 2dgridsearch=%d time=%d msecs 2Dsolcost_inmm=%d largestoptfval=%d (start=%d %d goal=%d %d)\n", 
00824                 numofExpands, (int)(((clock()-starttime)/(double)CLOCKS_PER_SEC)*1000), searchStates2D_[goalx_c][goaly_c].g, largestcomputedoptf_,
00825                         startx_c, starty_c, goalx_c, goaly_c);
00826 
00827 #if DEBUG
00828   SBPL_FCLOSE(f2Dsearch);
00829 #endif
00830         return false;
00831 }
00832 //-----------------------------------------------------------------------------------------------------------------------
00833 
00834 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


sbpl
Author(s): Maxim Likhachev/maximl@seas.upenn.edu
autogenerated on Fri Jan 18 2013 13:41:52