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