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