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/sbpl_arm_planner_params.h>
00032
00033 SBPLArmPlannerParams::SBPLArmPlannerParams()
00034 {
00035 epsilon_ = 10;
00036 use_multires_mprims_ = true;
00037 use_dijkstra_heuristic_ = true;
00038 use_smoothing_ = false;
00039 use_6d_pose_goal_ = true;
00040 sum_heuristics_ = false;
00041 use_uniform_cost_ = true;
00042 use_ik_ = true;
00043 use_orientation_solver_ = true;
00044
00045 verbose_ = false;
00046 verbose_heuristics_ = false;
00047 verbose_collisions_ = false;
00048 angle_delta_ = 360;
00049
00050 num_mprims_ = 0;
00051 num_long_dist_mprims_ = 0;
00052 num_short_dist_mprims_ = 0;
00053
00054 short_dist_mprims_thresh_c_ = 20;
00055 short_dist_mprims_thresh_m_ = 0.2;
00056
00057 cost_multiplier_ = 1000;
00058 cost_per_cell_ = 0;
00059 cost_per_meter_ = 0;
00060
00061 range1_cost_ = 12;
00062 range2_cost_ = 7;
00063 range3_cost_ = 2;
00064
00065 solve_for_ik_thresh_ = 1000;
00066 solve_for_ik_thresh_m_= 0.20;
00067
00068 two_calls_to_op_ = false;
00069 is_goal_function_ = 0;
00070 }
00071
00072 void SBPLArmPlannerParams::initFromParamServer()
00073 {
00074 ros::NodeHandle nh("~");
00075
00076
00077 nh.param("planner/epsilon",epsilon_, 10.0);
00078 nh.param("planner/use_dijkstra_heuristic",use_dijkstra_heuristic_,true);
00079 nh.param("planner/use_research_heuristic",use_research_heuristic_,false);
00080 nh.param("planner/use_multiresolution_motion_primitives",use_multires_mprims_,true);
00081 nh.param("planner/use_uniform_obstacle_cost", use_uniform_cost_,false);
00082 nh.param("planner/verbose",verbose_,false);
00083 nh.param("planner/obstacle_distance_cost_far",range3_cost_,12);
00084 nh.param("planner/obstacle_distance_cost_mid",range2_cost_,7);
00085 nh.param("planner/obstacle_distance_cost_near",range1_cost_,2);
00086
00087
00088 nh.param("planner/research/solve_with_ik_threshold",solve_for_ik_thresh_m_,0.15);
00089 nh.param("planner/research/sum_heuristics",sum_heuristics_,false);
00090 nh.param("planner/research/short_distance_mprims_threshold",short_dist_mprims_thresh_m_, 0.2);
00091
00092
00093 nh.param("collision_space/resolution",resolution_,0.02);
00094 nh.param("collision_space/occupancy_grid/origin_x",originX_,-0.6);
00095 nh.param("collision_space/occupancy_grid/origin_y",originY_,-1.15);
00096 nh.param("collision_space/occupancy_grid/origin_z",originZ_,-0.05);
00097 nh.param("collision_space/occupancy_grid/size_x",sizeX_,1.6);
00098 nh.param("collision_space/occupancy_grid/size_y",sizeY_,1.8);
00099 nh.param("collision_space/occupancy_grid/size_z",sizeZ_,1.4);
00100 }
00101
00102 bool SBPLArmPlannerParams::initFromParamFile(std::string param_file)
00103 {
00104 char* filename = new char[param_file.length()+1];
00105 param_file.copy(filename, param_file.length(),0);
00106 filename[param_file.length()] = '\0';
00107 FILE* fCfg = fopen(filename, "r");
00108
00109 if(initFromParamFile(fCfg))
00110 {
00111 delete filename;
00112 SBPL_FCLOSE(fCfg);
00113 delete fCfg;
00114 return true;
00115 }
00116 else
00117 {
00118 delete filename;
00119 SBPL_FCLOSE(fCfg);
00120 delete fCfg;
00121 return false;
00122 }
00123 }
00124
00125 bool SBPLArmPlannerParams::initMotionPrimsFromFile(FILE* fCfg)
00126 {
00127 char sTemp[1024];
00128 int nrows=0,ncols=0, short_mprims=0;
00129
00130
00131 if(fCfg == NULL)
00132 {
00133 SBPL_ERROR("ERROR: unable to open the params file. Exiting.");
00134 return false;
00135 }
00136
00137 if(fscanf(fCfg,"%s",sTemp) < 1)
00138 SBPL_WARN("Parsed string has length < 1.");
00139 if(strcmp(sTemp, "Motion_Primitives(degrees):") != 0)
00140 {
00141 SBPL_ERROR("ERROR: First line of motion primitive file should be 'Motion_Primitives(degrees):'. Please check your file. (parsed string: %s)\n", sTemp);
00142 return false;
00143 }
00144
00145
00146 if(fscanf(fCfg,"%s",sTemp) < 1)
00147 {
00148 SBPL_WARN("Parsed string has length < 1.");
00149 return false;
00150 }
00151 else
00152 nrows = atoi(sTemp);
00153
00154
00155 if(fscanf(fCfg,"%s",sTemp) < 1)
00156 {
00157 SBPL_WARN("Parsed string has length < 1.");
00158 return false;
00159 }
00160 else
00161 ncols = atoi(sTemp);
00162
00163
00164 if(fscanf(fCfg,"%s",sTemp) < 1)
00165 {
00166 SBPL_WARN("Parsed string has length < 1.");
00167 return false;
00168 }
00169 else
00170 short_mprims = atoi(sTemp);
00171
00172 std::vector<double> mprim(ncols,0);
00173
00174 for (int i=0; i < nrows; ++i)
00175 {
00176 for(int j=0; j < ncols; ++j)
00177 {
00178 if(fscanf(fCfg,"%s",sTemp) < 1)
00179 SBPL_WARN("Parsed string has length < 1.");
00180 if(!feof(fCfg) && strlen(sTemp) != 0)
00181 mprim[j] = atof(sTemp);
00182 else
00183 {
00184 SBPL_ERROR("ERROR: End of parameter file reached prematurely. Check for newline.");
00185 return false;
00186 }
00187 }
00188 if(i < (nrows-short_mprims))
00189 addMotionPrim(mprim,true,false);
00190 else
00191 addMotionPrim(mprim,true,true);
00192 }
00193
00194 max_mprim_offset_ = getLargestMotionPrimOffset();
00195
00196 return true;
00197 }
00198
00199 bool SBPLArmPlannerParams::initFromParamFile(FILE* fCfg)
00200 {
00201 char sTemp[1024];
00202 int nrows=0,ncols=0, short_mprims=0;
00203
00204 if(fCfg == NULL)
00205 {
00206 SBPL_ERROR("ERROR: unable to open the params file. Exiting.\n");
00207 return false;
00208 }
00209
00210 if(fscanf(fCfg,"%s",sTemp) < 1)
00211 SBPL_PRINTF("Parsed string has length < 1.\n");
00212 while(!feof(fCfg) && strlen(sTemp) != 0)
00213 {
00214 if(strcmp(sTemp, "environment_size(meters):") == 0)
00215 {
00216 if(fscanf(fCfg,"%s",sTemp) < 1)
00217 SBPL_PRINTF("Parsed string has length < 1.\n");
00218 sizeX_ = atof(sTemp);
00219 if(fscanf(fCfg,"%s",sTemp) < 1)
00220 SBPL_PRINTF("Parsed string has length < 1.\n");
00221 sizeY_ = atof(sTemp);
00222 if(fscanf(fCfg,"%s",sTemp) < 1)
00223 SBPL_PRINTF("Parsed string has length < 1.\n");
00224 sizeZ_ = atof(sTemp);
00225 }
00226 else if(strcmp(sTemp, "environment_origin(meters):") == 0)
00227 {
00228 if(fscanf(fCfg,"%s",sTemp) < 1)
00229 SBPL_PRINTF("Parsed string has length < 1.\n");
00230 originX_ = atof(sTemp);
00231 if(fscanf(fCfg,"%s",sTemp) < 1)
00232 SBPL_PRINTF("Parsed string has length < 1.\n");
00233 originY_ = atof(sTemp);
00234 if(fscanf(fCfg,"%s",sTemp) < 1)
00235 SBPL_PRINTF("Parsed string has length < 1.\n");
00236 originZ_ = atof(sTemp);
00237 }
00238 else if(strcmp(sTemp, "resolution(meters):") == 0)
00239 {
00240 if(fscanf(fCfg,"%s",sTemp) < 1)
00241 SBPL_PRINTF("Parsed string has length < 1.\n");
00242 resolution_ = atof(sTemp);
00243 }
00244 else if(strcmp(sTemp, "use_dijkstra_heuristic:") == 0)
00245 {
00246 if(fscanf(fCfg,"%s",sTemp) < 1)
00247 SBPL_PRINTF("Parsed string has length < 1.\n");
00248 use_dijkstra_heuristic_ = atoi(sTemp);
00249 }
00250 else if(strcmp(sTemp, "use_orientation_solver:") == 0)
00251 {
00252 if(fscanf(fCfg,"%s",sTemp) < 1)
00253 SBPL_PRINTF("Parsed string has length < 1.\n");
00254 use_orientation_solver_ = atoi(sTemp);
00255 }
00256 else if(strcmp(sTemp, "use_ik:") == 0)
00257 {
00258 if(fscanf(fCfg,"%s",sTemp) < 1)
00259 SBPL_PRINTF("Parsed string has length < 1.\n");
00260 use_ik_ = atoi(sTemp);
00261 }
00262 else if(strcmp(sTemp, "sum_heuristics:") == 0)
00263 {
00264 if(fscanf(fCfg,"%s",sTemp) < 1)
00265 SBPL_PRINTF("Parsed string has length < 1.\n");
00266 sum_heuristics_ = atoi(sTemp);
00267 }
00268 else if(strcmp(sTemp, "use_research_heuristic:") == 0)
00269 {
00270 if(fscanf(fCfg,"%s",sTemp) < 1)
00271 SBPL_PRINTF("Parsed string has length < 1.\n");
00272 use_research_heuristic_ = atoi(sTemp);
00273 }
00274 else if(strcmp(sTemp, "plan_to_6d_pose_constraint:") == 0)
00275 {
00276 if(fscanf(fCfg,"%s",sTemp) < 1)
00277 SBPL_PRINTF("Parsed string has length < 1.\n");
00278 use_6d_pose_goal_ = atoi(sTemp);
00279 }
00280 else if(strcmp(sTemp,"planner_epsilon:") == 0)
00281 {
00282 if(fscanf(fCfg,"%s",sTemp) < 1)
00283 SBPL_PRINTF("Parsed string has length < 1.\n");
00284 epsilon_ = atof(sTemp);
00285 }
00286 else if(strcmp(sTemp,"use_multiresolution_motion_primitives:") == 0)
00287 {
00288 if(fscanf(fCfg,"%s",sTemp) < 1)
00289 SBPL_PRINTF("Parsed string has length < 1.\n");
00290 use_multires_mprims_ = atoi(sTemp);
00291 }
00292 else if(strcmp(sTemp,"use_uniform_obstacle_cost:") == 0)
00293 {
00294 if(fscanf(fCfg,"%s",sTemp) < 1)
00295 SBPL_PRINTF("Parsed string has length < 1.\n");
00296 use_uniform_cost_ = atoi(sTemp);
00297 }
00298 else if(strcmp(sTemp,"short_distance_mprims_threshold(meters):") == 0)
00299 {
00300 if(fscanf(fCfg,"%s",sTemp) < 1)
00301 SBPL_PRINTF("Parsed string has length < 1.\n");
00302 short_dist_mprims_thresh_m_ = atof(sTemp);
00303 }
00304 else if(strcmp(sTemp,"check_if_at_goal_function(0:IK,1:OP):") == 0)
00305 {
00306 if(fscanf(fCfg,"%s",sTemp) < 1)
00307 SBPL_PRINTF("Parsed string has length < 1.\n");
00308 is_goal_function_ = atoi(sTemp);
00309 }
00310 else if(strcmp(sTemp,"two_calls_to_orientation_planner:") == 0)
00311 {
00312 if(fscanf(fCfg,"%s",sTemp) < 1)
00313 SBPL_PRINTF("Parsed string has length < 1.\n");
00314 two_calls_to_op_ = atoi(sTemp);
00315 }
00316 else if(strcmp(sTemp,"verbose:") == 0)
00317 {
00318 if(fscanf(fCfg,"%s",sTemp) < 1)
00319 SBPL_PRINTF("Parsed string has length < 1.");
00320 verbose_ = atoi(sTemp);
00321 }
00322 else if(strcmp(sTemp,"solve_for_ik_threshold(distance):") == 0)
00323 {
00324 if(fscanf(fCfg,"%s",sTemp) < 1)
00325 SBPL_PRINTF("Parsed string has length < 1.");
00326 solve_for_ik_thresh_m_ = atof(sTemp);
00327 }
00328
00329
00330 else if(strcmp(sTemp, "Motion_Primitives(degrees):") == 0)
00331 {
00332 break;
00333 }
00334
00335 else
00336 {
00337 SBPL_PRINTF("Error: Invalid Field name (%s) in parameter file.",sTemp);
00338
00339 }
00340 if(fscanf(fCfg,"%s",sTemp) < 1)
00341 SBPL_PRINTF("Parsed string has length < 1.");
00342 }
00343
00344
00345
00346 if(fscanf(fCfg,"%s",sTemp) < 1)
00347 {
00348 SBPL_PRINTF("Parsed string has length < 1.");
00349 return false;
00350 }
00351 else
00352 nrows = atoi(sTemp);
00353
00354
00355 if(fscanf(fCfg,"%s",sTemp) < 1)
00356 {
00357 SBPL_PRINTF("Parsed string has length < 1.");
00358 return false;
00359 }
00360 else
00361 ncols = atoi(sTemp);
00362
00363
00364 if(fscanf(fCfg,"%s",sTemp) < 1)
00365 {
00366 SBPL_PRINTF("Parsed string has length < 1.");
00367 return false;
00368 }
00369 else
00370 short_mprims = atoi(sTemp);
00371
00372 std::vector<double> mprim(ncols,0);
00373
00374 for (int i=0; i < nrows; ++i)
00375 {
00376 for(int j=0; j < ncols; ++j)
00377 {
00378 if(fscanf(fCfg,"%s",sTemp) < 1)
00379 SBPL_WARN("Parsed string has length < 1.");
00380 if(!feof(fCfg) && strlen(sTemp) != 0)
00381 mprim[j] = atof(sTemp);
00382 else
00383 {
00384 SBPL_ERROR("ERROR: End of parameter file reached prematurely. Check for newline.");
00385 return false;
00386 }
00387 }
00388 if(i < (nrows-short_mprims))
00389 addMotionPrim(mprim,true,false);
00390 else
00391 addMotionPrim(mprim,true,true);
00392 }
00393
00394
00395 short_dist_mprims_thresh_c_ = short_dist_mprims_thresh_m_ / resolution_;
00396
00397 solve_for_ik_thresh_ = (solve_for_ik_thresh_m_ /resolution_) * cost_per_cell_;
00398
00399 max_mprim_offset_ = getLargestMotionPrimOffset();
00400
00401 SBPL_PRINTF("Successfully parsed parameters file");
00402 return true;
00403 }
00404
00405 void SBPLArmPlannerParams::setCellCost(int cost_per_cell)
00406 {
00407 cost_per_cell_ = cost_per_cell;
00408 solve_for_ik_thresh_ = (solve_for_ik_thresh_m_ / resolution_) * cost_per_cell_;
00409 short_dist_mprims_thresh_c_ = short_dist_mprims_thresh_m_/resolution_ * cost_per_cell;
00410 }
00411
00412 void SBPLArmPlannerParams::addMotionPrim(std::vector<double> mprim, bool add_converse, bool short_dist_mprim)
00413 {
00414 if(short_dist_mprim)
00415 {
00416 mprims_.push_back(mprim);
00417 num_short_dist_mprims_++;
00418 if(add_converse)
00419 {
00420 for(int i = 0; i < int(mprim.size()); ++i)
00421 {
00422 if(mprim[i] != 0)
00423 mprim[i] *= -1;
00424 }
00425 mprims_.push_back(mprim);
00426 num_short_dist_mprims_++;
00427 }
00428 }
00429 else
00430 {
00431 std::vector<std::vector<double> >::iterator it_long_dist;
00432 it_long_dist = mprims_.begin();
00433 if(num_long_dist_mprims_ > 1)
00434 {
00435 advance(it_long_dist,num_long_dist_mprims_);
00436 mprims_.insert(it_long_dist, mprim);
00437 }
00438 else if(it_long_dist == mprims_.end() || mprims_.empty())
00439 mprims_.push_back(mprim);
00440
00441 num_long_dist_mprims_++;
00442 if(add_converse)
00443 {
00444 for(int i = 0; i < int(mprim.size()); ++i)
00445 {
00446 if(mprim[i] != 0)
00447 mprim[i] *= -1;
00448 }
00449
00450 it_long_dist=mprims_.begin();
00451 advance(it_long_dist,num_long_dist_mprims_);
00452 mprims_.insert(it_long_dist,mprim);
00453 num_long_dist_mprims_++;
00454 }
00455 }
00456 num_mprims_ = num_short_dist_mprims_ + num_long_dist_mprims_;
00457 }
00458
00459 void SBPLArmPlannerParams::printMotionPrims(FILE* fOut)
00460 {
00461 int i;
00462 SBPL_FPRINTF(fOut,"Long Distance Motion Primitives: %d\n", num_long_dist_mprims_);
00463 for(i = 0; i < num_long_dist_mprims_; ++i)
00464 {
00465 SBPL_FPRINTF(fOut,"%2d: ",i);
00466 for(int j = 0; j < int(mprims_[i].size()); ++j)
00467 SBPL_FPRINTF(fOut,"%4.1f ",mprims_[i][j]);
00468 SBPL_FPRINTF(fOut,"\n");
00469 }
00470
00471 SBPL_FPRINTF(fOut,"Short Distance Motion Primitives: %d\n", num_short_dist_mprims_);
00472 for(; i < num_mprims_; ++i)
00473 {
00474 SBPL_FPRINTF(fOut,"%2d: ",i);
00475 for(int j = 0; j < int(mprims_[i].size()); ++j)
00476 SBPL_FPRINTF(fOut,"%4.1f ",mprims_[i][j]);
00477 SBPL_FPRINTF(fOut,"\n");
00478 }
00479 }
00480
00481 void SBPLArmPlannerParams::printParams(FILE* fOut)
00482 {
00483 SBPL_DEBUG_NAMED(fOut,"\nArm Planner Parameters:\n");
00484 SBPL_DEBUG_NAMED(fOut,"%40s: %d\n", "# motion primitives",num_mprims_);
00485 SBPL_DEBUG_NAMED(fOut,"%40s: %d\n", "# short distance motion primitives", num_short_dist_mprims_);
00486 SBPL_DEBUG_NAMED(fOut,"%40s: %d\n", "# long distance motion primitives", num_long_dist_mprims_);
00487 SBPL_DEBUG_NAMED(fOut,"%40s: %.2f\n", "epsilon",epsilon_);
00488 SBPL_DEBUG_NAMED(fOut,"%40s: %s\n", "use multi-resolution motion primitives", use_multires_mprims_ ? "yes" : "no");
00489 SBPL_DEBUG_NAMED(fOut,"%40s: %s\n", "use dijkstra heuristic", use_dijkstra_heuristic_ ? "yes" : "no");
00490 SBPL_DEBUG_NAMED(fOut,"%40s: %s\n", "use research heuristic", use_research_heuristic_ ? "yes" : "no");
00491 SBPL_DEBUG_NAMED(fOut,"%40s: %s\n", "h = h_elbow + h_endeff", sum_heuristics_ ? "yes" : "no");
00492 SBPL_DEBUG_NAMED(fOut,"%40s: %s\n", "use a uniform cost",use_uniform_cost_ ? "yes" : "no");
00493 SBPL_DEBUG_NAMED(fOut,"%40s: %d\n", "cost per cell", cost_per_cell_);
00494 SBPL_DEBUG_NAMED(fOut,"%40s: %.5f\n", "distance from goal to start using IK:",solve_for_ik_thresh_m_);
00495 SBPL_DEBUG_NAMED(fOut,"%40s: %d\n", "cost from goal to start using IK:",solve_for_ik_thresh_);
00496 SBPL_DEBUG_NAMED(fOut,"\n");
00497 }
00498
00499 void SBPLArmPlannerParams::precomputeSmoothingCosts()
00500 {
00501 int i,x,y;
00502 double temp = 0.0;
00503
00504 smoothing_cost_.resize(num_mprims_);
00505
00506 for (x = 0; x < num_mprims_; x++)
00507 {
00508 smoothing_cost_[x].resize(num_mprims_);
00509 for (y = 0; y < num_mprims_; y++)
00510 {
00511 temp = 0.0;
00512 for (i = 0; i < int(mprims_[y].size()); i++)
00513 temp += ((mprims_[x][i]-mprims_[y][i])*(mprims_[x][i]-mprims_[y][i]));
00514
00515 smoothing_cost_[x][y] = temp * (double)cost_multiplier_ * (double)use_smoothing_;
00516 }
00517 }
00518 }
00519
00520 void SBPLArmPlannerParams::printSmoothingCosts(FILE* fOut)
00521 {
00522 int x,y;
00523
00524 if(fOut == NULL)
00525 fOut = stdout;
00526
00527 if(smoothing_cost_.empty())
00528 return;
00529
00530 SBPL_FPRINTF(fOut,"Smoothing Costs Table:\n");
00531 SBPL_FPRINTF(fOut," ");
00532 for(x = 0; x < num_mprims_; x++)
00533 SBPL_FPRINTF(fOut, "%4d ",x);
00534 SBPL_FPRINTF(fOut,"\n");
00535
00536 for (x = 0; x < int(smoothing_cost_.size()); x++)
00537 {
00538 SBPL_FPRINTF(fOut,"%2d: ",x);
00539 for (y = 0; y < int(smoothing_cost_[x].size()); y++)
00540 SBPL_FPRINTF(fOut,"%4d ", smoothing_cost_[x][y]);
00541 SBPL_FPRINTF(fOut,"\n");
00542 }
00543 }
00544
00545 double SBPLArmPlannerParams::getSmallestShoulderPanMotion()
00546 {
00547 double min_pan = 360.0;
00548 for (int i = 0; i < num_mprims_; i++)
00549 {
00550 if(mprims_[i][0] > 0 && mprims_[i][0] < min_pan)
00551 min_pan = mprims_[i][0];
00552 }
00553
00554 min_pan = angles::normalize_angle(angles::from_degrees(min_pan));
00555 SBPL_PRINTF("[getSmallestShoulderPanMotion] Smallest shoulder pan motion is %0.3f rad.\n", min_pan);
00556
00557 return min_pan;
00558 }
00559
00560 double SBPLArmPlannerParams::getLargestMotionPrimOffset()
00561 {
00562 double max_offset = 0;
00563 for (int i = 0; i < num_mprims_; i++)
00564 {
00565 for(size_t j = 0; j < mprims_[i].size(); j++)
00566 {
00567 if(fabs(mprims_[i][j]) > max_offset)
00568 max_offset = fabs(mprims_[i][j]);
00569 }
00570 }
00571
00572 max_offset = angles::normalize_angle(angles::from_degrees(max_offset));
00573 SBPL_PRINTF("[getLargestMotionPrimOffset] Largest single Joint Offset in all Motion Prims is %0.3f rad.\n", max_offset);
00574
00575 return max_offset;
00576 }
00577