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
00031 #include <sbpl_arm_planner/robarm3d/environment_robarm3d.h>
00032
00033 #define DEG2RAD(d) ((d)*(M_PI/180.0))
00034 #define RAD2DEG(r) ((r)*(180.0/M_PI))
00035
00036 #define DEBUG_SEARCH 0
00037 #define DEBUG_HEURISTIC 0
00038
00039 #if DEBUG_SEARCH
00040 FILE* fSucc = SBPL_FOPEN("/tmp/debug_succs.txt", "w");
00041 #endif
00042
00043 #if DEBUG_HEURISTIC
00044 FILE* fHeur = SBPL_FOPEN("/tmp/debug_heur.txt","w");
00045 #endif
00046
00047
00048 bool near_goal = false;
00049 clock_t starttime;
00050 double time_to_goal_region;
00051
00052 using namespace std;
00053
00054 static bool xyzCompare (vector<int> i, vector<int> j)
00055 {
00056 if(i[0] < j[0])
00057 return true;
00058 else if(i[1] < j[1])
00059 return true;
00060 else if(i[2] < j[2])
00061 return true;
00062 else
00063 return false;
00064 };
00065
00066 namespace sbpl_arm_planner{
00067
00068 EnvironmentROBARM3D::EnvironmentROBARM3D() : grid_(NULL),dijkstra_(NULL),elbow_dijkstra_(NULL),arm_(NULL),rpysolver_(NULL),cspace_(NULL)
00069 {
00070 EnvROBARM.Coord2StateIDHashTable = NULL;
00071 EnvROBARMCfg.bInitialized = false;
00072 EnvROBARMCfg.ik_solution_is_valid = false;
00073 EnvROBARMCfg.solved_by_ik = 0;
00074 EnvROBARMCfg.solved_by_os = 0;
00075 EnvROBARMCfg.num_calls_to_ik = 0;
00076 EnvROBARMCfg.num_ik_invalid_path = 0;
00077 EnvROBARMCfg.num_invalid_ik_solutions = 0;
00078 EnvROBARMCfg.num_no_ik_solutions = 0;
00079 EnvROBARMCfg.num_ik_invalid_joint_limits = 0;
00080 EnvROBARMCfg.ik_solution.resize(7,0);
00081 save_expanded_states = true;
00082 using_short_mprims_ = false;
00083
00084 getHeuristic_ = &sbpl_arm_planner::EnvironmentROBARM3D::getEndEffectorHeuristic;
00085
00086 params_filename_ = "./config/params.cfg";
00087 arm_desc_filename_ = "./config/pr2_right_arm.cfg";
00088
00089 elbow_heuristic_completed_ = false;
00090 }
00091
00092 EnvironmentROBARM3D::~EnvironmentROBARM3D()
00093 {
00094 if(rpysolver_ != NULL)
00095 delete rpysolver_;
00096 if(cspace_ != NULL)
00097 delete cspace_;
00098 if(arm_ != NULL)
00099 delete arm_;
00100 if(dijkstra_ != NULL)
00101 delete dijkstra_;
00102 if(elbow_dijkstra_ != NULL)
00103 delete elbow_dijkstra_;
00104 if(grid_ != NULL)
00105 delete grid_;
00106
00107 for(size_t i = 0; i < EnvROBARM.StateID2CoordTable.size(); i++)
00108 {
00109 delete EnvROBARM.StateID2CoordTable.at(i);
00110 EnvROBARM.StateID2CoordTable.at(i) = NULL;
00111 }
00112 EnvROBARM.StateID2CoordTable.clear();
00113
00114 if(EnvROBARM.Coord2StateIDHashTable != NULL)
00115 {
00116 delete [] EnvROBARM.Coord2StateIDHashTable;
00117 EnvROBARM.Coord2StateIDHashTable = NULL;
00118 }
00119
00120 #if DEBUG_SEARCH
00121 SBPL_FCLOSE(fSucc);
00122 #endif
00123
00124 #if DEBUG_HEURISTIC
00125 SBPL_FCLOSE(fHeur);
00126 #endif
00127
00128 }
00129
00131
00133
00134 bool EnvironmentROBARM3D::InitializeMDPCfg(MDPConfig *MDPCfg)
00135 {
00136
00137 MDPCfg->goalstateid = EnvROBARM.goalHashEntry->stateID;
00138 MDPCfg->startstateid = EnvROBARM.startHashEntry->stateID;
00139 return true;
00140 }
00141
00142 bool EnvironmentROBARM3D::InitializeEnv(const char* sEnvFile, std::string params_file, std::string arm_file)
00143 {
00144 params_filename_ = params_file;
00145 arm_desc_filename_ = arm_file;
00146
00147 return InitializeEnv(sEnvFile);
00148 }
00149
00150 bool EnvironmentROBARM3D::InitializeEnv(const char* sEnvFile)
00151 {
00152
00153 FILE* fCfg = fopen(params_filename_.c_str(), "r");
00154 if(fCfg == NULL)
00155 {
00156 SBPL_ERROR("Unable to open params file: %s. Exiting.", params_filename_.c_str());
00157 return false;
00158 }
00159
00160 SBPL_DEBUG("[InitializeEnv] Using param file: %s", params_filename_.c_str());
00161 prms_.initFromParamFile(fCfg);
00162 SBPL_FCLOSE(fCfg);
00163
00164 FILE* aCfg = fopen(arm_desc_filename_.c_str(), "r");
00165 if(aCfg == NULL)
00166 {
00167 SBPL_ERROR("Unable to open arm_desc file: %s. Exiting.", arm_desc_filename_.c_str());
00168 return false;
00169 }
00170
00171 SBPL_DEBUG("Using arm description file: %s", arm_desc_filename_.c_str());
00172
00173 std::string robot_description("ROS_PARAM");
00174 SBPL_DEBUG("[InitializeEnv] Getting URDF from ROS Param server.");
00175 initArmModel(aCfg, robot_description);
00176 SBPL_FCLOSE(aCfg);
00177
00178
00179 fCfg = fopen(sEnvFile, "r");
00180 if(fCfg == NULL)
00181 {
00182 SBPL_ERROR("Unable to open environment file: %s. Exiting.", sEnvFile);
00183 return false;
00184 }
00185
00186 readConfiguration(fCfg);
00187 SBPL_FCLOSE(fCfg);
00188
00189 SBPL_DEBUG("Parsed arm description, parameter file, environment file.");
00190
00191 if(!initGeneral())
00192 {
00193 SBPL_ERROR("InitGeneral() failed.");
00194 return false;
00195 }
00196
00197 SBPL_DEBUG("Ready to start planning. Setting start configuration.");
00198
00199
00200 cspace_->addArmCuboidsToGrid();
00201
00202
00203 for(int i = 0; i < (int)EnvROBARMCfg.obstacles.size(); i++)
00204 {
00205 if(EnvROBARMCfg.obstacles[i].size() == 6)
00206 grid_->addCollisionCuboid(EnvROBARMCfg.obstacles[i][0],EnvROBARMCfg.obstacles[i][1],EnvROBARMCfg.obstacles[i][2],EnvROBARMCfg.obstacles[i][3],EnvROBARMCfg.obstacles[i][4],EnvROBARMCfg.obstacles[i][5]);
00207 else
00208 SBPL_DEBUG("[InitializeEnv] Obstacle #%d has an incomplete obstacle description. Not adding obstacle it to grid.", i);
00209 }
00210
00211
00212 if(!setStartConfiguration(EnvROBARMCfg.start_configuration))
00213 {
00214 SBPL_ERROR("Failed to set initial state of robot. Exiting.");
00215 return false;
00216 }
00217
00218
00219 EnvROBARMCfg.bInitialized = true;
00220
00221
00222 if(!setGoalPosition(EnvROBARMCfg.ParsedGoals,EnvROBARMCfg.ParsedGoalTolerance))
00223 {
00224 SBPL_ERROR("Failed to set goal pose. Exiting.");
00225 return false;
00226 }
00227
00228 grid_->visualize();
00229
00230
00231 starttime = clock();
00232
00233 SBPL_INFO("Successfully initialized environment.");
00234 return true;
00235 }
00236
00237 int EnvironmentROBARM3D::GetFromToHeuristic(int FromStateID, int ToStateID)
00238 {
00239 return (*this.*getHeuristic_)(FromStateID,ToStateID);
00240 }
00241
00242 int EnvironmentROBARM3D::GetGoalHeuristic(int stateID)
00243 {
00244 #if DEBUG_HEUR
00245 if(stateID >= (int)EnvROBARM.StateID2CoordTable.size())
00246 {
00247 SBPL_ERROR("ERROR in EnvROBARM... function: stateID illegal");
00248 return -1;
00249 }
00250 #endif
00251
00252 return GetFromToHeuristic(stateID, EnvROBARM.goalHashEntry->stateID);
00253 }
00254
00255 int EnvironmentROBARM3D::GetStartHeuristic(int stateID)
00256 {
00257 #if DEBUG_HEUR
00258 if(stateID >= (int)EnvROBARM.StateID2CoordTable.size())
00259 {
00260 SBPL_ERROR("ERROR in EnvROBARM... function: stateID illegal\n");
00261 return -1;
00262 }
00263 #endif
00264
00265 return GetFromToHeuristic(stateID, EnvROBARM.startHashEntry->stateID);
00266 }
00267
00268 int EnvironmentROBARM3D::SizeofCreatedEnv()
00269 {
00270 return EnvROBARM.StateID2CoordTable.size();
00271 }
00272
00273 void EnvironmentROBARM3D::PrintState(int stateID, bool bVerbose, FILE* fOut )
00274 {
00275 #if DEBUG_HEUR
00276 if(stateID >= (int)EnvROBARM.StateID2CoordTable.size())
00277 {
00278 SBPL_ERROR("ERROR in EnvROBARM... function: stateID illegal (2)\n");
00279 throw new SBPL_Exception();
00280 }
00281 #endif
00282
00283 if(fOut == NULL)
00284 fOut = stdout;
00285
00286 EnvROBARM3DHashEntry_t* HashEntry = EnvROBARM.StateID2CoordTable[stateID];
00287
00288 bool bGoal = false;
00289 if(stateID == EnvROBARM.goalHashEntry->stateID)
00290 bGoal = true;
00291
00292 if(stateID == EnvROBARM.goalHashEntry->stateID && bVerbose)
00293 {
00294
00295 bGoal = true;
00296 }
00297
00298 printJointArray(fOut, HashEntry, bGoal, bVerbose);
00299 }
00300
00301 void EnvironmentROBARM3D::PrintEnv_Config(FILE* fOut)
00302 {
00303
00304
00305 SBPL_ERROR("ERROR in EnvROBARM... function: PrintEnv_Config is undefined\n");
00306 throw new SBPL_Exception();
00307 }
00308
00309 void EnvironmentROBARM3D::GetSuccs(int SourceStateID, vector<int>* SuccIDV, vector<int>* CostV)
00310 {
00311 int i, a, final_mp_cost = 0;
00312 unsigned char dist=0;
00313 int endeff[3]={0};
00314 std::vector<short unsigned int> succcoord(arm_->num_joints_,0);
00315 std::vector<double> pose(6,0), angles(arm_->num_joints_,0), source_angles(arm_->num_joints_,0);
00316
00317
00318 int actions_i_min = 0, actions_i_max = prms_.num_long_dist_mprims_;
00319
00320
00321 SuccIDV->clear();
00322 CostV->clear();
00323
00324
00325 if(SourceStateID == EnvROBARM.goalHashEntry->stateID)
00326 return;
00327
00328
00329 EnvROBARM3DHashEntry_t* HashEntry = EnvROBARM.StateID2CoordTable[SourceStateID];
00330
00331
00332 for(i = 0; i < arm_->num_joints_; i++)
00333 succcoord[i] = HashEntry->coord[i];
00334
00335
00336 coordToAngles(succcoord, source_angles);
00337
00338
00339 int dist_to_goal = getDijkstraDistToGoal(HashEntry->xyz[0],HashEntry->xyz[1],HashEntry->xyz[2]);
00340
00341 if(prms_.use_multires_mprims_)
00342 {
00343 if(dist_to_goal <= prms_.short_dist_mprims_thresh_c_)
00344 {
00345 if(!using_short_mprims_)
00346 {
00347 SBPL_DEBUG("[GetSuccs] Switching to short distance motion prims after %d expansions. (SourceState with ID, #%d, is %0.3fm from goal)", int(expanded_states.size()), SourceStateID, double(dist_to_goal)/double(prms_.cost_per_cell_)*prms_.resolution_);
00348 using_short_mprims_ = true;
00349 }
00350 actions_i_min = prms_.num_long_dist_mprims_;
00351 actions_i_max = prms_.num_mprims_;
00352 }
00353 }
00354
00355 #if DEBUG_SEARCH
00356 if(prms_.verbose_)
00357 SBPL_DEBUG_NAMED("search", "\nstate %d: %.2f %.2f %.2f %.2f %.2f %.2f %.2f endeff: %3d %3d %3d",SourceStateID, source_angles[0],source_angles[1],source_angles[2],source_angles[3],source_angles[4],source_angles[5],source_angles[6], HashEntry->xyz[0],HashEntry->xyz[1],HashEntry->xyz[2]);
00358 #endif
00359
00360
00361 for (i = actions_i_min; i < actions_i_max; i++)
00362 {
00363
00364 for(a = 0; a < arm_->num_joints_; ++a)
00365 {
00366 if((HashEntry->coord[a] + int(prms_.mprims_[i][a])) < 0)
00367 succcoord[a] = ((EnvROBARMCfg.anglevals[a] + HashEntry->coord[a] + int(prms_.mprims_[i][a])) % EnvROBARMCfg.anglevals[a]);
00368 else
00369 succcoord[a] = ((int)(HashEntry->coord[a] + int(prms_.mprims_[i][a])) % EnvROBARMCfg.anglevals[a]);
00370 }
00371
00372
00373 EnvROBARM3DHashEntry_t* OutHashEntry;
00374 bool bSuccisGoal = false;
00375 final_mp_cost = 0;
00376
00377
00378 coordToAngles(succcoord, angles);
00379
00380
00381 if(!arm_->checkJointLimits(angles, prms_.verbose_))
00382 continue;
00383
00384
00385 if(!cspace_->checkCollision(angles, prms_.verbose_, false, dist))
00386 {
00387 #if DEBUG_SEARCH
00388 if(prms_.verbose_)
00389 SBPL_DEBUG_NAMED("search", " succ: %2d dist: %2d is in collision.", i, int(dist));
00390 #endif
00391 continue;
00392 }
00393
00394
00395 if(!cspace_->checkPathForCollision(source_angles, angles, prms_.verbose_, dist))
00396 {
00397 #if DEBUG_SEARCH
00398 if(prms_.verbose_)
00399 SBPL_DEBUG_NAMED("search", " succ: %2d dist: %2d is in collision along interpolated path.", i, int(dist));
00400 #endif
00401 continue;
00402 }
00403
00404
00405 if(!arm_->getPlanningJointPose(angles, pose))
00406 continue;
00407
00408
00409 grid_->worldToGrid(pose[0],pose[1],pose[2],endeff[0],endeff[1],endeff[2]);
00410
00411 short unsigned int endeff_short[3]={endeff[0],endeff[1],endeff[2]};
00412
00413
00414 if(isGoalPosition(pose,EnvROBARMCfg.EndEffGoals[0], angles, final_mp_cost))
00415 {
00416 bSuccisGoal = true;
00417
00418 for (int j = 0; j < arm_->num_joints_; j++)
00419 EnvROBARM.goalHashEntry->coord[j] = succcoord[j];
00420
00421 EnvROBARM.goalHashEntry->xyz[0] = endeff[0];
00422 EnvROBARM.goalHashEntry->xyz[1] = endeff[1];
00423 EnvROBARM.goalHashEntry->xyz[2] = endeff[2];
00424 EnvROBARM.goalHashEntry->action = i;
00425 EnvROBARM.goalHashEntry->dist = dist;
00426
00427 SBPL_DEBUG("[GetSuccs] Goal successor is generated. SourceStateID: %d (distance to nearest obstacle: %0.2fm)",SourceStateID, (double)dist*grid_->getResolution());
00428 }
00429
00430
00431 if((OutHashEntry = getHashEntry(succcoord, i, bSuccisGoal)) == NULL)
00432 {
00433 OutHashEntry = createHashEntry(succcoord, endeff_short, i);
00434 OutHashEntry->rpy[0] = pose[3];
00435 OutHashEntry->rpy[1] = pose[4];
00436 OutHashEntry->rpy[2] = pose[5];
00437 OutHashEntry->dist = dist;
00438
00439 #if DEBUG_SEARCH
00440 if(prms_.verbose_)
00441 SBPL_DEBUG_NAMED("search", "%5i: action: %2d dist: %2d edge_distance_cost: %5d edge_smoothing_cost: %2d heur: %2d endeff: %3d %3d %3d", OutHashEntry->stateID, i, int(OutHashEntry->dist), cost(HashEntry,OutHashEntry,bSuccisGoal), prms_.smoothing_cost_[HashEntry->action][OutHashEntry->action], GetFromToHeuristic(OutHashEntry->stateID, EnvROBARM.goalHashEntry->stateID), OutHashEntry->xyz[0],OutHashEntry->xyz[1],OutHashEntry->xyz[2]);
00442 #endif
00443 }
00444
00445
00446 SuccIDV->push_back(OutHashEntry->stateID);
00447 CostV->push_back(cost(HashEntry,OutHashEntry,bSuccisGoal) + prms_.smoothing_cost_[HashEntry->action][OutHashEntry->action] + final_mp_cost);
00448 }
00449
00450 if(save_expanded_states)
00451 expanded_states.push_back(SourceStateID);
00452 }
00453
00454 void EnvironmentROBARM3D::GetPreds(int TargetStateID, vector<int>* PredIDV, vector<int>* CostV)
00455 {
00456 SBPL_ERROR("ERROR in EnvROBARM... function: GetPreds is undefined\n");
00457 throw new SBPL_Exception();
00458 }
00459
00460 bool EnvironmentROBARM3D::AreEquivalent(int StateID1, int StateID2)
00461 {
00462 SBPL_ERROR("ERROR in EnvROBARM... function: AreEquivalent is undefined\n");
00463 throw new SBPL_Exception();
00464 }
00465
00466 void EnvironmentROBARM3D::SetAllActionsandAllOutcomes(CMDPSTATE* state)
00467 {
00468 SBPL_ERROR("ERROR in EnvROBARM..function: SetAllActionsandOutcomes is undefined\n");
00469 throw new SBPL_Exception();
00470 }
00471
00472 void EnvironmentROBARM3D::SetAllPreds(CMDPSTATE* state)
00473 {
00474 SBPL_ERROR("ERROR in EnvROBARM... function: SetAllPreds is undefined\n");
00475 throw new SBPL_Exception();
00476 }
00477
00479
00481
00482 void EnvironmentROBARM3D::printHashTableHist()
00483 {
00484 int s0=0, s1=0, s50=0, s100=0, s200=0, s300=0, slarge=0;
00485
00486 for(int j = 0; j < EnvROBARM.HashTableSize; j++)
00487 {
00488 if((int)EnvROBARM.Coord2StateIDHashTable[j].size() == 0)
00489 s0++;
00490 else if((int)EnvROBARM.Coord2StateIDHashTable[j].size() < 50)
00491 s1++;
00492 else if((int)EnvROBARM.Coord2StateIDHashTable[j].size() < 100)
00493 s50++;
00494 else if((int)EnvROBARM.Coord2StateIDHashTable[j].size() < 200)
00495 s100++;
00496 else if((int)EnvROBARM.Coord2StateIDHashTable[j].size() < 300)
00497 s200++;
00498 else if((int)EnvROBARM.Coord2StateIDHashTable[j].size() < 400)
00499 s300++;
00500 else
00501 slarge++;
00502 }
00503 SBPL_DEBUG("hash table histogram: 0:%d, <50:%d, <100:%d, <200:%d, <300:%d, <400:%d >400:%d",
00504 s0,s1, s50, s100, s200,s300,slarge);
00505 }
00506
00507 EnvROBARM3DHashEntry_t* EnvironmentROBARM3D::getHashEntry(const std::vector<short unsigned int> &coord, short unsigned int action, bool bIsGoal)
00508 {
00509
00510 if(bIsGoal)
00511 return EnvROBARM.goalHashEntry;
00512
00513 int binid = getHashBin(coord);
00514
00515 #if DEBUG
00516 if ((int)EnvROBARM.Coord2StateIDHashTable[binid].size() > 500)
00517 {
00518 SBPL_WARN("WARNING: Hash table has a bin %d (coord0=%d) of size %d",
00519 binid, coord[0], int(EnvROBARM.Coord2StateIDHashTable[binid].size()));
00520 printHashTableHist();
00521 }
00522 #endif
00523
00524
00525 for(int ind = 0; ind < (int)EnvROBARM.Coord2StateIDHashTable[binid].size(); ind++)
00526 {
00527 int j = 0;
00528
00529 if(prms_.use_smoothing_)
00530 {
00531
00532 if (EnvROBARM.Coord2StateIDHashTable[binid][ind]->action != action)
00533 continue;
00534 }
00535
00536 for(j = 0; j < int(coord.size()); j++)
00537 {
00538 if(EnvROBARM.Coord2StateIDHashTable[binid][ind]->coord[j] != coord[j])
00539 break;
00540 }
00541
00542 if (j == int(coord.size()))
00543 return EnvROBARM.Coord2StateIDHashTable[binid][ind];
00544 }
00545
00546 return NULL;
00547 }
00548
00549 EnvROBARM3DHashEntry_t* EnvironmentROBARM3D::createHashEntry(const std::vector<short unsigned int> &coord, short unsigned int endeff[3], short unsigned int action)
00550 {
00551 int i;
00552 EnvROBARM3DHashEntry_t* HashEntry = new EnvROBARM3DHashEntry_t;
00553
00554
00555
00556 HashEntry->coord = coord;
00557
00558 memcpy(HashEntry->xyz, endeff, 3*sizeof(short unsigned int));
00559
00560 HashEntry->action = action;
00561
00562
00563 HashEntry->stateID = EnvROBARM.StateID2CoordTable.size();
00564
00565
00566 EnvROBARM.StateID2CoordTable.push_back(HashEntry);
00567
00568
00569 i = getHashBin(HashEntry->coord);
00570
00571
00572 EnvROBARM.Coord2StateIDHashTable[i].push_back(HashEntry);
00573
00574
00575 int* entry = new int [NUMOFINDICES_STATEID2IND];
00576 StateID2IndexMapping.push_back(entry);
00577 for(i = 0; i < NUMOFINDICES_STATEID2IND; i++)
00578 {
00579 StateID2IndexMapping[HashEntry->stateID][i] = -1;
00580 }
00581
00582 if(HashEntry->stateID != (int)StateID2IndexMapping.size()-1)
00583 {
00584 SBPL_ERROR("ERROR in Env... function: last state has incorrect stateID");
00585 throw new SBPL_Exception();
00586 }
00587
00588 return HashEntry;
00589 }
00590
00591 void EnvironmentROBARM3D::initDijkstra()
00592 {
00593 int dimX,dimY,dimZ;
00594 grid_->getGridSize(dimX, dimY, dimZ);
00595
00596 dijkstra_ = new BFS3D(dimX, dimY, dimZ, int(arm_->getLinkRadiusCells(2)), prms_.cost_per_cell_);
00597
00598 dijkstra_->configDistanceField(true, grid_->getDistanceFieldPtr());
00599
00600 #if DEBUG_SEARCH
00601 if(prms_.verbose_)
00602 dijkstra_->printConfig(fSucc);
00603 #endif
00604 SBPL_DEBUG("[initDijkstra] BFS is initialized.");
00605 }
00606
00607 void EnvironmentROBARM3D::initElbowDijkstra()
00608 {
00609 int dimX,dimY,dimZ;
00610 grid_->getGridSize(dimX, dimY, dimZ);
00611
00612 elbow_dijkstra_ = new BFS3D(dimX, dimY, dimZ, int(arm_->getLinkRadiusCells(2)), prms_.cost_per_cell_);
00613
00614 elbow_dijkstra_->configDistanceField(true, grid_->getDistanceFieldPtr());
00615
00616 #if DEBUG_SEARCH
00617 if(prms_.verbose_)
00618 elbow_dijkstra_->printConfig(fSucc);
00619 #endif
00620
00621 SBPL_DEBUG("[initElbowDijkstra] BFS is initialized.");
00622 }
00623
00624 void EnvironmentROBARM3D::discretizeAngles()
00625 {
00626 for(int i = 0; i < arm_->num_joints_; i++)
00627 {
00628 EnvROBARMCfg.angledelta[i] = (2.0*M_PI) / prms_.angle_delta_;
00629 EnvROBARMCfg.anglevals[i] = prms_.angle_delta_;
00630 }
00631 }
00632
00633 int EnvironmentROBARM3D::cost(EnvROBARM3DHashEntry_t* HashEntry1, EnvROBARM3DHashEntry_t* HashEntry2, bool bState2IsGoal)
00634 {
00635 if(prms_.use_uniform_cost_)
00636 return prms_.cost_multiplier_;
00637 else
00638 {
00639
00640
00641 if(int(HashEntry2->dist) < 7)
00642 {
00643
00644 return prms_.cost_multiplier_ * prms_.range1_cost_;
00645 }
00646 else if(int(HashEntry2->dist) < 12)
00647 return prms_.cost_multiplier_ * prms_.range2_cost_;
00648 else if(int(HashEntry2->dist) < 17)
00649 return prms_.cost_multiplier_ * prms_.range3_cost_;
00650 else
00651 return prms_.cost_multiplier_;
00652 }
00653 }
00654
00655 bool EnvironmentROBARM3D::initEnvConfig()
00656 {
00657 short unsigned int endeff[3] = {0};
00658 std::vector<short unsigned int> coord(arm_->num_joints_,0);
00659
00660
00661 EnvROBARMCfg.start_configuration.resize(arm_->num_joints_);
00662 EnvROBARMCfg.ik_solution.resize(arm_->num_joints_,0);
00663
00664 EnvROBARMCfg.angledelta.resize(arm_->num_joints_);
00665 EnvROBARMCfg.anglevals.resize(arm_->num_joints_);
00666
00667 discretizeAngles();
00668
00669
00670 EnvROBARM.HashTableSize = 32*1024;
00671 EnvROBARM.Coord2StateIDHashTable = new std::vector<EnvROBARM3DHashEntry_t*>[EnvROBARM.HashTableSize];
00672
00673
00674 EnvROBARM.StateID2CoordTable.clear();
00675
00676
00677 EnvROBARM.startHashEntry = createHashEntry(coord, endeff, 0);
00678
00679
00680 EnvROBARM.goalHashEntry = createHashEntry(coord, endeff, 0);
00681
00682 return true;
00683 }
00684
00685 bool EnvironmentROBARM3D::initArmModel(FILE* aCfg, const std::string robot_description)
00686 {
00687 arm_ = new SBPLArmModel(aCfg);
00688
00689 arm_->setResolution(prms_.resolution_);
00690
00691 if(robot_description.compare("ROS_PARAM") == 0)
00692 {
00693 if(arm_->initKDLChainFromParamServer())
00694 return true;
00695 }
00696 else
00697 {
00698 if(arm_->initKDLChain(robot_description))
00699 return true;
00700 }
00701
00702 return false;
00703 }
00704
00705 bool EnvironmentROBARM3D::initEnvironment(std::string arm_description_filename, std::string mprims_filename)
00706 {
00707 FILE* mprims_fp=NULL;
00708 FILE* arm_fp=NULL;
00709
00710
00711 prms_.initFromParamServer();
00712
00713
00714 if((mprims_fp=fopen(mprims_filename.c_str(),"r")) == NULL)
00715 return false;
00716 if(!prms_.initMotionPrimsFromFile(mprims_fp))
00717 return false;
00718 fclose(mprims_fp);
00719
00720
00721 if((arm_fp=fopen(arm_description_filename.c_str(),"r")) == NULL)
00722 return false;
00723 std::string ros_param("ROS_PARAM");
00724 if(!initArmModel(arm_fp,ros_param))
00725 return false;
00726 fclose(arm_fp);
00727
00728
00729 if(!initGeneral())
00730 return false;
00731
00732
00733 EnvROBARMCfg.bInitialized = true;
00734
00735 prms_.printMotionPrims(stdout);
00736
00737 SBPL_INFO("[initEnvironment] Environment has been initialized.");
00738
00739
00740 starttime = clock();
00741
00742 return true;
00743 }
00744
00745 bool EnvironmentROBARM3D::initGeneral()
00746 {
00747
00748 grid_ = new OccupancyGrid(prms_.sizeX_,prms_.sizeY_,prms_.sizeZ_, prms_.resolution_,prms_.originX_,prms_.originY_,prms_.originZ_);
00749
00750
00751 cspace_ = new SBPLCollisionSpace(arm_, grid_);
00752
00753
00754 rpysolver_ = new RPYSolver(arm_, cspace_);
00755
00756 #if DEBUG_SEARCH
00757 cspace_->setDebugFile(fSucc);
00758 arm_->setDebugFile(fSucc);
00759 #endif
00760
00761
00762 if(initEnvConfig() == false)
00763 return false;
00764
00765
00766 prms_.precomputeSmoothingCosts();
00767
00768
00769 computeCostPerCell();
00770
00771
00772 initDijkstra();
00773
00774 if(prms_.use_research_heuristic_)
00775 initElbowDijkstra();
00776
00777 if(prms_.verbose_)
00778 {
00779 arm_->printArmDescription(stdout);
00780 prms_.printParams(stdout);
00781 prms_.printMotionPrims(stdout);
00782 if(prms_.use_smoothing_)
00783 prms_.printSmoothingCosts(stdout);
00784 }
00785
00786 if(prms_.verbose_)
00787 {
00788 arm_->printArmDescription(stdout);
00789 prms_.printParams(stdout);
00790 }
00791
00792
00793 if(prms_.use_research_heuristic_)
00794 getHeuristic_ = &sbpl_arm_planner::EnvironmentROBARM3D::getCombinedHeuristic;
00795 else
00796 getHeuristic_ = &sbpl_arm_planner::EnvironmentROBARM3D::getEndEffectorHeuristic;
00797
00798 prefinal_joint_config.resize(7);
00799 final_joint_config.resize(7);
00800
00801 return true;
00802 }
00803
00804 double EnvironmentROBARM3D::getEpsilon()
00805 {
00806 return prms_.epsilon_;
00807 }
00808
00809 void EnvironmentROBARM3D::readConfiguration(FILE* fCfg)
00810 {
00811 char sTemp[1024];
00812 int i;
00813 std::vector<double> cube(6,0);
00814
00815 if(fscanf(fCfg,"%s",sTemp) < 1)
00816 SBPL_DEBUG("Parsed string has length < 1.\n");
00817 while(!feof(fCfg) && strlen(sTemp) != 0)
00818 {
00819 if(strcmp(sTemp, "linkstartangles(radians):") == 0)
00820 {
00821 EnvROBARMCfg.start_configuration.resize(arm_->num_joints_,0);
00822 for(i = 0; i < arm_->num_joints_; i++)
00823 {
00824 if(fscanf(fCfg,"%s",sTemp) < 1)
00825 SBPL_DEBUG("Parsed string has length < 1.\n");
00826 EnvROBARMCfg.start_configuration[i] = atof(sTemp);
00827 }
00828 }
00829 else if(strcmp(sTemp, "endeffectorgoal(meters):") == 0)
00830 {
00831 if(fscanf(fCfg,"%s",sTemp) < 1)
00832 SBPL_DEBUG("Parsed string has length < 1.\n");
00833 EnvROBARMCfg.ParsedGoals.resize(atoi(sTemp));
00834 EnvROBARMCfg.ParsedGoalTolerance.resize(1);
00835 EnvROBARMCfg.ParsedGoalTolerance[0].resize(2);
00836 EnvROBARMCfg.ParsedGoalTolerance[0][0] = 0.04;
00837 EnvROBARMCfg.ParsedGoalTolerance[0][1] = 0.25;
00838
00839 for(unsigned int i = 0; i < EnvROBARMCfg.ParsedGoals.size(); i++)
00840 {
00841 EnvROBARMCfg.ParsedGoals[i].resize(7);
00842
00843 for(unsigned int k = 0; k < 7; k++)
00844 {
00845 if(fscanf(fCfg,"%s",sTemp) < 1)
00846 SBPL_DEBUG("Parsed string has length < 1.\n");
00847 EnvROBARMCfg.ParsedGoals[i][k] = atof(sTemp);
00848 }
00849 }
00850 }
00851 else if(strcmp(sTemp, "goal_tolerance(meters,radians):") == 0)
00852 {
00853 EnvROBARMCfg.ParsedGoalTolerance.resize(1);
00854 EnvROBARMCfg.ParsedGoalTolerance[0].resize(2);
00855
00856
00857 if(fscanf(fCfg,"%s",sTemp) < 1)
00858 SBPL_DEBUG("Parsed string has length < 1.\n");
00859 EnvROBARMCfg.ParsedGoalTolerance[0][0] = atof(sTemp);
00860
00861 if(fscanf(fCfg,"%s",sTemp) < 1)
00862 SBPL_DEBUG("Parsed string has length < 1.\n");
00863 EnvROBARMCfg.ParsedGoalTolerance[0][1] = atof(sTemp);
00864 }
00865 else if(strcmp(sTemp, "cube:") == 0)
00866 {
00867 for(int j = 0; j < 6; j++)
00868 {
00869 if(fscanf(fCfg,"%s",sTemp) < 1)
00870 SBPL_DEBUG("Parsed string has length < 1.\n");
00871 cube[j] = atof(sTemp);
00872 }
00873 EnvROBARMCfg.obstacles.push_back(cube);
00874 }
00875 else
00876 SBPL_WARN("ERROR: Unknown parameter name in environment config file: %s.\n", sTemp);
00877
00878 if(fscanf(fCfg,"%s",sTemp) < 1)
00879 SBPL_DEBUG("Parsed string has length < 1.\n");
00880 }
00881 }
00882
00883 bool EnvironmentROBARM3D::isGoalPosition(const std::vector<double> &pose, const GoalPos &goal, std::vector<double> jnt_angles, int &cost)
00884 {
00885 if(goal.is_6dof_goal)
00886 {
00887
00888 if(fabs(pose[0]-goal.pos[0]) <= goal.pos_tolerance[0] &&
00889 fabs(pose[1]-goal.pos[1]) <= goal.pos_tolerance[1] &&
00890 fabs(pose[2]-goal.pos[2]) <= goal.pos_tolerance[2])
00891 {
00892
00893 if(!near_goal)
00894 {
00895 time_to_goal_region = (clock() - starttime) / (double)CLOCKS_PER_SEC;
00896 near_goal = true;
00897 printf("Search is at %0.2f %0.2f %0.2f, within %0.3fm of the goal (%0.2f %0.2f %0.2f) after %.4f sec. (after %d expansions)\n", pose[0],pose[1],pose[2],goal.pos_tolerance[0], goal.pos[0], goal.pos[1], goal.pos[2], time_to_goal_region,(int)expanded_states.size());
00898 EnvROBARMCfg.num_expands_to_position_constraint = expanded_states.size();
00899 }
00900
00901 if(prms_.use_orientation_solver_)
00902 {
00903
00904 if(isGoalStateWithOrientationSolver(goal,jnt_angles))
00905 {
00906 EnvROBARMCfg.solved_by_os++;
00907
00908
00909 cost = getActionCost(jnt_angles,final_joint_config,0);
00910 return true;
00911 }
00912 }
00913 }
00914
00915 if(prms_.use_ik_)
00916 {
00917
00918 if(isGoalStateWithIK(pose,goal,jnt_angles))
00919 {
00920 EnvROBARMCfg.solved_by_ik++;
00921
00922
00923 cost = getActionCost(jnt_angles,final_joint_config,0);
00924 return true;
00925 }
00926 }
00927 }
00928 else
00929 {
00930
00931 if(fabs(pose[0]-goal.pos[0]) <= goal.pos_tolerance[0] &&
00932 fabs(pose[1]-goal.pos[1]) <= goal.pos_tolerance[1] &&
00933 fabs(pose[2]-goal.pos[2]) <= goal.pos_tolerance[2])
00934 return true;
00935 }
00936
00937 return false;
00938 }
00939
00940 bool EnvironmentROBARM3D::isGoalStateWithIK(const std::vector<double> &pose, const GoalPos &goal, std::vector<double> jnt_angles)
00941 {
00942
00943 if(prms_.use_dijkstra_heuristic_)
00944 {
00945 int endeff[3];
00946 grid_->worldToGrid(pose[0],pose[1],pose[2],endeff[0],endeff[1],endeff[2]);
00947 short unsigned int endeff_short[3]={endeff[0],endeff[1],endeff[2]};
00948
00949 if(dijkstra_->getDist(endeff_short[0],endeff_short[1],endeff_short[2]) > prms_.solve_for_ik_thresh_)
00950 return false;
00951 }
00952
00953 EnvROBARMCfg.ik_solution=jnt_angles;
00954
00955 std::vector<double> goal_pose(7,0);
00956 unsigned char dist = 0;
00957
00958 goal_pose[0] = goal.pos[0];
00959 goal_pose[1] = goal.pos[1];
00960 goal_pose[2] = goal.pos[2];
00961
00962
00963
00964
00965
00966 goal_pose[3] = goal.q[0];
00967 goal_pose[4] = goal.q[1];
00968 goal_pose[5] = goal.q[2];
00969 goal_pose[6] = goal.q[3];
00970
00971 EnvROBARMCfg.num_calls_to_ik++;
00972
00973
00974 if(!arm_->computeIK(goal_pose, jnt_angles, EnvROBARMCfg.ik_solution))
00975 {
00976 EnvROBARMCfg.num_no_ik_solutions++;
00977 return false;
00978 }
00979
00980
00981 if(!arm_->checkJointLimits(EnvROBARMCfg.ik_solution, false))
00982 {
00983 EnvROBARMCfg.num_ik_invalid_joint_limits++;
00984 return false;
00985 }
00986
00987
00988 if(!cspace_->checkCollision(EnvROBARMCfg.ik_solution, prms_.verbose_, false, dist))
00989 {
00990 EnvROBARMCfg.num_invalid_ik_solutions++;
00991 return false;
00992 }
00993
00994 std::vector<std::vector<double> > path(2, std::vector<double>(arm_->num_joints_,0));
00995 for(unsigned int i = 0; i < path[0].size(); ++i)
00996 {
00997 path[0][i] = jnt_angles[i];
00998 path[1][i] = EnvROBARMCfg.ik_solution[i];
00999 }
01000
01001
01002 if(!cspace_->checkPathForCollision(jnt_angles, EnvROBARMCfg.ik_solution, prms_.verbose_, dist))
01003 {
01004 EnvROBARMCfg.num_ik_invalid_path++;
01005 return false;
01006 }
01007
01008 SBPL_DEBUG("[isGoalStateWithIK] The path to the IK solution for the goal is valid.");
01009
01010
01011 prefinal_joint_config = jnt_angles;
01012 final_joint_config = EnvROBARMCfg.ik_solution;
01013
01014 EnvROBARMCfg.ik_solution_is_valid = true;
01015
01016 return true;
01017 }
01018
01019 int EnvironmentROBARM3D::getActionCost(const std::vector<double> &from_config, const std::vector<double> &to_config, int dist)
01020 {
01021 int num_prims = 0, cost = 0;
01022 double diff = 0, max_diff = 0;
01023
01024 if(from_config.size() != to_config.size())
01025 return -1;
01026
01027
01028
01029 for(size_t i = 0; i < 6; i++)
01030 {
01031 if(i == 4)
01032 continue;
01033
01034 diff = fabs(angles::shortest_angular_distance(from_config[i], to_config[i]));
01035 if(max_diff < diff)
01036 max_diff = diff;
01037 }
01038
01039 num_prims = max_diff / prms_.max_mprim_offset_ + 0.5;
01040 cost = num_prims * prms_.cost_multiplier_;
01041
01042 #if DEBUG_SEARCH
01043 SBPL_DEBUG_NAMED("search", "from: %0.2f %0.2f %0.2f %0.2f %0.2f %0.2f %0.2f", angles::normalize_angle(from_config[0]),angles::normalize_angle(from_config[1]),angles::normalize_angle(from_config[2]),angles::normalize_angle(from_config[3]),angles::normalize_angle(from_config[4]),angles::normalize_angle(from_config[5]),angles::normalize_angle(from_config[6]));
01044 SBPL_DEBUG_NAMED("search", " to: %0.2f %0.2f %0.2f %0.2f %0.2f %0.2f %0.2f diff: %0.2f num_prims: %d cost: %d (mprim_size: %0.3f)", to_config[0],to_config[1],to_config[2],to_config[3],to_config[4],to_config[5],to_config[6], max_diff, num_prims, cost, prms_.max_mprim_offset_);
01045 #endif
01046
01047 return cost;
01048 }
01049
01050 int EnvironmentROBARM3D::getEdgeCost(int FromStateID, int ToStateID)
01051 {
01052 #if DEBUG
01053 if(FromStateID >= (int)EnvROBARM.StateID2CoordTable.size()
01054 || ToStateID >= (int)EnvROBARM.StateID2CoordTable.size())
01055 {
01056 SBPL_ERROR("ERROR in EnvROBARM... function: stateID illegal\n");
01057 throw new SBPL_Exception();
01058 }
01059 #endif
01060
01061
01062 EnvROBARM3DHashEntry_t* FromHashEntry = EnvROBARM.StateID2CoordTable[FromStateID];
01063 EnvROBARM3DHashEntry_t* ToHashEntry = EnvROBARM.StateID2CoordTable[ToStateID];
01064
01065 return cost(FromHashEntry, ToHashEntry, false);
01066 }
01067
01068 bool EnvironmentROBARM3D::isGoalStateWithOrientationSolver(const GoalPos &goal, std::vector<double> jnt_angles)
01069 {
01070 return rpysolver_->isOrientationFeasible(goal.rpy, jnt_angles, prefinal_joint_config, final_joint_config);
01071 }
01072
01073 bool EnvironmentROBARM3D::setStartConfiguration(const std::vector<double> angles)
01074 {
01075 unsigned char dist = 255;
01076 int x,y,z;
01077 std::vector<double> pose(6,0);
01078
01079 if(int(angles.size()) < arm_->num_joints_)
01080 return false;
01081
01082
01083 if(!arm_->getPlanningJointPose(angles, pose))
01084 SBPL_WARN("Unable to compute forward kinematics for initial robot state. Attempting to plan anyway.");
01085
01086
01087 if(!arm_->checkJointLimits(angles, true))
01088 SBPL_WARN("Starting configuration violates the joint limits. Attempting to plan anyway.");
01089
01090
01091 if(!cspace_->checkCollision(angles, true, false, dist))
01092 SBPL_WARN("The starting configuration is in collision. Attempting to plan anyway. (distance to nearest obstacle %0.2fm)", double(dist)*grid_->getResolution());
01093
01094
01095 anglesToCoord(angles, EnvROBARM.startHashEntry->coord);
01096
01097 grid_->worldToGrid(pose[0],pose[1],pose[2],x,y,z);
01098 EnvROBARM.startHashEntry->xyz[0] = (short unsigned int)x;
01099 EnvROBARM.startHashEntry->xyz[1] = (short unsigned int)y;
01100 EnvROBARM.startHashEntry->xyz[2] = (short unsigned int)z;
01101
01102 EnvROBARM.startHashEntry->rpy[0] = pose[3];
01103 EnvROBARM.startHashEntry->rpy[1] = pose[4];
01104 EnvROBARM.startHashEntry->rpy[2] = pose[5];
01105
01106 return true;
01107 }
01108
01109 bool EnvironmentROBARM3D::setGoalPosition(const std::vector <std::vector<double> > &goals, const std::vector<std::vector<double> > &tolerances)
01110 {
01111
01112
01113 if(!EnvROBARMCfg.bInitialized)
01114 {
01115 SBPL_ERROR("Cannot set goal position because environment is not initialized.");
01116 return false;
01117 }
01118
01119 if(goals.empty())
01120 {
01121 SBPL_ERROR("[setGoalPosition] No goal constraint set.");
01122 return false;
01123 }
01124
01125
01126
01127 std::vector<double> pose(7,0);
01128 std::vector<double> jnt_angles(7,0);
01129 pose = goals[0];
01130 unsigned char dist_ik;
01131 if(!arm_->computeIK(pose, jnt_angles, EnvROBARMCfg.ik_solution))
01132 SBPL_DEBUG("[setGoalPosition] No valid IK solution for the goal pose.");
01133 else
01134 {
01135 if(!cspace_->checkCollision(EnvROBARMCfg.ik_solution, false, false, dist_ik))
01136 SBPL_DEBUG("[setGoalPosition] An IK solution for the goal pose was found but it's in collision. Valid solutions may exist.");
01137 else
01138 SBPL_DEBUG("[setGoalPosition] A valid IK solution for the goal pose was found.");
01139 }
01140
01141 EnvROBARMCfg.EndEffGoals.resize(goals.size());
01142 for(unsigned int i = 0; i < EnvROBARMCfg.EndEffGoals.size(); i++)
01143 {
01144 EnvROBARMCfg.EndEffGoals[i].pos[0] = goals[i][0];
01145 EnvROBARMCfg.EndEffGoals[i].pos[1] = goals[i][1];
01146 EnvROBARMCfg.EndEffGoals[i].pos[2] = goals[i][2];
01147
01148 EnvROBARMCfg.EndEffGoals[i].rpy[0] = goals[i][3];
01149 EnvROBARMCfg.EndEffGoals[i].rpy[1] = goals[i][4];
01150 EnvROBARMCfg.EndEffGoals[i].rpy[2] = goals[i][5];
01151
01152 EnvROBARMCfg.EndEffGoals[i].xyz_tolerance = tolerances[i][0] / grid_->getResolution();
01153
01154 EnvROBARMCfg.EndEffGoals[i].pos_tolerance[0] = tolerances[i][0];
01155 EnvROBARMCfg.EndEffGoals[i].pos_tolerance[1] = tolerances[i][1];
01156 EnvROBARMCfg.EndEffGoals[i].pos_tolerance[2] = tolerances[i][2];
01157
01158 EnvROBARMCfg.EndEffGoals[i].rpy_tolerance[0] = tolerances[i][3];
01159 EnvROBARMCfg.EndEffGoals[i].rpy_tolerance[1] = tolerances[i][4];
01160 EnvROBARMCfg.EndEffGoals[i].rpy_tolerance[2] = tolerances[i][5];
01161
01162 EnvROBARMCfg.EndEffGoals[i].is_6dof_goal = goals[i][6];
01163 prms_.use_6d_pose_goal_ = goals[i][6];
01164
01165 EnvROBARMCfg.EndEffGoals[i].q[0] = goals[i][7];
01166 EnvROBARMCfg.EndEffGoals[i].q[1] = goals[i][8];
01167 EnvROBARMCfg.EndEffGoals[i].q[2] = goals[i][9];
01168 EnvROBARMCfg.EndEffGoals[i].q[3] = goals[i][10];
01169
01170 if(!prms_.use_6d_pose_goal_)
01171 SBPL_DEBUG("[setGoalPosition] Goal position constraint set. No goal orientation constraint requested.\n");
01172
01173
01174 grid_->worldToGrid(goals[i][0], goals[i][1], goals[i][2], EnvROBARMCfg.EndEffGoals[i].xyz[0], EnvROBARMCfg.EndEffGoals[i].xyz[1], EnvROBARMCfg.EndEffGoals[i].xyz[2]);
01175
01176
01177 }
01178
01179
01180 EnvROBARM.goalHashEntry->xyz[0] = EnvROBARMCfg.EndEffGoals[0].xyz[0];
01181 EnvROBARM.goalHashEntry->xyz[1] = EnvROBARMCfg.EndEffGoals[0].xyz[1];
01182 EnvROBARM.goalHashEntry->xyz[2] = EnvROBARMCfg.EndEffGoals[0].xyz[2];
01183 EnvROBARM.goalHashEntry->rpy[0] = EnvROBARMCfg.EndEffGoals[0].rpy[0];
01184 EnvROBARM.goalHashEntry->rpy[1] = EnvROBARMCfg.EndEffGoals[0].rpy[1];
01185 EnvROBARM.goalHashEntry->rpy[2] = EnvROBARMCfg.EndEffGoals[0].rpy[2];
01186 EnvROBARM.goalHashEntry->action = 0;
01187
01188 for(int i = 0; i < arm_->num_joints_; i++)
01189 EnvROBARM.goalHashEntry->coord[i] = 0;
01190
01191 for(unsigned int i = 0; i < EnvROBARMCfg.EndEffGoals.size(); i++)
01192 {
01193 SBPL_INFO("goal %i: grid: %u %u %u (cells) xyz: %0.2f %0.2f %0.2f (meters) (tol: %0.3fm %0.3fm %0.3fm) rpy: %1.2f %1.2f %1.2f (radians) (tol: %0.3f %0.3f %0.3f)",i,EnvROBARMCfg.EndEffGoals[i].xyz[0], EnvROBARMCfg.EndEffGoals[i].xyz[1],EnvROBARMCfg.EndEffGoals[i].xyz[2],EnvROBARMCfg.EndEffGoals[i].pos[0],EnvROBARMCfg.EndEffGoals[i].pos[1],EnvROBARMCfg.EndEffGoals[i].pos[2],tolerances[i][0],tolerances[i][1],tolerances[i][2],EnvROBARMCfg.EndEffGoals[i].rpy[0],EnvROBARMCfg.EndEffGoals[i].rpy[1],EnvROBARMCfg.EndEffGoals[i].rpy[2],tolerances[i][3],tolerances[i][4],tolerances[i][5]);
01194 SBPL_DEBUG("quat: %0.3f %0.3f %0.3f %0.3f",EnvROBARMCfg.EndEffGoals[i].q[0], EnvROBARMCfg.EndEffGoals[i].q[1], EnvROBARMCfg.EndEffGoals[i].q[2], EnvROBARMCfg.EndEffGoals[i].q[3]);
01195 }
01196
01197 #if DEBUG_SEARCH
01198 if(prms_.verbose_)
01199 {
01200 SBPL_DEBUG_NAMED("search", "\n-----------------------------------------------------------------------------------");
01201 SBPL_DEBUG_NAMED("search", "time: %f", clock() / (double)CLOCKS_PER_SEC);
01202 SBPL_DEBUG_NAMED("search", "A new goal has been set.");
01203 SBPL_DEBUG_NAMED("search", "grid: %u %u %u (cells) xyz: %.2f %.2f %.2f (meters) (tol: %.3f) rpy: %1.2f %1.2f %1.2f (radians) (tol: %.3f)",
01204 EnvROBARMCfg.EndEffGoals[0].xyz[0], EnvROBARMCfg.EndEffGoals[0].xyz[1],EnvROBARMCfg.EndEffGoals[0].xyz[2],
01205 EnvROBARMCfg.EndEffGoals[0].pos[0],EnvROBARMCfg.EndEffGoals[0].pos[1],EnvROBARMCfg.EndEffGoals[0].pos[2],tolerances[0][0],
01206 EnvROBARMCfg.EndEffGoals[0].rpy[0],EnvROBARMCfg.EndEffGoals[0].rpy[1],EnvROBARMCfg.EndEffGoals[0].rpy[2],tolerances[0][1]);
01207
01208 SBPL_DEBUG_NAMED("search", "-----------------------------------------------------------------------------------\n");
01209 }
01210 #endif
01211
01212
01213 if(!precomputeHeuristics())
01214 {
01215 SBPL_ERROR("Precomputing heuristics failed. Exiting.");
01216 return false;
01217 }
01218
01219 clearStats();
01220
01221 return true;
01222 }
01223
01224 bool EnvironmentROBARM3D::precomputeHeuristics()
01225 {
01226 std::vector<short unsigned int> dij_goal(3,0);
01227
01228 dij_goal[0] = EnvROBARMCfg.EndEffGoals[0].xyz[0];
01229 dij_goal[1] = EnvROBARMCfg.EndEffGoals[0].xyz[1];
01230 dij_goal[2] = EnvROBARMCfg.EndEffGoals[0].xyz[2];
01231
01232 SBPL_DEBUG("[precomputeHeuristics] Dijkstra Goal: %d %d %d",dij_goal[0],dij_goal[1],dij_goal[2]);
01233
01234
01235 if(!dijkstra_->setGoal(dij_goal))
01236 {
01237 SBPL_ERROR("[precomputeHeuristics] Failed to set goal for Dijkstra search.");
01238 return false;
01239 }
01240
01241
01242 if(prms_.use_research_heuristic_)
01243 {
01244 SBPL_DEBUG("[precomputeHeuristics] Spawning a new thread to compute elbow heuristic.");
01245 heuristic_thread_ = new boost::thread(boost::bind(&EnvironmentROBARM3D::precomputeElbowHeuristic, this));
01246 }
01247
01248
01249 if(!dijkstra_->runBFS())
01250 {
01251 SBPL_ERROR("Executing the BFS for the end-effector heuristic failed. Exiting.");
01252 return false;
01253 }
01254
01255
01256 if(prms_.use_research_heuristic_)
01257 {
01258 SBPL_DEBUG("[precomputeHeuristics] Attempting to get the heuristic mutex.");
01259 heuristic_mutex_.lock();
01260 SBPL_DEBUG("[precomputeHeuristics] Got the heuristic mutex. Now killing the thread.");
01261 if(!elbow_heuristic_completed_)
01262 {
01263 SBPL_ERROR("[precomputeHeuristics] elbow heuristic failed.");
01264 if(heuristic_thread_ != NULL)
01265 {
01266 heuristic_thread_->join();
01267 delete heuristic_thread_;
01268 }
01269 heuristic_mutex_.unlock();
01270 return false;
01271 }
01272
01273 if(heuristic_thread_ != NULL)
01274 {
01275 heuristic_thread_->join();
01276 delete heuristic_thread_;
01277 }
01278
01279 heuristic_mutex_.unlock();
01280 }
01281
01282 SBPL_DEBUG("Completed heuristic pre-computation");
01283 return true;
01284 }
01285
01286 bool EnvironmentROBARM3D::precomputeElbowHeuristic()
01287 {
01288 heuristic_mutex_.lock();
01289 elbow_heuristic_completed_ = false;
01290
01291 std::vector<std::vector<int> > elbow_cells;
01292
01293
01294 std::vector<double> angles(7,0);
01295 std::vector<double> xyzrpy(6,0), goal(3,0);
01296 std::vector<int> shoulder(3,0);
01297 if(!arm_->computeFK(angles, 1, xyzrpy))
01298 {
01299 elbow_heuristic_completed_ = false;
01300 heuristic_mutex_.unlock();
01301 return false;
01302 }
01303
01304 goal[0] = EnvROBARMCfg.EndEffGoals[0].pos[0];
01305 goal[1] = EnvROBARMCfg.EndEffGoals[0].pos[1];
01306 goal[2] = EnvROBARMCfg.EndEffGoals[0].pos[2];
01307
01308 grid_->worldToGrid(xyzrpy[0],xyzrpy[1],xyzrpy[2],shoulder[0],shoulder[1],shoulder[2]);
01309 if(!getElbowCellsAtGoal(shoulder, goal, arm_->getLinkRadius(0), arm_->getLinkRadius(1), elbow_cells))
01310 {
01311 SBPL_WARN("[precomputeElbowHeuristic] No elbow cells returned. Exiting.\n");
01312 elbow_heuristic_completed_ = false;
01313 heuristic_mutex_.unlock();
01314 return false;
01315 }
01316
01317 std::vector<std::vector<short unsigned int> > elbow_shorts(elbow_cells.size(), std::vector<short unsigned int> (3,0));
01318 for(unsigned int q = 0; q < elbow_cells.size(); q++)
01319 {
01320 elbow_shorts[q][0] = elbow_cells[q][0];
01321 elbow_shorts[q][1] = elbow_cells[q][1];
01322 elbow_shorts[q][2] = elbow_cells[q][2];
01323 }
01324
01325 if(!elbow_dijkstra_->setGoals(elbow_shorts))
01326 {
01327 SBPL_ERROR("[setGoalPosition] Failed to set goal for the h_elbow computation.\n");
01328 elbow_heuristic_completed_ = false;
01329 heuristic_mutex_.unlock();
01330 return false;
01331 }
01332
01333 if(!elbow_dijkstra_->runBFS())
01334 {
01335 elbow_heuristic_completed_ = false;
01336 heuristic_mutex_.unlock();
01337 return false;
01338 }
01339
01340 elbow_heuristic_completed_ = true;
01341 heuristic_mutex_.unlock();
01342
01343 SBPL_DEBUG("[precomputeElbowHeuristic] Exiting.\n");
01344 return true;
01345 }
01346
01347 void EnvironmentROBARM3D::clearStats()
01348 {
01349
01350 near_goal = false;
01351
01352
01353 expanded_states.clear();
01354 EnvROBARMCfg.ik_solution_is_valid = false;
01355
01356 EnvROBARMCfg.num_calls_to_ik = 0;
01357 EnvROBARMCfg.num_ik_invalid_path = 0;
01358 EnvROBARMCfg.num_invalid_ik_solutions = 0;
01359 EnvROBARMCfg.num_no_ik_solutions = 0;
01360 EnvROBARMCfg.num_ik_invalid_joint_limits = 0;
01361
01362
01363 int xyz[3] = {(int)(EnvROBARMCfg.EndEffGoals[0].xyz[0]),
01364 (int)(EnvROBARMCfg.EndEffGoals[0].xyz[1]),
01365 (int)(EnvROBARMCfg.EndEffGoals[0].xyz[2])};
01366 EnvROBARMCfg.goal_to_obstacle_distance = grid_->getCell(xyz);
01367
01368
01369 EnvROBARMCfg.solved_by_os = 0;
01370 EnvROBARMCfg.solved_by_ik = 0;
01371 EnvROBARMCfg.num_expands_to_position_constraint = 0;
01372
01373 elbow_cells_.clear();
01374 elbow_poses_.clear();
01375
01376
01377 starttime = clock();
01378 }
01379
01380 void EnvironmentROBARM3D::StateID2Angles(int stateID, std::vector<double> &angles)
01381 {
01382 EnvROBARM3DHashEntry_t* HashEntry = EnvROBARM.StateID2CoordTable[stateID];
01383
01384 if(stateID == EnvROBARM.goalHashEntry->stateID)
01385 {
01386 coordToAngles(EnvROBARM.goalHashEntry->coord, angles);
01387
01388 angles.resize(14);
01389 for(unsigned int i = 0; i < (unsigned int)angles.size(); i++)
01390 {
01391 if(i < 7)
01392 angles[i] = prefinal_joint_config[i];
01393 else
01394 angles[i] = final_joint_config[i-7];
01395 }
01396 }
01397 else
01398 coordToAngles(HashEntry->coord, angles);
01399
01400 for (size_t i = 0; i < angles.size(); i++)
01401 {
01402 if(angles[i] >= M_PI)
01403 angles[i] = -2.0*M_PI + angles[i];
01404 }
01405 }
01406
01407 void EnvironmentROBARM3D::printJointArray(FILE* fOut, EnvROBARM3DHashEntry_t* HashEntry, bool bGoal, bool bVerbose)
01408 {
01409 int i;
01410 std::vector<double> angles(arm_->num_joints_,0);
01411
01412 if(bGoal)
01413 coordToAngles(EnvROBARM.goalHashEntry->coord, angles);
01414 else
01415 coordToAngles(HashEntry->coord, angles);
01416
01417 if(bVerbose)
01418 SBPL_DEBUG_NAMED(fOut, "angles: ");
01419
01420 for(i = 0; i < int(angles.size()); i++)
01421 {
01422 if(i > 0)
01423 SBPL_DEBUG_NAMED(fOut, "%-.3f ", angles[i]-angles[i-1]);
01424 else
01425 SBPL_DEBUG_NAMED(fOut, "%-.3f ", angles[i]);
01426 }
01427
01428 if(bVerbose)
01429 SBPL_DEBUG_NAMED(fOut, " xyz: %-2d %-2d %-2d rpy: %2.2f %2.2f %2.2f action: %d", HashEntry->xyz[0],HashEntry->xyz[1],HashEntry->xyz[2], HashEntry->rpy[0], HashEntry->rpy[1], HashEntry->rpy[2], HashEntry->action);
01430 else
01431 SBPL_DEBUG_NAMED(fOut, "%-2d %-2d %-2d %-2d", HashEntry->xyz[0],HashEntry->xyz[1],HashEntry->xyz[2],HashEntry->action);
01432 }
01433
01434 std::vector<int> EnvironmentROBARM3D::debugExpandedStates()
01435 {
01436 return expanded_states;
01437 }
01438
01439 void EnvironmentROBARM3D::getExpandedStates(std::vector<std::vector<double> >* ara_states)
01440 {
01441 std::vector<double> angles(arm_->num_joints_,0);
01442 std::vector<double>state(7,0);
01443
01444 for(unsigned int i = 0; i < expanded_states.size(); ++i)
01445 {
01446 StateID2Angles(expanded_states[i],angles);
01447 arm_->getPlanningJointPose(angles,state);
01448 state[6] = EnvROBARM.StateID2CoordTable[expanded_states[i]]->heur;
01449 ara_states->push_back(state);
01450 }
01451 }
01452
01453 void EnvironmentROBARM3D::computeCostPerCell()
01454 {
01455 int largest_action=0;
01456 double gridcell_size, eucl_dist, max_dist = 0;
01457 std::vector<double> pose(6,0), start_pose(6,0), angles(arm_->num_joints_,0), start_angles(arm_->num_joints_,0);
01458
01459 gridcell_size = grid_->getResolution();
01460
01461
01462 arm_->getPlanningJointPose(start_angles, start_pose);
01463
01464
01465 for (int i = 0; i < prms_.num_mprims_; i++)
01466 {
01467 for(int j = 0; j < arm_->num_joints_; j++)
01468 angles[j] = DEG2RAD(prms_.mprims_[i][j]);
01469
01470
01471 if(!arm_->getPlanningJointPose(angles, pose))
01472 {
01473 SBPL_WARN("Failed to compute cost per cell because forward kinematics is returning an error.");
01474 return;
01475 }
01476
01477 eucl_dist = sqrt((start_pose[0]-pose[0])*(start_pose[0]-pose[0]) +
01478 (start_pose[1]-pose[1])*(start_pose[1]-pose[1]) +
01479 (start_pose[2]-pose[2])*(start_pose[2]-pose[2]));
01480
01481 if (eucl_dist > max_dist)
01482 {
01483 max_dist = eucl_dist;
01484 largest_action = i;
01485 }
01486 }
01487
01488 prms_.setCellCost(int(prms_.cost_multiplier_ / (max_dist/gridcell_size)));
01489
01490 prms_.cost_per_meter_ = int(prms_.cost_per_cell_ / gridcell_size);
01491
01492 SBPL_DEBUG("[computeCostPerCell] cost per cell: %d cost per meter: %d",prms_.cost_per_cell_,prms_.cost_per_meter_);
01493 }
01494
01495 double EnvironmentROBARM3D::getDistToClosestGoal(double *xyz, int* goal_num)
01496 {
01497 unsigned int i,ind = 0;
01498 double dist, min_dist = 10000000;
01499
01500 for(i=0; i < EnvROBARMCfg.EndEffGoals.size(); i++)
01501 {
01502 dist = sqrt((EnvROBARMCfg.EndEffGoals[i].pos[0] - xyz[0])*(EnvROBARMCfg.EndEffGoals[i].pos[0] - xyz[0]) +
01503 (EnvROBARMCfg.EndEffGoals[i].pos[1] - xyz[1])*(EnvROBARMCfg.EndEffGoals[i].pos[1] - xyz[1]) +
01504 (EnvROBARMCfg.EndEffGoals[i].pos[2] - xyz[2])*(EnvROBARMCfg.EndEffGoals[i].pos[2] - xyz[2]));
01505 if(dist < min_dist)
01506 {
01507 ind = i;
01508 min_dist = dist;
01509 }
01510 }
01511
01512 (*goal_num) = ind;
01513 return min_dist;
01514 }
01515
01516 int EnvironmentROBARM3D::getDijkstraDistToGoal(short unsigned int x, short unsigned int y, short unsigned int z) const
01517 {
01518 int endeff_cc[3] = {x, y, z};
01519
01520 return int(dijkstra_->getDist(endeff_cc[0],endeff_cc[1],endeff_cc[2]));
01521 }
01522
01523 void EnvironmentROBARM3D::updateOccupancyGridFromCollisionMap(const mapping_msgs::CollisionMap &collision_map)
01524 {
01525 if(collision_map.boxes.empty())
01526 {
01527 SBPL_ERROR("[updateOccupancyGridFromCollisionMap] collision map received is empty.");
01528 return;
01529 }
01530 else
01531 SBPL_DEBUG("[updateOccupancyGridFromCollisionMap] updating distance field with collision map with %d boxes.", int(collision_map.boxes.size()));
01532
01533 grid_->updateFromCollisionMap(collision_map);
01534 }
01535
01536 bool EnvironmentROBARM3D::isValidJointConfiguration(const std::vector<double> angles)
01537 {
01538 unsigned char dist;
01539 return cspace_->checkCollision(angles,prms_.verbose_, false, dist);
01540 }
01541
01542 bool EnvironmentROBARM3D::isPathValid(const std::vector<std::vector<double> > path)
01543 {
01544 unsigned char dist;
01545
01546
01547 for(int i = 0; i < int(path.size()); ++i)
01548 {
01549 if(!cspace_->checkCollision(path[i], false, false, dist))
01550 {
01551 SBPL_ERROR("[isPathValid] Waypoint #%d in path is invalid.", i);
01552 return false;
01553 }
01554 }
01555 return true;
01556 }
01557
01558 bool EnvironmentROBARM3D::interpolatePathToGoal(std::vector<std::vector<double> > &path, double inc)
01559 {
01560 unsigned int i = 0, completed_joints = 0, pind = path.size() - 2;
01561 double diff;
01562 std::vector<double> waypoint(path[pind].size(), 0);
01563 std::vector<double> angles(arm_->num_joints_,0);
01564
01565 if(path.size() < 2)
01566 {
01567 SBPL_ERROR("[interpolatePathToGoal] no waypoints in path.");
01568 return false;
01569 }
01570
01571 for(unsigned int i = 0; i < path.size(); ++i)
01572 {
01573
01574 for(unsigned int j = 0; j < path[0].size(); ++j)
01575 {
01576 if(path[i][j] < 0)
01577 path[i][j] = 2.0*M_PI + path[i][j];
01578 }
01579 }
01580
01581 while(path[pind].size() != completed_joints)
01582 {
01583 completed_joints = 0;
01584 for(i = 0; i < path[pind].size(); ++i)
01585 {
01586 if(path[pind][i] == path.back()[i])
01587 {
01588 waypoint[i] = path[pind][i];
01589 ++completed_joints;
01590 }
01591 else
01592 {
01593 diff = path.back()[i] - path[pind][i];
01594 if(diff < 0)
01595 {
01596 if(min(fabs(diff), inc) == inc)
01597 waypoint[i]= path[pind][i] - inc;
01598 else
01599 waypoint[i]= path[pind][i] + diff;
01600 }
01601 else
01602 {
01603 if(min(fabs(diff), inc) == inc)
01604 waypoint[i]= path[pind][i] + inc;
01605 else
01606 waypoint[i]= path[pind][i] + diff;
01607 }
01608 }
01609 }
01610 ++pind;
01611
01612 for(int j = 0; j < arm_->num_joints_; ++j)
01613 angles[j] = waypoint[j];
01614
01615 if(!isValidJointConfiguration(waypoint))
01616 return false;
01617
01618 path.insert(path.begin()+pind, waypoint);
01619 }
01620 return true;
01621 }
01622
01623 std::vector<std::vector<double> > EnvironmentROBARM3D::getShortestPath()
01624 {
01625 std::vector<short unsigned int> start(3,0);
01626 std::vector<double> waypoint(3,0);
01627 std::vector<std::vector<int> > path;
01628 std::vector<std::vector<double> > dpath;
01629
01630
01631 if(prms_.use_dijkstra_heuristic_)
01632 {
01633 start[0] = EnvROBARM.startHashEntry->xyz[0];
01634 start[1] = EnvROBARM.startHashEntry->xyz[1];
01635 start[2] = EnvROBARM.startHashEntry->xyz[2];
01636
01637 if(!dijkstra_->getShortestPath(start, path))
01638 {
01639 ROS_WARN("Unable to retrieve shortest path.");
01640 return dpath;
01641 }
01642
01643 for(int i=0; i < (int)path.size(); ++i)
01644 {
01645 grid_->gridToWorld(path[i][0], path[i][1], path[i][2], waypoint[0], waypoint[1], waypoint[2]);
01646 dpath.push_back(waypoint);
01647 }
01648 }
01649
01650 else
01651 {
01652 getBresenhamPath(EnvROBARM.startHashEntry->xyz,EnvROBARM.goalHashEntry->xyz,&path);
01653 }
01654
01655 for(int i=0; i < int(path.size()); ++i)
01656 {
01657 grid_->gridToWorld(path[i][0], path[i][1], path[i][2], waypoint[0], waypoint[1], waypoint[2]);
01658 dpath.push_back(waypoint);
01659 }
01660
01661 return dpath;
01662 }
01663
01664 void EnvironmentROBARM3D::getBresenhamPath(const short unsigned int a[],const short unsigned int b[], std::vector<std::vector<int> > *path)
01665 {
01666 bresenham3d_param_t params;
01667 std::vector<int> nXYZ(3,0);
01668
01669
01670 get_bresenham3d_parameters(a[0], a[1], a[2], b[0], b[1], b[2], ¶ms);
01671 do {
01672 get_current_point3d(¶ms, &(nXYZ[0]), &(nXYZ[1]), &(nXYZ[2]));
01673
01674 path->push_back(nXYZ);
01675 } while (get_next_point3d(¶ms));
01676
01677 SBPL_DEBUG("[getBresenhamPath] Path has %d waypoints.",int(path->size()));
01678 }
01679
01680 void EnvironmentROBARM3D::debugAdaptiveMotionPrims()
01681 {
01682 if(prms_.use_6d_pose_goal_)
01683 {
01684 rpysolver_->printStats();
01685
01686 SBPL_INFO("Calls to IK: %d No Solutions: %d Invalid Joint Limits: %d Invalid Solutions: %d Invalid Paths: %d", EnvROBARMCfg.num_calls_to_ik, EnvROBARMCfg.num_no_ik_solutions, EnvROBARMCfg.num_ik_invalid_joint_limits,EnvROBARMCfg.num_invalid_ik_solutions, EnvROBARMCfg.num_ik_invalid_path);
01687 }
01688
01689
01690 if(prms_.use_research_heuristic_)
01691 {
01692 int x,y,z;
01693 std::vector<double> pose(6,0);
01694 if(arm_->computeFK(final_joint_config, 7, pose))
01695 {
01696 grid_->worldToGrid(pose[0],pose[1],pose[2], x, y, z);
01697 bool in_list = false;
01698 for(size_t i = 0; i < elbow_cells_.size(); i++)
01699 {
01700 if(elbow_cells_[i][0] == x && elbow_cells_[i][1] == y && elbow_cells_[i][2] ==z)
01701 {
01702 SBPL_DEBUG("Elbow pose at goal *is* one of the elbow goal poses.");
01703 in_list = true;
01704 }
01705 }
01706 if(!in_list)
01707 {
01708 SBPL_DEBUG("Elbow pose at goal (%d %d %d) *is not* one of the elbow goal poses.\nPoses are:", x, y, z);
01709 for(size_t i = 0; i < elbow_cells_.size(); i++)
01710 SBPL_DEBUG("%d: %d %d %d\n", int(i), elbow_cells_[i][0], elbow_cells_[i][1], elbow_cells_[i][2]);
01711 }
01712 }
01713 }
01714 }
01715
01716 void EnvironmentROBARM3D::visualizeOccupancyGrid()
01717 {
01718 grid_->visualize();
01719 }
01720
01721 void EnvironmentROBARM3D::setReferenceFrameTransform(KDL::Frame f, std::string &name)
01722 {
01723 arm_->setRefFrameTransform(f, name);
01724 }
01725
01726 void EnvironmentROBARM3D::getArmChainRootLinkName(std::string &name)
01727 {
01728 arm_->getArmChainRootLinkName(name);
01729 }
01730
01731 std::vector<double> EnvironmentROBARM3D::getPlanningStats()
01732 {
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742 bool in_list = false;
01743 int x,y,z;
01744 std::vector<double> stats, pose(6,0), angles(7,0);
01745
01746
01747 if(prms_.use_6d_pose_goal_)
01748 angles = final_joint_config;
01749 else
01750 coordToAngles(EnvROBARM.goalHashEntry->coord, angles);
01751
01752 if(!arm_->getPlanningJointPose(angles, pose))
01753 {
01754 SBPL_ERROR("[getPlanningStats] Can not compute final pose of trajectory.\n");
01755 return stats;
01756 }
01757
01758
01759 if(prms_.use_research_heuristic_)
01760 {
01761 if(arm_->computeFK(final_joint_config, 7, pose))
01762 {
01763 grid_->worldToGrid(pose[0],pose[1],pose[2],x,y,z);
01764 for(size_t i = 0; i < elbow_cells_.size(); i++)
01765 {
01766 if(elbow_cells_[i][0] == x && elbow_cells_[i][1] == y && elbow_cells_[i][2] ==z)
01767 in_list = true;
01768 }
01769 }
01770 }
01771
01772
01773 stats.push_back(EnvROBARMCfg.goal_to_obstacle_distance);
01774
01775
01776 stats.push_back(fabs(EnvROBARMCfg.EndEffGoals[0].pos[0] - pose[0]));
01777 stats.push_back(fabs(EnvROBARMCfg.EndEffGoals[0].pos[1] - pose[1]));
01778 stats.push_back(fabs(EnvROBARMCfg.EndEffGoals[0].pos[2] - pose[2]));
01779 stats.push_back(fabs(EnvROBARMCfg.EndEffGoals[0].rpy[0] - pose[3]));
01780 stats.push_back(fabs(EnvROBARMCfg.EndEffGoals[0].rpy[1] - pose[4]));
01781 stats.push_back(fabs(EnvROBARMCfg.EndEffGoals[0].rpy[2] - pose[5]));
01782
01783
01784
01785
01786
01787
01788 stats.push_back(EnvROBARMCfg.num_calls_to_ik);
01789 stats.push_back(EnvROBARMCfg.num_no_ik_solutions);
01790 stats.push_back(EnvROBARMCfg.num_invalid_ik_solutions);
01791 stats.push_back(EnvROBARMCfg.num_ik_invalid_path);
01792
01793
01794 stats.push_back(EnvROBARMCfg.num_expands_to_position_constraint);
01795
01796 stats.push_back(EnvROBARMCfg.solved_by_ik);
01797 stats.push_back(EnvROBARMCfg.solved_by_os);
01798
01799
01800 stats.push_back(elbow_cells_.size());
01801
01802
01803 stats.push_back(double(in_list));
01804
01805 return stats;
01806 }
01807
01808 bool EnvironmentROBARM3D::getElbowCellsAtGoal(std::vector<int> &shoulder, std::vector<double> &goal_m, double rad1, double rad2, std::vector<std::vector<int> > &cells)
01809 {
01810 std::vector<int> cell(3,0), goal(3,0);
01811 std::list<std::vector<int> > valid_cells;
01812 std::vector<double> angles(7,0);
01813 std::vector<std::vector<double> > points_vector;
01814
01815 grid_->worldToGrid(goal_m[0], goal_m[1], goal_m[2], cell[0], cell[1], cell[2]);
01816
01817
01818 coordToAngles(EnvROBARM.startHashEntry->coord, angles);
01819
01820 points_vector = elbow_positions_given_endeff_pose(angles::normalize_angle(angles[0]), prms_.getSmallestShoulderPanMotion(), goal_m[0], goal_m[1], goal_m[2]);
01821 std::list<std::vector<double> > valid_points(points_vector.begin(), points_vector.end());
01822
01823 if(points_vector.empty())
01824 {
01825 SBPL_ERROR("No potential elbow cells found. Exiting.");
01826 return false;
01827 }
01828
01829
01830 elbow_poses_ = points_vector;
01831
01832
01833 for(std::list<std::vector<double> >::iterator it = valid_points.begin(); it != valid_points.end(); ++it)
01834 {
01835 grid_->worldToGrid((*it)[0], (*it)[1], (*it)[2], cell[0], cell[1], cell[2]);
01836 valid_cells.push_back(cell);
01837 }
01838
01839 SBPL_DEBUG("[getElbowCellsAtGoal] There are %d cells before removing of duplicates",int(valid_cells.size()));
01840
01841
01842 valid_cells.sort(xyzCompare);
01843
01844 std::list<std::vector<int> >::iterator last_dup, next_it, end_it, delete_it;
01845
01846 end_it = valid_cells.end();
01847 end_it--;
01848
01849
01850 for(std::list<std::vector<int> >::iterator it = valid_cells.begin(); it != end_it; ++it)
01851 {
01852 next_it = it;
01853 next_it++;
01854
01855 for (std::list<std::vector<int> >::iterator jt = next_it; jt != valid_cells.end(); ++jt)
01856 {
01857 last_dup = jt;
01858
01859 if((*it)[0] != (*jt)[0] || (*it)[1] != (*jt)[1] || (*it)[2] != (*jt)[2])
01860 break;
01861
01862
01863 }
01864
01865 if(last_dup != next_it)
01866 valid_cells.erase(next_it, last_dup);
01867
01868
01869 if(cspace_->isValidLineSegment(goal, (*it), rad1) <= rad1)
01870 {
01871 delete_it = it;
01872 it--;
01873 valid_cells.erase(delete_it);
01874 }
01875 else if(cspace_->isValidLineSegment(shoulder, (*it), rad2) <= rad2)
01876 {
01877 delete_it = it;
01878 it--;
01879 valid_cells.erase(delete_it);
01880 }
01881 }
01882
01883 SBPL_DEBUG("After removing duplicates & points in collision, %d cells remain.", int(valid_cells.size()));
01884
01885 for(std::list<std::vector<int> >::iterator it = valid_cells.begin(); it != valid_cells.end(); ++it)
01886 cells.push_back((*it));
01887
01888 elbow_cells_ = cells;
01889 return true;
01890 }
01891
01892 int EnvironmentROBARM3D::getElbowHeuristic(int FromStateID, int ToStateID)
01893 {
01894 int x,y,z,heur = 0;
01895 std::vector<double> angles(7,0);
01896 KDL::Frame F;
01897 std::vector<std::vector<double> > links;
01898
01899 EnvROBARM3DHashEntry_t* FromHashEntry = EnvROBARM.StateID2CoordTable[FromStateID];
01900
01901 if(!prms_.use_research_heuristic_)
01902 return 0;
01903
01904
01905 coordToAngles(FromHashEntry->coord, angles);
01906 arm_->getJointPositions(angles, links, F);
01907
01908 grid_->worldToGrid(links[1][0],links[1][1],links[1][2],x,y,z);
01909
01910
01911 if(prms_.use_dijkstra_heuristic_)
01912 heur = elbow_dijkstra_->getDist(x,y,z);
01913
01914 return heur;
01915 }
01916
01917 int EnvironmentROBARM3D::getEndEffectorHeuristic(int FromStateID, int ToStateID)
01918 {
01919 int heur = 0, closest_goal = 0;
01920 double FromEndEff_m[3];
01921 double edist_to_goal_m;
01922
01923
01924 EnvROBARM3DHashEntry_t* FromHashEntry = EnvROBARM.StateID2CoordTable[FromStateID];
01925 int temp[3] = {FromHashEntry->xyz[0], FromHashEntry->xyz[1], FromHashEntry->xyz[2]};
01926
01927
01928 grid_->gridToWorld(FromHashEntry->xyz[0],FromHashEntry->xyz[1],FromHashEntry->xyz[2],FromEndEff_m[0],FromEndEff_m[1],FromEndEff_m[2]);
01929 edist_to_goal_m = getDistToClosestGoal(FromEndEff_m, &closest_goal);
01930
01931
01932 if(prms_.use_dijkstra_heuristic_)
01933 heur = dijkstra_->getDist(temp[0],temp[1],temp[2]);
01934 else
01935 heur = edist_to_goal_m * prms_.cost_per_meter_;
01936
01937
01938 FromHashEntry->heur = heur;
01939
01940 return heur;
01941 }
01942
01943 int EnvironmentROBARM3D::getCombinedHeuristic(int FromStateID, int ToStateID)
01944 {
01945 int h_endeff = 0, h_elbow = 0, heur = 0;
01946
01947 h_endeff = getEndEffectorHeuristic(FromStateID, ToStateID);
01948 h_elbow = getElbowHeuristic(FromStateID, ToStateID);
01949
01950
01951 if(prms_.sum_heuristics_ == 1)
01952 heur = h_endeff + h_elbow;
01953
01954 else
01955 heur = max(h_endeff, h_elbow);
01956
01957 #if DEBUG_HEURISTIC
01958 SBPL_DEBUG_NAMED("heuristic","%5d: h_endeff: %5d h_elbow: %5d heur: %5d", FromStateID, h_endeff, h_elbow, heur);
01959 #endif
01960
01961 return heur;
01962 }
01963
01964 void EnvironmentROBARM3D::getElbowPoints(std::vector<std::vector<double> > &elbow_points)
01965 {
01966 elbow_points = elbow_poses_;
01967 }
01968
01969 }
01970