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