utils.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 #if MEM_CHECK == 1
00035 void DisableMemCheck()
00036 {
00037 // Get the current state of the flag
00038 // and store it in a temporary variable
00039 int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
00040 
00041 // Turn On (OR) - All freed memory is re-initialized with xDD
00042 tmpFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
00043 
00044 // Turn Off (AND) - memory checking is disabled for future allocations
00045 tmpFlag &= ~_CRTDBG_ALLOC_MEM_DF;
00046 
00047 // Set the new state for the flag
00048 _CrtSetDbgFlag( tmpFlag );
00049 
00050 }
00051 
00052 void EnableMemCheck()
00053 {
00054 // Get the current state of the flag
00055 // and store it in a temporary variable
00056 int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
00057 
00058 // Turn On (OR) - All freed memory is re-initialized with xDD
00059 tmpFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
00060 
00061 // Turn On (OR) - memory checking is enabled for future allocations
00062 tmpFlag |= _CRTDBG_ALLOC_MEM_DF;
00063 
00064 // Set the new state for the flag
00065 _CrtSetDbgFlag( tmpFlag );
00066 
00067 }
00068 #endif
00069 
00070 void checkmdpstate(CMDPSTATE* state)
00071 {
00072 #if DEBUG == 0
00073         SBPL_ERROR("ERROR: checkMDPstate is too expensive for not in DEBUG mode\n");
00074         throw new SBPL_Exception();
00075 #endif
00076 
00077         for(int aind = 0; aind < (int)state->Actions.size(); aind++)
00078         {
00079                 for(int aind1 = 0; aind1 < (int)state->Actions.size(); aind1++)
00080                 {
00081                         if(state->Actions[aind1]->ActionID == state->Actions[aind]->ActionID &&
00082                                 aind1 != aind)
00083                         {
00084                                 SBPL_ERROR("ERROR in CheckMDP: multiple actions with the same ID exist\n");
00085                                 throw new SBPL_Exception();
00086                         }
00087                 }
00088                 for(int sind = 0; sind < (int)state->Actions[aind]->SuccsID.size(); sind++)
00089                 {       
00090                         for(int sind1 = 0; sind1 < (int)state->Actions[aind]->SuccsID.size(); sind1++)
00091                         {
00092                                 if(state->Actions[aind]->SuccsID[sind] == state->Actions[aind]->SuccsID[sind1] &&
00093                                         sind != sind1)
00094                                 {
00095                                         SBPL_ERROR("ERROR in CheckMDP: multiple outcomes with the same ID exist\n");
00096                                         throw new SBPL_Exception();
00097                                 }
00098                         }
00099                 }               
00100         }
00101 }
00102 
00103 
00104 void CheckMDP(CMDP* mdp)
00105 {
00106         for(int i = 0; i < (int)mdp->StateArray.size(); i++)
00107         {
00108                 checkmdpstate(mdp->StateArray[i]);
00109         }
00110 }
00111 
00112 
00113 
00114 
00115 void PrintMatrix(int** matrix, int rows, int cols, FILE* fOut)
00116 {
00117         for(int r = 0; r < rows; r++)
00118         {
00119                 for(int c = 0; c < cols; c++)
00120                 {
00121                         SBPL_FPRINTF(fOut, "%d ", matrix[r][c]);
00122                 }
00123                 SBPL_FPRINTF(fOut, "\n");
00124         }
00125 }
00126 
00127 
00128 //return true if there exists a path from sourcestate to targetstate and false otherwise
00129 bool PathExists(CMDP* pMarkovChain, CMDPSTATE* sourcestate, CMDPSTATE* targetstate)
00130 {
00131         CMDPSTATE* state;
00132         vector<CMDPSTATE*> WorkList;
00133         int i;
00134         bool *bProcessed = new bool [pMarkovChain->StateArray.size()];
00135         bool bFound = false;
00136 
00137         //insert the source state
00138         WorkList.push_back(sourcestate);
00139         while((int)WorkList.size() > 0)
00140         {
00141                 //get the state and its info
00142                 state = WorkList[WorkList.size()-1];
00143                 WorkList.pop_back();
00144 
00145                 //Markov Chain should just contain a single policy
00146                 if((int)state->Actions.size() > 1)
00147                 {
00148                         SBPL_ERROR("ERROR in PathExists: Markov Chain is a general MDP\n");
00149                         throw new SBPL_Exception();
00150                 }
00151 
00152                 if(state == targetstate)
00153                 {
00154                         //path found
00155                         bFound = true;
00156                         break;
00157                 }
00158 
00159                 //otherwise just insert policy successors into the worklist unless it is a goal state
00160                 for(int sind = 0; (int)state->Actions.size() != 0 && sind < (int)state->Actions[0]->SuccsID.size(); sind++)
00161                 {
00162                         //get a successor
00163                         for(i = 0; i < (int)pMarkovChain->StateArray.size(); i++)
00164                         {
00165                                 if(pMarkovChain->StateArray[i]->StateID == state->Actions[0]->SuccsID[sind])
00166                                         break;
00167                         }
00168                         if(i == (int)pMarkovChain->StateArray.size())
00169                         {       
00170                                 SBPL_ERROR("ERROR in PathExists: successor is not found\n");
00171                                 throw new SBPL_Exception();
00172                         }
00173                         CMDPSTATE* SuccState = pMarkovChain->StateArray[i];
00174                                         
00175                         //insert at the end of list if not there or processed already
00176                         if(!bProcessed[i])
00177                         {
00178                                 bProcessed[i] = true;
00179                                 WorkList.push_back(SuccState);
00180                         }
00181                 } //for successors
00182         }//while WorkList is non empty
00183 
00184         delete [] bProcessed;
00185 
00186         return bFound;
00187 }       
00188 
00189 int ComputeNumofStochasticActions(CMDP* pMDP)
00190 {
00191         int i;
00192         int nNumofStochActions = 0;
00193         SBPL_PRINTF("ComputeNumofStochasticActions...\n");
00194 
00195         for(i = 0; i < (int)pMDP->StateArray.size(); i++)
00196         {
00197                 for(int aind = 0; aind < (int)pMDP->StateArray[i]->Actions.size(); aind++)
00198                 {
00199                         if((int)pMDP->StateArray[i]->Actions[aind]->SuccsID.size() > 1)
00200                                 nNumofStochActions++;
00201                 }
00202         }
00203         SBPL_PRINTF("done\n");
00204 
00205         return nNumofStochActions;
00206 }
00207 
00208 
00209 void EvaluatePolicy(CMDP* PolicyMDP, int StartStateID, int GoalStateID,
00210                                         double* PolValue, bool *bFullPolicy, double* Pcgoal, int *nMerges,
00211                                         bool* bCycles)
00212 {
00213         int i, j, startind=-1;
00214         double delta = INFINITECOST;
00215         double mindelta = 0.1;
00216 
00217         *Pcgoal = 0;
00218         *nMerges = 0;
00219 
00220         SBPL_PRINTF("Evaluating policy...\n");
00221 
00222         //create and initialize values
00223         double* vals = new double [PolicyMDP->StateArray.size()];
00224         double* Pcvals = new double [PolicyMDP->StateArray.size()];
00225         for(i = 0; i < (int)PolicyMDP->StateArray.size(); i++)
00226         {
00227                 vals[i] = 0;
00228                 Pcvals[i] = 0;
00229 
00230                 //remember the start index
00231                 if(PolicyMDP->StateArray[i]->StateID == StartStateID)
00232                 {
00233                         startind = i;
00234                         Pcvals[i] = 1;
00235                 }
00236         }
00237 
00238         //initially assume full policy
00239         *bFullPolicy = true;
00240         bool bFirstIter = true;
00241         while(delta > mindelta)
00242         {
00243                 delta = 0;
00244                 for(i = 0; i < (int)PolicyMDP->StateArray.size(); i++)
00245                 {
00246                         //get the state
00247                         CMDPSTATE* state = PolicyMDP->StateArray[i];
00248 
00249                         //do the backup for values
00250                         if(state->StateID == GoalStateID)
00251                         {
00252                                 vals[i] = 0;
00253                         }
00254                         else if((int)state->Actions.size() == 0)
00255                         {
00256                                 *bFullPolicy = false;
00257                                 vals[i] = UNKNOWN_COST;
00258                                 *PolValue = vals[startind];
00259                                 return;
00260                         }
00261                         else
00262                         {
00263                                 //normal backup
00264                                 CMDPACTION* action = state->Actions[0];
00265 
00266                                 //do backup
00267                                 double Q = 0;
00268                                 for(int oind = 0; oind < (int)action->SuccsID.size(); oind++)
00269                                 {
00270                                         //get the state
00271                                         for(j = 0; j < (int)PolicyMDP->StateArray.size(); j++)
00272                                         {       
00273                                                 if(PolicyMDP->StateArray[j]->StateID == action->SuccsID[oind])
00274                                                         break;
00275                                         }
00276                                         if(j == (int)PolicyMDP->StateArray.size())
00277                                         {
00278                                                 SBPL_ERROR("ERROR in EvaluatePolicy: incorrect successor %d\n", 
00279                                                         action->SuccsID[oind]);
00280                                                 throw new SBPL_Exception();
00281                                         }
00282                                         Q += action->SuccsProb[oind]*(vals[j] + action->Costs[oind]);
00283                                 }
00284 
00285                                 if(vals[i] > Q)
00286                                 {
00287                                         SBPL_ERROR("ERROR in EvaluatePolicy: val is decreasing\n"); 
00288                                         throw new SBPL_Exception();
00289                                 }
00290 
00291                                 //update delta
00292                                 if(delta < Q - vals[i])
00293                                         delta = Q-vals[i];
00294 
00295                                 //set the value
00296                                 vals[i] = Q;
00297                         }
00298 
00299                         //iterate through all the predecessors and compute Pc
00300                         double Pc = 0;
00301                         //go over all predecessor states
00302                         int nMerge = 0;
00303                         for(j = 0; j < (int)PolicyMDP->StateArray.size(); j++)
00304                         {
00305                                 for(int oind = 0; (int)PolicyMDP->StateArray[j]->Actions.size() > 0 && 
00306                                         oind <  (int)PolicyMDP->StateArray[j]->Actions[0]->SuccsID.size(); oind++)
00307                                 {
00308                                         if(PolicyMDP->StateArray[j]->Actions[0]->SuccsID[oind] == state->StateID)
00309                                         {
00310                                                 //process the predecessor
00311                                                 double PredPc = Pcvals[j];
00312                                                 double OutProb = PolicyMDP->StateArray[j]->Actions[0]->SuccsProb[oind];
00313                                 
00314                                                 //accumulate into Pc
00315                                                 Pc = Pc + OutProb*PredPc;
00316                                                 nMerge++;
00317 
00318                                                 //check for cycles
00319                                                 if(bFirstIter && !(*bCycles))
00320                                                 {
00321                                                         if(PathExists(PolicyMDP, state, PolicyMDP->StateArray[j]))
00322                                                                 *bCycles = true;
00323                                                 }
00324                                         }
00325                                 }
00326                         }
00327                         if(bFirstIter && state->StateID != GoalStateID && nMerge > 0)
00328                                 *nMerges += (nMerge-1);
00329 
00330                         //assign Pc
00331                         if(state->StateID != StartStateID)
00332                                 Pcvals[i] = Pc;
00333 
00334                         if(state->StateID == GoalStateID)
00335                                 *Pcgoal = Pcvals[i];
00336                 } //over  states
00337                 bFirstIter = false;
00338         } //until delta small
00339 
00340         *PolValue = vals[startind];
00341         
00342         SBPL_PRINTF("done\n");
00343 }
00344 
00345 
00346 
00347 void get_bresenham_parameters(int p1x, int p1y, int p2x, int p2y, bresenham_param_t *params)
00348 {
00349   params->UsingYIndex = 0;
00350 
00351   if (fabs((double)(p2y-p1y)/(double)(p2x-p1x)) > 1)
00352     (params->UsingYIndex)++;
00353 
00354   if (params->UsingYIndex)
00355     {
00356       params->Y1=p1x;
00357       params->X1=p1y;
00358       params->Y2=p2x;
00359       params->X2=p2y;
00360     }
00361   else
00362     {
00363       params->X1=p1x;
00364       params->Y1=p1y;
00365       params->X2=p2x;
00366       params->Y2=p2y;
00367     }
00368 
00369    if ((p2x - p1x) * (p2y - p1y) < 0)
00370     {
00371       params->Flipped = 1;
00372       params->Y1 = -params->Y1;
00373       params->Y2 = -params->Y2;
00374     }
00375   else
00376     params->Flipped = 0;
00377 
00378   if (params->X2 > params->X1)
00379     params->Increment = 1;
00380   else
00381     params->Increment = -1;
00382 
00383   params->DeltaX=params->X2-params->X1;
00384   params->DeltaY=params->Y2-params->Y1;
00385 
00386   params->IncrE=2*params->DeltaY*params->Increment;
00387   params->IncrNE=2*(params->DeltaY-params->DeltaX)*params->Increment;
00388   params->DTerm=(2*params->DeltaY-params->DeltaX)*params->Increment;
00389 
00390   params->XIndex = params->X1;
00391   params->YIndex = params->Y1;
00392 }
00393 
00394 void get_current_point(bresenham_param_t *params, int *x, int *y)
00395 {
00396   if (params->UsingYIndex)
00397     {
00398       *y = params->XIndex;
00399       *x = params->YIndex;
00400       if (params->Flipped)
00401         *x = -*x;
00402     }
00403   else
00404     {
00405       *x = params->XIndex;
00406       *y = params->YIndex;
00407       if (params->Flipped)
00408         *y = -*y;
00409     }
00410 }
00411 
00412 int get_next_point(bresenham_param_t *params)
00413 {
00414   if (params->XIndex == params->X2)
00415     {
00416       return 0;
00417     }
00418   params->XIndex += params->Increment;
00419   if (params->DTerm < 0 || (params->Increment < 0 && params->DTerm <= 0))
00420     params->DTerm += params->IncrE;
00421   else
00422     {
00423       params->DTerm += params->IncrNE;
00424       params->YIndex += params->Increment;
00425     }
00426   return 1;
00427 }
00428 
00429 
00430 
00431 //converts discretized version of angle into continuous (radians)
00432 //maps 0->0, 1->delta, 2->2*delta, ...
00433 double DiscTheta2Cont(int nTheta, int NUMOFANGLEVALS)
00434 {
00435     double thetaBinSize = 2.0*PI_CONST/NUMOFANGLEVALS;
00436     return nTheta*thetaBinSize;
00437 }
00438 
00439 
00440 
00441 //converts continuous (radians) version of angle into discrete
00442 //maps 0->0, [delta/2, 3/2*delta)->1, [3/2*delta, 5/2*delta)->2,...
00443 int ContTheta2Disc(double fTheta, int NUMOFANGLEVALS)
00444 {
00445 
00446     double thetaBinSize = 2.0*PI_CONST/NUMOFANGLEVALS;
00447     return (int)(normalizeAngle(fTheta+thetaBinSize/2.0)/(2.0*PI_CONST)*(NUMOFANGLEVALS));
00448 
00449 }
00450 
00451 
00452 
00453 
00454 //input angle should be in radians
00455 //counterclockwise is positive
00456 //output is an angle in the range of from 0 to 2*PI
00457 double normalizeAngle(double angle)
00458 {
00459     double retangle = angle;
00460 
00461     //get to the range from -2PI, 2PI
00462     if(fabs(retangle) > 2*PI_CONST)
00463         retangle = retangle - ((int)(retangle/(2*PI_CONST)))*2*PI_CONST; 
00464 
00465     //get to the range 0, 2PI
00466     if(retangle < 0)
00467         retangle += 2*PI_CONST;
00468 
00469     if(retangle < 0 || retangle > 2*PI_CONST)
00470         {
00471         SBPL_ERROR("ERROR: after normalization of angle=%f we get angle=%f\n", angle, retangle);
00472         }
00473 
00474     return retangle;
00475 }
00476 
00477 
00478 
00479 /*
00480  * point - the point to test
00481  *
00482  * Function derived from http://ozviz.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/
00483  */
00484 bool IsInsideFootprint(sbpl_2Dpt_t pt, vector<sbpl_2Dpt_t>* bounding_polygon){
00485   
00486   int counter = 0;
00487   int i;
00488   double xinters;
00489   sbpl_2Dpt_t p1;
00490   sbpl_2Dpt_t p2;
00491   int N = bounding_polygon->size();
00492 
00493   p1 = bounding_polygon->at(0);
00494   for (i=1;i<=N;i++) {
00495     p2 = bounding_polygon->at(i % N);
00496     if (pt.y > __min(p1.y,p2.y)) {
00497       if (pt.y <= __max(p1.y,p2.y)) {
00498         if (pt.x <= __max(p1.x,p2.x)) {
00499           if (p1.y != p2.y) {
00500             xinters = (pt.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;
00501             if (p1.x == p2.x || pt.x <= xinters)
00502               counter++;
00503           }
00504         }
00505       }
00506     }
00507     p1 = p2;
00508   }
00509 
00510   if (counter % 2 == 0)
00511     return false;
00512   else
00513     return true;
00514 #if DEBUG
00515   //SBPL_PRINTF("Returning from inside footprint: %d\n", c);
00516 #endif
00517   //  return c;
00518 
00519 }
00520 
00521 
00522 double computeMinUnsignedAngleDiff(double angle1, double angle2)
00523 {
00524     //get the angles into 0-2*PI range
00525     angle1 = normalizeAngle(angle1);
00526     angle2 = normalizeAngle(angle2);
00527 
00528     double anglediff = fabs(angle1-angle2);
00529 
00530     //see if we can take a shorter route
00531     if(anglediff > PI_CONST){
00532         anglediff = fabs(anglediff - 2*PI_CONST);
00533     }
00534 
00535     return anglediff;
00536 }
00537 
00538 
00539 //computes 8-connected distances to obstacles and non-free areas in two linear passes and returns them in disttoObs_incells 
00540 //and disttoNonfree_incells arrays. The distances are in terms of the number of cells but are floats. These distances
00541 //can then be converted into the actual distances using the actual discretization values
00542 //areas outside of the map are considered to be obstacles
00543 void computeDistancestoNonfreeAreas(unsigned char** Grid2D, int width_x, int height_y, unsigned char obsthresh, float** disttoObs_incells, 
00544                                                                         float** disttoNonfree_incells)
00545 {
00546         int x,y,nbrx,nbry;
00547         float mindisttoObs, mindisttoNonfree;
00548         float maxDist = (float)(__min(width_x, height_y));
00549         float disttoObs, disttoNonfree;
00550         int dir;
00551         const int NUMOF2DQUASIDIRS = 4;
00552 
00553     // for quasi-Euclidean distance transform
00554     // going left-to-right, top-to-bottom
00555     int dxdownlefttoright_[NUMOF2DQUASIDIRS];
00556     int dydownlefttoright_[NUMOF2DQUASIDIRS];
00557     int dxdownrighttoleft_[NUMOF2DQUASIDIRS];
00558     int dydownrighttoleft_[NUMOF2DQUASIDIRS];
00559 
00560     // going right-to-left, bottom-to-top
00561     int dxuprighttoleft_[NUMOF2DQUASIDIRS];
00562     int dyuprighttoleft_[NUMOF2DQUASIDIRS];
00563     int dxuplefttoright_[NUMOF2DQUASIDIRS];
00564     int dyuplefttoright_[NUMOF2DQUASIDIRS];
00565 
00566     // distances to the above nbrs
00567     float distdownlefttoright_[NUMOF2DQUASIDIRS];
00568     float distdownrighttoleft_[NUMOF2DQUASIDIRS];
00569     float distuprighttoleft_[NUMOF2DQUASIDIRS];
00570     float distuplefttoright_[NUMOF2DQUASIDIRS];
00571 
00572         // and for distance transform:
00573     // increasing x (outer)
00574     // increasing y (inner)
00575     //  [2]
00576     //  [1][s]
00577     //  [0][3]
00578     dxdownlefttoright_[0] = -1; dydownlefttoright_[0] = -1;     
00579         dxdownlefttoright_[1] = -1; dydownlefttoright_[1] = 0;  
00580         dxdownlefttoright_[2] = -1; dydownlefttoright_[2] = 1;  
00581         dxdownlefttoright_[3] = 0; dydownlefttoright_[3] = -1;  
00582 
00583     // increasing x (outer)
00584     // decreasing y (inner)
00585     //  [2][3]
00586     //  [1][s]
00587     //  [0] 
00588     dxdownrighttoleft_[0] = -1; dydownrighttoleft_[0] = -1;     
00589         dxdownrighttoleft_[1] = -1; dydownrighttoleft_[1] = 0;  
00590         dxdownrighttoleft_[2] = -1; dydownrighttoleft_[2] = 1;  
00591         dxdownrighttoleft_[3] = 0; dydownrighttoleft_[3] = 1;   
00592     
00593     // decreasing x (outer)
00594     // decreasing y (inner)
00595     //  [3][2]
00596     //  [s][1]
00597     //     [0] 
00598     dxuprighttoleft_[0] = 1; dyuprighttoleft_[0] = -1;  
00599         dxuprighttoleft_[1] = 1; dyuprighttoleft_[1] = 0;       
00600         dxuprighttoleft_[2] = 1; dyuprighttoleft_[2] = 1;       
00601         dxuprighttoleft_[3] = 0; dyuprighttoleft_[3] = 1;       
00602 
00603     // decreasing x (outer)
00604     // increasing y (inner)
00605     //     [2]
00606     //  [s][1]
00607     //  [3][0] 
00608     dxuplefttoright_[0] = 1; dyuplefttoright_[0] = -1;  
00609         dxuplefttoright_[1] = 1; dyuplefttoright_[1] = 0;       
00610         dxuplefttoright_[2] = 1; dyuplefttoright_[2] = 1;       
00611         dxuplefttoright_[3] = 0; dyuplefttoright_[3] = -1;      
00612 
00613     // insert the corresponding distances
00614     distdownlefttoright_[0] = (float)1.414;
00615     distdownlefttoright_[1] = (float)1.0;
00616     distdownlefttoright_[2] = (float)1.414;
00617     distdownlefttoright_[3] = (float)1.0;
00618 
00619     distdownrighttoleft_[0] = (float)1.414;
00620     distdownrighttoleft_[1] = (float)1.0;
00621     distdownrighttoleft_[2] = (float)1.414;
00622     distdownrighttoleft_[3] = (float)1.0;
00623 
00624     distuprighttoleft_[0] = (float)1.414;
00625     distuprighttoleft_[1] = (float)1.0;
00626     distuprighttoleft_[2] = (float)1.414;
00627     distuprighttoleft_[3] = (float)1.0;
00628 
00629     distuplefttoright_[0] = (float)1.414;
00630     distuplefttoright_[1] = (float)1.0;
00631     distuplefttoright_[2] = (float)1.414;
00632     distuplefttoright_[3] = (float)1.0;
00633 
00634 
00635         // step through the map from top to bottom,
00636         // alternating left-to-right then right-to-left
00637         // This order maintains the invariant that the min distance for each
00638         // cell to all previously-visited obstacles is accurate
00639         for(x = 0; x < width_x; x++)
00640         {
00641                 // move from left to right
00642                 if (x%2 == 0) {
00643         
00644                         for(y = 0; y < height_y; y++)
00645                                 {
00646                 
00647                                         mindisttoObs = maxDist; // initialize to max distance
00648                                         mindisttoNonfree = maxDist;
00649 
00650                                         // if cell is an obstacle, set disttoObs to 0 and continue
00651                                         if (Grid2D[x][y] >= obsthresh){
00652                                                 disttoObs_incells[x][y] = 0;
00653                                                 disttoNonfree_incells[x][y] = 0;
00654                                                 continue;
00655                                         }
00656                                         
00657                                         if(Grid2D[x][y] > 0){
00658                                                 mindisttoNonfree = 0;
00659                                         }
00660                                         
00661                                         //iterate over predecessors
00662                                         for(dir = 0; dir < NUMOF2DQUASIDIRS; dir++){
00663                                                 nbrx = x + dxdownlefttoright_[dir];
00664                                                 nbry = y + dydownlefttoright_[dir];             
00665                     
00666                                                 //make sure it is inside the map and has no obstacle
00667                                                 // compute min cost to an obstacle for each cell, using 
00668                                                 // *just* the cells already computed this pass for checking distance
00669                                                 if(nbrx < 0 || nbrx >= width_x || nbry < 0 || nbry >= height_y){
00670                                                         disttoObs = distdownlefttoright_[dir];
00671                                                         disttoNonfree = disttoObs;
00672                                                 } 
00673                                                 else 
00674                                                 {
00675                                                         disttoObs = distdownlefttoright_[dir] + disttoObs_incells[nbrx][nbry];
00676                                                         disttoNonfree = distdownlefttoright_[dir] + disttoNonfree_incells[nbrx][nbry];
00677                                                 }
00678                     
00679                                                 if (disttoObs < mindisttoObs)
00680                                                         mindisttoObs = disttoObs;
00681                                                 if (disttoNonfree < mindisttoNonfree)
00682                                                         mindisttoNonfree = disttoNonfree;
00683                                         }//over preds
00684             
00685                                         disttoObs_incells[x][y] = mindisttoObs;
00686                                         disttoNonfree_incells[x][y] = mindisttoNonfree;
00687                                 }
00688         
00689                 } else {
00690                                                 
00691                         // move from right to left
00692                         for(y = height_y-1; y >= 0; y--)
00693                                 {
00694 
00695                                         mindisttoObs = maxDist; // initialize to max distance
00696                                         mindisttoNonfree = maxDist;
00697 
00698                                         // if cell is an obstacle, set disttoObs to 0 and continue
00699                                         if (Grid2D[x][y] >= obsthresh){
00700                                                 disttoObs_incells[x][y] = 0;
00701                                                 disttoNonfree_incells[x][y] = 0;
00702                                                 continue;
00703                                         }
00704                                         
00705                                         if(Grid2D[x][y] > 0){
00706                                                 mindisttoNonfree = 0;
00707                                         }
00708 
00709 
00710                                         //iterate over predecessors
00711                                         for(dir = 0; dir < NUMOF2DQUASIDIRS; dir++)
00712                                                 {
00713                                                         nbrx = x + dxdownrighttoleft_[dir];
00714                                                         nbry = y + dydownrighttoleft_[dir];             
00715                         
00716                                                         //make sure it is inside the map and has no obstacle
00717                                                         // compute min cost to an obstacle for each cell, using 
00718                                                         // *just* the cells already computed this pass for checking distance
00719                                                         if(nbrx < 0 || nbrx >= width_x || nbry < 0 || nbry >= height_y){
00720                                                                 disttoObs = distdownrighttoleft_[dir];
00721                                                                 disttoNonfree = disttoObs;
00722                                                         } else {
00723                                                                 disttoObs = distdownrighttoleft_[dir] + disttoObs_incells[nbrx][nbry];
00724                                                                 disttoNonfree = distdownrighttoleft_[dir] + disttoNonfree_incells[nbrx][nbry];
00725                                                         }
00726                         
00727                                                         if (disttoObs < mindisttoObs)
00728                                                                 mindisttoObs = disttoObs;
00729                                                         if (disttoNonfree < mindisttoNonfree)
00730                                                                 mindisttoNonfree = disttoNonfree;
00731                                                 }
00732                 
00733                                         disttoObs_incells[x][y] = mindisttoObs;
00734                                         disttoNonfree_incells[x][y] = mindisttoNonfree;
00735                                 }   
00736                         //SBPL_PRINTF("x=%d\n", x);
00737                 }
00738         }
00739 
00740         // step through the map from bottom to top
00741         for(x = width_x-1; x >= 0; x--)
00742         {
00743     
00744                 // move from right to left
00745                 if (x%2 == 0) {
00746         
00747                         for(y = height_y-1; y >= 0; y--)
00748                                 {
00749                 
00750                                         // initialize to current distance
00751                                         mindisttoObs = disttoObs_incells[x][y];
00752                                         mindisttoNonfree = disttoNonfree_incells[x][y];
00753 
00754                                         //iterate over predecessors
00755                                         for(dir = 0; dir < NUMOF2DQUASIDIRS; dir++)
00756                                                 {
00757                                                         nbrx = x + dxuprighttoleft_[dir];
00758                                                         nbry = y + dyuprighttoleft_[dir];               
00759                         
00760                                                         //make sure it is inside the map and has no obstacle
00761                                                         // compute min cost to an obstacle for each cell, using 
00762                                                         // *just* the cells already computed this pass for checking distance
00763                                                         if(nbrx < 0 || nbrx >= width_x || nbry < 0 || nbry >= height_y){
00764                                                                 disttoObs = distuprighttoleft_[dir];
00765                                                                 disttoNonfree = disttoObs;
00766                                                         } else {
00767                                                                 disttoObs = distuprighttoleft_[dir] + disttoObs_incells[nbrx][nbry];
00768                                                                 disttoNonfree = distuprighttoleft_[dir] + disttoNonfree_incells[nbrx][nbry];
00769                                                         }
00770                         
00771                                                         if (disttoObs < mindisttoObs)
00772                                                                 mindisttoObs = disttoObs;
00773                                                         if (disttoNonfree < mindisttoNonfree)
00774                                                                 mindisttoNonfree = disttoNonfree;
00775                                                 }//over preds
00776                 
00777                                         disttoObs_incells[x][y] = mindisttoObs;
00778                                         disttoNonfree_incells[x][y] = mindisttoNonfree;
00779                                 }//for y        
00780                 } else {
00781         
00782                         // move from left to right
00783                         for(y = 0; y< height_y; y++)
00784                                 {
00785                                         // initialize to current distance
00786                                         mindisttoObs = disttoObs_incells[x][y]; 
00787                                         mindisttoNonfree = disttoNonfree_incells[x][y];
00788 
00789                                         //iterate over predecessors
00790                                         for(dir = 0; dir < NUMOF2DQUASIDIRS; dir++)
00791                                                 {
00792                                                         nbrx = x + dxuplefttoright_[dir];
00793                                                         nbry = y + dyuplefttoright_[dir];               
00794                         
00795                                                         //make sure it is inside the map and has no obstacle
00796                                                         // compute min cost to an obstacle for each cell, using 
00797                                                         // *just* the cells already computed this pass for checking distance
00798                                                         if(nbrx < 0 || nbrx >= width_x || nbry < 0 || nbry >= height_y){
00799                                                                 disttoObs = distuplefttoright_[dir];
00800                                                                 disttoNonfree = disttoObs;
00801                                                         } else {
00802                                                                 disttoObs = distuplefttoright_[dir] + disttoObs_incells[nbrx][nbry];
00803                                                                 disttoNonfree = distuplefttoright_[dir] + disttoNonfree_incells[nbrx][nbry];
00804                                                         }
00805                         
00806                                                         if (disttoObs < mindisttoObs)
00807                                                                 mindisttoObs = disttoObs;
00808                                                         if (disttoNonfree < mindisttoNonfree)
00809                                                                 mindisttoNonfree = disttoNonfree;
00810                                                 }
00811                 
00812                                         disttoObs_incells[x][y] = mindisttoObs;
00813                                         disttoNonfree_incells[x][y] = mindisttoNonfree;
00814                         }//over y                
00815                 }//direction
00816         }//over x
00817 }
 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:53