$search
00001 /* 00002 * Copyright (c) 2009, 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 //extern clock_t time3_addallout; 00037 //extern clock_t time_gethash; 00038 //extern clock_t time_createhash; 00039 00040 #define NAV2DUU_ERR_EPS 0.00001 00041 00042 //function prototypes 00043 00044 //-------------------constructors--------------------- 00045 EnvironmentNAV2DUU::EnvironmentNAV2DUU() 00046 { 00047 EnvNAV2DUU.bInitialized = false; 00048 00049 }; 00050 //----------------------------------------------------- 00051 00052 00053 //-------------------problem specific and local functions--------------------- 00054 00055 00056 00057 void EnvironmentNAV2DUU::ReadConfiguration(FILE* fCfg) 00058 { 00059 //read in the configuration of environment and initialize EnvCfg structure 00060 char sTemp[1024], sTemp1[1024]; 00061 //int dTemp; 00062 int x, y; 00063 float fTemp; 00064 00065 //discretization(cells) 00066 if(fscanf(fCfg, "%s", sTemp) != 1){ 00067 SBPL_ERROR("ERROR: ran out of env file early\n"); 00068 throw new SBPL_Exception(); 00069 } 00070 strcpy(sTemp1, "discretization(cells):"); 00071 if(strcmp(sTemp1, sTemp) != 0) 00072 { 00073 SBPL_ERROR("ERROR: configuration file has incorrect format\n"); 00074 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp); 00075 throw new SBPL_Exception(); 00076 } 00077 if(fscanf(fCfg, "%s", sTemp) != 1){ 00078 SBPL_ERROR("ERROR: ran out of env file early\n"); 00079 throw new SBPL_Exception(); 00080 } 00081 EnvNAV2DUUCfg.EnvWidth_c = atoi(sTemp); 00082 if(fscanf(fCfg, "%s", sTemp) != 1){ 00083 SBPL_ERROR("ERROR: ran out of env file early\n"); 00084 throw new SBPL_Exception(); 00085 } 00086 EnvNAV2DUUCfg.EnvHeight_c = atoi(sTemp); 00087 00088 00089 //obsthresh: 00090 if(fscanf(fCfg, "%s", sTemp) != 1){ 00091 SBPL_ERROR("ERROR: ran out of env file early\n"); 00092 throw new SBPL_Exception(); 00093 } 00094 strcpy(sTemp1, "obsthresh:"); 00095 if(strcmp(sTemp1, sTemp) != 0) 00096 { 00097 SBPL_ERROR("ERROR: configuration file has incorrect format\n"); 00098 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp); 00099 throw new SBPL_Exception(); 00100 } 00101 if(fscanf(fCfg, "%s", sTemp) != 1){ 00102 SBPL_ERROR("ERROR: ran out of env file early\n"); 00103 throw new SBPL_Exception(); 00104 } 00105 EnvNAV2DUUCfg.obsthresh = (int)(atof(sTemp)); 00106 00107 //start(cells): 00108 if(fscanf(fCfg, "%s", sTemp) != 1){ 00109 SBPL_ERROR("ERROR: ran out of env file early\n"); 00110 throw new SBPL_Exception(); 00111 } 00112 if(fscanf(fCfg, "%s", sTemp) != 1){ 00113 SBPL_ERROR("ERROR: ran out of env file early\n"); 00114 throw new SBPL_Exception(); 00115 } 00116 EnvNAV2DUUCfg.StartX_c = atoi(sTemp); 00117 if(fscanf(fCfg, "%s", sTemp) != 1){ 00118 SBPL_ERROR("ERROR: ran out of env file early\n"); 00119 throw new SBPL_Exception(); 00120 } 00121 EnvNAV2DUUCfg.StartY_c = atoi(sTemp); 00122 00123 00124 if(EnvNAV2DUUCfg.StartX_c < 0 || EnvNAV2DUUCfg.StartX_c >= EnvNAV2DUUCfg.EnvWidth_c) 00125 { 00126 SBPL_ERROR("ERROR: illegal start coordinates\n"); 00127 throw new SBPL_Exception(); 00128 } 00129 if(EnvNAV2DUUCfg.StartY_c < 0 || EnvNAV2DUUCfg.StartY_c >= EnvNAV2DUUCfg.EnvHeight_c) 00130 { 00131 SBPL_ERROR("ERROR: illegal start coordinates\n"); 00132 throw new SBPL_Exception(); 00133 } 00134 00135 //end(cells): 00136 if(fscanf(fCfg, "%s", sTemp) != 1){ 00137 SBPL_ERROR("ERROR: ran out of env file early\n"); 00138 throw new SBPL_Exception(); 00139 } 00140 if(fscanf(fCfg, "%s", sTemp) != 1){ 00141 SBPL_ERROR("ERROR: ran out of env file early\n"); 00142 throw new SBPL_Exception(); 00143 } 00144 EnvNAV2DUUCfg.EndX_c = atoi(sTemp); 00145 if(fscanf(fCfg, "%s", sTemp) != 1){ 00146 SBPL_ERROR("ERROR: ran out of env file early\n"); 00147 throw new SBPL_Exception(); 00148 } 00149 EnvNAV2DUUCfg.EndY_c = atoi(sTemp); 00150 00151 if(EnvNAV2DUUCfg.EndX_c < 0 || EnvNAV2DUUCfg.EndX_c >= EnvNAV2DUUCfg.EnvWidth_c) 00152 { 00153 SBPL_ERROR("ERROR: illegal end coordinates\n"); 00154 throw new SBPL_Exception(); 00155 } 00156 if(EnvNAV2DUUCfg.EndY_c < 0 || EnvNAV2DUUCfg.EndY_c >= EnvNAV2DUUCfg.EnvHeight_c) 00157 { 00158 SBPL_ERROR("ERROR: illegal end coordinates\n"); 00159 throw new SBPL_Exception(); 00160 } 00161 00162 00163 //allocate the 2D environment and corresponding uncertainty matrix 00164 EnvNAV2DUUCfg.Grid2D = new unsigned char* [EnvNAV2DUUCfg.EnvWidth_c]; 00165 EnvNAV2DUUCfg.UncertaintyGrid2D = new float* [EnvNAV2DUUCfg.EnvWidth_c]; 00166 for (x = 0; x < EnvNAV2DUUCfg.EnvWidth_c; x++) 00167 { 00168 EnvNAV2DUUCfg.Grid2D[x] = new unsigned char [EnvNAV2DUUCfg.EnvHeight_c]; 00169 EnvNAV2DUUCfg.UncertaintyGrid2D[x] = new float [EnvNAV2DUUCfg.EnvHeight_c]; 00170 } 00171 00172 //environment: 00173 EnvNAV2DUUCfg.sizeofH = 0; 00174 if(fscanf(fCfg, "%s", sTemp) != 1){ 00175 SBPL_ERROR("ERROR: ran out of env file early\n"); 00176 throw new SBPL_Exception(); 00177 } 00178 for (y = 0; y < EnvNAV2DUUCfg.EnvHeight_c; y++) 00179 for (x = 0; x < EnvNAV2DUUCfg.EnvWidth_c; x++) 00180 { 00181 if(fscanf(fCfg, "%f", &fTemp) != 1) 00182 { 00183 SBPL_ERROR("ERROR: incorrect format of config file\n"); 00184 throw new SBPL_Exception(); 00185 } 00186 00187 if(fTemp > 1.0-NAV2DUU_ERR_EPS || fTemp < NAV2DUU_ERR_EPS){ 00188 //we assume that the value is just a cost 00189 EnvNAV2DUUCfg.Grid2D[x][y] = (int)fTemp; 00190 if(EnvNAV2DUUCfg.Grid2D[x][y] >= EnvNAV2DUUCfg.obsthresh) 00191 EnvNAV2DUUCfg.UncertaintyGrid2D[x][y] = 1.0; 00192 else 00193 EnvNAV2DUUCfg.UncertaintyGrid2D[x][y] = 0.0; 00194 } 00195 else{ 00196 //the value is probability of being free 00197 EnvNAV2DUUCfg.Grid2D[x][y] = 0; //assume cost is 0 if traversable 00198 EnvNAV2DUUCfg.UncertaintyGrid2D[x][y] = fTemp; 00199 EnvNAV2DUUCfg.sizeofH++; 00200 } 00201 } 00202 00203 00204 EnvNAV2DUUCfg.sizeofS = this->EnvNAV2DUUCfg.EnvWidth_c*this->EnvNAV2DUUCfg.EnvHeight_c; 00205 00206 SBPL_PRINTF("total size of environment=%d, number of unknown cells=%d\n", EnvNAV2DUUCfg.sizeofS, EnvNAV2DUUCfg.sizeofH); 00207 } 00208 00209 00210 //mapdata and uncertaintymapdata is assumed to be organized into a linear array with y being major: map[x+y*width] 00211 void EnvironmentNAV2DUU::SetConfiguration(int width, int height, 00212 const unsigned char* mapdata, const float* uncertaintymapdata) 00213 { 00214 EnvNAV2DUUCfg.EnvWidth_c = width; 00215 EnvNAV2DUUCfg.EnvHeight_c = height; 00216 00217 int x,y; 00218 00219 //set start and goal to zeros for now 00220 EnvNAV2DUUCfg.StartX_c = 0; 00221 EnvNAV2DUUCfg.StartY_c = 0; 00222 EnvNAV2DUUCfg.EndX_c = 0; 00223 EnvNAV2DUUCfg.EndY_c = 0; 00224 00225 00226 //environment: 00227 //allocate the 2D environment and corresponding uncertainty matrix 00228 EnvNAV2DUUCfg.Grid2D = new unsigned char* [EnvNAV2DUUCfg.EnvWidth_c]; 00229 EnvNAV2DUUCfg.UncertaintyGrid2D = new float* [EnvNAV2DUUCfg.EnvWidth_c]; 00230 for (x = 0; x < EnvNAV2DUUCfg.EnvWidth_c; x++) 00231 { 00232 EnvNAV2DUUCfg.Grid2D[x] = new unsigned char [EnvNAV2DUUCfg.EnvHeight_c]; 00233 EnvNAV2DUUCfg.UncertaintyGrid2D[x] = new float [EnvNAV2DUUCfg.EnvHeight_c]; 00234 } 00235 00236 //initialize the mape 00237 EnvNAV2DUUCfg.sizeofH = 0; 00238 for (y = 0; y < EnvNAV2DUUCfg.EnvHeight_c; y++){ 00239 for (x = 0; x < EnvNAV2DUUCfg.EnvWidth_c; x++) 00240 { 00241 if(mapdata == NULL){ 00242 //special case - all is traversable 00243 EnvNAV2DUUCfg.Grid2D[x][y] = 0; 00244 EnvNAV2DUUCfg.UncertaintyGrid2D[x][y] = 0; 00245 } 00246 else { 00247 EnvNAV2DUUCfg.Grid2D[x][y] = mapdata[x + y*width]; 00248 EnvNAV2DUUCfg.UncertaintyGrid2D[x][y] = uncertaintymapdata[x+y*width]; 00249 if(EnvNAV2DUUCfg.UncertaintyGrid2D[x][y] >= NAV2DUU_ERR_EPS && EnvNAV2DUUCfg.UncertaintyGrid2D[x][y] <= (1.0-NAV2DUU_ERR_EPS)) 00250 EnvNAV2DUUCfg.sizeofH++; 00251 } 00252 } 00253 } 00254 00255 00256 EnvNAV2DUUCfg.sizeofS = this->EnvNAV2DUUCfg.EnvWidth_c*this->EnvNAV2DUUCfg.EnvHeight_c; 00257 00258 SBPL_PRINTF("total size of environment=%d, number of unknown cells=%d\n", EnvNAV2DUUCfg.sizeofS, EnvNAV2DUUCfg.sizeofH); 00259 } 00260 00261 00262 00263 void EnvironmentNAV2DUU::InitializeEnvironment() 00264 { 00265 //initialize goal/start IDs 00266 EnvNAV2DUU.startstateid = ENVNAV2DUU_XYTOSTATEID(EnvNAV2DUUCfg.StartX_c, EnvNAV2DUUCfg.StartY_c); 00267 EnvNAV2DUU.goalstateid = ENVNAV2DUU_XYTOSTATEID(EnvNAV2DUUCfg.EndX_c, EnvNAV2DUUCfg.EndY_c); 00268 00269 //environment initialized 00270 EnvNAV2DUU.bInitialized = true; 00271 00272 00273 } 00274 00275 void EnvironmentNAV2DUU::InitializeEnvConfig() 00276 { 00277 //aditional to configuration file initialization if necessary 00278 Computedxy(); 00279 00280 //compute IDs of hidden variables 00281 int x,y; 00282 int idcount = 0; 00283 EnvNAV2DUUCfg.HiddenVariableXY2ID = new int* [EnvNAV2DUUCfg.EnvWidth_c]; 00284 for (x = 0; x < EnvNAV2DUUCfg.EnvWidth_c; x++) 00285 { 00286 EnvNAV2DUUCfg.HiddenVariableXY2ID[x] = new int [EnvNAV2DUUCfg.EnvHeight_c]; 00287 for (y = 0; y < EnvNAV2DUUCfg.EnvWidth_c; y++) 00288 { 00289 if(EnvNAV2DUUCfg.UncertaintyGrid2D[x][y] >= NAV2DUU_ERR_EPS && EnvNAV2DUUCfg.UncertaintyGrid2D[x][y] <= (1.0-NAV2DUU_ERR_EPS)) 00290 { 00291 EnvNAV2DUUCfg.HiddenVariableXY2ID[x][y] = idcount; 00292 idcount++; 00293 } 00294 else 00295 EnvNAV2DUUCfg.HiddenVariableXY2ID[x][y] = -1; 00296 } 00297 } 00298 00299 if(idcount != EnvNAV2DUUCfg.sizeofH) 00300 { 00301 SBPL_ERROR("ERROR: idcount not equal to sizeofH\n"); 00302 throw new SBPL_Exception(); 00303 } 00304 00305 } 00306 00307 int EnvironmentNAV2DUU::SizeofCreatedEnv() 00308 { 00309 return EnvNAV2DUUCfg.sizeofS; 00310 } 00311 00312 int EnvironmentNAV2DUU::SizeofH() 00313 { 00314 return EnvNAV2DUUCfg.sizeofH; 00315 } 00316 00317 00318 bool EnvironmentNAV2DUU::IsValidRobotPosition(int X, int Y) 00319 { 00320 return (X >= 0 && X < EnvNAV2DUUCfg.EnvWidth_c && 00321 Y >= 0 && Y < EnvNAV2DUUCfg.EnvHeight_c && 00322 EnvNAV2DUUCfg.Grid2D[X][Y] < EnvNAV2DUUCfg.obsthresh && EnvNAV2DUUCfg.UncertaintyGrid2D[X][Y] < NAV2DUU_ERR_EPS); 00323 } 00324 00325 bool EnvironmentNAV2DUU::IsWithinMapCell(int X, int Y) 00326 { 00327 return (X >= 0 && X < EnvNAV2DUUCfg.EnvWidth_c && 00328 Y >= 0 && Y < EnvNAV2DUUCfg.EnvHeight_c); 00329 } 00330 00331 void EnvironmentNAV2DUU::Computedxy() 00332 { 00333 //initialize some constants for 2D search 00334 EnvNAV2DUUCfg.dx_[0] = 1; EnvNAV2DUUCfg.dy_[0] = 1; EnvNAV2DUUCfg.dxintersects_[0][0] = 0; EnvNAV2DUUCfg.dyintersects_[0][0] = 1; EnvNAV2DUUCfg.dxintersects_[0][1] = 1; EnvNAV2DUUCfg.dyintersects_[0][1] = 0; 00335 EnvNAV2DUUCfg.dx_[1] = 1; EnvNAV2DUUCfg.dy_[1] = 0; EnvNAV2DUUCfg.dxintersects_[1][0] = 0; EnvNAV2DUUCfg.dyintersects_[1][0] = 0; EnvNAV2DUUCfg.dxintersects_[1][1] = 0; EnvNAV2DUUCfg.dyintersects_[1][1] = 0; 00336 EnvNAV2DUUCfg.dx_[2] = 1; EnvNAV2DUUCfg.dy_[2] = -1; EnvNAV2DUUCfg.dxintersects_[2][0] = 0; EnvNAV2DUUCfg.dyintersects_[2][0] = -1; EnvNAV2DUUCfg.dxintersects_[2][1] = 1; EnvNAV2DUUCfg.dyintersects_[2][1] = 0; 00337 EnvNAV2DUUCfg.dx_[3] = 0; EnvNAV2DUUCfg.dy_[3] = 1; EnvNAV2DUUCfg.dxintersects_[3][0] = 0; EnvNAV2DUUCfg.dyintersects_[3][0] = 0; EnvNAV2DUUCfg.dxintersects_[3][1] = 0; EnvNAV2DUUCfg.dyintersects_[3][1] = 0; 00338 EnvNAV2DUUCfg.dx_[4] = 0; EnvNAV2DUUCfg.dy_[4] = -1; EnvNAV2DUUCfg.dxintersects_[4][0] = 0; EnvNAV2DUUCfg.dyintersects_[4][0] = 0; EnvNAV2DUUCfg.dxintersects_[4][1] = 0; EnvNAV2DUUCfg.dyintersects_[4][1] = 0; 00339 EnvNAV2DUUCfg.dx_[5] = -1; EnvNAV2DUUCfg.dy_[5] = 1; EnvNAV2DUUCfg.dxintersects_[5][0] = 0; EnvNAV2DUUCfg.dyintersects_[5][0] = 1; EnvNAV2DUUCfg.dxintersects_[5][1] = -1; EnvNAV2DUUCfg.dyintersects_[5][1] = 0; 00340 EnvNAV2DUUCfg.dx_[6] = -1; EnvNAV2DUUCfg.dy_[6] = 0; EnvNAV2DUUCfg.dxintersects_[6][0] = 0; EnvNAV2DUUCfg.dyintersects_[6][0] = 0; EnvNAV2DUUCfg.dxintersects_[6][1] = 0; EnvNAV2DUUCfg.dyintersects_[6][1] = 0; 00341 EnvNAV2DUUCfg.dx_[7] = -1; EnvNAV2DUUCfg.dy_[7] = -1; EnvNAV2DUUCfg.dxintersects_[7][0] = 0; EnvNAV2DUUCfg.dyintersects_[7][0] = -1; EnvNAV2DUUCfg.dxintersects_[7][1] = -1; EnvNAV2DUUCfg.dyintersects_[7][1] = 0; 00342 00343 //compute distances 00344 for(int dind = 0; dind < ENVNAV2DUU_MAXDIRS; dind++) 00345 { 00346 00347 if(EnvNAV2DUUCfg.dx_[dind] != 0 && EnvNAV2DUUCfg.dy_[dind] != 0){ 00348 if(dind <= 7) 00349 EnvNAV2DUUCfg.dxy_distance_mm_[dind] = (int)(ENVNAV2DUU_COSTMULT*1.414); //the cost of a diagonal move in millimeters 00350 else 00351 EnvNAV2DUUCfg.dxy_distance_mm_[dind] = (int)(ENVNAV2DUU_COSTMULT*2.236); //the cost of a move to 1,2 or 2,1 or so on in millimeters 00352 } 00353 else 00354 EnvNAV2DUUCfg.dxy_distance_mm_[dind] = ENVNAV2DUU_COSTMULT; //the cost of a horizontal move in millimeters 00355 } 00356 } 00357 00358 /* 00359 void EnvironmentNAV2DUU::ComputeReversedxy() 00360 { 00361 int revaind; 00362 00363 //iterate over actions 00364 for (int aind = 0; aind < NAVLSENV_ROBOTNAVACTIONSWIDTH; aind++) 00365 { 00366 //get the cell location and reverse it 00367 int dX = -EnvNAVLSCfg.dXY[aind][0]; 00368 int dY = -EnvNAVLSCfg.dXY[aind][1]; 00369 00370 //find the index that corresponds to these offsets 00371 for (revaind = 0; revaind < NAVLSENV_ROBOTNAVACTIONSWIDTH; revaind++) 00372 { 00373 if(EnvNAVLSCfg.dXY[revaind][0] == dX && EnvNAVLSCfg.dXY[revaind][1] == dY) 00374 { 00375 EnvNAVLSCfg.reversedXY[aind] = revaind; 00376 break; 00377 } 00378 } 00379 00380 if(revaind == NAVLSENV_ROBOTNAVACTIONSWIDTH) 00381 { 00382 SBPL_ERROR("ERROR: can not determine a reversed index for aind=%d (dX=%d dY=%d)\n", 00383 aind, EnvNAVLSCfg.dXY[aind][0], EnvNAVLSCfg.dXY[aind][1]); 00384 } 00385 } 00386 } 00387 */ 00388 00389 00390 //------------------------------------------------------------------------------ 00391 00392 //------------------------------Heuristic computation-------------------------- 00393 00394 void EnvironmentNAV2DUU::ComputeHeuristicValues() 00395 { 00396 //whatever necessary pre-computation of heuristic values is done here 00397 SBPL_PRINTF("Precomputing heuristics\n"); 00398 00399 00400 00401 SBPL_PRINTF("done\n"); 00402 00403 } 00404 00405 //------------------------------------------------------------------------------ 00406 00407 //-----------------Printing Routines-------------------------------------------- 00408 void EnvironmentNAV2DUU::PrintState(int stateID, bool bVerbose, FILE* fOut /*=NULL*/) 00409 { 00410 #if DEBUG 00411 if(stateID >= this->EnvNAV2DUUCfg.EnvWidth_c*this->EnvNAV2DUUCfg.EnvHeight_c) 00412 { 00413 SBPL_ERROR("ERROR in EnvNAV2DUU... function: stateID illegal (2)\n"); 00414 throw new SBPL_Exception(); 00415 } 00416 #endif 00417 00418 if(fOut == NULL) 00419 fOut = stdout; 00420 00421 if(stateID == EnvNAV2DUU.goalstateid && bVerbose) 00422 { 00423 SBPL_FPRINTF(fOut, "the state is a goal state\n"); 00424 } 00425 00426 if(bVerbose) 00427 SBPL_FPRINTF(fOut, "X=%d Y=%d\n", ENVNAV2DUU_STATEIDTOX(stateID), ENVNAV2DUU_STATEIDTOY(stateID)); 00428 else 00429 SBPL_FPRINTF(fOut, "%d %d\n", ENVNAV2DUU_STATEIDTOX(stateID), ENVNAV2DUU_STATEIDTOY(stateID)); 00430 00431 } 00432 00433 void EnvironmentNAV2DUU::PrintEnv_Config(FILE* fOut) 00434 { 00435 00436 //implement this if the planner needs to print out EnvNAV2DUU. configuration 00437 00438 SBPL_ERROR("ERROR in EnvNAV2DUU... function: PrintEnv_Config is undefined\n"); 00439 throw new SBPL_Exception(); 00440 00441 } 00442 00443 //------------------------------------------------------------------------------- 00444 00445 00446 //-----------interface with outside functions----------------------------------- 00447 bool EnvironmentNAV2DUU::InitializeEnv(const char* sEnvFile) 00448 { 00449 00450 FILE* fCfg = fopen(sEnvFile, "r"); 00451 if(fCfg == NULL) 00452 { 00453 SBPL_ERROR("ERROR: unable to open %s\n", sEnvFile); 00454 throw new SBPL_Exception(); 00455 } 00456 ReadConfiguration(fCfg); 00457 fclose(fCfg); 00458 00459 InitGeneral(); 00460 00461 return true; 00462 } 00463 00464 00465 bool EnvironmentNAV2DUU::InitializeEnv(int width, int height, 00466 const unsigned char* mapdata, const float* uncertaintymapdata, unsigned char obsthresh) 00467 { 00468 00469 SBPL_PRINTF("env: initialized with width=%d height=%d, obsthresh=%d\n", 00470 width, height, obsthresh); 00471 00472 EnvNAV2DUUCfg.obsthresh = obsthresh; 00473 00474 SetConfiguration(width, height, mapdata, uncertaintymapdata); 00475 00476 InitGeneral(); 00477 00478 return true; 00479 } 00480 00481 00482 bool EnvironmentNAV2DUU::InitGeneral() 00483 { 00484 00485 //initialize other variables in Cfg 00486 InitializeEnvConfig(); 00487 00488 //initialize Environment 00489 InitializeEnvironment(); 00490 00491 //pre-compute heuristics 00492 ComputeHeuristicValues(); 00493 00494 return true; 00495 } 00496 00497 00498 bool EnvironmentNAV2DUU::InitializeMDPCfg(MDPConfig *MDPCfg) 00499 { 00500 //initialize MDPCfg with the start and goal ids 00501 MDPCfg->goalstateid = EnvNAV2DUU.goalstateid; 00502 MDPCfg->startstateid = EnvNAV2DUU.startstateid; 00503 00504 return true; 00505 } 00506 00507 00508 00509 int EnvironmentNAV2DUU::GetFromToHeuristic(int FromStateID, int ToStateID) 00510 { 00511 #if USE_HEUR==0 00512 return 0; 00513 #endif 00514 00515 00516 //define this function if it is used in the planner 00517 00518 SBPL_ERROR("ERROR in EnvNAV2DUU.. function: FromToHeuristic is undefined\n"); 00519 throw new SBPL_Exception(); 00520 00521 return 0; 00522 00523 } 00524 00525 00526 int EnvironmentNAV2DUU::GetGoalHeuristic(int stateID) 00527 { 00528 #if USE_HEUR==0 00529 return 0; 00530 #endif 00531 00532 00533 00534 //define this function if it used in the planner (heuristic forward search would use it) 00535 00536 SBPL_ERROR("ERROR in EnvNAV2DUU..function: GetGoalHeuristic is undefined\n"); 00537 throw new SBPL_Exception(); 00538 } 00539 00540 00541 int EnvironmentNAV2DUU::GetStartHeuristic(int stateID) 00542 { 00543 #if USE_HEUR==0 00544 return 0; 00545 #endif 00546 00547 00548 //define this function if it used in the planner (heuristic backward search would use it) 00549 00550 SBPL_ERROR("ERROR in EnvNAV2DUU.. function: GetStartHeuristic is undefined\n"); 00551 throw new SBPL_Exception(); 00552 00553 return 0; 00554 00555 00556 } 00557 00558 00559 void EnvironmentNAV2DUU::GetPreds(int stateID, const vector<sbpl_BinaryHiddenVar_t>* updatedhvaluesV, vector<CMDPACTION>* IncomingDetActionV, 00560 vector<CMDPACTION>* IncomingStochActionV, vector<sbpl_BinaryHiddenVar_t>* StochActionNonpreferredOutcomeV) 00561 { 00562 int aind; 00563 00564 //get state coords 00565 int destx = ENVNAV2DUU_STATEIDTOX(stateID); 00566 int desty = ENVNAV2DUU_STATEIDTOY(stateID); 00567 00568 //clear succs 00569 IncomingDetActionV->clear(); 00570 IncomingStochActionV->clear(); 00571 StochActionNonpreferredOutcomeV->clear(); 00572 00573 //check that the destination is valid 00574 if(!IsWithinMapCell(destx, desty) || EnvNAV2DUUCfg.Grid2D[destx][desty] >= EnvNAV2DUUCfg.obsthresh) 00575 return; 00576 00577 //see if the destination was originally uncertain 00578 bool bDet = false; 00579 if(EnvNAV2DUUCfg.UncertaintyGrid2D[destx][desty] < NAV2DUU_ERR_EPS) //no need to worry about ==1.0 since obstacles are rejected above 00580 bDet = true; 00581 00582 //if yes, then figure out the probability of being an obstacle 00583 float ProbObs = EnvNAV2DUUCfg.UncertaintyGrid2D[destx][desty]; 00584 int desth_ID = EnvNAV2DUUCfg.HiddenVariableXY2ID[destx][desty]; 00585 bool bFreeh = false; 00586 00587 //iterate over updated h-values to make sure dest cell is not in there 00588 for(int hind = 0; hind < (int)updatedhvaluesV->size(); hind++) 00589 { 00590 if(updatedhvaluesV->at(hind).Prob < NAV2DUU_ERR_EPS) 00591 bFreeh = true; //there are elements that are free 00592 00593 if(updatedhvaluesV->at(hind).h_ID == desth_ID) 00594 { 00595 ProbObs = updatedhvaluesV->at(hind).Prob; //found 00596 } 00597 } 00598 00599 //if now known to be an obstacle, then no preds 00600 if(ProbObs > 1.0 - NAV2DUU_ERR_EPS) 00601 return; 00602 else if(ProbObs < NAV2DUU_ERR_EPS) 00603 bDet = false; //now it is a deterministic cell 00604 00605 //get the destination costmult 00606 int destcostmult = EnvNAV2DUUCfg.Grid2D[destx][desty]; 00607 00608 #if DEBUG 00609 if (EnvNAV2DUUCfg.numofdirs > 8) 00610 { 00611 SBPL_ERROR("ERROR: number of directions can not exceed 8 for now\n"); 00612 throw new SBPL_Exception(); 00613 } 00614 #endif 00615 00616 //iterate over neighbors 00617 for (aind = 0; aind < EnvNAV2DUUCfg.numofdirs; aind++) 00618 { 00619 //the actions are undirected, so we can use the same array of actions as in getsuccs case 00620 int predX = destx + EnvNAV2DUUCfg.dx_[aind]; 00621 int predY = desty + EnvNAV2DUUCfg.dy_[aind]; 00622 00623 //skip the invalid cells 00624 if(!IsWithinMapCell(predX, predY) || EnvNAV2DUUCfg.Grid2D[predX][predY] >= EnvNAV2DUUCfg.obsthresh) 00625 continue; 00626 00627 //running costmult 00628 int costmult = destcostmult; 00629 00630 //get the costmultiplier of pred and update total costmult 00631 costmult = __max(costmult, EnvNAV2DUUCfg.Grid2D[predX][predY]); 00632 00633 //if diagonal move 00634 if(predX != destx && predY != desty) 00635 { 00636 //check intersecting cells to make sure they are not uncertain 00637 if(EnvNAV2DUUCfg.UncertaintyGrid2D[destx][predY] >= NAV2DUU_ERR_EPS) 00638 { 00639 if(!bFreeh) 00640 continue; 00641 00642 //check that it is not known to be free. Otherwise - invalid move 00643 int tempID = EnvNAV2DUUCfg.HiddenVariableXY2ID[destx][predY]; 00644 bool btempfree = false; 00645 for(int hind = 0; hind < (int)updatedhvaluesV->size(); hind++) 00646 { 00647 if(updatedhvaluesV->at(hind).h_ID == tempID) 00648 { 00649 if(updatedhvaluesV->at(hind).Prob < NAV2DUU_ERR_EPS) 00650 { 00651 btempfree = true; 00652 break; 00653 } 00654 } 00655 } 00656 if(!btempfree) 00657 continue; 00658 } 00659 00660 if(EnvNAV2DUUCfg.UncertaintyGrid2D[predX][desty] >= NAV2DUU_ERR_EPS) 00661 { 00662 if(!bFreeh) 00663 continue; 00664 00665 //check that it is not known to be free. Otherwise - invalid move 00666 int tempID = EnvNAV2DUUCfg.HiddenVariableXY2ID[predX][desty]; 00667 bool btempfree = false; 00668 for(int hind = 0; hind < (int)updatedhvaluesV->size(); hind++) 00669 { 00670 if(updatedhvaluesV->at(hind).h_ID == tempID) 00671 { 00672 if(updatedhvaluesV->at(hind).Prob < NAV2DUU_ERR_EPS) 00673 { 00674 btempfree = true; 00675 break; 00676 } 00677 } 00678 } 00679 if(!btempfree) 00680 continue; 00681 } 00682 00683 00684 //compute the costmultiplier of intersect cells and update total costmult 00685 costmult = __max(costmult, EnvNAV2DUUCfg.Grid2D[destx][predY]); 00686 costmult = __max(costmult, EnvNAV2DUUCfg.Grid2D[predX][desty]); 00687 } 00688 00689 //make sure cost is still valid 00690 if(costmult >= EnvNAV2DUUCfg.obsthresh) 00691 continue; 00692 00693 //otherwise compute the actual cost (once again we use the fact that actions are undirected to determine the cost) 00694 int cost = (((int)costmult)+1)*EnvNAV2DUUCfg.dxy_distance_mm_[aind]; 00695 00696 //create action 00697 int predstateID = ENVNAV2DUU_XYTOSTATEID(predX,predY); 00698 CMDPACTION action(aind, predstateID); //TODO-use reverseindex 00699 00700 if(bDet) 00701 { 00702 //if dest is known - then form a deterministic action 00703 action.AddOutcome(stateID, cost, 1.0); 00704 IncomingDetActionV->push_back(action); 00705 } 00706 else{ 00707 //if dest is unknown - then form a stoch action and compute the corresponding belief part 00708 action.AddOutcome(stateID, cost, 1 - ProbObs); //preferred outcome 00709 action.AddOutcome(predstateID, 2*cost, ProbObs); //non-preferred outcome (stateID is untraversable) 00710 IncomingStochActionV->push_back(action); 00711 //also insert the corresponding hidden variable value 00712 sbpl_BinaryHiddenVar_t hval; 00713 hval.h_ID = desth_ID; 00714 hval.Prob = 1; //known to be an obstacle 00715 StochActionNonpreferredOutcomeV->push_back(hval); 00716 } 00717 } 00718 } 00719 00720 //returns the stateid if success, and -1 otherwise 00721 int EnvironmentNAV2DUU::SetGoal(int x, int y){ 00722 00723 if(!IsWithinMapCell(x,y)) 00724 { 00725 SBPL_ERROR("ERROR: trying to set a goal cell %d %d that is outside of map\n", x,y); 00726 return -1; 00727 } 00728 00729 if(!IsValidRobotPosition(x,y)) 00730 { 00731 SBPL_PRINTF("WARNING: goal cell is invalid\n"); 00732 } 00733 00734 00735 EnvNAV2DUU.goalstateid = ENVNAV2DUU_XYTOSTATEID(x,y); 00736 EnvNAV2DUUCfg.EndX_c = x; 00737 EnvNAV2DUUCfg.EndY_c = y; 00738 00739 00740 return EnvNAV2DUU.goalstateid; 00741 00742 } 00743 00744 00745 00746 //returns the stateid if success, and -1 otherwise 00747 int EnvironmentNAV2DUU::SetStart(int x, int y){ 00748 00749 if(!IsWithinMapCell(x,y)) 00750 { 00751 SBPL_ERROR("ERROR: trying to set a start cell %d %d that is outside of map\n", x,y); 00752 return -1; 00753 } 00754 00755 if(!IsValidRobotPosition(x,y)) 00756 { 00757 SBPL_PRINTF("WARNING: start cell is invalid\n"); 00758 } 00759 00760 00761 EnvNAV2DUU.startstateid = ENVNAV2DUU_XYTOSTATEID(x,y); 00762 EnvNAV2DUUCfg.StartX_c = x; 00763 EnvNAV2DUUCfg.StartY_c = y; 00764 00765 return EnvNAV2DUU.startstateid; 00766 00767 } 00768 00769 bool EnvironmentNAV2DUU::UpdateCost(int x, int y, unsigned char newcost) 00770 { 00771 00772 EnvNAV2DUUCfg.Grid2D[x][y] = newcost; 00773 00774 return true; 00775 } 00776 00777 00778 //------------------------------------------------------------------------------