00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <iostream>
00030 using namespace std;
00031
00032 #include "../../sbpl/headers.h"
00033
00034
00035 #if TIME_DEBUG
00036 static clock_t time3_addallout = 0;
00037 static clock_t time_gethash = 0;
00038 static clock_t time_createhash = 0;
00039 static clock_t time_getsuccs = 0;
00040 #endif
00041
00042
00043
00044
00045
00046 EnvironmentNAV2D::EnvironmentNAV2D()
00047 {
00048 EnvNAV2DCfg.obsthresh = ENVNAV2D_DEFAULTOBSTHRESH;
00049
00050 EnvNAV2DCfg.numofdirs = 8;
00051 EnvNAV2D.bInitialized = false;
00052
00053 };
00054
00055
00056
00057
00058
00059
00060 static unsigned int inthash(unsigned int key)
00061 {
00062 key += (key << 12);
00063 key ^= (key >> 22);
00064 key += (key << 4);
00065 key ^= (key >> 9);
00066 key += (key << 10);
00067 key ^= (key >> 2);
00068 key += (key << 7);
00069 key ^= (key >> 12);
00070 return key;
00071 }
00072
00073
00074
00075
00076 unsigned int EnvironmentNAV2D::GETHASHBIN(unsigned int X1, unsigned int X2)
00077 {
00078
00079 return inthash(inthash(X1)+(inthash(X2)<<1)) & (EnvNAV2D.HashTableSize-1);
00080 }
00081
00082
00083
00084 void EnvironmentNAV2D::PrintHashTableHist()
00085 {
00086 int s0=0, s1=0, s50=0, s100=0, s200=0, s300=0, slarge=0;
00087
00088 for(int j = 0; j < EnvNAV2D.HashTableSize; j++)
00089 {
00090 if((int)EnvNAV2D.Coord2StateIDHashTable[j].size() == 0)
00091 s0++;
00092 else if((int)EnvNAV2D.Coord2StateIDHashTable[j].size() < 50)
00093 s1++;
00094 else if((int)EnvNAV2D.Coord2StateIDHashTable[j].size() < 100)
00095 s50++;
00096 else if((int)EnvNAV2D.Coord2StateIDHashTable[j].size() < 200)
00097 s100++;
00098 else if((int)EnvNAV2D.Coord2StateIDHashTable[j].size() < 300)
00099 s200++;
00100 else if((int)EnvNAV2D.Coord2StateIDHashTable[j].size() < 400)
00101 s300++;
00102 else
00103 slarge++;
00104 }
00105 SBPL_PRINTF("hash table histogram: 0:%d, <50:%d, <100:%d, <200:%d, <300:%d, <400:%d >400:%d\n",
00106 s0,s1, s50, s100, s200,s300,slarge);
00107 }
00108
00109 void EnvironmentNAV2D::SetConfiguration(int width, int height,
00110 const unsigned char* mapdata,
00111 int startx, int starty,
00112 int goalx, int goaly) {
00113 EnvNAV2DCfg.EnvWidth_c = width;
00114 EnvNAV2DCfg.EnvHeight_c = height;
00115 EnvNAV2DCfg.StartX_c = startx;
00116 EnvNAV2DCfg.StartY_c = starty;
00117 int x;
00118
00119 if(EnvNAV2DCfg.StartX_c < 0 || EnvNAV2DCfg.StartX_c >= EnvNAV2DCfg.EnvWidth_c) {
00120 SBPL_ERROR("ERROR: illegal start coordinates\n");
00121 throw new SBPL_Exception();
00122 }
00123 if(EnvNAV2DCfg.StartY_c < 0 || EnvNAV2DCfg.StartY_c >= EnvNAV2DCfg.EnvHeight_c) {
00124 SBPL_ERROR("ERROR: illegal start coordinates\n");
00125 throw new SBPL_Exception();
00126 }
00127
00128 EnvNAV2DCfg.EndX_c = goalx;
00129 EnvNAV2DCfg.EndY_c = goaly;
00130
00131
00132 EnvNAV2DCfg.Grid2D = new unsigned char* [EnvNAV2DCfg.EnvWidth_c];
00133 for (x = 0; x < EnvNAV2DCfg.EnvWidth_c; x++) {
00134 EnvNAV2DCfg.Grid2D[x] = new unsigned char [EnvNAV2DCfg.EnvHeight_c];
00135 }
00136
00137
00138
00139 if (0 == mapdata) {
00140 for (int y = 0; y < EnvNAV2DCfg.EnvHeight_c; y++) {
00141 for (int x = 0; x < EnvNAV2DCfg.EnvWidth_c; x++) {
00142 EnvNAV2DCfg.Grid2D[x][y] = 0;
00143 }
00144 }
00145 }
00146 else {
00147 for (int y = 0; y < EnvNAV2DCfg.EnvHeight_c; y++) {
00148 for (int x = 0; x < EnvNAV2DCfg.EnvWidth_c; x++) {
00149 unsigned char cval = mapdata[x+y*width];
00150 EnvNAV2DCfg.Grid2D[x][y] = cval;
00151 }
00152 }
00153 }
00154
00155 }
00156
00157 void EnvironmentNAV2D::ReadConfiguration(FILE* fCfg)
00158 {
00159
00160 char sTemp[1024], sTemp1[1024];
00161 int dTemp;
00162 int x, y;
00163
00164
00165 if(fscanf(fCfg, "%s", sTemp) != 1){
00166 SBPL_ERROR("ERROR: ran out of env file early\n");
00167 throw new SBPL_Exception();
00168 }
00169 if(fscanf(fCfg, "%s", sTemp) != 1){
00170 SBPL_ERROR("ERROR: ran out of env file early\n");
00171 throw new SBPL_Exception();
00172 }
00173 EnvNAV2DCfg.EnvWidth_c = atoi(sTemp);
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 EnvNAV2DCfg.EnvHeight_c = atoi(sTemp);
00179
00180
00181 if(fscanf(fCfg, "%s", sTemp) != 1){
00182 SBPL_ERROR("ERROR: ran out of env file early\n");
00183 throw new SBPL_Exception();
00184 }
00185 strcpy(sTemp1, "obsthresh:");
00186 if(strcmp(sTemp1, sTemp) != 0)
00187 {
00188 SBPL_ERROR("ERROR: configuration file has incorrect format\n");
00189 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00190 throw new SBPL_Exception();
00191 }
00192 if(fscanf(fCfg, "%s", sTemp) != 1){
00193 SBPL_ERROR("ERROR: ran out of env file early\n");
00194 throw new SBPL_Exception();
00195 }
00196 EnvNAV2DCfg.obsthresh = (int)(atof(sTemp));
00197 SBPL_PRINTF("obsthresh = %d\n", EnvNAV2DCfg.obsthresh);
00198
00199
00200
00201 if(fscanf(fCfg, "%s", sTemp) != 1){
00202 SBPL_ERROR("ERROR: ran out of env file early\n");
00203 throw new SBPL_Exception();
00204 }
00205 if(fscanf(fCfg, "%s", sTemp) != 1){
00206 SBPL_ERROR("ERROR: ran out of env file early\n");
00207 throw new SBPL_Exception();
00208 }
00209 EnvNAV2DCfg.StartX_c = atoi(sTemp);
00210 if(fscanf(fCfg, "%s", sTemp) != 1){
00211 SBPL_ERROR("ERROR: ran out of env file early\n");
00212 throw new SBPL_Exception();
00213 }
00214 EnvNAV2DCfg.StartY_c = atoi(sTemp);
00215
00216 if(EnvNAV2DCfg.StartX_c < 0 || EnvNAV2DCfg.StartX_c >= EnvNAV2DCfg.EnvWidth_c)
00217 {
00218 SBPL_ERROR("ERROR: illegal start coordinates\n");
00219 throw new SBPL_Exception();
00220 }
00221 if(EnvNAV2DCfg.StartY_c < 0 || EnvNAV2DCfg.StartY_c >= EnvNAV2DCfg.EnvHeight_c)
00222 {
00223 SBPL_ERROR("ERROR: illegal start coordinates\n");
00224 throw new SBPL_Exception();
00225 }
00226
00227
00228 if(fscanf(fCfg, "%s", sTemp) != 1){
00229 SBPL_ERROR("ERROR: ran out of env file early\n");
00230 throw new SBPL_Exception();
00231 }
00232 if(fscanf(fCfg, "%s", sTemp) != 1){
00233 SBPL_ERROR("ERROR: ran out of env file early\n");
00234 throw new SBPL_Exception();
00235 }
00236 EnvNAV2DCfg.EndX_c = atoi(sTemp);
00237 if(fscanf(fCfg, "%s", sTemp) != 1){
00238 SBPL_ERROR("ERROR: ran out of env file early\n");
00239 throw new SBPL_Exception();
00240 }
00241 EnvNAV2DCfg.EndY_c = atoi(sTemp);
00242
00243 if(EnvNAV2DCfg.EndX_c < 0 || EnvNAV2DCfg.EndX_c >= EnvNAV2DCfg.EnvWidth_c)
00244 {
00245 SBPL_ERROR("ERROR: illegal end coordinates\n");
00246 throw new SBPL_Exception();
00247 }
00248 if(EnvNAV2DCfg.EndY_c < 0 || EnvNAV2DCfg.EndY_c >= EnvNAV2DCfg.EnvHeight_c)
00249 {
00250 SBPL_ERROR("ERROR: illegal end coordinates\n");
00251 throw new SBPL_Exception();
00252 }
00253
00254
00255
00256 EnvNAV2DCfg.Grid2D = new unsigned char* [EnvNAV2DCfg.EnvWidth_c];
00257 for (x = 0; x < EnvNAV2DCfg.EnvWidth_c; x++)
00258 {
00259 EnvNAV2DCfg.Grid2D[x] = new unsigned char [EnvNAV2DCfg.EnvHeight_c];
00260 }
00261
00262
00263 if(fscanf(fCfg, "%s", sTemp) != 1){
00264 SBPL_ERROR("ERROR: ran out of env file early\n");
00265 throw new SBPL_Exception();
00266 }
00267 for (y = 0; y < EnvNAV2DCfg.EnvHeight_c; y++)
00268 for (x = 0; x < EnvNAV2DCfg.EnvWidth_c; x++)
00269 {
00270 if(fscanf(fCfg, "%d", &dTemp) != 1)
00271 {
00272 SBPL_ERROR("ERROR: incorrect format of config file\n");
00273 throw new SBPL_Exception();
00274 }
00275 EnvNAV2DCfg.Grid2D[x][y] = dTemp;
00276 }
00277
00278
00279
00280 SBPL_PRINTF("start has cost=%d goal has cost=%d\n", EnvNAV2DCfg.Grid2D[EnvNAV2DCfg.StartX_c][EnvNAV2DCfg.StartY_c], EnvNAV2DCfg.Grid2D[EnvNAV2DCfg.EndX_c][EnvNAV2DCfg.EndY_c]);
00281 }
00282
00283
00284 void EnvironmentNAV2D::InitializeEnvConfig()
00285 {
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 Computedxy();
00308
00309
00310 }
00311
00312 void EnvironmentNAV2D::Computedxy()
00313 {
00314
00315
00316 EnvNAV2DCfg.dx_[0] = 1; EnvNAV2DCfg.dy_[0] = 1; EnvNAV2DCfg.dxintersects_[0][0] = 0; EnvNAV2DCfg.dyintersects_[0][0] = 1; EnvNAV2DCfg.dxintersects_[0][1] = 1; EnvNAV2DCfg.dyintersects_[0][1] = 0;
00317 EnvNAV2DCfg.dx_[1] = 1; EnvNAV2DCfg.dy_[1] = 0; EnvNAV2DCfg.dxintersects_[1][0] = 0; EnvNAV2DCfg.dyintersects_[1][0] = 0; EnvNAV2DCfg.dxintersects_[1][1] = 0; EnvNAV2DCfg.dyintersects_[1][1] = 0;
00318 EnvNAV2DCfg.dx_[2] = 1; EnvNAV2DCfg.dy_[2] = -1; EnvNAV2DCfg.dxintersects_[2][0] = 0; EnvNAV2DCfg.dyintersects_[2][0] = -1; EnvNAV2DCfg.dxintersects_[2][1] = 1; EnvNAV2DCfg.dyintersects_[2][1] = 0;
00319 EnvNAV2DCfg.dx_[3] = 0; EnvNAV2DCfg.dy_[3] = 1; EnvNAV2DCfg.dxintersects_[3][0] = 0; EnvNAV2DCfg.dyintersects_[3][0] = 0; EnvNAV2DCfg.dxintersects_[3][1] = 0; EnvNAV2DCfg.dyintersects_[3][1] = 0;
00320 EnvNAV2DCfg.dx_[4] = 0; EnvNAV2DCfg.dy_[4] = -1; EnvNAV2DCfg.dxintersects_[4][0] = 0; EnvNAV2DCfg.dyintersects_[4][0] = 0; EnvNAV2DCfg.dxintersects_[4][1] = 0; EnvNAV2DCfg.dyintersects_[4][1] = 0;
00321 EnvNAV2DCfg.dx_[5] = -1; EnvNAV2DCfg.dy_[5] = 1; EnvNAV2DCfg.dxintersects_[5][0] = 0; EnvNAV2DCfg.dyintersects_[5][0] = 1; EnvNAV2DCfg.dxintersects_[5][1] = -1; EnvNAV2DCfg.dyintersects_[5][1] = 0;
00322 EnvNAV2DCfg.dx_[6] = -1; EnvNAV2DCfg.dy_[6] = 0; EnvNAV2DCfg.dxintersects_[6][0] = 0; EnvNAV2DCfg.dyintersects_[6][0] = 0; EnvNAV2DCfg.dxintersects_[6][1] = 0; EnvNAV2DCfg.dyintersects_[6][1] = 0;
00323 EnvNAV2DCfg.dx_[7] = -1; EnvNAV2DCfg.dy_[7] = -1; EnvNAV2DCfg.dxintersects_[7][0] = 0; EnvNAV2DCfg.dyintersects_[7][0] = -1; EnvNAV2DCfg.dxintersects_[7][1] = -1; EnvNAV2DCfg.dyintersects_[7][1] = 0;
00324
00325
00326
00327 EnvNAV2DCfg.dx_[8] = 2; EnvNAV2DCfg.dy_[8] = 1; EnvNAV2DCfg.dxintersects_[8][0] = 1; EnvNAV2DCfg.dyintersects_[8][0] = 0; EnvNAV2DCfg.dxintersects_[8][1] = 1; EnvNAV2DCfg.dyintersects_[8][1] = 1;
00328 EnvNAV2DCfg.dx_[9] = 1; EnvNAV2DCfg.dy_[9] = 2; EnvNAV2DCfg.dxintersects_[9][0] = 0; EnvNAV2DCfg.dyintersects_[9][0] = 1; EnvNAV2DCfg.dxintersects_[9][1] = 1; EnvNAV2DCfg.dyintersects_[9][1] = 1;
00329 EnvNAV2DCfg.dx_[10] = -1; EnvNAV2DCfg.dy_[10] = 2; EnvNAV2DCfg.dxintersects_[10][0] = 0; EnvNAV2DCfg.dyintersects_[10][0] = 1; EnvNAV2DCfg.dxintersects_[10][1] = -1; EnvNAV2DCfg.dyintersects_[10][1] = 1;
00330 EnvNAV2DCfg.dx_[11] = -2; EnvNAV2DCfg.dy_[11] = 1; EnvNAV2DCfg.dxintersects_[11][0] = -1; EnvNAV2DCfg.dyintersects_[11][0] = 0; EnvNAV2DCfg.dxintersects_[11][1] = -1; EnvNAV2DCfg.dyintersects_[11][1] = 1;
00331 EnvNAV2DCfg.dx_[12] = -2; EnvNAV2DCfg.dy_[12] = -1; EnvNAV2DCfg.dxintersects_[12][0] = -1; EnvNAV2DCfg.dyintersects_[12][0] = 0; EnvNAV2DCfg.dxintersects_[12][1] = -1; EnvNAV2DCfg.dyintersects_[12][1] = -1;
00332 EnvNAV2DCfg.dx_[13] = -1; EnvNAV2DCfg.dy_[13] = -2; EnvNAV2DCfg.dxintersects_[13][0] = 0; EnvNAV2DCfg.dyintersects_[13][0] = -1; EnvNAV2DCfg.dxintersects_[13][1] = -1; EnvNAV2DCfg.dyintersects_[13][1] = -1;
00333 EnvNAV2DCfg.dx_[14] = 1; EnvNAV2DCfg.dy_[14] = -2; EnvNAV2DCfg.dxintersects_[14][0] = 0; EnvNAV2DCfg.dyintersects_[14][0] = -1; EnvNAV2DCfg.dxintersects_[14][1] = 1; EnvNAV2DCfg.dyintersects_[14][1] = -1;
00334 EnvNAV2DCfg.dx_[15] = 2; EnvNAV2DCfg.dy_[15] = -1; EnvNAV2DCfg.dxintersects_[15][0] = 1; EnvNAV2DCfg.dyintersects_[15][0] = 0; EnvNAV2DCfg.dxintersects_[15][1] = 1; EnvNAV2DCfg.dyintersects_[15][1] = -1;
00335
00336
00337 for(int dind = 0; dind < ENVNAV2D_MAXDIRS; dind++)
00338 {
00339
00340 if(EnvNAV2DCfg.dx_[dind] != 0 && EnvNAV2DCfg.dy_[dind] != 0){
00341 if(dind <= 7)
00342 EnvNAV2DCfg.dxy_distance_mm_[dind] = (int)(ENVNAV2D_COSTMULT*1.414);
00343 else
00344 EnvNAV2DCfg.dxy_distance_mm_[dind] = (int)(ENVNAV2D_COSTMULT*2.236);
00345 }
00346 else
00347 EnvNAV2DCfg.dxy_distance_mm_[dind] = ENVNAV2D_COSTMULT;
00348 }
00349 }
00350
00351
00352
00353 EnvNAV2DHashEntry_t* EnvironmentNAV2D::GetHashEntry(int X, int Y)
00354 {
00355
00356 #if TIME_DEBUG
00357 clock_t currenttime = clock();
00358 #endif
00359
00360 int binid = GETHASHBIN(X, Y);
00361
00362 #if DEBUG
00363 if ((int)EnvNAV2D.Coord2StateIDHashTable[binid].size() > 500)
00364 {
00365 SBPL_PRINTF("WARNING: Hash table has a bin %d (X=%d Y=%d) of size %d\n",
00366 binid, X, Y, EnvNAV2D.Coord2StateIDHashTable[binid].size());
00367
00368 PrintHashTableHist();
00369 }
00370 #endif
00371
00372
00373 for(int ind = 0; ind < (int)EnvNAV2D.Coord2StateIDHashTable[binid].size(); ind++)
00374 {
00375 if( EnvNAV2D.Coord2StateIDHashTable[binid][ind]->X == X
00376 && EnvNAV2D.Coord2StateIDHashTable[binid][ind]->Y == Y)
00377 {
00378 #if TIME_DEBUG
00379 time_gethash += clock()-currenttime;
00380 #endif
00381 return EnvNAV2D.Coord2StateIDHashTable[binid][ind];
00382 }
00383 }
00384
00385 #if TIME_DEBUG
00386 time_gethash += clock()-currenttime;
00387 #endif
00388
00389 return NULL;
00390 }
00391
00392
00393 EnvNAV2DHashEntry_t* EnvironmentNAV2D::CreateNewHashEntry(int X, int Y)
00394 {
00395 int i;
00396
00397 #if TIME_DEBUG
00398 clock_t currenttime = clock();
00399 #endif
00400
00401 EnvNAV2DHashEntry_t* HashEntry = new EnvNAV2DHashEntry_t;
00402
00403 HashEntry->X = X;
00404 HashEntry->Y = Y;
00405
00406 HashEntry->stateID = EnvNAV2D.StateID2CoordTable.size();
00407
00408
00409 EnvNAV2D.StateID2CoordTable.push_back(HashEntry);
00410
00411
00412
00413 i = GETHASHBIN(HashEntry->X, HashEntry->Y);
00414
00415
00416 EnvNAV2D.Coord2StateIDHashTable[i].push_back(HashEntry);
00417
00418
00419 int* entry = new int [NUMOFINDICES_STATEID2IND];
00420 StateID2IndexMapping.push_back(entry);
00421 for(i = 0; i < NUMOFINDICES_STATEID2IND; i++)
00422 {
00423 StateID2IndexMapping[HashEntry->stateID][i] = -1;
00424 }
00425
00426 if(HashEntry->stateID != (int)StateID2IndexMapping.size()-1)
00427 {
00428 SBPL_ERROR("ERROR in Env... function: last state has incorrect stateID\n");
00429 throw new SBPL_Exception();
00430 }
00431
00432 #if TIME_DEBUG
00433 time_createhash += clock()-currenttime;
00434 #endif
00435
00436 return HashEntry;
00437 }
00438
00439 bool EnvironmentNAV2D::IsValidCell(int X, int Y)
00440 {
00441 return (X >= 0 && X < EnvNAV2DCfg.EnvWidth_c &&
00442 Y >= 0 && Y < EnvNAV2DCfg.EnvHeight_c &&
00443 EnvNAV2DCfg.Grid2D[X][Y] < EnvNAV2DCfg.obsthresh);
00444 }
00445
00446 bool EnvironmentNAV2D::IsWithinMapCell(int X, int Y)
00447 {
00448 return (X >= 0 && X < EnvNAV2DCfg.EnvWidth_c &&
00449 Y >= 0 && Y < EnvNAV2DCfg.EnvHeight_c);
00450 }
00451
00452
00453
00454 EnvironmentNAV2D::~EnvironmentNAV2D(){
00455 if(EnvNAV2D.Coord2StateIDHashTable != NULL){
00456 delete[] EnvNAV2D.Coord2StateIDHashTable;
00457 }
00458
00459 for(unsigned int i = 0; i < EnvNAV2D.StateID2CoordTable.size(); ++i){
00460 if(EnvNAV2D.StateID2CoordTable[i] != NULL)
00461 delete EnvNAV2D.StateID2CoordTable[i];
00462 }
00463
00464 if(EnvNAV2DCfg.Grid2D != NULL){
00465 for (int x = 0; x < EnvNAV2DCfg.EnvWidth_c; x++) {
00466 if(EnvNAV2DCfg.Grid2D[x] != NULL)
00467 delete[] EnvNAV2DCfg.Grid2D[x];
00468 }
00469 delete[] EnvNAV2DCfg.Grid2D;
00470 }
00471
00472 }
00473
00474 void EnvironmentNAV2D::InitializeEnvironment()
00475 {
00476 EnvNAV2DHashEntry_t* HashEntry;
00477
00478
00479 EnvNAV2D.HashTableSize = 64*1024;
00480 EnvNAV2D.Coord2StateIDHashTable = new vector<EnvNAV2DHashEntry_t*>[EnvNAV2D.HashTableSize];
00481
00482
00483 EnvNAV2D.StateID2CoordTable.clear();
00484
00485
00486 if((HashEntry = GetHashEntry(EnvNAV2DCfg.StartX_c, EnvNAV2DCfg.StartY_c)) == NULL)
00487 {
00488 HashEntry = CreateNewHashEntry(EnvNAV2DCfg.StartX_c, EnvNAV2DCfg.StartY_c);
00489 }
00490 EnvNAV2D.startstateid = HashEntry->stateID;
00491
00492
00493 if((HashEntry = GetHashEntry(EnvNAV2DCfg.EndX_c, EnvNAV2DCfg.EndY_c)) == NULL)
00494 {
00495 HashEntry = CreateNewHashEntry(EnvNAV2DCfg.EndX_c, EnvNAV2DCfg.EndY_c);
00496 }
00497 EnvNAV2D.goalstateid = HashEntry->stateID;
00498
00499 EnvNAV2D.bInitialized = true;
00500 }
00501
00502 static int EuclideanDistance(int X1, int Y1, int X2, int Y2)
00503 {
00504 int sqdist = ((X1-X2)*(X1-X2)+(Y1-Y2)*(Y1-Y2));
00505 double dist = sqrt((double)sqdist);
00506 return (int)(ENVNAV2D_COSTMULT*dist);
00507
00508 }
00509
00510
00511
00512
00513 void EnvironmentNAV2D::GetRandomNeighs(int stateID, std::vector<int>* NeighIDV, std::vector<int>* CLowV, int nNumofNeighs, int nDist_c, bool bSuccs)
00514 {
00515
00516
00517 NeighIDV->clear();
00518 CLowV->clear();
00519
00520
00521 EnvNAV2DHashEntry_t* HashEntry = EnvNAV2D.StateID2CoordTable[stateID];
00522 int X = HashEntry->X;
00523 int Y = HashEntry->Y;
00524
00525
00526 for (int i = 0, nAttempts = 0; i < nNumofNeighs && nAttempts < 5*nNumofNeighs; i++, nAttempts++)
00527 {
00528 int dX = 0;
00529 int dY = 0;
00530
00531
00532 float fDir = (float)(2*PI_CONST*(((double)rand())/RAND_MAX));
00533
00534
00535
00536 float fRadius = 0;
00537 if(fabs(cos(fDir)) > fabs(sin(fDir)))
00538 {
00539 fRadius = (float)((nDist_c+0.5)/fabs(cos(fDir)));
00540 }
00541 else
00542 {
00543 fRadius = (float)((nDist_c+0.5)/fabs(sin(fDir)));
00544 }
00545
00546 dX = (int)(fRadius*cos(fDir));
00547 dY = (int)(fRadius*sin(fDir));
00548
00549 if((fabs((float)dX) < nDist_c && fabs((float)dY) < nDist_c) || fabs((float)dX) > nDist_c ||
00550 fabs((float)dY) > nDist_c)
00551 {
00552 SBPL_ERROR("ERROR in EnvNav2D genneighs function: dX=%d dY=%d\n", dX, dY);
00553 throw new SBPL_Exception();
00554 }
00555
00556
00557 int newX = X + dX;
00558 int newY = Y + dY;
00559
00560
00561 if(!IsValidCell(newX, newY))
00562 {
00563 i--;
00564 continue;
00565 }
00566
00567
00568 EnvNAV2DHashEntry_t* OutHashEntry;
00569 if((OutHashEntry = GetHashEntry(newX, newY)) == NULL)
00570 {
00571
00572 OutHashEntry = CreateNewHashEntry(newX, newY);
00573 }
00574
00575
00576 int clow;
00577 if(bSuccs)
00578 clow = GetFromToHeuristic(stateID, OutHashEntry->stateID);
00579 else
00580 clow = GetFromToHeuristic(OutHashEntry->stateID, stateID);
00581
00582
00583 NeighIDV->push_back(OutHashEntry->stateID);
00584 CLowV->push_back(clow);
00585
00586 }
00587
00588
00589 int desX_c = EnvNAV2DCfg.EndX_c;
00590 int desY_c = EnvNAV2DCfg.EndY_c;
00591 int desstateID = EnvNAV2D.goalstateid;
00592 if(bSuccs == false)
00593 {
00594 desX_c = EnvNAV2DCfg.StartX_c;
00595 desY_c = EnvNAV2DCfg.StartY_c;
00596 desstateID = EnvNAV2D.startstateid;
00597 }
00598
00599 if(abs(desX_c - X) <= nDist_c && abs(desY_c - Y) <= nDist_c)
00600 {
00601
00602 int clow;
00603 if(bSuccs)
00604 clow = GetFromToHeuristic(stateID, desstateID);
00605 else
00606 clow = GetFromToHeuristic(desstateID, stateID);
00607
00608 NeighIDV->push_back(desstateID);
00609 CLowV->push_back(clow);
00610 }
00611 }
00612
00613
00614
00615
00616
00617
00618
00619 void EnvironmentNAV2D::ComputeHeuristicValues()
00620 {
00621
00622 SBPL_PRINTF("Precomputing heuristics...\n");
00623
00624
00625
00626 SBPL_PRINTF("done\n");
00627
00628 }
00629
00630
00631 bool EnvironmentNAV2D::InitializeEnv(const char* sEnvFile)
00632 {
00633
00634 FILE* fCfg = fopen(sEnvFile, "r");
00635 if(fCfg == NULL)
00636 {
00637 SBPL_ERROR("ERROR: unable to open %s\n", sEnvFile);
00638 throw new SBPL_Exception();
00639 }
00640 ReadConfiguration(fCfg);
00641 fclose(fCfg);
00642
00643 InitGeneral();
00644
00645 return true;
00646 }
00647
00648
00649 bool EnvironmentNAV2D::InitializeEnv(int width, int height,
00650 const unsigned char* mapdata,
00651 unsigned char obsthresh)
00652 {
00653 return InitializeEnv(width, height, mapdata,
00654 0, 0, 0, 0,
00655 obsthresh);
00656 }
00657
00658
00659 bool EnvironmentNAV2D::InitializeEnv(int width, int height,
00660 const unsigned char* mapdata,
00661 int startx, int starty,
00662 int goalx, int goaly, unsigned char obsthresh)
00663 {
00664
00665 SBPL_PRINTF("env: initialized with width=%d height=%d, start=%d %d, goal=%d %d, obsthresh=%d\n",
00666 width, height, startx, starty, goalx, goaly, obsthresh);
00667
00668 EnvNAV2DCfg.obsthresh = obsthresh;
00669
00670 SetConfiguration(width, height,
00671 mapdata,
00672 startx, starty,
00673 goalx, goaly);
00674
00675 InitGeneral();
00676
00677 return true;
00678 }
00679
00680
00681 bool EnvironmentNAV2D::InitGeneral() {
00682
00683 InitializeEnvConfig();
00684
00685
00686 InitializeEnvironment();
00687
00688
00689 ComputeHeuristicValues();
00690
00691 return true;
00692 }
00693
00694 bool EnvironmentNAV2D::InitializeMDPCfg(MDPConfig *MDPCfg)
00695 {
00696
00697 MDPCfg->goalstateid = EnvNAV2D.goalstateid;
00698 MDPCfg->startstateid = EnvNAV2D.startstateid;
00699
00700 return true;
00701 }
00702
00703
00704
00705 int EnvironmentNAV2D::GetFromToHeuristic(int FromStateID, int ToStateID)
00706 {
00707 #if USE_HEUR==0
00708 return 0;
00709 #endif
00710
00711
00712 #if DEBUG
00713 if(FromStateID >= (int)EnvNAV2D.StateID2CoordTable.size()
00714 || ToStateID >= (int)EnvNAV2D.StateID2CoordTable.size())
00715 {
00716 SBPL_ERROR("ERROR in EnvNAV2D... function: stateID illegal\n");
00717 throw new SBPL_Exception();
00718 }
00719 #endif
00720
00721
00722 EnvNAV2DHashEntry_t* FromHashEntry = EnvNAV2D.StateID2CoordTable[FromStateID];
00723 EnvNAV2DHashEntry_t* ToHashEntry = EnvNAV2D.StateID2CoordTable[ToStateID];
00724
00725
00726 return EuclideanDistance(FromHashEntry->X, FromHashEntry->Y, ToHashEntry->X, ToHashEntry->Y);
00727
00728 }
00729
00730
00731 int EnvironmentNAV2D::GetGoalHeuristic(int stateID)
00732 {
00733 #if USE_HEUR==0
00734 return 0;
00735 #endif
00736
00737 #if DEBUG
00738 if(stateID >= (int)EnvNAV2D.StateID2CoordTable.size())
00739 {
00740 SBPL_ERROR("ERROR in EnvNAV2D... function: stateID illegal\n");
00741 throw new SBPL_Exception();
00742 }
00743 #endif
00744
00745
00746
00747 return GetFromToHeuristic(stateID, EnvNAV2D.goalstateid);
00748
00749 }
00750
00751
00752 int EnvironmentNAV2D::GetStartHeuristic(int stateID)
00753 {
00754 #if USE_HEUR==0
00755 return 0;
00756 #endif
00757
00758
00759 #if DEBUG
00760 if(stateID >= (int)EnvNAV2D.StateID2CoordTable.size())
00761 {
00762 SBPL_ERROR("ERROR in EnvNAV2D... function: stateID illegal\n");
00763 throw new SBPL_Exception();
00764 }
00765 #endif
00766
00767
00768
00769 return GetFromToHeuristic(EnvNAV2D.startstateid, stateID);
00770
00771
00772 }
00773
00774
00775
00776 void EnvironmentNAV2D::SetAllActionsandAllOutcomes(CMDPSTATE* state)
00777 {
00778
00779 int cost;
00780
00781 #if DEBUG
00782 if(state->StateID >= (int)EnvNAV2D.StateID2CoordTable.size())
00783 {
00784 SBPL_ERROR("ERROR in Env... function: stateID illegal\n");
00785 throw new SBPL_Exception();
00786 }
00787
00788 if((int)state->Actions.size() != 0)
00789 {
00790 SBPL_ERROR("ERROR in Env_setAllActionsandAllOutcomes: actions already exist for the state\n");
00791 throw new SBPL_Exception();
00792 }
00793 #endif
00794
00795
00796
00797 if(state->StateID == EnvNAV2D.goalstateid)
00798 return;
00799
00800
00801 EnvNAV2DHashEntry_t* HashEntry = EnvNAV2D.StateID2CoordTable[state->StateID];
00802
00803
00804 bool bTestBounds = false;
00805 if(HashEntry->X <= 1 || HashEntry->X >= EnvNAV2DCfg.EnvWidth_c-2 ||
00806 HashEntry->Y <= 1 || HashEntry->Y >= EnvNAV2DCfg.EnvHeight_c-2)
00807 bTestBounds = true;
00808 for (int aind = 0; aind < EnvNAV2DCfg.numofdirs; aind++)
00809 {
00810 int newX = HashEntry->X + EnvNAV2DCfg.dx_[aind];
00811 int newY = HashEntry->Y + EnvNAV2DCfg.dy_[aind];
00812
00813
00814 if(bTestBounds){
00815 if(!IsValidCell(newX, newY))
00816 continue;
00817 }
00818
00819
00820 int costmult = EnvNAV2DCfg.Grid2D[newX][newY];
00821
00822 if(newX != HashEntry->X && newY != HashEntry->Y && aind <= 7)
00823 {
00824
00825 costmult = __max(costmult, EnvNAV2DCfg.Grid2D[HashEntry->X][newY]);
00826 costmult = __max(costmult, EnvNAV2DCfg.Grid2D[newX][HashEntry->Y]);
00827 }
00828 else if(aind > 7)
00829 {
00830
00831 costmult = __max(costmult, EnvNAV2DCfg.Grid2D[HashEntry->X + EnvNAV2DCfg.dxintersects_[aind][0]][HashEntry->Y + EnvNAV2DCfg.dyintersects_[aind][0]]);
00832 costmult = __max(costmult, EnvNAV2DCfg.Grid2D[HashEntry->X + EnvNAV2DCfg.dxintersects_[aind][1]][HashEntry->Y + EnvNAV2DCfg.dyintersects_[aind][1]]);
00833 }
00834
00835
00836
00837 if(costmult >= EnvNAV2DCfg.obsthresh)
00838 continue;
00839
00840
00841 cost = (costmult+1)*EnvNAV2DCfg.dxy_distance_mm_[aind];
00842
00843
00844 CMDPACTION* action = state->AddAction(aind);
00845
00846 #if TIME_DEBUG
00847 clock_t currenttime = clock();
00848 #endif
00849
00850
00851 EnvNAV2DHashEntry_t* OutHashEntry;
00852 if((OutHashEntry = GetHashEntry(newX, newY)) == NULL)
00853 {
00854
00855 OutHashEntry = CreateNewHashEntry(newX, newY);
00856 }
00857 action->AddOutcome(OutHashEntry->stateID, cost, 1.0);
00858
00859 #if TIME_DEBUG
00860 time3_addallout += clock()-currenttime;
00861 #endif
00862
00863 }
00864 }
00865
00866
00867
00868 void EnvironmentNAV2D::SetAllPreds(CMDPSTATE* state)
00869 {
00870
00871
00872 SBPL_ERROR("ERROR in EnvNAV2D... function: SetAllPreds is undefined\n");
00873 throw new SBPL_Exception();
00874 }
00875
00876
00877 void EnvironmentNAV2D::GetSuccs(int SourceStateID, vector<int>* SuccIDV, vector<int>* CostV)
00878 {
00879 int aind;
00880
00881 #if TIME_DEBUG
00882 clock_t currenttime = clock();
00883 #endif
00884
00885
00886 SuccIDV->clear();
00887 CostV->clear();
00888 SuccIDV->reserve(EnvNAV2DCfg.numofdirs);
00889 CostV->reserve(EnvNAV2DCfg.numofdirs);
00890
00891
00892 if(SourceStateID == EnvNAV2D.goalstateid)
00893 return;
00894
00895
00896 EnvNAV2DHashEntry_t* HashEntry = EnvNAV2D.StateID2CoordTable[SourceStateID];
00897
00898
00899 bool bTestBounds = false;
00900 if(HashEntry->X <= 1 || HashEntry->X >= EnvNAV2DCfg.EnvWidth_c-2 ||
00901 HashEntry->Y <= 1 || HashEntry->Y >= EnvNAV2DCfg.EnvHeight_c-2)
00902 bTestBounds = true;
00903 for (aind = 0; aind < EnvNAV2DCfg.numofdirs; aind++)
00904 {
00905 int newX = HashEntry->X + EnvNAV2DCfg.dx_[aind];
00906 int newY = HashEntry->Y + EnvNAV2DCfg.dy_[aind];
00907
00908
00909 if(bTestBounds){
00910 if(!IsValidCell(newX, newY))
00911 continue;
00912 }
00913
00914 int costmult = EnvNAV2DCfg.Grid2D[newX][newY];
00915
00916
00917 if(newX != HashEntry->X && newY != HashEntry->Y && aind <= 7)
00918 {
00919 costmult = __max(costmult, EnvNAV2DCfg.Grid2D[HashEntry->X][newY]);
00920 costmult = __max(costmult, EnvNAV2DCfg.Grid2D[newX][HashEntry->Y]);
00921 }
00922 else if(aind > 7)
00923 {
00924
00925 costmult = __max(costmult, EnvNAV2DCfg.Grid2D[HashEntry->X + EnvNAV2DCfg.dxintersects_[aind][0]][HashEntry->Y + EnvNAV2DCfg.dyintersects_[aind][0]]);
00926 costmult = __max(costmult, EnvNAV2DCfg.Grid2D[HashEntry->X + EnvNAV2DCfg.dxintersects_[aind][1]][HashEntry->Y + EnvNAV2DCfg.dyintersects_[aind][1]]);
00927 }
00928
00929
00930
00931 if(costmult >= EnvNAV2DCfg.obsthresh)
00932 continue;
00933
00934
00935 int cost = (costmult+1)*EnvNAV2DCfg.dxy_distance_mm_[aind];
00936
00937 EnvNAV2DHashEntry_t* OutHashEntry;
00938 if((OutHashEntry = GetHashEntry(newX, newY)) == NULL)
00939 {
00940
00941 OutHashEntry = CreateNewHashEntry(newX, newY);
00942 }
00943
00944 SuccIDV->push_back(OutHashEntry->stateID);
00945 CostV->push_back(cost);
00946 }
00947
00948 #if TIME_DEBUG
00949 time_getsuccs += clock()-currenttime;
00950 #endif
00951
00952 }
00953
00954 void EnvironmentNAV2D::GetPreds(int TargetStateID, vector<int>* PredIDV, vector<int>* CostV)
00955 {
00956
00957 int aind;
00958
00959 #if TIME_DEBUG
00960 clock_t currenttime = clock();
00961 #endif
00962
00963
00964 PredIDV->clear();
00965 CostV->clear();
00966 PredIDV->reserve(EnvNAV2DCfg.numofdirs);
00967 CostV->reserve(EnvNAV2DCfg.numofdirs);
00968
00969
00970 EnvNAV2DHashEntry_t* HashEntry = EnvNAV2D.StateID2CoordTable[TargetStateID];
00971
00972
00973 if(EnvNAV2DCfg.Grid2D[HashEntry->X][HashEntry->Y] >= EnvNAV2DCfg.obsthresh)
00974 return;
00975
00976 int targetcostmult = EnvNAV2DCfg.Grid2D[HashEntry->X][HashEntry->Y];
00977
00978
00979 bool bTestBounds = false;
00980 if(HashEntry->X <= 1 || HashEntry->X >= EnvNAV2DCfg.EnvWidth_c-2 ||
00981 HashEntry->Y <= 1 || HashEntry->Y >= EnvNAV2DCfg.EnvHeight_c-2)
00982 bTestBounds = true;
00983 for (aind = 0; aind < EnvNAV2DCfg.numofdirs; aind++)
00984 {
00985
00986 int predX = HashEntry->X + EnvNAV2DCfg.dx_[aind];
00987 int predY = HashEntry->Y + EnvNAV2DCfg.dy_[aind];
00988
00989
00990 if(bTestBounds){
00991 if(!IsValidCell(predX, predY))
00992 continue;
00993 }
00994
00995
00996 int costmult = targetcostmult;
00997
00998 if(predX != HashEntry->X && predY != HashEntry->Y && aind <= 7)
00999 {
01000 costmult = __max(costmult, EnvNAV2DCfg.Grid2D[HashEntry->X][predY]);
01001 costmult = __max(costmult, EnvNAV2DCfg.Grid2D[predX][HashEntry->Y]);
01002 }
01003 else if(aind > 7)
01004 {
01005
01006
01007
01008 costmult = __max(costmult, EnvNAV2DCfg.Grid2D[HashEntry->X + EnvNAV2DCfg.dxintersects_[aind][0]][HashEntry->Y + EnvNAV2DCfg.dyintersects_[aind][0]]);
01009 costmult = __max(costmult, EnvNAV2DCfg.Grid2D[HashEntry->X + EnvNAV2DCfg.dxintersects_[aind][1]][HashEntry->Y + EnvNAV2DCfg.dyintersects_[aind][1]]);
01010 }
01011
01012
01013 if(costmult >= EnvNAV2DCfg.obsthresh)
01014 continue;
01015
01016
01017 int cost = (costmult+1)*EnvNAV2DCfg.dxy_distance_mm_[aind];
01018
01019 EnvNAV2DHashEntry_t* OutHashEntry;
01020 if((OutHashEntry = GetHashEntry(predX, predY)) == NULL)
01021 {
01022
01023 OutHashEntry = CreateNewHashEntry(predX, predY);
01024 }
01025
01026
01027 PredIDV->push_back(OutHashEntry->stateID);
01028 CostV->push_back(cost);
01029 }
01030
01031 #if TIME_DEBUG
01032 time_getsuccs += clock()-currenttime;
01033 #endif
01034
01035
01036 }
01037
01038
01039
01040 int EnvironmentNAV2D::SizeofCreatedEnv()
01041 {
01042 return (int)EnvNAV2D.StateID2CoordTable.size();
01043
01044 }
01045
01046 void EnvironmentNAV2D::PrintState(int stateID, bool bVerbose, FILE* fOut )
01047 {
01048 #if DEBUG
01049 if(stateID >= (int)EnvNAV2D.StateID2CoordTable.size())
01050 {
01051 SBPL_ERROR("ERROR in EnvNAV2D... function: stateID illegal (2)\n");
01052 throw new SBPL_Exception();
01053 }
01054 #endif
01055
01056 if(fOut == NULL)
01057 fOut = stdout;
01058
01059 EnvNAV2DHashEntry_t* HashEntry = EnvNAV2D.StateID2CoordTable[stateID];
01060
01061 if(stateID == EnvNAV2D.goalstateid && bVerbose)
01062 {
01063 SBPL_FPRINTF(fOut, "the state is a goal state\n");
01064 }
01065
01066 if(bVerbose)
01067 SBPL_FPRINTF(fOut, "X=%d Y=%d\n", HashEntry->X, HashEntry->Y);
01068 else
01069 SBPL_FPRINTF(fOut, "%d %d\n", HashEntry->X, HashEntry->Y);
01070
01071 }
01072
01073 void EnvironmentNAV2D::GetCoordFromState(int stateID, int& x, int& y) const {
01074 EnvNAV2DHashEntry_t* HashEntry = EnvNAV2D.StateID2CoordTable[stateID];
01075 x = HashEntry->X;
01076 y = HashEntry->Y;
01077 }
01078
01079 int EnvironmentNAV2D::GetStateFromCoord(int x, int y) {
01080
01081 EnvNAV2DHashEntry_t* OutHashEntry;
01082 if((OutHashEntry = GetHashEntry(x, y)) == NULL){
01083
01084 OutHashEntry = CreateNewHashEntry(x, y);
01085 }
01086 return OutHashEntry->stateID;
01087 }
01088
01089 const EnvNAV2DConfig_t* EnvironmentNAV2D::GetEnvNavConfig() {
01090 return &EnvNAV2DCfg;
01091 }
01092
01093
01094 int EnvironmentNAV2D::SetGoal(int x, int y){
01095
01096 if(!IsWithinMapCell(x,y))
01097 {
01098 SBPL_ERROR("ERROR: trying to set a goal cell %d %d that is outside of map\n", x,y);
01099 return -1;
01100 }
01101
01102 if(!IsValidCell(x,y))
01103 {
01104 SBPL_PRINTF("WARNING: goal cell is invalid\n");
01105 }
01106
01107
01108 EnvNAV2DHashEntry_t* OutHashEntry;
01109 if((OutHashEntry = GetHashEntry(x, y)) == NULL){
01110
01111 OutHashEntry = CreateNewHashEntry(x, y);
01112 }
01113 EnvNAV2D.goalstateid = OutHashEntry->stateID;
01114 EnvNAV2DCfg.EndX_c = x;
01115 EnvNAV2DCfg.EndY_c = y;
01116
01117
01118 return EnvNAV2D.goalstateid;
01119
01120 }
01121
01122
01123 void EnvironmentNAV2D::SetGoalTolerance(double tol_x, double tol_y, double tol_theta)
01124 {
01125
01126 }
01127
01128
01129
01130 int EnvironmentNAV2D::SetStart(int x, int y){
01131
01132 if(!IsWithinMapCell(x,y))
01133 {
01134 SBPL_ERROR("ERROR: trying to set a start cell %d %d that is outside of map\n", x,y);
01135 return -1;
01136 }
01137
01138 if(!IsValidCell(x,y))
01139 {
01140 SBPL_PRINTF("WARNING: start cell is invalid\n");
01141 }
01142
01143
01144 EnvNAV2DHashEntry_t* OutHashEntry;
01145 if((OutHashEntry = GetHashEntry(x, y)) == NULL){
01146
01147 OutHashEntry = CreateNewHashEntry(x, y);
01148 }
01149 EnvNAV2D.startstateid = OutHashEntry->stateID;
01150 EnvNAV2DCfg.StartX_c = x;
01151 EnvNAV2DCfg.StartY_c = y;
01152
01153 return EnvNAV2D.startstateid;
01154
01155 }
01156
01157 bool EnvironmentNAV2D::UpdateCost(int x, int y, unsigned char newcost)
01158 {
01159
01160 EnvNAV2DCfg.Grid2D[x][y] = newcost;
01161
01162 return true;
01163 }
01164
01165
01166 void EnvironmentNAV2D::PrintEnv_Config(FILE* fOut)
01167 {
01168
01169
01170
01171 SBPL_ERROR("ERROR in EnvNAV2D... function: PrintEnv_Config is undefined\n");
01172 throw new SBPL_Exception();
01173
01174 }
01175
01176 void EnvironmentNAV2D::PrintTimeStat(FILE* fOut)
01177 {
01178
01179 #if TIME_DEBUG
01180 SBPL_FPRINTF(fOut, "time3_addallout = %f secs, time_gethash = %f secs, time_createhash = %f secs, time_getsuccs = %f\n",
01181 time3_addallout/(double)CLOCKS_PER_SEC, time_gethash/(double)CLOCKS_PER_SEC,
01182 time_createhash/(double)CLOCKS_PER_SEC, time_getsuccs/(double)CLOCKS_PER_SEC);
01183 #endif
01184 }
01185
01186
01187 void EnvironmentNAV2D::GetPredsofChangedEdges(vector<nav2dcell_t> const * changedcellsV, vector<int> *preds_of_changededgesIDV)
01188 {
01189 nav2dcell_t cell;
01190 int aind;
01191
01192 for(int i = 0; i < (int)changedcellsV->size(); i++)
01193 {
01194 cell = changedcellsV->at(i);
01195 preds_of_changededgesIDV->push_back(GetStateFromCoord(cell.x,cell.y));
01196
01197 for (aind = 0; aind < EnvNAV2DCfg.numofdirs; aind++)
01198 {
01199
01200 int affx = cell.x + EnvNAV2DCfg.dx_[aind];
01201 int affy = cell.y + EnvNAV2DCfg.dy_[aind];
01202 if(affx < 0 || affx >= EnvNAV2DCfg.EnvWidth_c || affy < 0 || affy >= EnvNAV2DCfg.EnvHeight_c)
01203 continue;
01204 preds_of_changededgesIDV->push_back(GetStateFromCoord(affx,affy));
01205 }
01206 }
01207 }
01208
01209
01210
01211
01212 void EnvironmentNAV2D::GetSuccsofChangedEdges(vector<nav2dcell_t> const * changedcellsV, vector<int> *succs_of_changededgesIDV)
01213 {
01214 nav2dcell_t cell;
01215 int aind;
01216
01217 for(int i = 0; i < (int)changedcellsV->size(); i++)
01218 {
01219 cell = changedcellsV->at(i);
01220 succs_of_changededgesIDV->push_back(GetStateFromCoord(cell.x,cell.y));
01221 for (aind = 0; aind < EnvNAV2DCfg.numofdirs; aind++)
01222 {
01223 int affx = cell.x + EnvNAV2DCfg.dx_[aind];
01224 int affy = cell.y + EnvNAV2DCfg.dy_[aind];
01225 if(affx < 0 || affx >= EnvNAV2DCfg.EnvWidth_c || affy < 0 || affy >= EnvNAV2DCfg.EnvHeight_c)
01226 continue;
01227 succs_of_changededgesIDV->push_back(GetStateFromCoord(affx,affy));
01228 }
01229 }
01230 }
01231
01232
01233 bool EnvironmentNAV2D::IsObstacle(int x, int y)
01234 {
01235
01236 return (EnvNAV2DCfg.Grid2D[x][y] >= EnvNAV2DCfg.obsthresh);
01237
01238 }
01239
01240 unsigned char EnvironmentNAV2D::GetMapCost(int x, int y)
01241 {
01242 return EnvNAV2DCfg.Grid2D[x][y];
01243 }
01244
01245
01246
01247 void EnvironmentNAV2D::GetEnvParms(int *size_x, int *size_y, int* startx, int* starty, int* goalx, int* goaly, unsigned char* obsthresh)
01248 {
01249 *size_x = EnvNAV2DCfg.EnvWidth_c;
01250 *size_y = EnvNAV2DCfg.EnvHeight_c;
01251
01252 *startx = EnvNAV2DCfg.StartX_c;
01253 *starty = EnvNAV2DCfg.StartY_c;
01254 *goalx = EnvNAV2DCfg.EndX_c;
01255 *goaly = EnvNAV2DCfg.EndY_c;
01256
01257 *obsthresh = EnvNAV2DCfg.obsthresh;
01258 }
01259
01260 bool EnvironmentNAV2D::SetEnvParameter(const char* parameter, int value)
01261 {
01262
01263 if(EnvNAV2D.bInitialized == true)
01264 {
01265 SBPL_ERROR("ERROR: all parameters must be set before initialization of the environment\n");
01266 return false;
01267 }
01268
01269 SBPL_PRINTF("setting parameter %s to %d\n", parameter, value);
01270
01271 if(strcmp(parameter, "is16connected") == 0)
01272 {
01273 if(value != 0)
01274 EnvNAV2DCfg.numofdirs = 16;
01275 else
01276 EnvNAV2DCfg.numofdirs = 8;
01277 }
01278 else
01279 {
01280 SBPL_ERROR("ERROR: invalid parameter %s\n", parameter);
01281 return false;
01282 }
01283
01284 return true;
01285 }
01286
01287
01288
01289 bool EnvironmentNAV2D::AreEquivalent(int StateID1, int StateID2)
01290 {
01291
01292 #if DEBUG
01293 if(StateID1 >= (int)EnvNAV2D.StateID2CoordTable.size() || StateID2 >= (int)EnvNAV2D.StateID2CoordTable.size())
01294 {
01295 SBPL_ERROR("ERROR in EnvNAV2D... function: stateID illegal (2)\n");
01296 throw new SBPL_Exception();
01297 }
01298 #endif
01299
01300
01301 EnvNAV2DHashEntry_t* HashEntry1 = EnvNAV2D.StateID2CoordTable[StateID1];
01302 EnvNAV2DHashEntry_t* HashEntry2 = EnvNAV2D.StateID2CoordTable[StateID2];
01303
01304 if(HashEntry1->X == HashEntry2->X && HashEntry1->Y == HashEntry2->Y)
01305 return true;
01306
01307 return false;
01308 }
01309
01310
01311 void EnvironmentNAV2D::GetRandomSuccsatDistance(int SourceStateID, std::vector<int>* SuccIDV, std::vector<int>* CLowV)
01312 {
01313
01314 int nNumofNeighs = 10;
01315
01316 int nDist_c = 100;
01317
01318
01319 #if DEBUG
01320 if(SourceStateID >= (int)EnvNAV2D.StateID2CoordTable.size())
01321 {
01322 SBPL_ERROR("ERROR in EnvNAV2DGetRandSuccs... function: stateID illegal\n");
01323 throw new SBPL_Exception();
01324 }
01325 #endif
01326
01327
01328 if(SourceStateID == EnvNAV2D.goalstateid)
01329 return;
01330
01331
01332 bool bSuccs = true;
01333 GetRandomNeighs(SourceStateID, SuccIDV, CLowV, nNumofNeighs, nDist_c, bSuccs);
01334
01335 }
01336
01337
01338 void EnvironmentNAV2D::GetRandomPredsatDistance(int TargetStateID, std::vector<int>* PredIDV, std::vector<int>* CLowV)
01339 {
01340
01341 int nNumofNeighs = 10;
01342
01343 int nDist_c = 5;
01344
01345
01346 #if DEBUG
01347 if(TargetStateID >= (int)EnvNAV2D.StateID2CoordTable.size())
01348 {
01349 SBPL_ERROR("ERROR in EnvNAV2DGetRandSuccs... function: stateID illegal\n");
01350 throw new SBPL_Exception();
01351 }
01352 #endif
01353
01354
01355 if(TargetStateID == EnvNAV2D.startstateid)
01356 return;
01357
01358
01359 bool bSuccs = false;
01360 GetRandomNeighs(TargetStateID, PredIDV, CLowV, nNumofNeighs, nDist_c, bSuccs);
01361
01362
01363 }
01364
01365