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 #include <sbpl_dynamic_planner/envDBubble.h>
00034
00035 #define DRAW_MAP 0
00036 #define DEFAULT_TEMPORAL_PADDING 100 //15
00037
00038 #if TIME_DEBUG
00039 static clock_t time3_addallout = 0;
00040 static clock_t time_gethash = 0;
00041 static clock_t time_createhash = 0;
00042 static clock_t time_getsuccs = 0;
00043 #endif
00044
00045 static long int checks = 0;
00046
00047
00048
00049 EnvDBubbleLattice::EnvDBubbleLattice()
00050 {
00051 SBPL_PRINTF("u1\n");
00052 envDBubbleLatCfg.obsthresh = ENVDBUBBLELAT_DEFAULTOBSTHRESH;
00053 envDBubbleLatCfg.dynamic_obstacle_collision_cost_thresh = ENVDBUBBLELAT_DEFAULTDYNOBSTHRESH;
00054 envDBubbleLatCfg.cost_inscribed_thresh = envDBubbleLatCfg.obsthresh;
00055 envDBubbleLatCfg.cost_possibly_circumscribed_thresh = -1;
00056
00057 grid2Dsearchfromstart = NULL;
00058 grid2Dsearchfromgoal = NULL;
00059 bNeedtoRecomputeStartHeuristics = true;
00060 bNeedtoRecomputeGoalHeuristics = true;
00061 iteration = 0;
00062
00063 envDBubbleLat.bInitialized = false;
00064
00065 envDBubbleLatCfg.actionwidth = ENVDBUBBLELAT_DEFAULT_ACTIONWIDTH;
00066 }
00067
00068 EnvDBubbleLattice::~EnvDBubbleLattice()
00069 {
00070 if(grid2Dsearchfromstart != NULL)
00071 delete grid2Dsearchfromstart;
00072 grid2Dsearchfromstart = NULL;
00073
00074 if(grid2Dsearchfromgoal != NULL)
00075 delete grid2Dsearchfromgoal;
00076 grid2Dsearchfromgoal = NULL;
00077
00078
00079 for (int x = 0; x < envDBubbleLatCfg.EnvWidth_c; x++)
00080 delete [] envDBubbleLatCfg.Grid2D[x];
00081 delete [] envDBubbleLatCfg.Grid2D;
00082
00083 for(int i=0; i<ENVDBUBBLELAT_THETADIRS; i++)
00084 delete [] envDBubbleLatCfg.ActionsV[i];
00085 delete [] envDBubbleLatCfg.ActionsV;
00086
00087 for(int i=0; i<ENVDBUBBLELAT_THETADIRS; i++)
00088 envDBubbleLatCfg.PredActionsV[i].clear();
00089 delete [] envDBubbleLatCfg.PredActionsV;
00090 }
00091
00092 EnvDBubbleLat::~EnvDBubbleLat(){
00093 for(unsigned int i=0; i<StateID2CoordTable.size(); i++)
00094 delete StateID2CoordTable[i];
00095 delete [] Coord2StateIDHashTable;
00096 }
00097
00098
00099
00100
00101
00102
00103
00104 static unsigned int inthash(unsigned int key)
00105 {
00106 key += (key << 12);
00107 key ^= (key >> 22);
00108 key += (key << 4);
00109 key ^= (key >> 9);
00110 key += (key << 10);
00111 key ^= (key >> 2);
00112 key += (key << 7);
00113 key ^= (key >> 12);
00114 return key;
00115 }
00116
00117 void EnvDBubbleLattice::ReadDynamicObstacles(FILE* fDynObs){
00118 char sTemp[1024], sTemp1[1024];
00119 int iTemp;
00120
00121 SBPL_PRINTF("Reading Dynamic Obstacles...\n");
00122
00123
00124 if(fscanf(fDynObs, "%s", sTemp) != 1){
00125 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00126 throw new SBPL_Exception();
00127 }
00128 strcpy(sTemp1, "NumberOfDynamicObstacles:");
00129 if(strcmp(sTemp1, sTemp) != 0){
00130 SBPL_ERROR("ERROR: dynamic obstacle file has incorrect format\n");
00131 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00132 throw new SBPL_Exception();
00133 }
00134 if(fscanf(fDynObs, "%s", sTemp) != 1){
00135 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00136 throw new SBPL_Exception();
00137 }
00138 int numObs = atoi(sTemp);
00139
00140
00141 for(int i=0; i < numObs; i++){
00142
00143
00144 if(fscanf(fDynObs, "%s", sTemp) != 1){
00145 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00146 throw new SBPL_Exception();
00147 }
00148 strcpy(sTemp1, "DynamicObstacleID:");
00149 if(strcmp(sTemp1, sTemp) != 0){
00150 SBPL_ERROR("ERROR: dynamic obstacle file has incorrect format\n");
00151 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00152 throw new SBPL_Exception();
00153 }
00154 if(fscanf(fDynObs, "%s", sTemp) != 1){
00155 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00156 throw new SBPL_Exception();
00157 }
00158 iTemp = atoi(sTemp);
00159 if(iTemp != i){
00160 SBPL_ERROR("ERROR: dynamic obstacle file has incorrect format\n");
00161 SBPL_PRINTF("Expected %d got %d\n", i, iTemp);
00162 throw new SBPL_Exception();
00163 }
00164 SBPL_DynamicObstacle_t obs;
00165
00166
00167 if(fscanf(fDynObs, "%s", sTemp) != 1){
00168 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00169 throw new SBPL_Exception();
00170 }
00171 strcpy(sTemp1, "ObstacleRadius:");
00172 if(strcmp(sTemp1, sTemp) != 0){
00173 SBPL_ERROR("ERROR: dynamic obstacle file has incorrect format\n");
00174 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00175 throw new SBPL_Exception();
00176 }
00177 if(fscanf(fDynObs, "%s", sTemp) != 1){
00178 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00179 throw new SBPL_Exception();
00180 }
00181 obs.radius = atof(sTemp) + envDBubbleLatCfg.robotRadius;
00182
00183
00184 if(fscanf(fDynObs, "%s", sTemp) != 1){
00185 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00186 throw new SBPL_Exception();
00187 }
00188 strcpy(sTemp1, "NumberOfTrajectories:");
00189 if(strcmp(sTemp1, sTemp) != 0){
00190 SBPL_ERROR("ERROR: dynamic obstacle file has incorrect format\n");
00191 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00192 throw new SBPL_Exception();
00193 }
00194 if(fscanf(fDynObs, "%s", sTemp) != 1){
00195 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00196 throw new SBPL_Exception();
00197 }
00198 int numTraj = atoi(sTemp);
00199
00200
00201 double trajProbSum = 0;
00202 for(int j=0; j < numTraj; j++){
00203
00204
00205 if(fscanf(fDynObs, "%s", sTemp) != 1){
00206 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00207 throw new SBPL_Exception();
00208 }
00209 strcpy(sTemp1, "TrajectoryID:");
00210 if(strcmp(sTemp1, sTemp) != 0){
00211 SBPL_ERROR("ERROR: dynamic obstacle file has incorrect format\n");
00212 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00213 throw new SBPL_Exception();
00214 }
00215 if(fscanf(fDynObs, "%s", sTemp) != 1){
00216 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00217 throw new SBPL_Exception();
00218 }
00219 iTemp = atoi(sTemp);
00220 if(iTemp != j){
00221 SBPL_ERROR("ERROR: dynamic obstacle file has incorrect format\n");
00222 SBPL_PRINTF("Expected %d got %d\n", j, iTemp);
00223 throw new SBPL_Exception();
00224 }
00225 SBPL_Trajectory_t traj;
00226
00227
00228 if(fscanf(fDynObs, "%s", sTemp) != 1){
00229 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00230 throw new SBPL_Exception();
00231 }
00232 strcpy(sTemp1, "TrajectoryProbability:");
00233 if(strcmp(sTemp1, sTemp) != 0){
00234 SBPL_ERROR("ERROR: dynamic obstacle file has incorrect format\n");
00235 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00236 throw new SBPL_Exception();
00237 }
00238 if(fscanf(fDynObs, "%s", sTemp) != 1){
00239 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00240 throw new SBPL_Exception();
00241 }
00242 traj.prob = atof(sTemp);
00243 if(traj.prob < 0 || traj.prob > 1){
00244 SBPL_ERROR("ERROR: dynamic obstacle file has incorrect format\n");
00245 SBPL_PRINTF("Expected TrajectoryProbability on the interval [0,1] but got %f\n", traj.prob);
00246 throw new SBPL_Exception();
00247 }
00248 trajProbSum += traj.prob;
00249
00250
00251 if(fscanf(fDynObs, "%s", sTemp) != 1){
00252 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00253 throw new SBPL_Exception();
00254 }
00255 strcpy(sTemp1, "NumberOfPoints:");
00256 if(strcmp(sTemp1, sTemp) != 0){
00257 SBPL_ERROR("ERROR: dynamic obstacle file has incorrect format\n");
00258 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00259 throw new SBPL_Exception();
00260 }
00261 if(fscanf(fDynObs, "%s", sTemp) != 1){
00262 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00263 throw new SBPL_Exception();
00264 }
00265 int numPoints = atoi(sTemp);
00266
00267
00268 int prev_t = 0;
00269 for(int k=0; k < numPoints; k++){
00270
00271 SBPL_Traj_Pt_t pt;
00272 if(fscanf(fDynObs, "%s", sTemp) != 1){
00273 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00274 throw new SBPL_Exception();
00275 }
00276 pt.x = atof(sTemp);
00277 if(fscanf(fDynObs, "%s", sTemp) != 1){
00278 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00279 throw new SBPL_Exception();
00280 }
00281 pt.y = atof(sTemp);
00282 if(fscanf(fDynObs, "%s", sTemp) != 1){
00283 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00284 throw new SBPL_Exception();
00285 }
00286 pt.t = CONTTIME2DISC(atof(sTemp),envDBubbleLatCfg.timeResolution);
00287
00288 if(prev_t > pt.t && k != 0){
00289 SBPL_ERROR("ERROR: dynamic obstacle file has incorrect format\n");
00290 SBPL_PRINTF("dynamic obstacle trajectory times can't decrease!\n");
00291 throw new SBPL_Exception();
00292 }
00293 prev_t = pt.t;
00294
00295 if(fscanf(fDynObs, "%s", sTemp) != 1){
00296 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00297 throw new SBPL_Exception();
00298 }
00299 pt.std_dev = atof(sTemp);
00300
00301
00302 traj.points.push_back(pt);
00303 }
00304
00305
00306
00307 if(fscanf(fDynObs, "%s", sTemp) != 1){
00308 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00309 throw new SBPL_Exception();
00310 }
00311 strcpy(sTemp1, "ObstacleExistsAfterTrajectory:");
00312 if(strcmp(sTemp1, sTemp) != 0){
00313 SBPL_ERROR("ERROR: dynamic obstacle file has incorrect format\n");
00314 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00315 throw new SBPL_Exception();
00316 }
00317 if(fscanf(fDynObs, "%s", sTemp) != 1){
00318 SBPL_ERROR("ERROR: ran out of dynamic obstacle file early\n");
00319 throw new SBPL_Exception();
00320 }
00321 traj.existsAfter = atoi(sTemp);
00322 if(traj.existsAfter != 0 && traj.existsAfter != 1){
00323 SBPL_ERROR("ERROR: dynamic obstacle file has incorrect format\n");
00324 SBPL_PRINTF("ObstacleExistsAfterTrajectory is a boolean and needs to be 0 or 1\n");
00325 throw new SBPL_Exception();
00326 }
00327
00328
00329 obs.trajectories.push_back(traj);
00330 }
00331
00332
00333 if(fabs(trajProbSum - 1.0) > ERR_EPS){
00334 SBPL_ERROR("ERROR: dynamic obstacle file has incorrect format\n");
00335 SBPL_PRINTF("Probabilities for trajectories of dynamic obstacle %d sum to %f instead of 1\n", i, trajProbSum);
00336 throw new SBPL_Exception();
00337 }
00338
00339
00340 dynamicObstacles.push_back(obs);
00341
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355 SBPL_PRINTF("Done Reading Dynamic Obstacles\n");
00356 }
00357
00358 void EnvDBubbleLattice::InitializeBubbleMap(){
00359 SBPL_PRINTF("Initializing bubble map\n");
00360
00361 bubblemap.resize(envDBubbleLatCfg.EnvWidth_c);
00362 for (int x = 0; x < envDBubbleLatCfg.EnvWidth_c; x++){
00363 bubblemap[x].resize(envDBubbleLatCfg.EnvHeight_c);
00364 }
00365
00366 double maxMovement = 0;
00367 for (unsigned int i = 0; i < envDBubbleLatCfg.mprimV.size(); i++){
00368 SBPL_4Dpt_t p = envDBubbleLatCfg.mprimV[i].intermptV.back();
00369 double temp = p.x*p.x + p.y*p.y;
00370 if(temp > maxMovement)
00371 maxMovement = temp;
00372 }
00373 envDBubbleLatCfg.maxMovement = sqrt(maxMovement);
00374
00375 UpdateBubbleMap();
00376 }
00377
00378 void EnvDBubbleLattice::UpdateBubbleMap(){
00379 SBPL_PRINTF("clearing bubble map\n");
00380
00381 for(unsigned int x=0; x<bubblemap.size(); x++){
00382 for(unsigned int y=0; y<bubblemap[x].size(); y++){
00383 bubblemap[x][y].dynObs.clear();
00384 bubblemap[x][y].firstObsT = INFINITECOST;
00385 bubblemap[x][y].lastObsT = 0;
00386 }
00387 }
00388
00389 SBPL_PRINTF("filling in new bubble map\n");
00390 int bubbleCount = 0;
00391
00392 for(unsigned int i=0; i<dynamicObstacles.size(); i++){
00393 for(unsigned int j=0; j<dynamicObstacles[i].trajectories.size(); j++){
00394
00395 for(unsigned int k=0; k<dynamicObstacles[i].trajectories[j].points.size(); k++){
00396 SBPL_Traj_Pt_t p = dynamicObstacles[i].trajectories[j].points[k];
00397 int bubble_cell_rad = (int)ceil((dynamicObstacles[i].radius + p.std_dev*3 + envDBubbleLatCfg.maxMovement)/envDBubbleLatCfg.cellsize_m);
00398 int bubble_cell_inner_rad = (int)ceil((dynamicObstacles[i].radius + p.std_dev*3)/envDBubbleLatCfg.cellsize_m);
00399 FillInBubble(CONTXY2DISC(p.x, envDBubbleLatCfg.cellsize_m), CONTXY2DISC(p.y, envDBubbleLatCfg.cellsize_m), p.t, &(dynamicObstacles[i]), bubble_cell_inner_rad, bubbleCount, true);
00400 FillInBubble(CONTXY2DISC(p.x, envDBubbleLatCfg.cellsize_m), CONTXY2DISC(p.y, envDBubbleLatCfg.cellsize_m), p.t, &(dynamicObstacles[i]), bubble_cell_rad, bubbleCount, false);
00401 bubbleCount++;
00402 }
00403 }
00404 }
00405
00406 bubble4Dactive.resize(bubbleCount);
00407 for (int i=0; i < bubbleCount; i++)
00408 bubble4Dactive[i] = false;
00409 SBPL_PRINTF("%d bubbles\n", bubbleCount);
00410
00411 #if DRAW_MAP
00412 SBPL_PRINTF("BubbleMap with last obstacle time in each cell\n");
00413
00414 for(int y = 0; y < envDBubbleLatCfg.EnvHeight_c; y++){
00415 for(int x = 0; x < envDBubbleLatCfg.EnvWidth_c; x++){
00416 SBPL_PRINTF("%d ",bubblemap[x][y].lastObsT);
00417 }
00418 SBPL_PRINTF("\n");
00419 }
00420 SBPL_PRINTF("BubbleMap with collision intervals in each cell for obstacle 1\n");
00421
00422 for(int y = 0; y < envDBubbleLatCfg.EnvHeight_c; y++){
00423 for(int x = 0; x < envDBubbleLatCfg.EnvWidth_c; x++){
00424 if(bubblemap[x][y].dynObs.empty())
00425 SBPL_PRINTF("(*,*) ");
00426 else if(bubblemap[x][y].dynObs[0].collision_startt == INFINITECOST)
00427 SBPL_PRINTF("(*,*) ");
00428 else
00429 SBPL_PRINTF("(%d,%d) ",bubblemap[x][y].dynObs[0].collision_startt, bubblemap[x][y].dynObs[0].collision_endt);
00430 }
00431 SBPL_PRINTF("\n");
00432 }
00433 #endif
00434
00435 SBPL_PRINTF("done updating bubble map\n");
00436 }
00437
00438
00439 void EnvDBubbleLattice::FillInBubble(int CenterX, int CenterY, int T, SBPL_DynamicObstacle_t* obs, int rad, int ID, bool isInnerBubble){
00440
00441 int d = 3 - 2*rad;
00442 int x = 0;
00443 int y = rad;
00444
00445 while(x <= y){
00446
00447 FillInBubbleColumn(CenterX-y, CenterY+x, CenterY-x, T, obs, ID, isInnerBubble);
00448 FillInBubbleColumn(CenterX-x, CenterY+y, CenterY-y, T, obs, ID, isInnerBubble);
00449 FillInBubbleColumn(CenterX+x, CenterY+y, CenterY-y, T, obs, ID, isInnerBubble);
00450 FillInBubbleColumn(CenterX+y, CenterY+x, CenterY-x, T, obs, ID, isInnerBubble);
00451 if(d <= 0)
00452 d += 4*x + 6;
00453 else{
00454 d += 4*(x-y) + 10;
00455 y--;
00456 }
00457 x++;
00458 }
00459
00460 }
00461
00462 void EnvDBubbleLattice::FillInBubbleColumn(int x, int topY, int botY, int T, SBPL_DynamicObstacle_t* obs, int ID, bool isInnerBubble){
00463
00464
00465 if(x < 0 || x >= (int)bubblemap.size())
00466 return;
00467
00468 if(topY >= (int)bubblemap[x].size())
00469 topY = bubblemap[x].size()-1;
00470 if(botY < 0)
00471 botY = 0;
00472
00473 if(topY < 0 || botY >= (int)bubblemap[x].size())
00474 return;
00475
00476
00477
00478 FillInBubbleCell(x, topY, T, obs, ID, isInnerBubble);
00479
00480
00481
00482 FillInBubbleCell(x, botY, T, obs, ID, isInnerBubble);
00483
00484
00485
00486
00487 if(topY-botY <= 1)
00488 return;
00489
00490 if(bubblemap[x][topY-1].dynObs.size() == 0 || bubblemap[x][topY-1].dynObs.back().ID.back() != ID){
00491
00492 for(int y = topY-1; y>botY; y--){
00493 FillInBubbleCell(x, y, T, obs, ID, isInnerBubble);
00494 }
00495 }
00496
00497 if(bubblemap[x][botY+1].dynObs.size() == 0 || bubblemap[x][botY+1].dynObs.back().ID.back() != ID){
00498
00499 for(int y = botY+1; y<topY; y++){
00500 FillInBubbleCell(x, y, T, obs, ID, isInnerBubble);
00501 }
00502 }
00503
00504 }
00505
00506 void EnvDBubbleLattice::FillInBubbleCell(int x, int y, int T, SBPL_DynamicObstacle_t* obs, int ID, bool isInnerBubble){
00507 int minT = T - temporal_padding;
00508 int maxT = T + temporal_padding;
00509 if(bubblemap[x][y].dynObs.size() == 0 || bubblemap[x][y].dynObs.back().obs != obs){
00510 envDBubbleLat_BubbleCellObs_t cell;
00511 cell.startt = minT;
00512 cell.endt = maxT;
00513 cell.obs = obs;
00514 cell.ID.push_back(ID);
00515 if(isInnerBubble){
00516 cell.collision_startt = minT;
00517 cell.collision_endt = maxT;
00518 }
00519 else{
00520 cell.collision_startt = INFINITECOST;
00521 cell.collision_endt = -INFINITECOST;
00522 }
00523 bubblemap[x][y].dynObs.push_back(cell);
00524 }
00525 else{
00526 if(minT < bubblemap[x][y].dynObs.back().startt)
00527 bubblemap[x][y].dynObs.back().startt = minT;
00528 if(maxT > bubblemap[x][y].dynObs.back().endt)
00529 bubblemap[x][y].dynObs.back().endt = maxT;
00530 if(isInnerBubble){
00531 if(minT < bubblemap[x][y].dynObs.back().collision_startt)
00532 bubblemap[x][y].dynObs.back().collision_startt = minT;
00533 if(maxT > bubblemap[x][y].dynObs.back().collision_endt)
00534 bubblemap[x][y].dynObs.back().collision_endt = maxT;
00535 }
00536 if(ID != bubblemap[x][y].dynObs.back().ID.back())
00537 bubblemap[x][y].dynObs.back().ID.push_back(ID);
00538 }
00539 if(maxT > bubblemap[x][y].lastObsT)
00540 bubblemap[x][y].lastObsT = maxT;
00541 if(minT < bubblemap[x][y].firstObsT)
00542 bubblemap[x][y].firstObsT = minT;
00543 }
00544
00545 int EnvDBubbleLattice::getNumBubbles(){
00546 return bubble4Dactive.size();
00547 }
00548
00549 void EnvDBubbleLattice::SetConfiguration(int width, int height,
00550 const unsigned char* mapdata,
00551 int startx, int starty, int starttheta, int startTime,
00552 int goalx, int goaly, int goaltheta,
00553 double cellsize_m, double timeResolution, double nominalvel_mpersecs, double timetoturn45degsinplace_secs,
00554 const vector<sbpl_2Dpt_t> & robot_perimeterV) {
00555 envDBubbleLatCfg.EnvWidth_c = width;
00556 envDBubbleLatCfg.EnvHeight_c = height;
00557 envDBubbleLatCfg.StartX_c = startx;
00558 envDBubbleLatCfg.StartY_c = starty;
00559 envDBubbleLatCfg.StartTheta = starttheta;
00560 envDBubbleLatCfg.StartTime = startTime;
00561
00562 if(envDBubbleLatCfg.StartX_c < 0 || envDBubbleLatCfg.StartX_c >= envDBubbleLatCfg.EnvWidth_c) {
00563 SBPL_ERROR("ERROR: illegal start coordinates\n");
00564 throw new SBPL_Exception();
00565 }
00566 if(envDBubbleLatCfg.StartY_c < 0 || envDBubbleLatCfg.StartY_c >= envDBubbleLatCfg.EnvHeight_c) {
00567 SBPL_ERROR("ERROR: illegal start coordinates\n");
00568 throw new SBPL_Exception();
00569 }
00570 if(envDBubbleLatCfg.StartTheta < 0 || envDBubbleLatCfg.StartTheta >= ENVDBUBBLELAT_THETADIRS) {
00571 SBPL_ERROR("ERROR: illegal start coordinates for theta\n");
00572 throw new SBPL_Exception();
00573 }
00574
00575 envDBubbleLatCfg.EndX_c = goalx;
00576 envDBubbleLatCfg.EndY_c = goaly;
00577 envDBubbleLatCfg.EndTheta = goaltheta;
00578
00579 if(envDBubbleLatCfg.EndX_c < 0 || envDBubbleLatCfg.EndX_c >= envDBubbleLatCfg.EnvWidth_c) {
00580 SBPL_ERROR("ERROR: illegal goal coordinates\n");
00581 throw new SBPL_Exception();
00582 }
00583 if(envDBubbleLatCfg.EndY_c < 0 || envDBubbleLatCfg.EndY_c >= envDBubbleLatCfg.EnvHeight_c) {
00584 SBPL_ERROR("ERROR: illegal goal coordinates\n");
00585 throw new SBPL_Exception();
00586 }
00587 if(envDBubbleLatCfg.EndTheta < 0 || envDBubbleLatCfg.EndTheta >= ENVDBUBBLELAT_THETADIRS) {
00588 SBPL_ERROR("ERROR: illegal goal coordinates for theta\n");
00589 throw new SBPL_Exception();
00590 }
00591
00592 envDBubbleLatCfg.FootprintPolygon = robot_perimeterV;
00593
00594 envDBubbleLatCfg.nominalvel_mpersecs = nominalvel_mpersecs;
00595 envDBubbleLatCfg.cellsize_m = cellsize_m;
00596 envDBubbleLatCfg.timeResolution = timeResolution;
00597 envDBubbleLatCfg.timetoturn45degsinplace_secs = timetoturn45degsinplace_secs;
00598
00599
00600
00601 envDBubbleLatCfg.Grid2D = new unsigned char* [envDBubbleLatCfg.EnvWidth_c];
00602 for (int x = 0; x < envDBubbleLatCfg.EnvWidth_c; x++) {
00603 envDBubbleLatCfg.Grid2D[x] = new unsigned char [envDBubbleLatCfg.EnvHeight_c];
00604 }
00605
00606
00607 if (0 == mapdata) {
00608 for (int y = 0; y < envDBubbleLatCfg.EnvHeight_c; y++) {
00609 for (int x = 0; x < envDBubbleLatCfg.EnvWidth_c; x++) {
00610 envDBubbleLatCfg.Grid2D[x][y] = 0;
00611 }
00612 }
00613 }
00614 else {
00615 for (int y = 0; y < envDBubbleLatCfg.EnvHeight_c; y++) {
00616 for (int x = 0; x < envDBubbleLatCfg.EnvWidth_c; x++) {
00617 envDBubbleLatCfg.Grid2D[x][y] = mapdata[x+y*width];
00618 }
00619 }
00620 }
00621 }
00622
00623 void EnvDBubbleLattice::ReadConfiguration(FILE* fCfg)
00624 {
00625
00626 char sTemp[1024], sTemp1[1024];
00627 int dTemp;
00628 int x, y;
00629
00630
00631 if(fscanf(fCfg, "%s", sTemp) != 1){
00632 SBPL_ERROR("ERROR: ran out of env file early\n");
00633 throw new SBPL_Exception();
00634 }
00635 strcpy(sTemp1, "discretization(cells):");
00636 if(strcmp(sTemp1, sTemp) != 0)
00637 {
00638 SBPL_ERROR("ERROR: configuration file has incorrect format\n");
00639 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00640 throw new SBPL_Exception();
00641 }
00642 if(fscanf(fCfg, "%s", sTemp) != 1){
00643 SBPL_ERROR("ERROR: ran out of env file early\n");
00644 throw new SBPL_Exception();
00645 }
00646 envDBubbleLatCfg.EnvWidth_c = atoi(sTemp);
00647 if(fscanf(fCfg, "%s", sTemp) != 1){
00648 SBPL_ERROR("ERROR: ran out of env file early\n");
00649 throw new SBPL_Exception();
00650 }
00651 envDBubbleLatCfg.EnvHeight_c = atoi(sTemp);
00652
00653
00654 if(fscanf(fCfg, "%s", sTemp) != 1){
00655 SBPL_ERROR("ERROR: ran out of env file early\n");
00656 throw new SBPL_Exception();
00657 }
00658 strcpy(sTemp1, "obsthresh:");
00659 if(strcmp(sTemp1, sTemp) != 0)
00660 {
00661 SBPL_ERROR("ERROR: configuration file has incorrect format\n");
00662 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00663 SBPL_PRINTF("see existing examples of env files for the right format of heading\n");
00664 throw new SBPL_Exception();
00665 }
00666 if(fscanf(fCfg, "%s", sTemp) != 1){
00667 SBPL_ERROR("ERROR: ran out of env file early\n");
00668 throw new SBPL_Exception();
00669 }
00670 envDBubbleLatCfg.obsthresh = atoi(sTemp);
00671 SBPL_PRINTF("obsthresh = %d\n", envDBubbleLatCfg.obsthresh);
00672
00673
00674 if(fscanf(fCfg, "%s", sTemp) != 1){
00675 SBPL_ERROR("ERROR: ran out of env file early\n");
00676 throw new SBPL_Exception();
00677 }
00678 strcpy(sTemp1, "cost_inscribed_thresh:");
00679 if(strcmp(sTemp1, sTemp) != 0)
00680 {
00681 SBPL_ERROR("ERROR: configuration file has incorrect format\n");
00682 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00683 SBPL_PRINTF("see existing examples of env files for the right format of heading\n");
00684 throw new SBPL_Exception();
00685 }
00686 if(fscanf(fCfg, "%s", sTemp) != 1){
00687 SBPL_ERROR("ERROR: ran out of env file early\n");
00688 throw new SBPL_Exception();
00689 }
00690 envDBubbleLatCfg.cost_inscribed_thresh = atoi(sTemp);
00691 SBPL_PRINTF("cost_inscribed_thresh = %d\n", envDBubbleLatCfg.cost_inscribed_thresh);
00692
00693
00694
00695 if(fscanf(fCfg, "%s", sTemp) != 1){
00696 SBPL_ERROR("ERROR: ran out of env file early\n");
00697 throw new SBPL_Exception();
00698 }
00699 strcpy(sTemp1, "cost_possibly_circumscribed_thresh:");
00700 if(strcmp(sTemp1, sTemp) != 0)
00701 {
00702 SBPL_ERROR("ERROR: configuration file has incorrect format\n");
00703 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00704 SBPL_PRINTF("see existing examples of env files for the right format of heading\n");
00705 throw new SBPL_Exception();
00706 }
00707 if(fscanf(fCfg, "%s", sTemp) != 1){
00708 SBPL_ERROR("ERROR: ran out of env file early\n");
00709 throw new SBPL_Exception();
00710 }
00711 envDBubbleLatCfg.cost_possibly_circumscribed_thresh = atoi(sTemp);
00712 SBPL_PRINTF("cost_possibly_circumscribed_thresh = %d\n", envDBubbleLatCfg.cost_possibly_circumscribed_thresh);
00713
00714
00715 if(fscanf(fCfg, "%s", sTemp) != 1){
00716 SBPL_ERROR("ERROR: ran out of env file early\n");
00717 throw new SBPL_Exception();
00718 }
00719 strcpy(sTemp1, "dynamic_obstacle_collision_cost_thresh:");
00720 if(strcmp(sTemp1, sTemp) != 0)
00721 {
00722 SBPL_ERROR("ERROR: configuration file has incorrect format\n");
00723 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00724 SBPL_PRINTF("see existing examples of env files for the right format of heading\n");
00725 throw new SBPL_Exception();
00726 }
00727 if(fscanf(fCfg, "%s", sTemp) != 1){
00728 SBPL_ERROR("ERROR: ran out of env file early\n");
00729 throw new SBPL_Exception();
00730 }
00731 envDBubbleLatCfg.dynamic_obstacle_collision_cost_thresh = atoi(sTemp);
00732 SBPL_PRINTF("dynamic_obstacle_collision_cost_thresh = %d\n", envDBubbleLatCfg.dynamic_obstacle_collision_cost_thresh);
00733
00734
00735 if(fscanf(fCfg, "%s", sTemp) != 1){
00736 SBPL_ERROR("ERROR: ran out of env file early\n");
00737 throw new SBPL_Exception();
00738 }
00739 strcpy(sTemp1, "cellsize(meters):");
00740 if(strcmp(sTemp1, sTemp) != 0)
00741 {
00742 SBPL_ERROR("ERROR: configuration file has incorrect format\n");
00743 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00744 throw new SBPL_Exception();
00745 }
00746 if(fscanf(fCfg, "%s", sTemp) != 1){
00747 SBPL_ERROR("ERROR: ran out of env file early\n");
00748 throw new SBPL_Exception();
00749 }
00750 envDBubbleLatCfg.cellsize_m = atof(sTemp);
00751
00752
00753 if(fscanf(fCfg, "%s", sTemp) != 1){
00754 SBPL_ERROR("ERROR: ran out of env file early\n");
00755 throw new SBPL_Exception();
00756 }
00757 strcpy(sTemp1, "timeResolution(seconds):");
00758 if(strcmp(sTemp1, sTemp) != 0)
00759 {
00760 SBPL_ERROR("ERROR: configuration file has incorrect format\n");
00761 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00762 throw new SBPL_Exception();
00763 }
00764 if(fscanf(fCfg, "%s", sTemp) != 1){
00765 SBPL_ERROR("ERROR: ran out of env file early\n");
00766 throw new SBPL_Exception();
00767 }
00768 envDBubbleLatCfg.timeResolution = atof(sTemp);
00769
00770
00771 if(fscanf(fCfg, "%s", sTemp) != 1){
00772 SBPL_ERROR("ERROR: ran out of env file early\n");
00773 throw new SBPL_Exception();
00774 }
00775 strcpy(sTemp1, "temporal_padding(seconds):");
00776 if(strcmp(sTemp1, sTemp) != 0)
00777 {
00778 SBPL_ERROR("ERROR: configuration file has incorrect format\n");
00779 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00780 SBPL_PRINTF("see existing examples of env files for the right format of heading\n");
00781 throw new SBPL_Exception();
00782 }
00783 if(fscanf(fCfg, "%s", sTemp) != 1){
00784 SBPL_ERROR("ERROR: ran out of env file early\n");
00785 throw new SBPL_Exception();
00786 }
00787 temporal_padding = (int)ceil(atof(sTemp)/envDBubbleLatCfg.timeResolution);
00788 SBPL_PRINTF("temporal_padding = %d\n", temporal_padding);
00789
00790
00791 if(fscanf(fCfg, "%s", sTemp) != 1){
00792 SBPL_ERROR("ERROR: ran out of env file early\n");
00793 throw new SBPL_Exception();
00794 }
00795 strcpy(sTemp1, "nominalvel(mpersecs):");
00796 if(strcmp(sTemp1, sTemp) != 0)
00797 {
00798 SBPL_ERROR("ERROR: configuration file has incorrect format\n");
00799 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00800 throw new SBPL_Exception();
00801 }
00802 if(fscanf(fCfg, "%s", sTemp) != 1){
00803 SBPL_ERROR("ERROR: ran out of env file early\n");
00804 throw new SBPL_Exception();
00805 }
00806 envDBubbleLatCfg.nominalvel_mpersecs = atof(sTemp);
00807 if(fscanf(fCfg, "%s", sTemp) != 1){
00808 SBPL_ERROR("ERROR: ran out of env file early\n");
00809 throw new SBPL_Exception();
00810 }
00811 strcpy(sTemp1, "timetoturn45degsinplace(secs):");
00812 if(strcmp(sTemp1, sTemp) != 0)
00813 {
00814 SBPL_ERROR("ERROR: configuration file has incorrect format\n");
00815 SBPL_PRINTF("Expected %s got %s\n", sTemp1, sTemp);
00816 throw new SBPL_Exception();
00817 }
00818 if(fscanf(fCfg, "%s", sTemp) != 1){
00819 SBPL_ERROR("ERROR: ran out of env file early\n");
00820 throw new SBPL_Exception();
00821 }
00822 envDBubbleLatCfg.timetoturn45degsinplace_secs = atof(sTemp);
00823
00824
00825
00826 if(fscanf(fCfg, "%s", sTemp) != 1){
00827 SBPL_ERROR("ERROR: ran out of env file early\n");
00828 throw new SBPL_Exception();
00829 }
00830 if(fscanf(fCfg, "%s", sTemp) != 1){
00831 SBPL_ERROR("ERROR: ran out of env file early\n");
00832 throw new SBPL_Exception();
00833 }
00834 envDBubbleLatCfg.StartX_c = CONTXY2DISC(atof(sTemp),envDBubbleLatCfg.cellsize_m);
00835 if(fscanf(fCfg, "%s", sTemp) != 1){
00836 SBPL_ERROR("ERROR: ran out of env file early\n");
00837 throw new SBPL_Exception();
00838 }
00839 envDBubbleLatCfg.StartY_c = CONTXY2DISC(atof(sTemp),envDBubbleLatCfg.cellsize_m);
00840 if(fscanf(fCfg, "%s", sTemp) != 1){
00841 SBPL_ERROR("ERROR: ran out of env file early\n");
00842 throw new SBPL_Exception();
00843 }
00844 envDBubbleLatCfg.StartTheta = ContTheta2Disc(atof(sTemp), ENVDBUBBLELAT_THETADIRS);
00845 if(fscanf(fCfg, "%s", sTemp) != 1){
00846 SBPL_ERROR("ERROR: ran out of env file early\n");
00847 throw new SBPL_Exception();
00848 }
00849 envDBubbleLatCfg.StartTime = CONTTIME2DISC(atof(sTemp),envDBubbleLatCfg.timeResolution);
00850
00851
00852 if(envDBubbleLatCfg.StartX_c < 0 || envDBubbleLatCfg.StartX_c >= envDBubbleLatCfg.EnvWidth_c)
00853 {
00854 SBPL_ERROR("ERROR: illegal start coordinates\n");
00855 throw new SBPL_Exception();
00856 }
00857 if(envDBubbleLatCfg.StartY_c < 0 || envDBubbleLatCfg.StartY_c >= envDBubbleLatCfg.EnvHeight_c)
00858 {
00859 SBPL_ERROR("ERROR: illegal start coordinates\n");
00860 throw new SBPL_Exception();
00861 }
00862 if(envDBubbleLatCfg.StartTheta < 0 || envDBubbleLatCfg.StartTheta >= ENVDBUBBLELAT_THETADIRS) {
00863 SBPL_ERROR("ERROR: illegal start coordinates for theta\n");
00864 throw new SBPL_Exception();
00865 }
00866
00867
00868 if(fscanf(fCfg, "%s", sTemp) != 1){
00869 SBPL_ERROR("ERROR: ran out of env file early\n");
00870 throw new SBPL_Exception();
00871 }
00872 if(fscanf(fCfg, "%s", sTemp) != 1){
00873 SBPL_ERROR("ERROR: ran out of env file early\n");
00874 throw new SBPL_Exception();
00875 }
00876 envDBubbleLatCfg.EndX_c = CONTXY2DISC(atof(sTemp),envDBubbleLatCfg.cellsize_m);
00877 if(fscanf(fCfg, "%s", sTemp) != 1){
00878 SBPL_ERROR("ERROR: ran out of env file early\n");
00879 throw new SBPL_Exception();
00880 }
00881 envDBubbleLatCfg.EndY_c = CONTXY2DISC(atof(sTemp),envDBubbleLatCfg.cellsize_m);
00882 if(fscanf(fCfg, "%s", sTemp) != 1){
00883 SBPL_ERROR("ERROR: ran out of env file early\n");
00884 throw new SBPL_Exception();
00885 }
00886 envDBubbleLatCfg.EndTheta = ContTheta2Disc(atof(sTemp), ENVDBUBBLELAT_THETADIRS);;
00887
00888 if(envDBubbleLatCfg.EndX_c < 0 || envDBubbleLatCfg.EndX_c >= envDBubbleLatCfg.EnvWidth_c)
00889 {
00890 SBPL_ERROR("ERROR: illegal end coordinates\n");
00891 throw new SBPL_Exception();
00892 }
00893 if(envDBubbleLatCfg.EndY_c < 0 || envDBubbleLatCfg.EndY_c >= envDBubbleLatCfg.EnvHeight_c)
00894 {
00895 SBPL_ERROR("ERROR: illegal end coordinates\n");
00896 throw new SBPL_Exception();
00897 }
00898 if(envDBubbleLatCfg.EndTheta < 0 || envDBubbleLatCfg.EndTheta >= ENVDBUBBLELAT_THETADIRS) {
00899 SBPL_ERROR("ERROR: illegal goal coordinates for theta\n");
00900 throw new SBPL_Exception();
00901 }
00902
00903
00904
00905 if(fscanf(fCfg, "%s", sTemp) != 1){
00906 SBPL_ERROR("ERROR: ran out of env file early\n");
00907 throw new SBPL_Exception();
00908 }
00909 envDBubbleLatCfg.Grid2D = new unsigned char* [envDBubbleLatCfg.EnvWidth_c];
00910 for (x = 0; x < envDBubbleLatCfg.EnvWidth_c; x++)
00911 {
00912 envDBubbleLatCfg.Grid2D[x] = new unsigned char [envDBubbleLatCfg.EnvHeight_c];
00913 }
00914
00915
00916 for (y = 0; y < envDBubbleLatCfg.EnvHeight_c; y++){
00917 for (x = 0; x < envDBubbleLatCfg.EnvWidth_c; x++)
00918 {
00919 if(fscanf(fCfg, "%d", &dTemp) != 1)
00920 {
00921 SBPL_ERROR("ERROR: incorrect format of config file (%d,%d)\n",y,x);
00922 throw new SBPL_Exception();
00923 }
00924 envDBubbleLatCfg.Grid2D[x][y] = dTemp;
00925 #if DRAW_MAP
00926 SBPL_PRINTF("%d ",dTemp);
00927 #endif
00928 }
00929 #if DRAW_MAP
00930 SBPL_PRINTF("\n");
00931 #endif
00932 }
00933
00934 }
00935
00936 int EnvDBubbleLattice::ReadinCell(SBPL_4Dcell_t* cell, char* fIn)
00937 {
00938 char* temp;
00939 char* sptr;
00940
00941 if((temp = strtok_r(fIn, " ", &sptr)) == NULL)
00942 return FAIL;
00943 cell->x = atoi(temp);
00944
00945 if((temp = strtok_r(NULL, " ", &sptr)) == NULL)
00946 return FAIL;
00947 cell->y = atoi(temp);
00948
00949 if((temp = strtok_r(NULL, " ", &sptr)) == NULL)
00950 return FAIL;
00951 cell->theta = atoi(temp);
00952
00953 cell->theta = NORMALIZEDISCTHETA(cell->theta, ENVDBUBBLELAT_THETADIRS);
00954
00955
00956 if((temp = strtok_r(NULL, " ", &sptr)) != NULL){
00957 cell->t = atoi(temp);
00958 return SUCCESS_WITH_TIME;
00959 }
00960
00961 return SUCCESS_NO_TIME;
00962 }
00963
00964 int EnvDBubbleLattice::ReadinPose(SBPL_4Dpt_t* pose, char* fIn)
00965 {
00966 char* temp;
00967 char* sptr;
00968
00969 if((temp = strtok_r(fIn, " ", &sptr)) == NULL)
00970 return FAIL;
00971 pose->x = atof(temp);
00972
00973 if((temp = strtok_r(NULL, " ", &sptr)) == NULL)
00974 return FAIL;
00975 pose->y = atof(temp);
00976
00977 if((temp = strtok_r(NULL, " ", &sptr)) == NULL)
00978 return FAIL;
00979 pose->theta = atof(temp);
00980 pose->theta = normalizeAngle(pose->theta);
00981
00982
00983 if((temp = strtok_r(NULL, " ", &sptr)) != NULL){
00984 pose->t = atof(temp);
00985 return SUCCESS_WITH_TIME;
00986 }
00987
00988 return SUCCESS_NO_TIME;
00989 }
00990
00991 bool EnvDBubbleLattice::ReadinMotionPrimitive(SBPL_xythetatimebubble_mprimitive* pMotPrim, FILE* fIn, bool &isWaitMotion)
00992 {
00993 int bufSize = 1024;
00994 char sTemp[bufSize];
00995 int dTemp;
00996 char sExpected[bufSize];
00997 int numofIntermPoses;
00998 bool timeGiven = true;
00999 int timeGivenTemp;
01000
01001
01002 strcpy(sExpected, "primID:");
01003 if(fscanf(fIn, "%s", sTemp) == 0)
01004 return false;
01005 if(strcmp(sTemp, sExpected) != 0){
01006 SBPL_ERROR("ERROR: expected %s but got %s\n", sExpected, sTemp);
01007 return false;
01008 }
01009 if(fscanf(fIn, "%d", &pMotPrim->motprimID) != 1)
01010 return false;
01011
01012
01013 strcpy(sExpected, "startangle_c:");
01014 if(fscanf(fIn, "%s", sTemp) == 0)
01015 return false;
01016 if(strcmp(sTemp, sExpected) != 0){
01017 SBPL_ERROR("ERROR: expected %s but got %s\n", sExpected, sTemp);
01018 return false;
01019 }
01020 if(fscanf(fIn, "%d", &dTemp) == 0)
01021 {
01022 SBPL_ERROR("ERROR reading startangle\n");
01023 return false;
01024 }
01025 pMotPrim->starttheta_c = dTemp;
01026
01027
01028 strcpy(sExpected, "endpose_c:");
01029 if(fscanf(fIn, "%s", sTemp) == 0)
01030 return false;
01031 if(strcmp(sTemp, sExpected) != 0){
01032 SBPL_ERROR("ERROR: expected %s but got %s\n", sExpected, sTemp);
01033 return false;
01034 }
01035
01036 if(fgets(sTemp, bufSize, fIn) == NULL)
01037 return false;
01038 timeGivenTemp = ReadinCell(&pMotPrim->endcell, sTemp);
01039 if(timeGivenTemp == FAIL){
01040 SBPL_ERROR("ERROR: failed to read in endsearchpose\n");
01041 return false;
01042 }
01043 else if(timeGivenTemp == SUCCESS_NO_TIME)
01044 timeGiven = false;
01045
01046
01047
01048 strcpy(sExpected, "additionalactioncostmult:");
01049 if(fscanf(fIn, "%s", sTemp) == 0)
01050 return false;
01051 if(strcmp(sTemp, sExpected) != 0){
01052 SBPL_ERROR("ERROR: expected %s but got %s\n", sExpected, sTemp);
01053 return false;
01054 }
01055 if(fscanf(fIn, "%d", &dTemp) != 1)
01056 return false;
01057 pMotPrim->additionalactioncostmult = dTemp;
01058
01059
01060 strcpy(sExpected, "intermediateposes:");
01061 if(fscanf(fIn, "%s", sTemp) == 0)
01062 return false;
01063 if(strcmp(sTemp, sExpected) != 0){
01064 SBPL_ERROR("ERROR: expected %s but got %s\n", sExpected, sTemp);
01065 return false;
01066 }
01067 if(fscanf(fIn, "%d", &numofIntermPoses) != 1)
01068 return false;
01069
01070
01071
01072 if(fgets(sTemp, bufSize, fIn) == NULL)
01073 return false;
01074 isWaitMotion = true;
01075 for(int i = 0; i < numofIntermPoses; i++){
01076 SBPL_4Dpt_t intermpose;
01077 if(fgets(sTemp, bufSize, fIn) == NULL)
01078 return false;
01079 timeGivenTemp = ReadinPose(&intermpose, sTemp);
01080 if(timeGivenTemp == FAIL){
01081 SBPL_ERROR("ERROR: failed to read in intermediate pose %d\n",i);
01082 return false;
01083 }
01084 else if(timeGivenTemp == SUCCESS_NO_TIME)
01085 timeGiven = false;
01086
01087 isWaitMotion = isWaitMotion && intermpose.x == 0 && intermpose.y == 0 && (i==0 || intermpose.theta == pMotPrim->intermptV.back().theta);
01088 pMotPrim->intermptV.push_back(intermpose);
01089 }
01090
01091
01092 if(!timeGiven){
01093 double x = pMotPrim->intermptV[pMotPrim->intermptV.size()-1].x;
01094 double y = pMotPrim->intermptV[pMotPrim->intermptV.size()-1].y;
01095 double theta = fabs(computeMinUnsignedAngleDiff(pMotPrim->intermptV[pMotPrim->intermptV.size()-1].theta,
01096 pMotPrim->intermptV[0].theta));
01097 double timeFromTranslation = sqrt(x*x + y*y)/envDBubbleLatCfg.nominalvel_mpersecs;
01098 double timeFromRotation = theta/(PI_CONST/4.0)*envDBubbleLatCfg.timetoturn45degsinplace_secs;
01099 double t = __max(timeFromTranslation, timeFromRotation);
01100 if(t == 0)
01101 t = envDBubbleLatCfg.timeResolution;
01102
01103 pMotPrim->endcell.t = (int)(t/envDBubbleLatCfg.timeResolution);
01104 double step = t/(pMotPrim->intermptV.size()-1);
01105 double temp = 0;
01106 for(unsigned int i = 0; i < pMotPrim->intermptV.size(); i++){
01107 pMotPrim->intermptV[i].t = temp;
01108 temp += step;
01109 }
01110 }
01111
01112
01113
01114 SBPL_4Dpt_t sourcepose;
01115 sourcepose.x = DISCXY2CONT(0, envDBubbleLatCfg.cellsize_m);
01116 sourcepose.y = DISCXY2CONT(0, envDBubbleLatCfg.cellsize_m);
01117 sourcepose.theta = DiscTheta2Cont(pMotPrim->starttheta_c, ENVDBUBBLELAT_THETADIRS);
01118 sourcepose.t = 0;
01119 double mp_endx_m = sourcepose.x + pMotPrim->intermptV[pMotPrim->intermptV.size()-1].x;
01120 double mp_endy_m = sourcepose.y + pMotPrim->intermptV[pMotPrim->intermptV.size()-1].y;
01121 double mp_endtheta_rad = pMotPrim->intermptV[pMotPrim->intermptV.size()-1].theta;
01122 double mp_endt = pMotPrim->intermptV[pMotPrim->intermptV.size()-1].t;
01123 int endx_c = CONTXY2DISC(mp_endx_m, envDBubbleLatCfg.cellsize_m);
01124 int endy_c = CONTXY2DISC(mp_endy_m, envDBubbleLatCfg.cellsize_m);
01125 int endtheta_c = ContTheta2Disc(mp_endtheta_rad, ENVDBUBBLELAT_THETADIRS);
01126 int endt_c = CONTTIME2DISC(mp_endt, envDBubbleLatCfg.timeResolution);
01127 if(endx_c != pMotPrim->endcell.x || endy_c != pMotPrim->endcell.y || endtheta_c != pMotPrim->endcell.theta || endt_c != pMotPrim->endcell.t)
01128 {
01129 SBPL_ERROR("ERROR: incorrect primitive %d with startangle=%d last interm point %f %f %f %f does not match end pose %d %d %d %d\n",
01130 pMotPrim->motprimID, pMotPrim->starttheta_c,
01131 pMotPrim->intermptV[pMotPrim->intermptV.size()-1].x, pMotPrim->intermptV[pMotPrim->intermptV.size()-1].y, pMotPrim->intermptV[pMotPrim->intermptV.size()-1].theta, pMotPrim->intermptV[pMotPrim->intermptV.size()-1].t,
01132 pMotPrim->endcell.x, pMotPrim->endcell.y,pMotPrim->endcell.theta,pMotPrim->endcell.t);
01133 return false;
01134 }
01135
01136 return true;
01137 }
01138
01139
01140
01141 bool EnvDBubbleLattice::ReadMotionPrimitives(FILE* fMotPrims)
01142 {
01143 char sTemp[1024], sExpected[1024];
01144 float fTemp;
01145 int dTemp;
01146 int totalNumofActions = 0;
01147
01148 SBPL_PRINTF("Reading in motion primitives...");
01149
01150
01151 strcpy(sExpected, "resolution_m:");
01152 if(fscanf(fMotPrims, "%s", sTemp) == 0)
01153 return false;
01154 if(strcmp(sTemp, sExpected) != 0){
01155 SBPL_ERROR("ERROR: expected %s but got %s\n", sExpected, sTemp);
01156 return false;
01157 }
01158 if(fscanf(fMotPrims, "%f", &fTemp) == 0)
01159 return false;
01160 if(fabs(fTemp-envDBubbleLatCfg.cellsize_m) > ERR_EPS){
01161 SBPL_ERROR("ERROR: invalid grid resolution %f (instead of %f) in the dynamics file\n",
01162 fTemp, envDBubbleLatCfg.cellsize_m);
01163 return false;
01164 }
01165
01166
01167 strcpy(sExpected, "timeResolution:");
01168 if(fscanf(fMotPrims, "%s", sTemp) == 0)
01169 return false;
01170 if(strcmp(sTemp, sExpected) != 0){
01171 SBPL_ERROR("ERROR: expected %s but got %s\n", sExpected, sTemp);
01172 return false;
01173 }
01174 if(fscanf(fMotPrims, "%f", &fTemp) == 0)
01175 return false;
01176 if(fabs(fTemp-envDBubbleLatCfg.timeResolution) > ERR_EPS){
01177 SBPL_ERROR("ERROR: invalid time resolution %f (instead of %f) in the dynamics file\n",
01178 fTemp, envDBubbleLatCfg.timeResolution);
01179 return false;
01180 }
01181
01182
01183 strcpy(sExpected, "numberofangles:");
01184 if(fscanf(fMotPrims, "%s", sTemp) == 0)
01185 return false;
01186 if(strcmp(sTemp, sExpected) != 0){
01187 SBPL_ERROR("ERROR: expected %s but got %s\n", sExpected, sTemp);
01188 return false;
01189 }
01190 if(fscanf(fMotPrims, "%d", &dTemp) == 0)
01191 return false;
01192 if(dTemp != ENVDBUBBLELAT_THETADIRS){
01193 SBPL_ERROR("ERROR: invalid angular resolution %d angles (instead of %d angles) in the motion primitives file\n",
01194 dTemp, ENVDBUBBLELAT_THETADIRS);
01195 return false;
01196 }
01197
01198
01199
01200 strcpy(sExpected, "totalnumberofprimitives:");
01201 if(fscanf(fMotPrims, "%s", sTemp) == 0)
01202 return false;
01203 if(strcmp(sTemp, sExpected) != 0){
01204 SBPL_ERROR("ERROR: expected %s but got %s\n", sExpected, sTemp);
01205 return false;
01206 }
01207 if(fscanf(fMotPrims, "%d", &totalNumofActions) == 0){
01208 return false;
01209 }
01210
01211 vector<bool> waitMotFlags;
01212 waitMotFlags.resize(ENVDBUBBLELAT_THETADIRS);
01213 for(int i = 0; i < ENVDBUBBLELAT_THETADIRS; i++)
01214 waitMotFlags[i] = false;
01215 vector<SBPL_xythetatimebubble_mprimitive> waitMots;
01216 for(int i = 0; i < totalNumofActions; i++){
01217 SBPL_xythetatimebubble_mprimitive motprim;
01218
01219 bool isWaitMotion;
01220 if(EnvDBubbleLattice::ReadinMotionPrimitive(&motprim, fMotPrims, isWaitMotion) == false)
01221 return false;
01222
01223 if(isWaitMotion){
01224 if(!waitMotFlags[motprim.starttheta_c]){
01225 waitMotFlags[motprim.starttheta_c] = true;
01226 waitMots.push_back(motprim);
01227 }
01228 else{
01229 SBPL_ERROR("ERROR: only one wait in place motion is allowed per theta direction!\n");
01230 return false;
01231 }
01232 }
01233 else
01234 envDBubbleLatCfg.mprimV.push_back(motprim);
01235
01236 }
01237
01238
01239 if(waitMots.empty()){
01240
01241 SBPL_PRINTF("Adding a motion primitive since one was not provided...\n");
01242 int baseID = envDBubbleLatCfg.mprimV.back().motprimID + 1;
01243 for(int tind = 0; tind < ENVDBUBBLELAT_THETADIRS; tind++){
01244 SBPL_xythetatimebubble_mprimitive motprim;
01245 motprim.motprimID = baseID + tind;
01246 motprim.starttheta_c = tind;
01247 motprim.endcell.x = 0;
01248 motprim.endcell.y = 0;
01249 motprim.endcell.theta = tind;
01250 motprim.endcell.t = 1;
01251 motprim.additionalactioncostmult = 1;
01252
01253 SBPL_4Dpt_t intermpose1;
01254 intermpose1.x = 0;
01255 intermpose1.y = 0;
01256 intermpose1.theta = DiscTheta2Cont(tind, ENVDBUBBLELAT_THETADIRS);
01257 intermpose1.t = 0;
01258 motprim.intermptV.push_back(intermpose1);
01259
01260 SBPL_4Dpt_t intermpose2;
01261 intermpose2.x = 0;
01262 intermpose2.y = 0;
01263 intermpose2.theta = DiscTheta2Cont(tind, ENVDBUBBLELAT_THETADIRS);
01264 intermpose2.t = envDBubbleLatCfg.timeResolution;
01265 motprim.intermptV.push_back(intermpose2);
01266
01267 envDBubbleLatCfg.mprimV.push_back(motprim);
01268 }
01269 }
01270 else{
01271
01272 if(waitMots.size() != ENVDBUBBLELAT_THETADIRS){
01273 SBPL_PRINTF("Error: wait actions only provided for some theta directions\n");
01274 return false;
01275 }
01276 for(unsigned int i=0; i<waitMots.size(); i++)
01277 envDBubbleLatCfg.mprimV.push_back(waitMots[i]);
01278 }
01279 SBPL_PRINTF("done ");
01280
01281 return true;
01282 }
01283
01284
01285 void EnvDBubbleLattice::ComputeReplanningDataforAction(envDBubbleLatAction_t* action)
01286 {
01287 int j;
01288
01289
01290 SBPL_4Dcell_t startcell4d, endcell4d;
01291 for(int i = 0; i < (int)action->intersectingcellsV.size(); i++)
01292 {
01293
01294
01295 startcell4d.theta = action->starttheta;
01296 startcell4d.x = - action->intersectingcellsV.at(i).x;
01297 startcell4d.y = - action->intersectingcellsV.at(i).y;
01298 startcell4d.t = - action->intersectingcellsV.at(i).t;
01299
01300
01301 endcell4d.theta = NORMALIZEDISCTHETA(action->endtheta, ENVDBUBBLELAT_THETADIRS);
01302 endcell4d.x = startcell4d.x + action->dX;
01303 endcell4d.y = startcell4d.y + action->dY;
01304 endcell4d.t = startcell4d.t + action->dT;
01305
01306
01307 for(j = 0; j < (int)affectedsuccstatesV.size(); j++)
01308 {
01309 if(affectedsuccstatesV.at(j) == endcell4d)
01310 break;
01311 }
01312 if (j == (int)affectedsuccstatesV.size())
01313 affectedsuccstatesV.push_back(endcell4d);
01314
01315 for(j = 0; j < (int)affectedpredstatesV.size(); j++)
01316 {
01317 if(affectedpredstatesV.at(j) == startcell4d)
01318 break;
01319 }
01320 if (j == (int)affectedpredstatesV.size())
01321 affectedpredstatesV.push_back(startcell4d);
01322
01323 }
01324
01325
01326
01327
01328
01329
01330 startcell4d.theta = action->starttheta;
01331 startcell4d.x = - 0;
01332 startcell4d.y = - 0;
01333 startcell4d.t = - 0;
01334
01335
01336 endcell4d.theta = NORMALIZEDISCTHETA(action->endtheta, ENVDBUBBLELAT_THETADIRS);
01337 endcell4d.x = startcell4d.x + action->dX;
01338 endcell4d.y = startcell4d.y + action->dY;
01339 endcell4d.t = startcell4d.y + action->dT;
01340
01341
01342 for(j = 0; j < (int)affectedsuccstatesV.size(); j++)
01343 {
01344 if(affectedsuccstatesV.at(j) == endcell4d)
01345 break;
01346 }
01347 if (j == (int)affectedsuccstatesV.size())
01348 affectedsuccstatesV.push_back(endcell4d);
01349
01350 for(j = 0; j < (int)affectedpredstatesV.size(); j++)
01351 {
01352 if(affectedpredstatesV.at(j) == startcell4d)
01353 break;
01354 }
01355 if (j == (int)affectedpredstatesV.size())
01356 affectedpredstatesV.push_back(startcell4d);
01357
01358
01359
01360
01361 startcell4d.theta = action->starttheta;
01362 startcell4d.x = - action->dX;
01363 startcell4d.y = - action->dY;
01364 startcell4d.t = - action->dT;
01365
01366
01367 endcell4d.theta = NORMALIZEDISCTHETA(action->endtheta, ENVDBUBBLELAT_THETADIRS);
01368 endcell4d.x = startcell4d.x + action->dX;
01369 endcell4d.y = startcell4d.y + action->dY;
01370 endcell4d.t = startcell4d.t + action->dT;
01371
01372 for(j = 0; j < (int)affectedsuccstatesV.size(); j++)
01373 {
01374 if(affectedsuccstatesV.at(j) == endcell4d)
01375 break;
01376 }
01377 if (j == (int)affectedsuccstatesV.size())
01378 affectedsuccstatesV.push_back(endcell4d);
01379
01380 for(j = 0; j < (int)affectedpredstatesV.size(); j++)
01381 {
01382 if(affectedpredstatesV.at(j) == startcell4d)
01383 break;
01384 }
01385 if (j == (int)affectedpredstatesV.size())
01386 affectedpredstatesV.push_back(startcell4d);
01387
01388
01389 }
01390
01391
01392
01393
01394 void EnvDBubbleLattice::ComputeReplanningData()
01395 {
01396
01397
01398
01399 for(int tind = 0; tind < ENVDBUBBLELAT_THETADIRS; tind++)
01400 {
01401
01402 for(int aind = 0; aind < envDBubbleLatCfg.actionwidth; aind++)
01403 {
01404
01405 ComputeReplanningDataforAction(&envDBubbleLatCfg.ActionsV[tind][aind]);
01406 }
01407 }
01408 }
01409
01410
01411 void EnvDBubbleLattice::PrecomputeActionswithBaseMotionPrimitive(vector<SBPL_xythetatimebubble_mprimitive>* motionprimitiveV)
01412 {
01413
01414 SBPL_PRINTF("Pre-computing action data using base motion primitives...\n");
01415 envDBubbleLatCfg.ActionsV = new envDBubbleLatAction_t* [ENVDBUBBLELAT_THETADIRS];
01416 envDBubbleLatCfg.PredActionsV = new vector<envDBubbleLatAction_t*> [ENVDBUBBLELAT_THETADIRS];
01417 vector<sbpl_2Dcell_t> footprint;
01418
01419
01420 for(int tind = 0; tind < ENVDBUBBLELAT_THETADIRS; tind++)
01421 {
01422 SBPL_PRINTF("pre-computing action %d out of %d actions\n", tind, ENVDBUBBLELAT_THETADIRS);
01423 envDBubbleLatCfg.ActionsV[tind] = new envDBubbleLatAction_t[motionprimitiveV->size()];
01424
01425
01426 SBPL_4Dpt_t sourcepose;
01427 sourcepose.x = DISCXY2CONT(0, envDBubbleLatCfg.cellsize_m);
01428 sourcepose.y = DISCXY2CONT(0, envDBubbleLatCfg.cellsize_m);
01429 sourcepose.theta = DiscTheta2Cont(tind, ENVDBUBBLELAT_THETADIRS);
01430 sourcepose.t = DISCTIME2CONT(0, envDBubbleLatCfg.timeResolution);
01431
01432
01433 for(size_t aind = 0; aind < motionprimitiveV->size(); aind++)
01434 {
01435 envDBubbleLatCfg.ActionsV[tind][aind].starttheta = tind;
01436 double mp_endx_m = motionprimitiveV->at(aind).intermptV[motionprimitiveV->at(aind).intermptV.size()-1].x;
01437 double mp_endy_m = motionprimitiveV->at(aind).intermptV[motionprimitiveV->at(aind).intermptV.size()-1].y;
01438 double mp_endtheta_rad = motionprimitiveV->at(aind).intermptV[motionprimitiveV->at(aind).intermptV.size()-1].theta;
01439 double mp_endt = motionprimitiveV->at(aind).intermptV[motionprimitiveV->at(aind).intermptV.size()-1].t;
01440
01441 double endx = sourcepose.x + (mp_endx_m*cos(sourcepose.theta) - mp_endy_m*sin(sourcepose.theta));
01442 double endy = sourcepose.y + (mp_endx_m*sin(sourcepose.theta) + mp_endy_m*cos(sourcepose.theta));
01443
01444 int endx_c = CONTXY2DISC(endx, envDBubbleLatCfg.cellsize_m);
01445 int endy_c = CONTXY2DISC(endy, envDBubbleLatCfg.cellsize_m);
01446
01447
01448 envDBubbleLatCfg.ActionsV[tind][aind].endtheta = ContTheta2Disc(mp_endtheta_rad+sourcepose.theta, ENVDBUBBLELAT_THETADIRS);
01449 envDBubbleLatCfg.ActionsV[tind][aind].dX = endx_c;
01450 envDBubbleLatCfg.ActionsV[tind][aind].dY = endy_c;
01451 envDBubbleLatCfg.ActionsV[tind][aind].dT = CONTTIME2DISC(mp_endt + sourcepose.t, envDBubbleLatCfg.timeResolution);
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465 envDBubbleLatCfg.ActionsV[tind][aind].cost = (int)(ENVDBUBBLELAT_COSTMULT_MTOMM*envDBubbleLatCfg.ActionsV[tind][aind].dT*envDBubbleLatCfg.timeResolution);
01466
01467
01468 envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV.clear();
01469 envDBubbleLatCfg.ActionsV[tind][aind].intermptV.clear();
01470 envDBubbleLatCfg.ActionsV[tind][aind].interm4DcellsV.clear();
01471 SBPL_4Dcell_t previnterm4Dcell;
01472 previnterm4Dcell.theta = previnterm4Dcell.x = previnterm4Dcell.y = previnterm4Dcell.t = 0;
01473 for (int pind = 0; pind < (int)motionprimitiveV->at(aind).intermptV.size(); pind++)
01474 {
01475 SBPL_4Dpt_t intermpt = motionprimitiveV->at(aind).intermptV[pind];
01476
01477
01478 double rotx = intermpt.x*cos(sourcepose.theta) - intermpt.y*sin(sourcepose.theta);
01479 double roty = intermpt.x*sin(sourcepose.theta) + intermpt.y*cos(sourcepose.theta);
01480 intermpt.x = rotx;
01481 intermpt.y = roty;
01482 intermpt.theta = normalizeAngle(sourcepose.theta + intermpt.theta);
01483
01484
01485
01486 envDBubbleLatCfg.ActionsV[tind][aind].intermptV.push_back(intermpt);
01487
01488
01489 SBPL_4Dpt_t pose;
01490 pose = intermpt;
01491 pose.x += sourcepose.x;
01492 pose.y += sourcepose.y;
01493 pose.t += sourcepose.t;
01494 CalculateFootprintForPose(pose, &envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV);
01495
01496
01497 SBPL_4Dcell_t interm4Dcell;
01498 interm4Dcell.x = CONTXY2DISC(pose.x, envDBubbleLatCfg.cellsize_m);
01499 interm4Dcell.y = CONTXY2DISC(pose.y, envDBubbleLatCfg.cellsize_m);
01500 interm4Dcell.theta = ContTheta2Disc(pose.theta, ENVDBUBBLELAT_THETADIRS);
01501 interm4Dcell.t = CONTXY2DISC(pose.t, envDBubbleLatCfg.timeResolution);
01502 if(envDBubbleLatCfg.ActionsV[tind][aind].interm4DcellsV.size() == 0 ||
01503 previnterm4Dcell.theta != interm4Dcell.theta || previnterm4Dcell.x != interm4Dcell.x || previnterm4Dcell.y != interm4Dcell.y || previnterm4Dcell.t != interm4Dcell.t)
01504 {
01505 envDBubbleLatCfg.ActionsV[tind][aind].interm4DcellsV.push_back(interm4Dcell);
01506 }
01507 previnterm4Dcell = interm4Dcell;
01508
01509 }
01510
01511
01512 RemoveSourceFootprint(sourcepose, &envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV);
01513
01514 #if DEBUG
01515 SBPL_FPRINTF(fDeb, "action tind=%d aind=%d: dX=%d dY=%d dT=%d endtheta=%d (%.2f degs -> %.2f degs) cost=%d (mprim: %.2f %.2f %.2f %.2f)\n",
01516 tind, aind,
01517 envDBubbleLatCfg.ActionsV[tind][aind].dX, envDBubbleLatCfg.ActionsV[tind][aind].dY, envDBubbleLatCfg.ActionsV[tind][aind].dT,
01518 envDBubbleLatCfg.ActionsV[tind][aind].endtheta, sourcepose.theta*180/PI_CONST,
01519 envDBubbleLatCfg.ActionsV[tind][aind].intermptV[envDBubbleLatCfg.ActionsV[tind][aind].intermptV.size()-1].theta*180/PI_CONST,
01520 envDBubbleLatCfg.ActionsV[tind][aind].cost,
01521 mp_endx_m, mp_endy_m, mp_endt, mp_endtheta_rad);
01522 #endif
01523
01524
01525 int targettheta = envDBubbleLatCfg.ActionsV[tind][aind].endtheta;
01526 if (targettheta < 0)
01527 targettheta = targettheta + ENVDBUBBLELAT_THETADIRS;
01528 envDBubbleLatCfg.PredActionsV[targettheta].push_back(&(envDBubbleLatCfg.ActionsV[tind][aind]));
01529
01530 }
01531 }
01532
01533
01534 envDBubbleLatCfg.actionwidth = motionprimitiveV->size();
01535
01536
01537
01538 ComputeReplanningData();
01539
01540 SBPL_PRINTF("done pre-computing action data based on motion primitives\n");
01541
01542
01543 }
01544
01545
01546
01547 void EnvDBubbleLattice::PrecomputeActionswithCompleteMotionPrimitive(vector<SBPL_xythetatimebubble_mprimitive>* motionprimitiveV)
01548 {
01549
01550 SBPL_PRINTF("Pre-computing action data using motion primitives for every angle...\n");
01551 envDBubbleLatCfg.ActionsV = new envDBubbleLatAction_t* [ENVDBUBBLELAT_THETADIRS];
01552 envDBubbleLatCfg.PredActionsV = new vector<envDBubbleLatAction_t*> [ENVDBUBBLELAT_THETADIRS];
01553 vector<sbpl_2Dcell_t> footprint;
01554
01555 if(motionprimitiveV->size()%ENVDBUBBLELAT_THETADIRS != 0)
01556 {
01557 SBPL_ERROR("ERROR: motionprimitives should be uniform across actions\n");
01558 throw new SBPL_Exception();
01559 }
01560
01561 envDBubbleLatCfg.actionwidth = ((int)motionprimitiveV->size())/ENVDBUBBLELAT_THETADIRS;
01562
01563
01564 int maxnumofactions = 0;
01565 for(int tind = 0; tind < ENVDBUBBLELAT_THETADIRS; tind++)
01566 {
01567 SBPL_PRINTF("pre-computing action %d out of %d actions\n", tind, ENVDBUBBLELAT_THETADIRS);
01568
01569 envDBubbleLatCfg.ActionsV[tind] = new envDBubbleLatAction_t[envDBubbleLatCfg.actionwidth];
01570
01571
01572 SBPL_4Dpt_t sourcepose;
01573 sourcepose.x = DISCXY2CONT(0, envDBubbleLatCfg.cellsize_m);
01574 sourcepose.y = DISCXY2CONT(0, envDBubbleLatCfg.cellsize_m);
01575 sourcepose.theta = DiscTheta2Cont(tind, ENVDBUBBLELAT_THETADIRS);
01576 sourcepose.t = DISCTIME2CONT(0, envDBubbleLatCfg.timeResolution);
01577
01578
01579
01580 int numofactions = 0;
01581 int aind = -1;
01582 for(int mind = 0; mind < (int)motionprimitiveV->size(); mind++)
01583 {
01584
01585 if(motionprimitiveV->at(mind).starttheta_c != tind)
01586 continue;
01587
01588 aind++;
01589 numofactions++;
01590
01591
01592 envDBubbleLatCfg.ActionsV[tind][aind].starttheta = tind;
01593
01594
01595 envDBubbleLatCfg.ActionsV[tind][aind].endtheta = motionprimitiveV->at(mind).endcell.theta;
01596 envDBubbleLatCfg.ActionsV[tind][aind].dX = motionprimitiveV->at(mind).endcell.x;
01597 envDBubbleLatCfg.ActionsV[tind][aind].dY = motionprimitiveV->at(mind).endcell.y;
01598 envDBubbleLatCfg.ActionsV[tind][aind].dT = motionprimitiveV->at(mind).endcell.t;
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615 envDBubbleLatCfg.ActionsV[tind][aind].cost = (int)(ENVDBUBBLELAT_COSTMULT_MTOMM*envDBubbleLatCfg.ActionsV[tind][aind].dT*envDBubbleLatCfg.timeResolution);
01616
01617
01618
01619
01620
01621
01622 envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV.clear();
01623 envDBubbleLatCfg.ActionsV[tind][aind].intermptV.clear();
01624 envDBubbleLatCfg.ActionsV[tind][aind].interm4DcellsV.clear();
01625 SBPL_4Dcell_t previnterm4Dcell;
01626 previnterm4Dcell.theta = 0; previnterm4Dcell.x = 0; previnterm4Dcell.y = previnterm4Dcell.t = 0;
01627 for (int pind = 0; pind < (int)motionprimitiveV->at(mind).intermptV.size(); pind++)
01628 {
01629 SBPL_4Dpt_t intermpt = motionprimitiveV->at(mind).intermptV[pind];
01630
01631
01632 envDBubbleLatCfg.ActionsV[tind][aind].intermptV.push_back(intermpt);
01633
01634
01635 SBPL_4Dpt_t pose;
01636 pose = intermpt;
01637 pose.x += sourcepose.x;
01638 pose.y += sourcepose.y;
01639 pose.t += sourcepose.t;
01640 CalculateFootprintForPose(pose, &envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV);
01641
01642
01643 SBPL_4Dcell_t interm4Dcell;
01644 interm4Dcell.x = CONTXY2DISC(pose.x, envDBubbleLatCfg.cellsize_m);
01645 interm4Dcell.y = CONTXY2DISC(pose.y, envDBubbleLatCfg.cellsize_m);
01646 interm4Dcell.theta = ContTheta2Disc(pose.theta, ENVDBUBBLELAT_THETADIRS);
01647 interm4Dcell.t = CONTTIME2DISC(pose.t, envDBubbleLatCfg.timeResolution);
01648 if(envDBubbleLatCfg.ActionsV[tind][aind].interm4DcellsV.size() == 0 ||
01649 previnterm4Dcell.theta != interm4Dcell.theta || previnterm4Dcell.x != interm4Dcell.x || previnterm4Dcell.y != interm4Dcell.y || previnterm4Dcell.t != interm4Dcell.t)
01650 {
01651 envDBubbleLatCfg.ActionsV[tind][aind].interm4DcellsV.push_back(interm4Dcell);
01652 }
01653 previnterm4Dcell = interm4Dcell;
01654 }
01655
01656
01657 RemoveSourceFootprint(sourcepose, &envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV);
01658
01659 #if DEBUG
01660 SBPL_FPRINTF(fDeb, "action tind=%d aind=%d: dX=%d dY=%d dT=%d endtheta=%d (%.2f degs -> %.2f degs) cost=%d (mprimID %d: %d %d %d %d)\n",
01661 tind, aind,
01662 envDBubbleLatCfg.ActionsV[tind][aind].dX, envDBubbleLatCfg.ActionsV[tind][aind].dY, envDBubbleLatCfg.ActionsV[tind][aind].dT,
01663 envDBubbleLatCfg.ActionsV[tind][aind].endtheta,
01664 envDBubbleLatCfg.ActionsV[tind][aind].intermptV[0].theta*180/PI_CONST,
01665 envDBubbleLatCfg.ActionsV[tind][aind].intermptV[envDBubbleLatCfg.ActionsV[tind][aind].intermptV.size()-1].theta*180/PI_CONST,
01666 envDBubbleLatCfg.ActionsV[tind][aind].cost,
01667 motionprimitiveV->at(mind).motprimID,
01668 motionprimitiveV->at(mind).endcell.x, motionprimitiveV->at(mind).endcell.y, motionprimitiveV->at(mind).endcell.t, motionprimitiveV->at(mind).endcell.theta);
01669 #endif
01670
01671
01672 int targettheta = envDBubbleLatCfg.ActionsV[tind][aind].endtheta;
01673 if (targettheta < 0)
01674 targettheta = targettheta + ENVDBUBBLELAT_THETADIRS;
01675 envDBubbleLatCfg.PredActionsV[targettheta].push_back(&(envDBubbleLatCfg.ActionsV[tind][aind]));
01676
01677 }
01678
01679 if(maxnumofactions < numofactions)
01680 maxnumofactions = numofactions;
01681 }
01682
01683
01684
01685
01686 if(motionprimitiveV->size() != (size_t)(ENVDBUBBLELAT_THETADIRS*maxnumofactions))
01687 {
01688 SBPL_ERROR("ERROR: nonuniform number of actions is not supported (maxnumofactions=%d while motprims=%d thetas=%d\n",
01689 maxnumofactions, (int)motionprimitiveV->size(), ENVDBUBBLELAT_THETADIRS);
01690 throw new SBPL_Exception();
01691 }
01692
01693
01694 ComputeReplanningData();
01695
01696 SBPL_PRINTF("done pre-computing action data based on motion primitives\n");
01697
01698 }
01699
01700 void EnvDBubbleLattice::PrecomputeActions()
01701 {
01702
01703
01704 SBPL_PRINTF("Pre-computing action data using the motion primitives for a 4D kinematic planning...\n");
01705 envDBubbleLatCfg.ActionsV = new envDBubbleLatAction_t* [ENVDBUBBLELAT_THETADIRS];
01706 envDBubbleLatCfg.PredActionsV = new vector<envDBubbleLatAction_t*> [ENVDBUBBLELAT_THETADIRS];
01707 vector<sbpl_2Dcell_t> footprint;
01708
01709 for(int tind = 0; tind < ENVDBUBBLELAT_THETADIRS; tind++)
01710 {
01711 SBPL_PRINTF("processing angle %d\n", tind);
01712 envDBubbleLatCfg.ActionsV[tind] = new envDBubbleLatAction_t[envDBubbleLatCfg.actionwidth];
01713
01714
01715 SBPL_4Dpt_t sourcepose;
01716 sourcepose.x = DISCXY2CONT(0, envDBubbleLatCfg.cellsize_m);
01717 sourcepose.y = DISCXY2CONT(0, envDBubbleLatCfg.cellsize_m);
01718 sourcepose.theta = DiscTheta2Cont(tind, ENVDBUBBLELAT_THETADIRS);
01719 sourcepose.t = DISCTIME2CONT(0, envDBubbleLatCfg.timeResolution);
01720
01721
01722 int aind = 0;
01723 for(; aind < 3; aind++)
01724 {
01725 envDBubbleLatCfg.ActionsV[tind][aind].starttheta = tind;
01726 envDBubbleLatCfg.ActionsV[tind][aind].endtheta = (tind + aind - 1)%ENVDBUBBLELAT_THETADIRS;
01727 double angle = DiscTheta2Cont(envDBubbleLatCfg.ActionsV[tind][aind].endtheta, ENVDBUBBLELAT_THETADIRS);
01728 envDBubbleLatCfg.ActionsV[tind][aind].dX = (int)(cos(angle) + 0.5*(cos(angle)>0?1:-1));
01729 envDBubbleLatCfg.ActionsV[tind][aind].dY = (int)(sin(angle) + 0.5*(sin(angle)>0?1:-1));
01730
01731
01732 envDBubbleLatCfg.ActionsV[tind][aind].dT = (int)(ceil(envDBubbleLatCfg.cellsize_m/envDBubbleLatCfg.nominalvel_mpersecs*sqrt((double)(envDBubbleLatCfg.ActionsV[tind][aind].dX*envDBubbleLatCfg.ActionsV[tind][aind].dX + envDBubbleLatCfg.ActionsV[tind][aind].dY*envDBubbleLatCfg.ActionsV[tind][aind].dY))));
01733 envDBubbleLatCfg.ActionsV[tind][aind].cost = (int)(ceil(ENVDBUBBLELAT_COSTMULT_MTOMM*envDBubbleLatCfg.cellsize_m/envDBubbleLatCfg.nominalvel_mpersecs*sqrt((double)(envDBubbleLatCfg.ActionsV[tind][aind].dX*envDBubbleLatCfg.ActionsV[tind][aind].dX + envDBubbleLatCfg.ActionsV[tind][aind].dY*envDBubbleLatCfg.ActionsV[tind][aind].dY))));
01734
01735
01736 SBPL_4Dpt_t pose;
01737 pose.x = DISCXY2CONT(envDBubbleLatCfg.ActionsV[tind][aind].dX, envDBubbleLatCfg.cellsize_m);
01738 pose.y = DISCXY2CONT(envDBubbleLatCfg.ActionsV[tind][aind].dY, envDBubbleLatCfg.cellsize_m);
01739 pose.theta = angle;
01740 pose.t = DISCTIME2CONT(envDBubbleLatCfg.ActionsV[tind][aind].dT, envDBubbleLatCfg.timeResolution);
01741 envDBubbleLatCfg.ActionsV[tind][aind].intermptV.clear();
01742 envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV.clear();
01743 CalculateFootprintForPose(pose, &envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV);
01744 RemoveSourceFootprint(sourcepose, &envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV);
01745
01746 #if DEBUG
01747 SBPL_PRINTF("action tind=%d aind=%d: endtheta=%d (%f) dX=%d dY=%d dT=%d cost=%d\n",
01748 tind, aind, envDBubbleLatCfg.ActionsV[tind][aind].endtheta, angle,
01749 envDBubbleLatCfg.ActionsV[tind][aind].dX, envDBubbleLatCfg.ActionsV[tind][aind].dY,
01750 envDBubbleLatCfg.ActionsV[tind][aind].dT, envDBubbleLatCfg.ActionsV[tind][aind].cost);
01751 #endif
01752
01753
01754 int targettheta = envDBubbleLatCfg.ActionsV[tind][aind].endtheta;
01755 if (targettheta < 0)
01756 targettheta = targettheta + ENVDBUBBLELAT_THETADIRS;
01757 envDBubbleLatCfg.PredActionsV[targettheta].push_back(&(envDBubbleLatCfg.ActionsV[tind][aind]));
01758
01759 }
01760
01761
01762 aind = 3;
01763 envDBubbleLatCfg.ActionsV[tind][aind].starttheta = tind;
01764 envDBubbleLatCfg.ActionsV[tind][aind].endtheta = tind-1;
01765 if(envDBubbleLatCfg.ActionsV[tind][aind].endtheta < 0) envDBubbleLatCfg.ActionsV[tind][aind].endtheta += ENVDBUBBLELAT_THETADIRS;
01766 envDBubbleLatCfg.ActionsV[tind][aind].dX = 0;
01767 envDBubbleLatCfg.ActionsV[tind][aind].dY = 0;
01768 envDBubbleLatCfg.ActionsV[tind][aind].dT = (int)(envDBubbleLatCfg.timetoturn45degsinplace_secs);
01769 envDBubbleLatCfg.ActionsV[tind][aind].cost = (int)(ENVDBUBBLELAT_COSTMULT_MTOMM*envDBubbleLatCfg.timetoturn45degsinplace_secs);
01770
01771
01772 SBPL_4Dpt_t pose;
01773 pose.x = DISCXY2CONT(envDBubbleLatCfg.ActionsV[tind][aind].dX, envDBubbleLatCfg.cellsize_m);
01774 pose.y = DISCXY2CONT(envDBubbleLatCfg.ActionsV[tind][aind].dY, envDBubbleLatCfg.cellsize_m);
01775 pose.theta = DiscTheta2Cont(envDBubbleLatCfg.ActionsV[tind][aind].endtheta, ENVDBUBBLELAT_THETADIRS);
01776 pose.t = DISCTIME2CONT(envDBubbleLatCfg.ActionsV[tind][aind].dT, envDBubbleLatCfg.timeResolution);
01777 envDBubbleLatCfg.ActionsV[tind][aind].intermptV.clear();
01778 envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV.clear();
01779 CalculateFootprintForPose(pose, &envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV);
01780 RemoveSourceFootprint(sourcepose, &envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV);
01781
01782 #if DEBUG
01783 SBPL_PRINTF("action tind=%d aind=%d: endtheta=%d (%f) dX=%d dY=%d dT=%d cost=%d\n",
01784 tind, aind, envDBubbleLatCfg.ActionsV[tind][aind].endtheta, DiscTheta2Cont(envDBubbleLatCfg.ActionsV[tind][aind].endtheta, ENVDBUBBLELAT_THETADIRS),
01785 envDBubbleLatCfg.ActionsV[tind][aind].dX, envDBubbleLatCfg.ActionsV[tind][aind].dY,
01786 envDBubbleLatCfg.ActionsV[tind][aind].dT, envDBubbleLatCfg.ActionsV[tind][aind].cost);
01787 #endif
01788
01789
01790 int targettheta = envDBubbleLatCfg.ActionsV[tind][aind].endtheta;
01791 if (targettheta < 0)
01792 targettheta = targettheta + ENVDBUBBLELAT_THETADIRS;
01793 envDBubbleLatCfg.PredActionsV[targettheta].push_back(&(envDBubbleLatCfg.ActionsV[tind][aind]));
01794
01795
01796 aind = 4;
01797 envDBubbleLatCfg.ActionsV[tind][aind].starttheta = tind;
01798 envDBubbleLatCfg.ActionsV[tind][aind].endtheta = (tind + 1)%ENVDBUBBLELAT_THETADIRS;
01799 envDBubbleLatCfg.ActionsV[tind][aind].dX = 0;
01800 envDBubbleLatCfg.ActionsV[tind][aind].dY = 0;
01801 envDBubbleLatCfg.ActionsV[tind][aind].dT = (int)(envDBubbleLatCfg.timetoturn45degsinplace_secs);
01802 envDBubbleLatCfg.ActionsV[tind][aind].cost = (int)(ENVDBUBBLELAT_COSTMULT_MTOMM*envDBubbleLatCfg.timetoturn45degsinplace_secs);
01803
01804
01805 pose.x = DISCXY2CONT(envDBubbleLatCfg.ActionsV[tind][aind].dX, envDBubbleLatCfg.cellsize_m);
01806 pose.y = DISCXY2CONT(envDBubbleLatCfg.ActionsV[tind][aind].dY, envDBubbleLatCfg.cellsize_m);
01807 pose.theta = DiscTheta2Cont(envDBubbleLatCfg.ActionsV[tind][aind].endtheta, ENVDBUBBLELAT_THETADIRS);
01808 pose.t = DISCTIME2CONT(envDBubbleLatCfg.ActionsV[tind][aind].dT, envDBubbleLatCfg.timeResolution);
01809 envDBubbleLatCfg.ActionsV[tind][aind].intermptV.clear();
01810 envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV.clear();
01811 CalculateFootprintForPose(pose, &envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV);
01812 RemoveSourceFootprint(sourcepose, &envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV);
01813
01814
01815 #if DEBUG
01816 SBPL_PRINTF("action tind=%d aind=%d: endtheta=%d (%f) dX=%d dY=%d dT=%d cost=%d\n",
01817 tind, aind, envDBubbleLatCfg.ActionsV[tind][aind].endtheta, DiscTheta2Cont(envDBubbleLatCfg.ActionsV[tind][aind].endtheta, ENVDBUBBLELAT_THETADIRS),
01818 envDBubbleLatCfg.ActionsV[tind][aind].dX, envDBubbleLatCfg.ActionsV[tind][aind].dY,
01819 envDBubbleLatCfg.ActionsV[tind][aind].dT, envDBubbleLatCfg.ActionsV[tind][aind].cost);
01820 #endif
01821
01822
01823 targettheta = envDBubbleLatCfg.ActionsV[tind][aind].endtheta;
01824 if (targettheta < 0)
01825 targettheta = targettheta + ENVDBUBBLELAT_THETADIRS;
01826 envDBubbleLatCfg.PredActionsV[targettheta].push_back(&(envDBubbleLatCfg.ActionsV[tind][aind]));
01827
01828
01829 aind = 5;
01830 envDBubbleLatCfg.ActionsV[tind][aind].starttheta = tind;
01831 envDBubbleLatCfg.ActionsV[tind][aind].endtheta = tind;
01832 envDBubbleLatCfg.ActionsV[tind][aind].dX = 0;
01833 envDBubbleLatCfg.ActionsV[tind][aind].dY = 0;
01834 envDBubbleLatCfg.ActionsV[tind][aind].dT = 1;
01835 envDBubbleLatCfg.ActionsV[tind][aind].cost = (int)(ENVDBUBBLELAT_COSTMULT_MTOMM*envDBubbleLatCfg.ActionsV[tind][aind].dT*envDBubbleLatCfg.timeResolution);
01836
01837
01838
01839 pose.x = DISCXY2CONT(envDBubbleLatCfg.ActionsV[tind][aind].dX, envDBubbleLatCfg.cellsize_m);
01840 pose.y = DISCXY2CONT(envDBubbleLatCfg.ActionsV[tind][aind].dY, envDBubbleLatCfg.cellsize_m);
01841 pose.theta = DiscTheta2Cont(envDBubbleLatCfg.ActionsV[tind][aind].endtheta, ENVDBUBBLELAT_THETADIRS);
01842 pose.t = DISCTIME2CONT(envDBubbleLatCfg.ActionsV[tind][aind].dT, envDBubbleLatCfg.timeResolution);
01843 envDBubbleLatCfg.ActionsV[tind][aind].intermptV.clear();
01844 envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV.clear();
01845 CalculateFootprintForPose(pose, &envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV);
01846 RemoveSourceFootprint(sourcepose, &envDBubbleLatCfg.ActionsV[tind][aind].intersectingcellsV);
01847
01848
01849 #if DEBUG
01850 SBPL_PRINTF("action tind=%d aind=%d: endtheta=%d (%f) dX=%d dY=%d dT=%d cost=%d\n",
01851 tind, aind, envDBubbleLatCfg.ActionsV[tind][aind].endtheta, DiscTheta2Cont(envDBubbleLatCfg.ActionsV[tind][aind].endtheta, ENVDBUBBLELAT_THETADIRS),
01852 envDBubbleLatCfg.ActionsV[tind][aind].dX, envDBubbleLatCfg.ActionsV[tind][aind].dY,
01853 envDBubbleLatCfg.ActionsV[tind][aind].dT, envDBubbleLatCfg.ActionsV[tind][aind].cost);
01854 #endif
01855
01856
01857 targettheta = envDBubbleLatCfg.ActionsV[tind][aind].endtheta;
01858 if (targettheta < 0)
01859 targettheta = targettheta + ENVDBUBBLELAT_THETADIRS;
01860 envDBubbleLatCfg.PredActionsV[targettheta].push_back(&(envDBubbleLatCfg.ActionsV[tind][aind]));
01861 }
01862
01863
01864 ComputeReplanningData();
01865
01866 SBPL_PRINTF("done pre-computing action data\n");
01867
01868
01869 }
01870
01871
01872
01873 void EnvDBubbleLattice::InitializeEnvConfig(vector<SBPL_xythetatimebubble_mprimitive>* motionprimitiveV)
01874 {
01875
01876
01877
01878 envDBubbleLatCfg.dXY[0][0] = -1;
01879 envDBubbleLatCfg.dXY[0][1] = -1;
01880 envDBubbleLatCfg.dXY[1][0] = -1;
01881 envDBubbleLatCfg.dXY[1][1] = 0;
01882 envDBubbleLatCfg.dXY[2][0] = -1;
01883 envDBubbleLatCfg.dXY[2][1] = 1;
01884 envDBubbleLatCfg.dXY[3][0] = 0;
01885 envDBubbleLatCfg.dXY[3][1] = -1;
01886 envDBubbleLatCfg.dXY[4][0] = 0;
01887 envDBubbleLatCfg.dXY[4][1] = 1;
01888 envDBubbleLatCfg.dXY[5][0] = 1;
01889 envDBubbleLatCfg.dXY[5][1] = -1;
01890 envDBubbleLatCfg.dXY[6][0] = 1;
01891 envDBubbleLatCfg.dXY[6][1] = 0;
01892 envDBubbleLatCfg.dXY[7][0] = 1;
01893 envDBubbleLatCfg.dXY[7][1] = 1;
01894
01895
01896 SBPL_4Dpt_t temppose;
01897 temppose.x = 0.0;
01898 temppose.y = 0.0;
01899 temppose.theta = 0.0;
01900 temppose.t = 0.0;
01901 vector<SBPL_4Dcell_t> footprint;
01902 CalculateFootprintForPose(temppose, &footprint);
01903 SBPL_PRINTF("number of cells in footprint of the robot = %d\n", (int)footprint.size());
01904
01905 #if DEBUG
01906 SBPL_FPRINTF(fDeb, "footprint cells (size=%d):\n", footprint.size());
01907 for(int i = 0; i < (int) footprint.size(); i++)
01908 {
01909 SBPL_FPRINTF(fDeb, "%d %d (cont: %.3f %.3f)\n", footprint.at(i).x, footprint.at(i).y,
01910 DISCXY2CONT(footprint.at(i).x, envDBubbleLatCfg.cellsize_m),
01911 DISCXY2CONT(footprint.at(i).y, envDBubbleLatCfg.cellsize_m));
01912 }
01913 #endif
01914
01915
01916 if(motionprimitiveV == NULL)
01917 PrecomputeActions();
01918 else
01919 PrecomputeActionswithCompleteMotionPrimitive(motionprimitiveV);
01920
01921
01922 }
01923
01924
01925
01926 bool EnvDBubbleLattice::IsValidCell(int X, int Y)
01927 {
01928 return (X >= 0 && X < envDBubbleLatCfg.EnvWidth_c &&
01929 Y >= 0 && Y < envDBubbleLatCfg.EnvHeight_c &&
01930 envDBubbleLatCfg.Grid2D[X][Y] < envDBubbleLatCfg.obsthresh);
01931 }
01932
01933 bool EnvDBubbleLattice::IsWithinMapCell(int X, int Y)
01934 {
01935 return (X >= 0 && X < envDBubbleLatCfg.EnvWidth_c &&
01936 Y >= 0 && Y < envDBubbleLatCfg.EnvHeight_c);
01937 }
01938
01939 bool EnvDBubbleLattice::IsValidConfiguration(int X, int Y, int Theta)
01940 {
01941 vector<SBPL_4Dcell_t> footprint;
01942 SBPL_4Dpt_t pose;
01943
01944
01945 pose.x = DISCXY2CONT(X, envDBubbleLatCfg.cellsize_m);
01946 pose.y = DISCXY2CONT(Y, envDBubbleLatCfg.cellsize_m);
01947 pose.theta = DiscTheta2Cont(Theta, ENVDBUBBLELAT_THETADIRS);
01948
01949
01950 CalculateFootprintForPose(pose, &footprint);
01951
01952
01953 for(int find = 0; find < (int)footprint.size(); find++)
01954 {
01955 int x = footprint.at(find).x;
01956 int y = footprint.at(find).y;
01957
01958 if (x < 0 || x >= envDBubbleLatCfg.EnvWidth_c ||
01959 y < 0 || Y >= envDBubbleLatCfg.EnvHeight_c ||
01960 envDBubbleLatCfg.Grid2D[x][y] >= envDBubbleLatCfg.obsthresh)
01961 {
01962 return false;
01963 }
01964 }
01965
01966 return true;
01967 }
01968
01969
01970 int EnvDBubbleLattice::GetActionCost(int SourceX, int SourceY, int SourceTheta, int SourceT, envDBubbleLatAction_t* action, vector<int>* bubbleCollisions)
01971 {
01972 SBPL_4Dcell_t cell;
01973 SBPL_4Dcell_t interm4Dcell;
01974 int i;
01975
01976
01977
01978 if(!IsValidCell(SourceX, SourceY))
01979 return INFINITECOST;
01980 if(!IsValidCell(SourceX + action->dX, SourceY + action->dY))
01981 return INFINITECOST;
01982
01983
01984
01985
01986
01987 unsigned char maxcellcost = 0;
01988 for(i = 0; i < (int)action->interm4DcellsV.size(); i++)
01989 {
01990 interm4Dcell = action->interm4DcellsV.at(i);
01991 interm4Dcell.x = interm4Dcell.x + SourceX;
01992 interm4Dcell.y = interm4Dcell.y + SourceY;
01993 interm4Dcell.t = interm4Dcell.t + SourceT;
01994
01995 if(interm4Dcell.x < 0 || interm4Dcell.x >= envDBubbleLatCfg.EnvWidth_c ||
01996 interm4Dcell.y < 0 || interm4Dcell.y >= envDBubbleLatCfg.EnvHeight_c)
01997 return INFINITECOST;
01998
01999 maxcellcost = __max(maxcellcost, envDBubbleLatCfg.Grid2D[interm4Dcell.x][interm4Dcell.y]);
02000
02001 if(maxcellcost >= envDBubbleLatCfg.cost_inscribed_thresh)
02002 return INFINITECOST;
02003 if(getDynamicObstacleCost(interm4Dcell, bubbleCollisions) > envDBubbleLatCfg.dynamic_obstacle_collision_cost_thresh){
02004 return INFINITECOST;
02005 }
02006 }
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016 if(envDBubbleLatCfg.FootprintPolygon.size() > 1 && (int)maxcellcost >= envDBubbleLatCfg.cost_possibly_circumscribed_thresh)
02017 {
02018 checks++;
02019
02020 for(i = 0; i < (int)action->intersectingcellsV.size(); i++)
02021 {
02022
02023 cell = action->intersectingcellsV.at(i);
02024 cell.x = cell.x + SourceX;
02025 cell.y = cell.y + SourceY;
02026 cell.t = cell.t + SourceT;
02027
02028
02029 if(!IsValidCell(cell.x, cell.y))
02030 return INFINITECOST;
02031
02032 if(SourceX==1 && SourceY==1 && SourceTheta==0){
02033
02034
02035
02036
02037
02038
02039
02040 }
02041
02042
02043
02044 }
02045 }
02046
02047
02048
02049
02050
02051 maxcellcost = __max(maxcellcost, envDBubbleLatCfg.Grid2D[SourceX][SourceY]);
02052 int currentmaxcost = (int)__max(maxcellcost, envDBubbleLatCfg.Grid2D[SourceX + action->dX][SourceY + action->dY]);
02053
02054 return action->cost*(currentmaxcost+1);
02055
02056 }
02057
02058 unsigned char EnvDBubbleLattice::getDynamicObstacleCost(SBPL_4Dcell_t cell, vector<int>* bubbleCollisions){
02059
02060
02061
02062
02063
02064 if(cell.t > bubblemap[cell.x][cell.y].lastObsT || cell.t < bubblemap[cell.x][cell.y].firstObsT){
02065
02066 return 0;
02067 }
02068 vector<envDBubbleLat_BubbleCellObs_t> dynObs = bubblemap[cell.x][cell.y].dynObs;
02069
02070 if(dynObs.size() == 0)
02071 return 0;
02072
02073
02074 bool collision = false;
02075 for(unsigned int i=0; i < dynObs.size(); i++){
02076 if(cell.t <= dynObs[i].collision_endt && cell.t >= dynObs[i].collision_startt){
02077 if(bubbleCollisions){
02078 for(unsigned int m=0; m<dynObs[i].ID.size(); m++){
02079 int id = dynObs[i].ID[m];
02080 if(!bubble4Dactive[id]){
02081 bubbleCollisions->push_back(id);
02082 bubble4Dactive[id] = true;
02083 }
02084 }
02085 }
02086 else
02087 return 255;
02088 collision = true;
02089 }
02090 }
02091
02092 if(collision)
02093 return 255;
02094
02095 return 0;
02096 }
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205 double EnvDBubbleLattice::EuclideanDistance_m(int X1, int Y1, int X2, int Y2)
02206 {
02207 int sqdist = ((X1-X2)*(X1-X2)+(Y1-Y2)*(Y1-Y2));
02208 return envDBubbleLatCfg.cellsize_m*sqrt((double)sqdist);
02209
02210 }
02211
02212
02213
02214 void EnvDBubbleLattice::CalculateFootprintForPose(SBPL_4Dpt_t pose, vector<SBPL_4Dcell_t>* footprint)
02215 {
02216 int pind;
02217
02218 #if DEBUG
02219
02220
02221 #endif
02222
02223
02224 if(envDBubbleLatCfg.FootprintPolygon.size() <= 1){
02225 SBPL_4Dcell_t cell;
02226 cell.x = CONTXY2DISC(pose.x, envDBubbleLatCfg.cellsize_m);
02227 cell.y = CONTXY2DISC(pose.y, envDBubbleLatCfg.cellsize_m);
02228
02229 for(pind = 0; pind < (int)footprint->size(); pind++)
02230 {
02231 if(cell.x == footprint->at(pind).x && cell.y == footprint->at(pind).y)
02232 break;
02233 }
02234 if(pind == (int)footprint->size()) footprint->push_back(cell);
02235 return;
02236 }
02237
02238 vector<sbpl_2Dpt_t> bounding_polygon;
02239 unsigned int find;
02240 double max_x = -INFINITECOST, min_x = INFINITECOST, max_y = -INFINITECOST, min_y = INFINITECOST;
02241 sbpl_2Dpt_t pt = {0,0};
02242 for(find = 0; find < envDBubbleLatCfg.FootprintPolygon.size(); find++){
02243
02244
02245 pt = envDBubbleLatCfg.FootprintPolygon[find];
02246
02247
02248 sbpl_2Dpt_t corner;
02249 corner.x = cos(pose.theta)*pt.x - sin(pose.theta)*pt.y + pose.x;
02250 corner.y = sin(pose.theta)*pt.x + cos(pose.theta)*pt.y + pose.y;
02251 bounding_polygon.push_back(corner);
02252 #if DEBUG
02253
02254 #endif
02255 if(corner.x < min_x || find==0){
02256 min_x = corner.x;
02257 }
02258 if(corner.x > max_x || find==0){
02259 max_x = corner.x;
02260 }
02261 if(corner.y < min_y || find==0){
02262 min_y = corner.y;
02263 }
02264 if(corner.y > max_y || find==0){
02265 max_y = corner.y;
02266 }
02267
02268 }
02269
02270 #if DEBUG
02271
02272 #endif
02273
02274 int prev_discrete_x = CONTXY2DISC(pt.x, envDBubbleLatCfg.cellsize_m) + 1;
02275 int prev_discrete_y = CONTXY2DISC(pt.y, envDBubbleLatCfg.cellsize_m) + 1;
02276 int prev_inside = 0;
02277 int discrete_x;
02278 int discrete_y;
02279
02280 for(double x=min_x; x<=max_x; x+=envDBubbleLatCfg.cellsize_m/3){
02281 for(double y=min_y; y<=max_y; y+=envDBubbleLatCfg.cellsize_m/3){
02282 pt.x = x;
02283 pt.y = y;
02284 discrete_x = CONTXY2DISC(pt.x, envDBubbleLatCfg.cellsize_m);
02285 discrete_y = CONTXY2DISC(pt.y, envDBubbleLatCfg.cellsize_m);
02286
02287
02288 if(discrete_x != prev_discrete_x || discrete_y != prev_discrete_y || prev_inside==0){
02289
02290 #if DEBUG
02291
02292 #endif
02293
02294 if(IsInsideFootprint(pt, &bounding_polygon)){
02295
02296
02297 #if DEBUG
02298
02299 #endif
02300
02301 SBPL_4Dcell_t cell;
02302 cell.x = discrete_x;
02303 cell.y = discrete_y;
02304
02305
02306 int pind = 0;
02307 for(pind = 0; pind < (int)footprint->size(); pind++)
02308 {
02309 if(cell.x == footprint->at(pind).x && cell.y == footprint->at(pind).y)
02310 break;
02311 }
02312 if(pind == (int)footprint->size()) footprint->push_back(cell);
02313
02314 prev_inside = 1;
02315
02316 #if DEBUG
02317
02318 #endif
02319 }
02320 else{
02321 prev_inside = 0;
02322 }
02323
02324 }
02325 else
02326 {
02327 #if DEBUG
02328
02329 #endif
02330 }
02331
02332 prev_discrete_x = discrete_x;
02333 prev_discrete_y = discrete_y;
02334
02335 }
02336 }
02337 }
02338
02339
02340 void EnvDBubbleLattice::RemoveSourceFootprint(SBPL_4Dpt_t sourcepose, vector<SBPL_4Dcell_t>* footprint)
02341 {
02342 vector<SBPL_4Dcell_t> sourcefootprint;
02343
02344
02345 CalculateFootprintForPose(sourcepose, &sourcefootprint);
02346
02347
02348 for(int sind = 0; sind < (int)sourcefootprint.size(); sind++)
02349 {
02350 for(int find = 0; find < (int)footprint->size(); find++)
02351 {
02352 if(sourcefootprint.at(sind).x == footprint->at(find).x && sourcefootprint.at(sind).y == footprint->at(find).y)
02353 {
02354 footprint->erase(footprint->begin() + find);
02355 break;
02356 }
02357 }
02358 }
02359
02360
02361
02362 }
02363
02364
02365
02366
02367
02368
02369 void EnvDBubbleLattice::ComputeHeuristicValues()
02370 {
02371
02372 SBPL_PRINTF("Precomputing heuristics...\n");
02373
02374
02375 grid2Dsearchfromstart = new SBPL2DGridSearch(envDBubbleLatCfg.EnvWidth_c, envDBubbleLatCfg.EnvHeight_c, (float)envDBubbleLatCfg.cellsize_m);
02376 grid2Dsearchfromgoal = new SBPL2DGridSearch(envDBubbleLatCfg.EnvWidth_c, envDBubbleLatCfg.EnvHeight_c, (float)envDBubbleLatCfg.cellsize_m);
02377
02378 SBPL_PRINTF("done\n");
02379
02380 }
02381
02382
02383 bool EnvDBubbleLattice::CheckQuant(FILE* fOut)
02384 {
02385
02386 for(double theta = -10; theta < 10; theta += 2.0*PI_CONST/ENVDBUBBLELAT_THETADIRS*0.01)
02387 {
02388 int nTheta = ContTheta2Disc(theta, ENVDBUBBLELAT_THETADIRS);
02389 double newTheta = DiscTheta2Cont(nTheta, ENVDBUBBLELAT_THETADIRS);
02390 int nnewTheta = ContTheta2Disc(newTheta, ENVDBUBBLELAT_THETADIRS);
02391
02392 SBPL_FPRINTF(fOut, "theta=%f(%f)->%d->%f->%d\n", theta, theta*180/PI_CONST, nTheta, newTheta, nnewTheta);
02393
02394 if(nTheta != nnewTheta)
02395 {
02396 SBPL_ERROR("ERROR: invalid quantization\n");
02397 return false;
02398 }
02399 }
02400
02401 return true;
02402 }
02403
02404
02405
02406
02407
02408
02409 bool EnvDBubbleLattice::InitializeEnv(const char* sEnvFile, const vector<sbpl_2Dpt_t>& perimeterptsV, const char* sMotPrimFile, const char* sDynObsFile){
02410
02411 InitializeEnv(sEnvFile, perimeterptsV, sMotPrimFile);
02412
02413
02414 FILE* fDynObs = fopen(sDynObsFile, "r");
02415 if(fDynObs == NULL){
02416 SBPL_PRINTF("Error: unable to open %s\n", sDynObsFile);
02417 throw new SBPL_Exception();
02418 }
02419 ReadDynamicObstacles(fDynObs);
02420 fclose(fDynObs);
02421 UpdateBubbleMap();
02422
02423 return true;
02424 }
02425
02426 bool EnvDBubbleLattice::InitializeEnv(const char* sEnvFile, const vector<sbpl_2Dpt_t>& perimeterptsV, const char* sMotPrimFile)
02427 {
02428
02429
02430 double max_sqr_radius = 0;
02431 for(unsigned int i=0; i<perimeterptsV.size(); i++){
02432 double x = perimeterptsV.at(i).x;
02433 double y = perimeterptsV.at(i).y;
02434 double d = x*x + y*y;
02435 if(d > max_sqr_radius)
02436 max_sqr_radius = d;
02437 }
02438 envDBubbleLatCfg.robotRadius = sqrt(max_sqr_radius);
02439 SBPL_PRINTF("robotRadius=%f\n", envDBubbleLatCfg.robotRadius);
02440
02441 envDBubbleLatCfg.FootprintPolygon = perimeterptsV;
02442
02443 FILE* fCfg = fopen(sEnvFile, "r");
02444 if(fCfg == NULL)
02445 {
02446 SBPL_ERROR("ERROR: unable to open %s\n", sEnvFile);
02447 throw new SBPL_Exception();
02448 }
02449 ReadConfiguration(fCfg);
02450 fclose(fCfg);
02451
02452 if(sMotPrimFile != NULL)
02453 {
02454 FILE* fMotPrim = fopen(sMotPrimFile, "r");
02455 if(fMotPrim == NULL)
02456 {
02457 SBPL_ERROR("ERROR: unable to open %s\n", sMotPrimFile);
02458 throw new SBPL_Exception();
02459 }
02460 if(ReadMotionPrimitives(fMotPrim) == false)
02461 {
02462 SBPL_ERROR("ERROR: failed to read in motion primitive file\n");
02463 throw new SBPL_Exception();
02464 }
02465 fclose(fMotPrim);
02466 InitGeneral(&envDBubbleLatCfg.mprimV);
02467 }
02468 else
02469 InitGeneral(NULL);
02470
02471
02472 temporal_padding = DEFAULT_TEMPORAL_PADDING;
02473 InitializeBubbleMap();
02474 return true;
02475 }
02476
02477
02478 bool EnvDBubbleLattice::InitializeEnv(const char* sEnvFile)
02479 {
02480
02481 FILE* fCfg = fopen(sEnvFile, "r");
02482 if(fCfg == NULL)
02483 {
02484 SBPL_ERROR("ERROR: unable to open %s\n", sEnvFile);
02485 throw new SBPL_Exception();
02486 }
02487 ReadConfiguration(fCfg);
02488
02489 InitGeneral(NULL);
02490
02491
02492 return true;
02493 }
02494
02495 bool EnvDBubbleLattice::InitializeEnv(int width, int height,
02496 const unsigned char* mapdata,
02497 double startx, double starty, double starttheta, double startTime,
02498 double goalx, double goaly, double goaltheta,
02499 double goaltol_x, double goaltol_y, double goaltol_theta,
02500 const vector<sbpl_2Dpt_t> & perimeterptsV,
02501 double cellsize_m, double timeResolution,
02502 double nominalvel_mpersecs, double timetoturn45degsinplace_secs,
02503 unsigned char obsthresh, unsigned char dynobsthresh, const char* sMotPrimFile,
02504 vector<SBPL_DynamicObstacle_t> & dynObs)
02505 {
02506
02507 SBPL_PRINTF("env: initialize with width=%d height=%d start=%.3f %.3f %.3f %.3f goalx=%.3f %.3f %.3f cellsize=%.3f timeResolution=%.3f nomvel=%.3f timetoturn=%.3f, obsthresh=%d\n",
02508 width, height, startx, starty, starttheta, startTime, goalx, goaly, goaltheta, cellsize_m, timeResolution, nominalvel_mpersecs, timetoturn45degsinplace_secs, obsthresh);
02509
02510 SBPL_PRINTF("perimeter has size=%d\n", (int)perimeterptsV.size());
02511
02512 for(int i = 0; i < (int)perimeterptsV.size(); i++)
02513 {
02514 SBPL_PRINTF("perimeter(%d) = %.4f %.4f\n", i, perimeterptsV.at(i).x, perimeterptsV.at(i).y);
02515 }
02516
02517
02518 envDBubbleLatCfg.obsthresh = obsthresh;
02519 envDBubbleLatCfg.dynamic_obstacle_collision_cost_thresh = dynobsthresh;
02520
02521
02522 double max_sqr_radius = 0;
02523 for(unsigned int i=0; i<perimeterptsV.size(); i++){
02524 double x = perimeterptsV.at(i).x;
02525 double y = perimeterptsV.at(i).y;
02526 double d = x*x + y*y;
02527 if(d > max_sqr_radius)
02528 max_sqr_radius = d;
02529 }
02530 envDBubbleLatCfg.robotRadius = sqrt(max_sqr_radius);
02531 dynamicObstacles.clear();
02532 for(unsigned int i=0; i<dynObs.size(); i++){
02533 SBPL_DynamicObstacle_t obs;
02534 obs.radius = dynObs[i].radius + envDBubbleLatCfg.robotRadius;
02535 for(unsigned int j=0; j<dynObs[i].trajectories.size(); j++){
02536 SBPL_Trajectory_t traj;
02537 traj.prob = dynObs[i].trajectories[j].prob;
02538 traj.existsAfter = dynObs[i].trajectories[j].existsAfter;
02539 for(unsigned int k=0; k<dynObs[i].trajectories[j].points.size(); k++){
02540 SBPL_Traj_Pt_t p;
02541 p.x = dynObs[i].trajectories[j].points[k].x;
02542 p.y = dynObs[i].trajectories[j].points[k].y;
02543 p.t = dynObs[i].trajectories[j].points[k].t;
02544 p.std_dev = dynObs[i].trajectories[j].points[k].std_dev;
02545 traj.points.push_back(p);
02546 }
02547 obs.trajectories.push_back(traj);
02548 }
02549 dynamicObstacles.push_back(obs);
02550 }
02551
02552
02553
02554 SetConfiguration(width, height,
02555 mapdata,
02556 CONTXY2DISC(startx, cellsize_m), CONTXY2DISC(starty, cellsize_m), ContTheta2Disc(starttheta, ENVDBUBBLELAT_THETADIRS), CONTTIME2DISC(startTime, timeResolution),
02557 CONTXY2DISC(goalx, cellsize_m), CONTXY2DISC(goaly, cellsize_m), ContTheta2Disc(goaltheta, ENVDBUBBLELAT_THETADIRS),
02558 cellsize_m, timeResolution, nominalvel_mpersecs, timetoturn45degsinplace_secs, perimeterptsV);
02559
02560 if(sMotPrimFile != NULL)
02561 {
02562 FILE* fMotPrim = fopen(sMotPrimFile, "r");
02563 if(fMotPrim == NULL)
02564 {
02565 SBPL_ERROR("ERROR: unable to open %s\n", sMotPrimFile);
02566 throw new SBPL_Exception();
02567 }
02568
02569 if(ReadMotionPrimitives(fMotPrim) == false)
02570 {
02571 SBPL_ERROR("ERROR: failed to read in motion primitive file\n");
02572 throw new SBPL_Exception();
02573 }
02574 }
02575
02576 if(envDBubbleLatCfg.mprimV.size() != 0)
02577 {
02578 InitGeneral(&envDBubbleLatCfg.mprimV);
02579 }
02580 else
02581 InitGeneral(NULL);
02582
02583 temporal_padding = DEFAULT_TEMPORAL_PADDING;
02584 InitializeBubbleMap();
02585 return true;
02586 }
02587
02588
02589 bool EnvDBubbleLattice::InitializeEnv(int width, int height,
02590 const unsigned char* mapdata,
02591 double startx, double starty, double starttheta, double startTime,
02592 double goalx, double goaly, double goaltheta,
02593 double goaltol_x, double goaltol_y, double goaltol_theta,
02594 const vector<sbpl_2Dpt_t> & perimeterptsV,
02595 double cellsize_m, double timeResolution,
02596 double nominalvel_mpersecs, double timetoturn45degsinplace_secs,
02597 unsigned char obsthresh, unsigned char dynobsthresh, const char* sMotPrimFile)
02598 {
02599
02600 SBPL_PRINTF("env: initialize with width=%d height=%d start=%.3f %.3f %.3f %.3f goalx=%.3f %.3f %.3f cellsize=%.3f timeResolution=%.3f nomvel=%.3f timetoturn=%.3f, obsthresh=%d\n",
02601 width, height, startx, starty, starttheta, startTime, goalx, goaly, goaltheta, cellsize_m, timeResolution, nominalvel_mpersecs, timetoturn45degsinplace_secs, obsthresh);
02602
02603 SBPL_PRINTF("perimeter has size=%d\n", (int)perimeterptsV.size());
02604
02605 for(int i = 0; i < (int)perimeterptsV.size(); i++)
02606 {
02607 SBPL_PRINTF("perimeter(%d) = %.4f %.4f\n", i, perimeterptsV.at(i).x, perimeterptsV.at(i).y);
02608 }
02609
02610
02611 envDBubbleLatCfg.obsthresh = obsthresh;
02612 envDBubbleLatCfg.dynamic_obstacle_collision_cost_thresh = dynobsthresh;
02613
02614
02615
02616 SetConfiguration(width, height,
02617 mapdata,
02618 CONTXY2DISC(startx, cellsize_m), CONTXY2DISC(starty, cellsize_m), ContTheta2Disc(starttheta, ENVDBUBBLELAT_THETADIRS), CONTTIME2DISC(startTime, timeResolution),
02619 CONTXY2DISC(goalx, cellsize_m), CONTXY2DISC(goaly, cellsize_m), ContTheta2Disc(goaltheta, ENVDBUBBLELAT_THETADIRS),
02620 cellsize_m, timeResolution, nominalvel_mpersecs, timetoturn45degsinplace_secs, perimeterptsV);
02621
02622 if(sMotPrimFile != NULL)
02623 {
02624 FILE* fMotPrim = fopen(sMotPrimFile, "r");
02625 if(fMotPrim == NULL)
02626 {
02627 SBPL_ERROR("ERROR: unable to open %s\n", sMotPrimFile);
02628 throw new SBPL_Exception();
02629 }
02630
02631 if(ReadMotionPrimitives(fMotPrim) == false)
02632 {
02633 SBPL_ERROR("ERROR: failed to read in motion primitive file\n");
02634 throw new SBPL_Exception();
02635 }
02636 }
02637
02638 if(envDBubbleLatCfg.mprimV.size() != 0)
02639 {
02640 InitGeneral(&envDBubbleLatCfg.mprimV);
02641 }
02642 else
02643 InitGeneral(NULL);
02644
02645 return true;
02646 }
02647
02648
02649 bool EnvDBubbleLattice::InitGeneral(vector<SBPL_xythetatimebubble_mprimitive>* motionprimitiveV) {
02650
02651
02652
02653 InitializeEnvConfig(motionprimitiveV);
02654
02655
02656 InitializeEnvironment();
02657
02658
02659 ComputeHeuristicValues();
02660
02661 return true;
02662 }
02663
02664 bool EnvDBubbleLattice::InitializeMDPCfg(MDPConfig *MDPCfg)
02665 {
02666
02667 MDPCfg->goalstateid = envDBubbleLat.goalstateid;
02668 MDPCfg->startstateid = envDBubbleLat.startstateid;
02669
02670 return true;
02671 }
02672
02673
02674 void EnvDBubbleLattice::PrintHeuristicValues()
02675 {
02676 FILE* fHeur = fopen("heur.txt", "w");
02677 SBPL2DGridSearch* grid2Dsearch = NULL;
02678
02679 for(int i = 0; i < 2; i++)
02680 {
02681 if(i == 0 && grid2Dsearchfromstart != NULL)
02682 {
02683 grid2Dsearch = grid2Dsearchfromstart;
02684 SBPL_FPRINTF(fHeur, "start heuristics:\n");
02685 }
02686 else if(i == 1 && grid2Dsearchfromgoal != NULL)
02687 {
02688 grid2Dsearch = grid2Dsearchfromgoal;
02689 SBPL_FPRINTF(fHeur, "goal heuristics:\n");
02690 }
02691 else
02692 continue;
02693
02694 for (int y = 0; y < envDBubbleLatCfg.EnvHeight_c; y++) {
02695 for (int x = 0; x < envDBubbleLatCfg.EnvWidth_c; x++) {
02696 if(grid2Dsearch->getlowerboundoncostfromstart_inmm(x, y) < INFINITECOST)
02697 SBPL_FPRINTF(fHeur, "%5d ", grid2Dsearch->getlowerboundoncostfromstart_inmm(x, y));
02698 else
02699 SBPL_FPRINTF(fHeur, "XXXXX ");
02700 }
02701 SBPL_FPRINTF(fHeur, "\n");
02702 }
02703 }
02704 fclose(fHeur);
02705 }
02706
02707
02708
02709
02710 void EnvDBubbleLattice::SetAllPreds(CMDPSTATE* state)
02711 {
02712
02713
02714 SBPL_ERROR("ERROR in envDBubbleLat... function: SetAllPreds is undefined\n");
02715 throw new SBPL_Exception();
02716 }
02717
02718
02719 void EnvDBubbleLattice::GetSuccs(int SourceStateID, vector<int>* SuccIDV, vector<int>* CostV)
02720 {
02721 GetSuccs(SourceStateID, SuccIDV, CostV, NULL, NULL, NULL);
02722 }
02723
02724
02725 void EnvDBubbleLattice::GetSuccs(int SourceStateID, vector<int>* SuccIDV, vector<int>* CostV, vector<int>* stateBubbles, vector<int>* bubbleCollisions)
02726 {
02727 GetSuccs(SourceStateID, SuccIDV, CostV, stateBubbles, bubbleCollisions, NULL);
02728 }
02729
02730
02731
02732 const envDBubbleLatConfig_t* EnvDBubbleLattice::GetEnvNavConfig() {
02733 return &envDBubbleLatCfg;
02734 }
02735
02736
02737
02738 bool EnvDBubbleLattice::UpdateCost(int x, int y, unsigned char newcost)
02739 {
02740
02741 #if DEBUG
02742 SBPL_FPRINTF(fDeb, "Cost updated for cell %d %d from old cost=%d to new cost=%d\n", x,y,envDBubbleLatCfg.Grid2D[x][y], newcost);
02743 #endif
02744
02745 envDBubbleLatCfg.Grid2D[x][y] = newcost;
02746
02747 bNeedtoRecomputeStartHeuristics = true;
02748 bNeedtoRecomputeGoalHeuristics = true;
02749
02750 return true;
02751 }
02752
02753
02754 void EnvDBubbleLattice::PrintEnv_Config(FILE* fOut)
02755 {
02756
02757
02758
02759 SBPL_ERROR("ERROR in envDBubbleLat... function: PrintEnv_Config is undefined\n");
02760 throw new SBPL_Exception();
02761
02762 }
02763
02764 void EnvDBubbleLattice::PrintTimeStat(FILE* fOut)
02765 {
02766
02767 #if TIME_DEBUG
02768 SBPL_FPRINTF(fOut, "time3_addallout = %f secs, time_gethash = %f secs, time_createhash = %f secs, time_getsuccs = %f\n",
02769 time3_addallout/(double)CLOCKS_PER_SEC, time_gethash/(double)CLOCKS_PER_SEC,
02770 time_createhash/(double)CLOCKS_PER_SEC, time_getsuccs/(double)CLOCKS_PER_SEC);
02771 #endif
02772 }
02773
02774
02775
02776 bool EnvDBubbleLattice::IsObstacle(int x, int y)
02777 {
02778
02779 #if DEBUG
02780 SBPL_FPRINTF(fDeb, "Status of cell %d %d is queried. Its cost=%d\n", x,y,envDBubbleLatCfg.Grid2D[x][y]);
02781 #endif
02782
02783
02784 return (envDBubbleLatCfg.Grid2D[x][y] >= envDBubbleLatCfg.obsthresh);
02785
02786 }
02787
02788 int EnvDBubbleLattice::getStartID(){
02789 return envDBubbleLat.startstateid;
02790 }
02791
02792 int EnvDBubbleLattice::getGoalID(){
02793 return envDBubbleLat.goalstateid;
02794 }
02795
02796 void EnvDBubbleLattice::GetEnvParms(int *size_x, int *size_y, double* startx, double* starty, double*starttheta, double* startTime, double* goalx, double* goaly, double* goaltheta,
02797 double* cellsize_m, double* timeResolution, double* nominalvel_mpersecs, double* timetoturn45degsinplace_secs, unsigned char* obsthresh, unsigned char* dyn_obs_thresh,
02798 vector<SBPL_xythetatimebubble_mprimitive>* mprimitiveV)
02799 {
02800 *size_x = envDBubbleLatCfg.EnvWidth_c;
02801 *size_y = envDBubbleLatCfg.EnvHeight_c;
02802
02803 *startx = DISCXY2CONT(envDBubbleLatCfg.StartX_c, envDBubbleLatCfg.cellsize_m);
02804 *starty = DISCXY2CONT(envDBubbleLatCfg.StartY_c, envDBubbleLatCfg.cellsize_m);
02805 *starttheta = DiscTheta2Cont(envDBubbleLatCfg.StartTheta, ENVDBUBBLELAT_THETADIRS);
02806 *startTime = DISCTIME2CONT(envDBubbleLatCfg.StartTime, envDBubbleLatCfg.timeResolution);
02807 *goalx = DISCXY2CONT(envDBubbleLatCfg.EndX_c, envDBubbleLatCfg.cellsize_m);
02808 *goaly = DISCXY2CONT(envDBubbleLatCfg.EndY_c, envDBubbleLatCfg.cellsize_m);
02809 *goaltheta = DiscTheta2Cont(envDBubbleLatCfg.EndTheta, ENVDBUBBLELAT_THETADIRS);
02810
02811 *cellsize_m = envDBubbleLatCfg.cellsize_m;
02812 *timeResolution = envDBubbleLatCfg.timeResolution;
02813 *nominalvel_mpersecs = envDBubbleLatCfg.nominalvel_mpersecs;
02814 *timetoturn45degsinplace_secs = envDBubbleLatCfg.timetoturn45degsinplace_secs;
02815
02816 *dyn_obs_thresh = envDBubbleLatCfg.dynamic_obstacle_collision_cost_thresh;
02817 *obsthresh = envDBubbleLatCfg.obsthresh;
02818
02819 *mprimitiveV = envDBubbleLatCfg.mprimV;
02820 }
02821
02822 bool EnvDBubbleLattice::PoseContToDisc(double px, double py, double pth, double pt,
02823 int &ix, int &iy, int &ith, int &it) const
02824 {
02825 ix = CONTXY2DISC(px, envDBubbleLatCfg.cellsize_m);
02826 iy = CONTXY2DISC(py, envDBubbleLatCfg.cellsize_m);
02827 ith = ContTheta2Disc(pth, ENVDBUBBLELAT_THETADIRS);
02828 it = CONTTIME2DISC(pt, envDBubbleLatCfg.timeResolution);
02829 return (pth >= -2*PI_CONST) && (pth <= 2*PI_CONST)
02830 && (ix >= 0) && (ix < envDBubbleLatCfg.EnvWidth_c)
02831 && (iy >= 0) && (iy < envDBubbleLatCfg.EnvHeight_c);
02832 }
02833
02834 bool EnvDBubbleLattice::PoseDiscToCont(int ix, int iy, int ith, int it,
02835 double &px, double &py, double &pth, double &pt) const
02836 {
02837 px = DISCXY2CONT(ix, envDBubbleLatCfg.cellsize_m);
02838 py = DISCXY2CONT(iy, envDBubbleLatCfg.cellsize_m);
02839 pth = normalizeAngle(DiscTheta2Cont(ith, ENVDBUBBLELAT_THETADIRS));
02840 pt = DISCTIME2CONT(it, envDBubbleLatCfg.timeResolution);
02841 return (ith >= 0) && (ith < ENVDBUBBLELAT_THETADIRS)
02842 && (ix >= 0) && (ix < envDBubbleLatCfg.EnvWidth_c)
02843 && (iy >= 0) && (iy < envDBubbleLatCfg.EnvHeight_c);
02844 }
02845
02846 unsigned char EnvDBubbleLattice::GetMapCost(int x, int y)
02847 {
02848 return envDBubbleLatCfg.Grid2D[x][y];
02849 }
02850
02851
02852
02853 bool EnvDBubbleLattice::SetEnvParameter(const char* parameter, int value)
02854 {
02855
02856 if(envDBubbleLat.bInitialized == true)
02857 {
02858 SBPL_ERROR("ERROR: all parameters must be set before initialization of the environment\n");
02859 return false;
02860 }
02861
02862 SBPL_PRINTF("setting parameter %s to %d\n", parameter, value);
02863
02864 if(strcmp(parameter, "cost_inscribed_thresh") == 0)
02865 {
02866 if(value < 0 || value > 255)
02867 {
02868 SBPL_ERROR("ERROR: invalid value %d for parameter %s\n", value, parameter);
02869 return false;
02870 }
02871 envDBubbleLatCfg.cost_inscribed_thresh = (unsigned char)value;
02872 }
02873 else if(strcmp(parameter, "cost_possibly_circumscribed_thresh") == 0)
02874 {
02875 if(value < 0 || value > 255)
02876 {
02877 SBPL_ERROR("ERROR: invalid value %d for parameter %s\n", value, parameter);
02878 return false;
02879 }
02880 envDBubbleLatCfg.cost_possibly_circumscribed_thresh = value;
02881 }
02882 else if(strcmp(parameter, "cost_obsthresh") == 0)
02883 {
02884 if(value < 0 || value > 255)
02885 {
02886 SBPL_ERROR("ERROR: invalid value %d for parameter %s\n", value, parameter);
02887 return false;
02888 }
02889 envDBubbleLatCfg.obsthresh = (unsigned char)value;
02890 }
02891 else if(strcmp(parameter, "cost_dyn_obs_thresh") == 0)
02892 {
02893 if(value < 0 || value > 255)
02894 {
02895 SBPL_ERROR("ERROR: invalid value %d for parameter %s\n", value, parameter);
02896 return false;
02897 }
02898 envDBubbleLatCfg.dynamic_obstacle_collision_cost_thresh = (unsigned char)value;
02899 }
02900 else
02901 {
02902 SBPL_ERROR("ERROR: invalid parameter %s\n", parameter);
02903 return false;
02904 }
02905
02906 return true;
02907 }
02908
02909 int EnvDBubbleLattice::GetEnvParameter(const char* parameter)
02910 {
02911
02912 if(strcmp(parameter, "cost_inscribed_thresh") == 0)
02913 {
02914 return (int) envDBubbleLatCfg.cost_inscribed_thresh;
02915 }
02916 else if(strcmp(parameter, "cost_possibly_circumscribed_thresh") == 0)
02917 {
02918 return (int) envDBubbleLatCfg.cost_possibly_circumscribed_thresh;
02919 }
02920 else if(strcmp(parameter, "cost_obsthresh") == 0)
02921 {
02922 return (int) envDBubbleLatCfg.obsthresh;
02923 }
02924 else if(strcmp(parameter, "cost_dyn_obs_thresh") == 0)
02925 {
02926 return (int) envDBubbleLatCfg.dynamic_obstacle_collision_cost_thresh;
02927 }
02928 else
02929 {
02930 SBPL_ERROR("ERROR: invalid parameter %s\n", parameter);
02931 throw new SBPL_Exception();
02932 }
02933
02934 }
02935
02936
02937
02938
02939
02940
02941 void EnvDBubbleLat::GetCoordFromState(int stateID, int& x, int& y, int& theta, int& t) const {
02942 envDBubbleLatHashEntry_t* HashEntry = StateID2CoordTable[stateID];
02943 x = HashEntry->X;
02944 y = HashEntry->Y;
02945 theta = HashEntry->Theta;
02946 t = HashEntry->T;
02947 }
02948
02949 int EnvDBubbleLat::GetStateFromCoord(int x, int y, int theta, int t){
02950
02951 envDBubbleLatHashEntry_t* OutHashEntry;
02952 if((OutHashEntry = GetHashEntry(x, y, theta, t, isInBubble(x,y,t))) == NULL){
02953
02954 OutHashEntry = CreateNewHashEntry(x, y, theta, t, isInBubble(x,y,t));
02955 }
02956 return OutHashEntry->stateID;
02957 }
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025
03026 void EnvDBubbleLat::ConvertStateIDPathintoXYThetaPath(vector<int>* stateIDPath, vector<SBPL_4Dpt_t>* xythetaPath)
03027 {
03028 vector<envDBubbleLatAction_t*> actionV;
03029 vector<int> CostV;
03030 vector<int> SuccIDV;
03031 int targetx_c, targety_c, targettheta_c;
03032 int sourcex_c, sourcey_c, sourcetheta_c;
03033 int targett_c, sourcet_c;
03034
03035
03036
03037 xythetaPath->clear();
03038
03039 #if DEBUG
03040 SBPL_FPRINTF(fDeb, "converting stateid path into coordinates:\n");
03041 #endif
03042
03043 for(int pind = 0; pind < (int)(stateIDPath->size())-1; pind++)
03044 {
03045 int sourceID = stateIDPath->at(pind);
03046
03047
03048 int targetID = stateIDPath->at(pind+1);
03049
03050 #if DEBUG
03051 GetCoordFromState(sourceID, sourcex_c, sourcey_c, sourcetheta_c, sourcet_c);
03052 #endif
03053
03054
03055
03056 SuccIDV.clear();
03057 CostV.clear();
03058 actionV.clear();
03059 GetSuccs(sourceID, &SuccIDV, &CostV, NULL, NULL, &actionV);
03060
03061 int bestcost = INFINITECOST;
03062 int bestsind = -1;
03063
03064 #if DEBUG
03065 GetCoordFromState(sourceID, sourcex_c, sourcey_c, sourcetheta_c, sourcet_c);
03066 GetCoordFromState(targetID, targetx_c, targety_c, targettheta_c, targett_c);
03067 SBPL_FPRINTF(fDeb, "looking for %d %d %d %d -> %d %d %d %d (numofsuccs=%d)\n", sourcex_c, sourcey_c, sourcetheta_c, sourcet_c
03068 targetx_c, targety_c, targettheta_c, targett_c, SuccIDV.size());
03069
03070 #endif
03071
03072
03073 for(int sind = 0; sind < (int)SuccIDV.size(); sind++)
03074 {
03075
03076 #if DEBUG
03077 int x_c, y_c, theta_c, t_c;
03078 GetCoordFromState(SuccIDV[sind], x_c, y_c, theta_c, t_c);
03079 SBPL_FPRINTF(fDeb, "succ: %d %d %d %d\n", x_c, y_c, theta_c, t_c);
03080 #endif
03081
03082 if(SuccIDV[sind] == targetID && CostV[sind] <= bestcost)
03083 {
03084 bestcost = CostV[sind];
03085 bestsind = sind;
03086 }
03087 }
03088 if(bestsind == -1)
03089 {
03090 SBPL_ERROR("ERROR: successor not found for transition:\n");
03091 GetCoordFromState(sourceID, sourcex_c, sourcey_c, sourcetheta_c, sourcet_c);
03092 GetCoordFromState(targetID, targetx_c, targety_c, targettheta_c, targett_c);
03093 SBPL_PRINTF("ID=%d %d %d %d %d -> ID=%d %d %d %d %d\n", sourceID, sourcex_c, sourcey_c, sourcetheta_c, sourcet_c,
03094 targetID, targetx_c, targety_c, targettheta_c, targett_c);
03095 throw new SBPL_Exception();
03096 }
03097
03098
03099 int sourcex_c, sourcey_c, sourcetheta_c;
03100 int sourcet_c;
03101 GetCoordFromState(sourceID, sourcex_c, sourcey_c, sourcetheta_c, sourcet_c);
03102 double sourcex, sourcey, sourcet;
03103 sourcex = DISCXY2CONT(sourcex_c, envDBubbleLatCfg.cellsize_m);
03104 sourcey = DISCXY2CONT(sourcey_c, envDBubbleLatCfg.cellsize_m);
03105 sourcet = DISCTIME2CONT(sourcet_c, envDBubbleLatCfg.timeResolution);
03106
03107 for(int ipind = 0; ipind < ((int)actionV[bestsind]->intermptV.size())-1; ipind++)
03108 {
03109
03110 SBPL_4Dpt_t intermpt = actionV[bestsind]->intermptV[ipind];
03111 intermpt.x += sourcex;
03112 intermpt.y += sourcey;
03113 intermpt.t += sourcet;
03114
03115 #if DEBUG
03116 int nx = CONTXY2DISC(intermpt.x, envDBubbleLatCfg.cellsize_m);
03117 int ny = CONTXY2DISC(intermpt.y, envDBubbleLatCfg.cellsize_m);
03118 int nt = CONTTIME2DISC(intermpt.t, envDBubbleLatCfg.timeResolution);
03119 SBPL_FPRINTF(fDeb, "%.3f %.3f %.3f %.3f (%d %d %d cost=%d) ",
03120 intermpt.x, intermpt.y, intermpt.theta, intermpt.t
03121 nx, ny,
03122 ContTheta2Disc(intermpt.theta, ENVDBUBBLELAT_THETADIRS), nt, envDBubbleLatCfg.Grid2D[nx][ny]);
03123 if(ipind == 0) SBPL_FPRINTF(fDeb, "first (heur=%d)\n", GetStartHeuristic(sourceID));
03124 else SBPL_FPRINTF(fDeb, "\n");
03125 #endif
03126
03127
03128 xythetaPath->push_back(intermpt);
03129 }
03130 }
03131 }
03132
03133
03134
03135 int EnvDBubbleLat::SetGoal(double x_m, double y_m, double theta_rad){
03136
03137 int x = CONTXY2DISC(x_m, envDBubbleLatCfg.cellsize_m);
03138 int y = CONTXY2DISC(y_m, envDBubbleLatCfg.cellsize_m);
03139 int theta = ContTheta2Disc(theta_rad, ENVDBUBBLELAT_THETADIRS);
03140
03141 SBPL_PRINTF("env: setting goal to %.3f %.3f %.3f (%d %d %d)\n", x_m, y_m, theta_rad, x, y, theta);
03142
03143 if(!IsWithinMapCell(x,y))
03144 {
03145 SBPL_ERROR("ERROR: trying to set a goal cell %d %d that is outside of map\n", x,y);
03146 return -1;
03147 }
03148
03149 if(!IsValidConfiguration(x,y,theta))
03150 {
03151 SBPL_PRINTF("WARNING: goal configuration is invalid\n");
03152 }
03153
03154 envDBubbleLatHashEntry_t* OutHashEntry;
03155 if((OutHashEntry = GetHashEntry(x, y, theta, INFINITECOST, false)) == NULL){
03156
03157 OutHashEntry = CreateNewHashEntry(x, y, theta, INFINITECOST, false);
03158 }
03159
03160
03161
03162 int oldGoalX, oldGoalY, oldGoalTheta;
03163 int oldGoalT;
03164 GetCoordFromState(envDBubbleLat.goalstateid, oldGoalX, oldGoalY, oldGoalTheta, oldGoalT);
03165 if(oldGoalX != x || oldGoalY != y || oldGoalTheta != theta)
03166 {
03167 bNeedtoRecomputeStartHeuristics = true;
03168 bNeedtoRecomputeGoalHeuristics = true;
03169 }
03170
03171
03172
03173 envDBubbleLat.goalstateid = OutHashEntry->stateID;
03174
03175 envDBubbleLatCfg.EndX_c = x;
03176 envDBubbleLatCfg.EndY_c = y;
03177 envDBubbleLatCfg.EndTheta = theta;
03178
03179
03180 return envDBubbleLat.goalstateid;
03181
03182 }
03183
03184
03185
03186 int EnvDBubbleLat::SetStart(double x_m, double y_m, double theta_rad, double startTime){
03187
03188 int x = CONTXY2DISC(x_m, envDBubbleLatCfg.cellsize_m);
03189 int y = CONTXY2DISC(y_m, envDBubbleLatCfg.cellsize_m);
03190 int theta = ContTheta2Disc(theta_rad, ENVDBUBBLELAT_THETADIRS);
03191 int t = CONTTIME2DISC(startTime, envDBubbleLatCfg.timeResolution);
03192
03193 if(!IsWithinMapCell(x,y))
03194 {
03195 SBPL_ERROR("ERROR: trying to set a start cell %d %d that is outside of map\n", x,y);
03196 return -1;
03197 }
03198
03199 SBPL_PRINTF("env: setting start to %.3f %.3f %.3f %.3f (%d %d %d %d)\n", x_m, y_m, theta_rad, startTime, x, y, theta, t);
03200
03201 if(!IsValidConfiguration(x,y,theta))
03202 {
03203 SBPL_PRINTF("WARNING: start configuration %d %d %d is invalid\n", x,y,theta);
03204 }
03205
03206 envDBubbleLatHashEntry_t* OutHashEntry;
03207 if((OutHashEntry = GetHashEntry(x, y, theta, t, false)) == NULL){
03208
03209 OutHashEntry = CreateNewHashEntry(x, y, theta, t, false);
03210 }
03211
03212
03213
03214 int oldStartX, oldStartY, oldStartTheta;
03215 int oldStartT;
03216 GetCoordFromState(envDBubbleLat.startstateid, oldStartX, oldStartY, oldStartTheta, oldStartT);
03217 if(oldStartX != x || oldStartY != y || oldStartTheta != theta)
03218 {
03219 bNeedtoRecomputeStartHeuristics = true;
03220 bNeedtoRecomputeGoalHeuristics = true;
03221 }
03222
03223
03224 envDBubbleLat.startstateid = OutHashEntry->stateID;
03225 envDBubbleLatCfg.StartX_c = x;
03226 envDBubbleLatCfg.StartY_c = y;
03227 envDBubbleLatCfg.StartTheta = theta;
03228 envDBubbleLatCfg.StartTime = t;
03229
03230 return envDBubbleLat.startstateid;
03231
03232 }
03233
03234 bool EnvDBubbleLat::setDynamicObstacles(vector<SBPL_DynamicObstacle_t> dynObs, bool reset_states){
03235 dynamicObstacles.clear();
03236 for(unsigned int i=0; i<dynObs.size(); i++){
03237 SBPL_DynamicObstacle_t obs;
03238 obs.radius = dynObs[i].radius + envDBubbleLatCfg.robotRadius;
03239 for(unsigned int j=0; j<dynObs[i].trajectories.size(); j++){
03240 SBPL_Trajectory_t traj;
03241 traj.prob = dynObs[i].trajectories[j].prob;
03242 traj.existsAfter = dynObs[i].trajectories[j].existsAfter;
03243 for(unsigned int k=0; k<dynObs[i].trajectories[j].points.size(); k++){
03244 SBPL_Traj_Pt_t p;
03245 p.x = dynObs[i].trajectories[j].points[k].x;
03246 p.y = dynObs[i].trajectories[j].points[k].y;
03247 p.t = dynObs[i].trajectories[j].points[k].t;
03248 p.std_dev = dynObs[i].trajectories[j].points[k].std_dev;
03249 traj.points.push_back(p);
03250
03251 }
03252 obs.trajectories.push_back(traj);
03253 }
03254 dynamicObstacles.push_back(obs);
03255 }
03256 SBPL_PRINTF("we have %d dynamic obstacles\n", (int)dynamicObstacles.size());
03257
03258
03259
03260
03261 UpdateBubbleMap();
03262 return true;
03263 }
03264
03265 void EnvDBubbleLat::PrintState(int stateID, bool bVerbose, FILE* fOut )
03266 {
03267 #if DEBUG
03268 if(stateID >= (int)StateID2CoordTable.size())
03269 {
03270 SBPL_ERROR("ERROR in envDBubbleLat... function: stateID illegal (2)\n");
03271 throw new SBPL_Exception();
03272 }
03273 #endif
03274
03275 if(fOut == NULL)
03276 fOut = stdout;
03277
03278 envDBubbleLatHashEntry_t* HashEntry = StateID2CoordTable[stateID];
03279 envDBubbleLatHashEntry_t* GoalHashEntry = StateID2CoordTable[envDBubbleLat.goalstateid];
03280
03281 if(HashEntry->X == GoalHashEntry->X && HashEntry->Y == GoalHashEntry->Y && HashEntry->Theta == GoalHashEntry->Theta && bVerbose)
03282 {
03283 SBPL_FPRINTF(fOut, "the state is a goal state\n");
03284 }
03285
03286 if(bVerbose)
03287 SBPL_FPRINTF(fOut, "X=%d Y=%d Theta=%d T=%d\n", HashEntry->X, HashEntry->Y, HashEntry->Theta, HashEntry->T);
03288 else
03289 SBPL_FPRINTF(fOut, "%.3f %.3f %.3f %.3f\n", DISCXY2CONT(HashEntry->X, envDBubbleLatCfg.cellsize_m), DISCXY2CONT(HashEntry->Y,envDBubbleLatCfg.cellsize_m),
03290 DiscTheta2Cont(HashEntry->Theta, ENVDBUBBLELAT_THETADIRS), DISCTIME2CONT(HashEntry->T, envDBubbleLatCfg.timeResolution));
03291
03292 }
03293
03294
03295 envDBubbleLatHashEntry_t* EnvDBubbleLat::GetHashEntry(int X, int Y, int Theta, int T, bool inBubble)
03296 {
03297
03298 #if TIME_DEBUG
03299 clock_t currenttime = clock();
03300 #endif
03301
03302 int binid;
03303 if(!inBubble)
03304 binid = GETHASHBIN(X, Y, Theta, -1);
03305 else
03306 binid = GETHASHBIN(X, Y, Theta, T);
03307
03308 #if DEBUG
03309 if ((int)Coord2StateIDHashTable[binid].size() > 500)
03310 {
03311 SBPL_PRINTF("WARNING: Hash table has a bin %d (X=%d Y=%d) of size %d\n",
03312 binid, X, Y, Coord2StateIDHashTable[binid].size());
03313
03314 PrintHashTableHist();
03315 }
03316 #endif
03317
03318
03319 if(inBubble){
03320 for(int ind = 0; ind < (int)Coord2StateIDHashTable[binid].size(); ind++)
03321 {
03322 if( Coord2StateIDHashTable[binid][ind]->X == X
03323 && Coord2StateIDHashTable[binid][ind]->Y == Y
03324 && Coord2StateIDHashTable[binid][ind]->Theta == Theta
03325 && Coord2StateIDHashTable[binid][ind]->T == T
03326 && Coord2StateIDHashTable[binid][ind]->inBubble == inBubble)
03327 {
03328 #if TIME_DEBUG
03329 time_gethash += clock()-currenttime;
03330 #endif
03331 return Coord2StateIDHashTable[binid][ind];
03332 }
03333 }
03334 }
03335 else{
03336 for(int ind = 0; ind < (int)Coord2StateIDHashTable[binid].size(); ind++)
03337 {
03338 if( Coord2StateIDHashTable[binid][ind]->X == X
03339 && Coord2StateIDHashTable[binid][ind]->Y == Y
03340 && Coord2StateIDHashTable[binid][ind]->Theta == Theta
03341 && Coord2StateIDHashTable[binid][ind]->inBubble == inBubble)
03342 {
03343 #if TIME_DEBUG
03344 time_gethash += clock()-currenttime;
03345 #endif
03346 return Coord2StateIDHashTable[binid][ind];
03347 }
03348 }
03349
03350 }
03351
03352 #if TIME_DEBUG
03353 time_gethash += clock()-currenttime;
03354 #endif
03355
03356 return NULL;
03357 }
03358
03359
03360 envDBubbleLatHashEntry_t* EnvDBubbleLat::CreateNewHashEntry(int X, int Y, int Theta, int T, bool inBubble)
03361 {
03362 int i;
03363
03364 #if TIME_DEBUG
03365 clock_t currenttime = clock();
03366 #endif
03367
03368 envDBubbleLatHashEntry_t* HashEntry = new envDBubbleLatHashEntry_t;
03369
03370 HashEntry->X = X;
03371 HashEntry->Y = Y;
03372 HashEntry->Theta = Theta;
03373 HashEntry->inBubble = inBubble;
03374 HashEntry->T = T;
03375 HashEntry->iteration = 0;
03376
03377 HashEntry->stateID = StateID2CoordTable.size();
03378
03379
03380 StateID2CoordTable.push_back(HashEntry);
03381
03382
03383
03384 if(HashEntry->inBubble)
03385 i = GETHASHBIN(HashEntry->X, HashEntry->Y, HashEntry->Theta, HashEntry->T);
03386 else
03387 i = GETHASHBIN(HashEntry->X, HashEntry->Y, HashEntry->Theta, -1);
03388
03389
03390
03391 Coord2StateIDHashTable[i].push_back(HashEntry);
03392
03393
03394 int* entry = new int [NUMOFINDICES_STATEID2IND];
03395 StateID2IndexMapping.push_back(entry);
03396 for(i = 0; i < NUMOFINDICES_STATEID2IND; i++)
03397 {
03398 StateID2IndexMapping[HashEntry->stateID][i] = -1;
03399 }
03400
03401 if(HashEntry->stateID != (int)StateID2IndexMapping.size()-1)
03402 {
03403 SBPL_ERROR("ERROR in Env... function: last state has incorrect stateID\n");
03404 throw new SBPL_Exception();
03405 }
03406
03407 #if TIME_DEBUG
03408 time_createhash += clock()-currenttime;
03409 #endif
03410
03411 return HashEntry;
03412 }
03413
03414
03415 bool EnvDBubbleLattice::isInBubble(int x, int y, int t){
03416
03417
03418 return x >= 0 && x < envDBubbleLatCfg.EnvWidth_c &&
03419 y >= 0 && y < envDBubbleLatCfg.EnvHeight_c &&
03420 bubblemap[x][y].dynObs.size() > 0 && bubblemap[x][y].lastObsT >= t;
03421 }
03422
03423 void EnvDBubbleLat::GetSuccs(int SourceStateID, vector<int>* SuccIDV, vector<int>* CostV, vector<int>* stateBubbles , vector<int>* bubbleCollisions , vector<envDBubbleLatAction_t*>* actionV )
03424 {
03425 int aind;
03426
03427 #if TIME_DEBUG
03428 clock_t currenttime = clock();
03429 #endif
03430
03431
03432 SuccIDV->clear();
03433 CostV->clear();
03434 SuccIDV->reserve(envDBubbleLatCfg.actionwidth);
03435 CostV->reserve(envDBubbleLatCfg.actionwidth);
03436 if(actionV != NULL)
03437 {
03438 actionV->clear();
03439 actionV->reserve(envDBubbleLatCfg.actionwidth);
03440 }
03441
03442
03443 envDBubbleLatHashEntry_t* HashEntry = StateID2CoordTable[SourceStateID];
03444 envDBubbleLatHashEntry_t* GoalHashEntry = StateID2CoordTable[envDBubbleLat.goalstateid];
03445
03446
03447
03448 if(actionV != NULL)
03449 SBPL_PRINTF("stateid=%d x=%d, y=%d, theta=%d, t=%d bubble=%d\n",SourceStateID,HashEntry->X,HashEntry->Y,HashEntry->Theta,HashEntry->T,HashEntry->inBubble);
03450
03451 if(SourceStateID == envDBubbleLat.goalstateid){
03452 return;
03453 }
03454
03455
03456 for (aind = 0; aind < envDBubbleLatCfg.actionwidth; aind++)
03457 {
03458
03459
03460 if(aind == envDBubbleLatCfg.actionwidth-1 && !isInBubble(HashEntry->X, HashEntry->Y, HashEntry->T) )
03461 break;
03462 else if(aind == envDBubbleLatCfg.actionwidth-1 && isInBubble(HashEntry->X, HashEntry->Y, HashEntry->T) ){
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476 }
03477
03478
03479 envDBubbleLatAction_t* nav4daction = &envDBubbleLatCfg.ActionsV[(int)HashEntry->Theta][aind];
03480 int newX = HashEntry->X + nav4daction->dX;
03481 int newY = HashEntry->Y + nav4daction->dY;
03482 int newTheta = NORMALIZEDISCTHETA(nav4daction->endtheta, ENVDBUBBLELAT_THETADIRS);
03483 int newT = HashEntry->T + nav4daction->dT;
03484
03485
03486 if(!IsValidCell(newX, newY))
03487 continue;
03488
03489 bool newInBubble = isInBubble(newX, newY, newT);
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511 int cost = GetActionCost(HashEntry->X, HashEntry->Y, HashEntry->Theta, HashEntry->T, nav4daction, bubbleCollisions);
03512 if(cost >= INFINITECOST)
03513 continue;
03514
03515 envDBubbleLatHashEntry_t* OutHashEntry;
03516
03517 if(newX == GoalHashEntry->X &&
03518 newY == GoalHashEntry->Y &&
03519 newTheta == GoalHashEntry->Theta){
03520 OutHashEntry = GoalHashEntry;
03521 }
03522 else if((OutHashEntry = GetHashEntry(newX, newY, newTheta, newT, newInBubble)) == NULL){
03523
03524 OutHashEntry = CreateNewHashEntry(newX, newY, newTheta, newT, newInBubble);
03525 }
03526
03527
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540 SuccIDV->push_back(OutHashEntry->stateID);
03541
03542 if(actionV != NULL)
03543 SBPL_PRINTF(" stateID:=%d x=%d y=%d theta=%d t=%d bubble=%d h=%d cost=%d\n", OutHashEntry->stateID, newX, newY, newTheta, newT, OutHashEntry->inBubble, GetGoalHeuristic(OutHashEntry->stateID), cost);
03544 CostV->push_back(cost);
03545 if(actionV != NULL)
03546 actionV->push_back(nav4daction);
03547 }
03548
03549 #if TIME_DEBUG
03550 time_getsuccs += clock()-currenttime;
03551 #endif
03552
03553 }
03554
03555 void EnvDBubbleLat::Relax(int sourceID, int targetID){
03556 envDBubbleLatHashEntry_t* TargetEntry = StateID2CoordTable[targetID];
03557 if(TargetEntry->inBubble)
03558 return;
03559 envDBubbleLatHashEntry_t* HashEntry = StateID2CoordTable[sourceID];
03560
03561 for (int aind = 0; aind < envDBubbleLatCfg.actionwidth-1; aind++){
03562
03563 envDBubbleLatAction_t* nav4daction = &envDBubbleLatCfg.ActionsV[(int)HashEntry->Theta][aind];
03564 int newX = HashEntry->X + nav4daction->dX;
03565 int newY = HashEntry->Y + nav4daction->dY;
03566 int newTheta = NORMALIZEDISCTHETA(nav4daction->endtheta, ENVDBUBBLELAT_THETADIRS);
03567 int newT = HashEntry->T + nav4daction->dT;
03568
03569 if(GetHashEntry(newX, newY, newTheta, newT, false) == TargetEntry){
03570 if(newT < TargetEntry->T)
03571 TargetEntry->T = newT;
03572 return;
03573 }
03574 }
03575
03576 }
03577
03578
03579
03580 void EnvDBubbleLat::GetPreds(int TargetStateID, vector<int>* PredIDV, vector<int>* CostV)
03581 {
03582
03583 SBPL_PRINTF("Error: This environment currently does not support backward planning!\n");
03584 throw new SBPL_Exception();
03585
03586
03587
03588
03589 int aind;
03590
03591 #if TIME_DEBUG
03592 clock_t currenttime = clock();
03593 #endif
03594
03595
03596 PredIDV->clear();
03597 CostV->clear();
03598 PredIDV->reserve(envDBubbleLatCfg.actionwidth);
03599 CostV->reserve(envDBubbleLatCfg.actionwidth);
03600
03601
03602 envDBubbleLatHashEntry_t* HashEntry = StateID2CoordTable[TargetStateID];
03603
03604
03605 bool bTestBounds = false;
03606 if(HashEntry->X == 0 || HashEntry->X == envDBubbleLatCfg.EnvWidth_c-1 ||
03607 HashEntry->Y == 0 || HashEntry->Y == envDBubbleLatCfg.EnvHeight_c-1)
03608 bTestBounds = true;
03609
03610 for (aind = 0; aind < (int)envDBubbleLatCfg.PredActionsV[(int)HashEntry->Theta].size(); aind++)
03611 {
03612
03613 envDBubbleLatAction_t* nav4daction = envDBubbleLatCfg.PredActionsV[(int)HashEntry->Theta].at(aind);
03614
03615 int predX = HashEntry->X - nav4daction->dX;
03616 int predY = HashEntry->Y - nav4daction->dY;
03617 int predTheta = nav4daction->starttheta;
03618 int predT = HashEntry->T - nav4daction->dT;
03619
03620
03621
03622 if(bTestBounds){
03623 if(!IsValidCell(predX, predY))
03624 continue;
03625 }
03626
03627
03628 int cost = GetActionCost(predX, predY, predTheta, predT, nav4daction);
03629 if(cost >= INFINITECOST)
03630 continue;
03631
03632 envDBubbleLatHashEntry_t* OutHashEntry;
03633 if((OutHashEntry = GetHashEntry(predX, predY, predTheta, predT, false)) == NULL)
03634 {
03635
03636 OutHashEntry = CreateNewHashEntry(predX, predY, predTheta, predT, false);
03637 }
03638
03639 PredIDV->push_back(OutHashEntry->stateID);
03640 CostV->push_back(cost);
03641 }
03642
03643 #if TIME_DEBUG
03644 time_getsuccs += clock()-currenttime;
03645 #endif
03646
03647
03648 }
03649
03650 void EnvDBubbleLat::SetAllActionsandAllOutcomes(CMDPSTATE* state)
03651 {
03652
03653 int cost;
03654
03655 #if DEBUG
03656 if(state->StateID >= (int)StateID2CoordTable.size())
03657 {
03658 SBPL_ERROR("ERROR in Env... function: stateID illegal\n");
03659 throw new SBPL_Exception();
03660 }
03661
03662 if((int)state->Actions.size() != 0)
03663 {
03664 SBPL_ERROR("ERROR in Env_setAllActionsandAllOutcomes: actions already exist for the state\n");
03665 throw new SBPL_Exception();
03666 }
03667 #endif
03668
03669
03670
03671 envDBubbleLatHashEntry_t* HashEntry = StateID2CoordTable[state->StateID];
03672 envDBubbleLatHashEntry_t* GoalHashEntry = StateID2CoordTable[envDBubbleLat.goalstateid];
03673
03674
03675 if(HashEntry->X == GoalHashEntry->X && HashEntry->Y == GoalHashEntry->Y && HashEntry->Theta == GoalHashEntry->Theta)
03676 return;
03677
03678
03679 bool bTestBounds = false;
03680 if(HashEntry->X == 0 || HashEntry->X == envDBubbleLatCfg.EnvWidth_c-1 ||
03681 HashEntry->Y == 0 || HashEntry->Y == envDBubbleLatCfg.EnvHeight_c-1)
03682 bTestBounds = true;
03683 for (int aind = 0; aind < envDBubbleLatCfg.actionwidth; aind++)
03684 {
03685 envDBubbleLatAction_t* nav4daction = &envDBubbleLatCfg.ActionsV[(int)HashEntry->Theta][aind];
03686 int newX = HashEntry->X + nav4daction->dX;
03687 int newY = HashEntry->Y + nav4daction->dY;
03688 int newTheta = NORMALIZEDISCTHETA(nav4daction->endtheta, ENVDBUBBLELAT_THETADIRS);
03689 int newT = HashEntry->T + nav4daction->dT;
03690
03691
03692 if(bTestBounds){
03693 if(!IsValidCell(newX, newY))
03694 continue;
03695 }
03696
03697
03698 cost = GetActionCost(HashEntry->X, HashEntry->Y, HashEntry->Theta, HashEntry->T, nav4daction);
03699 if(cost >= INFINITECOST)
03700 continue;
03701
03702
03703 CMDPACTION* action = state->AddAction(aind);
03704
03705 #if TIME_DEBUG
03706 clock_t currenttime = clock();
03707 #endif
03708
03709 envDBubbleLatHashEntry_t* OutHashEntry;
03710 if((OutHashEntry = GetHashEntry(newX, newY, newTheta, newT, false)) == NULL)
03711 {
03712
03713 OutHashEntry = CreateNewHashEntry(newX, newY, newTheta, newT, false);
03714 }
03715 action->AddOutcome(OutHashEntry->stateID, cost, 1.0);
03716
03717 #if TIME_DEBUG
03718 time3_addallout += clock()-currenttime;
03719 #endif
03720
03721 }
03722 }
03723
03724
03725 void EnvDBubbleLat::GetPredsofChangedEdges(vector<nav2dcell_t> const * changedcellsV, vector<int> *preds_of_changededgesIDV)
03726 {
03727 nav2dcell_t cell;
03728 SBPL_4Dcell_t affectedcell;
03729 envDBubbleLatHashEntry_t* affectedHashEntry;
03730
03731
03732 iteration++;
03733
03734 for(int i = 0; i < (int)changedcellsV->size(); i++)
03735 {
03736 cell = changedcellsV->at(i);
03737
03738
03739 for(int sind = 0; sind < (int)affectedpredstatesV.size(); sind++)
03740 {
03741 affectedcell = affectedpredstatesV.at(sind);
03742
03743
03744 affectedcell.x = affectedcell.x + cell.x;
03745 affectedcell.y = affectedcell.y + cell.y;
03746
03747
03748 affectedHashEntry = GetHashEntry(affectedcell.x, affectedcell.y, affectedcell.theta, affectedcell.t, false);
03749 if(affectedHashEntry != NULL && affectedHashEntry->iteration < iteration)
03750 {
03751 preds_of_changededgesIDV->push_back(affectedHashEntry->stateID);
03752 affectedHashEntry->iteration = iteration;
03753 }
03754 }
03755 }
03756 }
03757
03758 void EnvDBubbleLat::GetSuccsofChangedEdges(vector<nav2dcell_t> const * changedcellsV, vector<int> *succs_of_changededgesIDV)
03759 {
03760 nav2dcell_t cell;
03761 SBPL_4Dcell_t affectedcell;
03762 envDBubbleLatHashEntry_t* affectedHashEntry;
03763
03764 SBPL_ERROR("ERROR: getsuccs is not supported currently\n");
03765 throw new SBPL_Exception();
03766
03767
03768 iteration++;
03769
03770
03771 for(int i = 0; i < (int)changedcellsV->size(); i++)
03772 {
03773 cell = changedcellsV->at(i);
03774
03775
03776 for(int sind = 0; sind < (int)affectedsuccstatesV.size(); sind++)
03777 {
03778 affectedcell = affectedsuccstatesV.at(sind);
03779
03780
03781 affectedcell.x = affectedcell.x + cell.x;
03782 affectedcell.y = affectedcell.y + cell.y;
03783
03784
03785 affectedHashEntry = GetHashEntry(affectedcell.x, affectedcell.y, affectedcell.theta, affectedcell.t, false);
03786 if(affectedHashEntry != NULL && affectedHashEntry->iteration < iteration)
03787 {
03788 succs_of_changededgesIDV->push_back(affectedHashEntry->stateID);
03789 affectedHashEntry->iteration = iteration;
03790 }
03791 }
03792 }
03793 }
03794
03795 void EnvDBubbleLat::InitializeEnvironment()
03796 {
03797 envDBubbleLatHashEntry_t* HashEntry;
03798
03799
03800 HashTableSize = 64*1024;
03801 Coord2StateIDHashTable = new vector<envDBubbleLatHashEntry_t*>[HashTableSize];
03802
03803
03804 StateID2CoordTable.clear();
03805
03806
03807 HashEntry = CreateNewHashEntry(envDBubbleLatCfg.StartX_c, envDBubbleLatCfg.StartY_c, envDBubbleLatCfg.StartTheta, envDBubbleLatCfg.StartTime, false);
03808 envDBubbleLat.startstateid = HashEntry->stateID;
03809
03810
03811 HashEntry = CreateNewHashEntry(envDBubbleLatCfg.EndX_c, envDBubbleLatCfg.EndY_c, envDBubbleLatCfg.EndTheta, INFINITECOST, false);
03812 envDBubbleLat.goalstateid = HashEntry->stateID;
03813
03814
03815 envDBubbleLat.bInitialized = true;
03816
03817 }
03818
03819
03820
03821
03822
03823 unsigned int EnvDBubbleLat::GETHASHBIN(unsigned int X1, unsigned int X2, unsigned int Theta, unsigned int T)
03824 {
03825
03826 return inthash(inthash(X1)+(inthash(X2)<<1)+(inthash(Theta)<<2)+(inthash(T)<<3)) & (HashTableSize-1);
03827 }
03828
03829 void EnvDBubbleLat::PrintHashTableHist()
03830 {
03831 int s0=0, s1=0, s50=0, s100=0, s200=0, s300=0, slarge=0;
03832
03833 for(int j = 0; j < HashTableSize; j++)
03834 {
03835 if((int)Coord2StateIDHashTable[j].size() == 0)
03836 s0++;
03837 else if((int)Coord2StateIDHashTable[j].size() < 50)
03838 s1++;
03839 else if((int)Coord2StateIDHashTable[j].size() < 100)
03840 s50++;
03841 else if((int)Coord2StateIDHashTable[j].size() < 200)
03842 s100++;
03843 else if((int)Coord2StateIDHashTable[j].size() < 300)
03844 s200++;
03845 else if((int)Coord2StateIDHashTable[j].size() < 400)
03846 s300++;
03847 else
03848 slarge++;
03849 }
03850 SBPL_PRINTF("hash table histogram: 0:%d, <50:%d, <100:%d, <200:%d, <300:%d, <400:%d >400:%d\n",
03851 s0,s1, s50, s100, s200,s300,slarge);
03852 }
03853
03854 void EnvDBubbleLat::dumpStatesToFile(){
03855 FILE* fout = fopen("state_dump_bubble.txt", "w");
03856 for(unsigned int i=0; i<StateID2CoordTable.size(); i++){
03857 envDBubbleLatHashEntry_t* state = StateID2CoordTable[i];
03858 SBPL_FPRINTF(fout, "%d %d %d %d\n", state->X, state->Y, state->Theta, state->T);
03859 }
03860 fclose(fout);
03861 }
03862
03863 int EnvDBubbleLat::GetFromToHeuristic(int FromStateID, int ToStateID)
03864 {
03865
03866 #if USE_HEUR==0
03867 return 0;
03868 #endif
03869
03870
03871 #if DEBUG
03872 if(FromStateID >= (int)StateID2CoordTable.size()
03873 || ToStateID >= (int)StateID2CoordTable.size())
03874 {
03875 SBPL_ERROR("ERROR in envDBubbleLat... function: stateID illegal\n");
03876 throw new SBPL_Exception();
03877 }
03878 #endif
03879
03880
03881 envDBubbleLatHashEntry_t* FromHashEntry = StateID2CoordTable[FromStateID];
03882 envDBubbleLatHashEntry_t* ToHashEntry = StateID2CoordTable[ToStateID];
03883
03884
03885
03886
03887 return (int)(ENVDBUBBLELAT_COSTMULT_MTOMM*EuclideanDistance_m(FromHashEntry->X, FromHashEntry->Y, ToHashEntry->X, ToHashEntry->Y)/envDBubbleLatCfg.nominalvel_mpersecs);
03888
03889 }
03890
03891
03892 int EnvDBubbleLat::GetGoalHeuristic(int stateID)
03893 {
03894 #if USE_HEUR==0
03895 return 0;
03896 #endif
03897
03898 #if DEBUG
03899 if(stateID >= (int)StateID2CoordTable.size())
03900 {
03901 SBPL_ERROR("ERROR in envDBubbleLat... function: stateID illegal\n");
03902 throw new SBPL_Exception();
03903 }
03904 #endif
03905
03906 if(bNeedtoRecomputeGoalHeuristics)
03907 {
03908 grid2Dsearchfromgoal->search(envDBubbleLatCfg.Grid2D, envDBubbleLatCfg.cost_inscribed_thresh,
03909 envDBubbleLatCfg.EndX_c, envDBubbleLatCfg.EndY_c, envDBubbleLatCfg.StartX_c, envDBubbleLatCfg.StartY_c,
03910 SBPL_2DGRIDSEARCH_TERM_CONDITION_ALLCELLS);
03911 bNeedtoRecomputeGoalHeuristics = false;
03912 SBPL_PRINTF("2dsolcost_infullunits=%d\n", (int)(grid2Dsearchfromgoal->getlowerboundoncostfromstart_inmm(envDBubbleLatCfg.StartX_c, envDBubbleLatCfg.StartY_c)
03913 /envDBubbleLatCfg.nominalvel_mpersecs));
03914
03915 #if DEBUG
03916 PrintHeuristicValues();
03917 #endif
03918
03919 }
03920
03921 envDBubbleLatHashEntry_t* HashEntry = StateID2CoordTable[stateID];
03922 int h2D = grid2Dsearchfromgoal->getlowerboundoncostfromstart_inmm(HashEntry->X, HashEntry->Y);
03923 int hEuclid = (int)(ENVDBUBBLELAT_COSTMULT_MTOMM*EuclideanDistance_m(HashEntry->X, HashEntry->Y, envDBubbleLatCfg.EndX_c, envDBubbleLatCfg.EndY_c));
03924
03925
03926 #if DEBUG
03927 SBPL_FPRINTF(fDeb, "h2D = %d hEuclid = %d\n", h2D, hEuclid);
03928 #endif
03929
03930
03931 return (int)(((double)__max(h2D,hEuclid))/envDBubbleLatCfg.nominalvel_mpersecs);
03932
03933 }
03934
03935
03936 int EnvDBubbleLat::GetStartHeuristic(int stateID)
03937 {
03938
03939
03940 #if USE_HEUR==0
03941 return 0;
03942 #endif
03943
03944
03945 #if DEBUG
03946 if(stateID >= (int)StateID2CoordTable.size())
03947 {
03948 SBPL_ERROR("ERROR in envDBubbleLat... function: stateID illegal\n");
03949 throw new SBPL_Exception();
03950 }
03951 #endif
03952
03953
03954 if(bNeedtoRecomputeStartHeuristics)
03955 {
03956 grid2Dsearchfromstart->search(envDBubbleLatCfg.Grid2D, envDBubbleLatCfg.cost_inscribed_thresh,
03957 envDBubbleLatCfg.StartX_c, envDBubbleLatCfg.StartY_c, envDBubbleLatCfg.EndX_c, envDBubbleLatCfg.EndY_c,
03958 SBPL_2DGRIDSEARCH_TERM_CONDITION_ALLCELLS);
03959 bNeedtoRecomputeStartHeuristics = false;
03960 SBPL_PRINTF("2dsolcost_infullunits=%d\n", (int)(grid2Dsearchfromstart->getlowerboundoncostfromstart_inmm(envDBubbleLatCfg.EndX_c, envDBubbleLatCfg.EndY_c)
03961 /envDBubbleLatCfg.nominalvel_mpersecs));
03962
03963 #if DEBUG
03964 PrintHeuristicValues();
03965 #endif
03966
03967 }
03968
03969 envDBubbleLatHashEntry_t* HashEntry = StateID2CoordTable[stateID];
03970 int h2D = grid2Dsearchfromstart->getlowerboundoncostfromstart_inmm(HashEntry->X, HashEntry->Y);
03971 int hEuclid = (int)(ENVDBUBBLELAT_COSTMULT_MTOMM*EuclideanDistance_m(envDBubbleLatCfg.StartX_c, envDBubbleLatCfg.StartY_c, HashEntry->X, HashEntry->Y));
03972
03973
03974 #if DEBUG
03975 SBPL_FPRINTF(fDeb, "h2D = %d hEuclid = %d\n", h2D, hEuclid);
03976 #endif
03977
03978
03979 return (int)(((double)__max(h2D,hEuclid))/envDBubbleLatCfg.nominalvel_mpersecs);
03980
03981 }
03982
03983 int EnvDBubbleLat::SizeofCreatedEnv()
03984 {
03985 return (int)StateID2CoordTable.size();
03986
03987 }
03988