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_model.h>
00032 #include <tf_conversions/tf_kdl.h>
00033
00034 using namespace std;
00035
00036 SBPLArmModel::SBPLArmModel(FILE* arm_file) : fk_solver_(NULL), ik_fk_solver_(NULL), ik_solver_(NULL), ik_solver_vel_(NULL), pr2_arm_ik_solver_(NULL)
00037 {
00038 num_joints_ = 7;
00039 num_links_ = 3;
00040 chain_root_name_ = "base_link";
00041 chain_tip_name_ = "r_wrist_roll_link";
00042 planning_joint_name_ = "r_wrist_roll_link";
00043 reference_frame_ = "base_link";
00044
00045 joints_.resize(num_joints_);
00046 links_.resize(num_links_);
00047
00048 for(unsigned int i = 0; i < joints_.size(); ++i)
00049 joints_[i].continuous = true;
00050
00051
00052 if(!getArmDescription(arm_file))
00053 SBPL_WARN("Parsing of sbpl arm description file failed. Will attempt to use defaults.");
00054
00055 fOut_ = stdout;
00056 max_radius_ = 0;
00057 resolution_ = 0.01;
00058 }
00059
00060 SBPLArmModel::~SBPLArmModel()
00061 {
00062 if(fk_solver_ != NULL)
00063 delete fk_solver_;
00064 if(ik_fk_solver_ != NULL)
00065 delete ik_fk_solver_;
00066 if(ik_solver_ != NULL)
00067 delete ik_solver_;
00068 if(ik_solver_vel_ != NULL)
00069 delete ik_solver_vel_;
00070 if(pr2_arm_ik_solver_ != NULL)
00071 delete pr2_arm_ik_solver_;
00072 }
00073
00074 void SBPLArmModel::setDebugFile(FILE* file)
00075 {
00076 fOut_ = file;
00077 }
00078
00079 bool SBPLArmModel::getArmDescription(FILE* fCfg)
00080 {
00081 if(fCfg == NULL)
00082 return false;
00083
00084 char sTemp[1024];
00085 int i;
00086
00087 if(fscanf(fCfg,"%s",sTemp) < 1)
00088 SBPL_WARN("Parsed string has length < 1.");
00089 while(!feof(fCfg) && strlen(sTemp) != 0)
00090 {
00091 if(strcmp(sTemp, "number_of_joints:") == 0)
00092 {
00093 if(fscanf(fCfg,"%s",sTemp) < 1)
00094 SBPL_WARN("Parsed string has length < 1.");
00095 num_joints_ = atoi(sTemp);
00096 joints_.resize(num_joints_);
00097 }
00098 else if(strcmp(sTemp, "number_of_links:") == 0)
00099 {
00100 if(fscanf(fCfg,"%s",sTemp) < 1)
00101 SBPL_WARN("Parsed string has length < 1.");
00102 num_links_ = atoi(sTemp);
00103 links_.resize(num_links_);
00104 }
00105 else if(strcmp(sTemp, "index_of_planning_joint:") == 0)
00106 {
00107 if(fscanf(fCfg,"%s",sTemp) < 1)
00108 SBPL_WARN("Parsed string has length < 1.");
00109 planning_joint_ = atoi(sTemp);
00110 }
00111 else if(strcmp(sTemp, "kdl_chain_root_name:") == 0)
00112 {
00113 if(fscanf(fCfg,"%s",sTemp) < 1)
00114 SBPL_WARN("Parsed string has length < 1.");
00115 chain_root_name_.assign(sTemp);
00116 }
00117 else if(strcmp(sTemp, "kdl_chain_tip_name:") == 0)
00118 {
00119 if(fscanf(fCfg,"%s",sTemp) < 1)
00120 SBPL_WARN("Parsed string has length < 1.");
00121 chain_tip_name_.assign(sTemp);
00122 }
00123 else if(strcmp(sTemp, "planning_joint_name:") == 0)
00124 {
00125 if(fscanf(fCfg,"%s",sTemp) < 1)
00126 SBPL_WARN("Parsed string has length < 1.");
00127 planning_joint_name_.assign(sTemp);
00128 }
00129 else if(strcmp(sTemp, "min_joint_limits:") == 0)
00130 {
00131 for(i = 0; i < num_joints_; i++)
00132 {
00133 if(fscanf(fCfg,"%s",sTemp) < 1)
00134 SBPL_WARN("Parsed string has length < 1.");
00135 joints_[i].min = atof(sTemp);
00136
00137 if(joints_[i].min != 0.0)
00138 joints_[i].continuous = false;
00139 }
00140 }
00141 else if(strcmp(sTemp, "max_joint_limits:") == 0)
00142 {
00143 for(i = 0; i < num_joints_; i++)
00144 {
00145 if(fscanf(fCfg,"%s",sTemp) < 1)
00146 SBPL_WARN("Parsed string has length < 1.");
00147 joints_[i].max = atof(sTemp);
00148
00149 if(joints_[i].max != 0.0)
00150 joints_[i].continuous = false;
00151 }
00152 }
00153 else if(strcmp(sTemp, "radius_of_links(meters):") == 0)
00154 {
00155 for(i = 0; i < num_links_; i++)
00156 {
00157 if(fscanf(fCfg,"%s",sTemp) < 1)
00158 SBPL_WARN("Parsed string has length < 1.");
00159 links_[i].radius = atof(sTemp);
00160 }
00161 }
00162 else if(strcmp(sTemp, "length_of_links(meters):") == 0)
00163 {
00164 for(i = 0; i < num_links_; i++)
00165 {
00166 if(fscanf(fCfg,"%s",sTemp) < 1)
00167 SBPL_WARN("Parsed string has length < 1.");
00168 links_[i].length = atof(sTemp);
00169 }
00170 }
00171 else if(strcmp(sTemp, "collision_cuboids:") == 0)
00172 {
00173 if(fscanf(fCfg,"%s",sTemp) < 1)
00174 SBPL_WARN("Parsed string has length < 1.");
00175
00176 num_collision_cuboids_ = atoi(sTemp);
00177 collision_cuboids_.resize(num_collision_cuboids_);
00178 for(i = 0; i < num_collision_cuboids_; i++)
00179 {
00180 collision_cuboids_[i].resize(6);
00181 for(int j = 0; j < 6; j++)
00182 {
00183 if(fscanf(fCfg,"%s",sTemp) < 1)
00184 SBPL_WARN("Parsed string has length < 1.");
00185 collision_cuboids_[i][j] = atof(sTemp);
00186 }
00187 }
00188 SBPL_DEBUG("Number of collision cuboids: %d", num_collision_cuboids_);
00189 }
00190 else if(strcmp(sTemp, "kdl_indeces_of_link_tips:") == 0)
00191 {
00192 joint_indeces_.resize(num_links_+1);
00193 for(i = 0; i < num_links_ + 1; i++)
00194 {
00195 if(fscanf(fCfg,"%s",sTemp) < 1)
00196 SBPL_WARN("Parsed string has length < 1.");
00197
00198 joint_indeces_[i] = atoi(sTemp);
00199 }
00200 }
00201
00202 if(fscanf(fCfg,"%s",sTemp) < 1)
00203 SBPL_DEBUG("Parsed string has length < 1.");
00204 }
00205
00206 SBPL_DEBUG("[getArmDescription] Finished parsing arm file.");
00207 return true;
00208 }
00209
00210 void SBPLArmModel::setResolution(double resolution)
00211 {
00212 resolution_ = resolution;
00213
00214
00215 for(int i = 0; i < num_links_; i++)
00216 {
00217 links_[i].radius_c = (links_[i].radius / resolution_) + 0.5;
00218 links_[i].length_c = (links_[i].length / resolution_) + 0.5;
00219
00220 if(links_[i].radius_c > max_radius_)
00221 max_radius_ = links_[i].radius_c;
00222 }
00223 }
00224
00225 bool SBPLArmModel::initKDLChainFromParamServer()
00226 {
00227 ros::NodeHandle nh("~");
00228 std::string robot_description;
00229 std::string robot_param;
00230
00231 nh.searchParam("robot_description",robot_param);
00232 nh.param<std::string>(robot_param,robot_description,"");
00233
00234 if(robot_description.empty())
00235 {
00236 SBPL_ERROR("[SBPLArmModel] Unable to get robot_description from rosparam server.");
00237 return false;
00238 }
00239
00240 return initKDLChain(robot_description);
00241 }
00242
00243 bool SBPLArmModel::initKDLChain(const std::string &fKDL)
00244 {
00245 if (!kdl_parser::treeFromString(fKDL, kdl_tree_))
00246 {
00247 SBPL_ERROR("Failed to parse tree from manipulator description file.");
00248 return false;;
00249 }
00250
00251 if (!kdl_tree_.getChain(chain_root_name_, chain_tip_name_, chain_))
00252 {
00253 SBPL_ERROR("Error: could not fetch the KDL chain for the desired manipulator. Exiting.");
00254 return false;
00255 }
00256
00257 fk_solver_ = new KDL::ChainFkSolverPos_recursive(chain_);
00258 jnt_pos_in_.resize(chain_.getNrOfJoints());
00259 jnt_pos_out_.resize(chain_.getNrOfJoints());
00260
00261 SBPL_DEBUG("[initKDLChain] The FK chain has %d segments with %d joints.", chain_.getNrOfSegments(), chain_.getNrOfJoints());
00262 SBPL_DEBUG("[initKDLChain] root: %s tip: %s.", chain_root_name_.c_str(), chain_tip_name_.c_str());
00263
00264 if (!kdl_tree_.getChain("torso_lift_link", chain_tip_name_, ik_chain_))
00265 {
00266 SBPL_ERROR("Error: could not fetch the KDL chain for the desired manipulator. Exiting.");
00267 return false;
00268 }
00269
00270 ik_fk_solver_ = new KDL::ChainFkSolverPos_recursive(ik_chain_);
00271 ik_solver_vel_ = new KDL::ChainIkSolverVel_pinv_givens(ik_chain_);
00272 ik_solver_ = new KDL::ChainIkSolverPos_NR(chain_, *(ik_fk_solver_), *(ik_solver_vel_));
00273 ik_jnt_pos_in_.resize(ik_chain_.getNrOfJoints());
00274 ik_jnt_pos_out_.resize(ik_chain_.getNrOfJoints());
00275
00276 SBPL_DEBUG("[initKDLChain] The IK chain has %d segments with %d joints.", ik_chain_.getNrOfSegments(), ik_chain_.getNrOfJoints());
00277
00278
00279 robot_model_.initString(fKDL);
00280 pr2_arm_ik_solver_ = new pr2_arm_kinematics::PR2ArmIKSolver(robot_model_,"torso_lift_link",planning_joint_name_, 0.02,2);
00281
00282 if(!pr2_arm_ik_solver_->active_)
00283 {
00284 SBPL_ERROR("Error: the IK solver is NOT active.");
00285 return false;
00286 }
00287
00288 printArmDescription(stdout);
00289 return true;
00290 }
00291
00292 void SBPLArmModel::parseKDLTree()
00293 {
00294 num_kdl_joints_ = kdl_tree_.getNrOfJoints();
00295
00296 SBPL_DEBUG("%d KDL joints:",num_kdl_joints_);
00297
00298
00299
00300 KDL::SegmentMap segment_map = kdl_tree_.getSegments();
00301
00302 for (KDL::SegmentMap::const_iterator it = segment_map.begin(); it != segment_map.end(); ++it)
00303 {
00304 if (it->second.segment.getJoint().getType() != KDL::Joint::None)
00305 {
00306 std::string joint_name = it->second.segment.getJoint().getName();
00307 SBPL_DEBUG("%s",joint_name.c_str());
00308 std::string segment_name = it->first;
00309 joint_segment_mapping_.insert(make_pair(joint_name, segment_name));
00310 }
00311 }
00312
00313 kdl_number_to_urdf_name_.resize(num_kdl_joints_);
00314
00315
00316 for (map<string, string>::iterator it = joint_segment_mapping_.begin(); it!= joint_segment_mapping_.end(); ++it)
00317 {
00318 std::string joint_name = it->first;
00319 std::string segment_name = it->second;
00320
00321 std::cout << joint_name << " -> " << segment_name << std::endl;
00322
00323 segment_joint_mapping_.insert(make_pair(segment_name, joint_name));
00324 int kdl_number = kdl_tree_.getSegment(segment_name)->second.q_nr;
00325 if (kdl_tree_.getSegment(segment_name)->second.segment.getJoint().getType() != KDL::Joint::None)
00326 {
00327 std::cout << "KDL number is: " << kdl_number << std::endl;
00328
00329 kdl_number_to_urdf_name_[kdl_number] = joint_name;
00330 urdf_name_to_kdl_number_.insert(make_pair(joint_name, kdl_number));
00331 }
00332 }
00333 }
00334
00335 bool SBPLArmModel::computeFK(const std::vector<double> angles, int frame_num, KDL::Frame *frame_out)
00336 {
00337 for(int i = 0; i < num_joints_; ++i)
00338 jnt_pos_in_(i) = angles::normalize_angle(angles[i]);
00339
00340 KDL::Frame fk_frame_out;
00341 if(fk_solver_->JntToCart(jnt_pos_in_, fk_frame_out, frame_num) < 0)
00342 {
00343 SBPL_ERROR("JntToCart returned < 0. Exiting.");
00344 return false;
00345 }
00346
00347 *frame_out = fk_frame_out;
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 frame_out->p = transform_ * fk_frame_out.p;
00360
00361
00362
00363 return true;
00364 }
00365
00366 bool SBPLArmModel::computeFK(const std::vector<double> angles, int frame_num, std::vector<double> &xyzrpy)
00367 {
00368 KDL::Frame frame_out;
00369 xyzrpy.resize(6);
00370 if(computeFK(angles,frame_num,&frame_out))
00371 {
00372 xyzrpy[0] = frame_out.p[0];
00373 xyzrpy[1] = frame_out.p[1];
00374 xyzrpy[2] = frame_out.p[2];
00375
00376 frame_out.M.GetRPY(xyzrpy[3],xyzrpy[4],xyzrpy[5]);
00377 return true;
00378 }
00379
00380 return false;
00381 }
00382
00383 bool SBPLArmModel::computeFK(const std::vector<double> angles, int frame_num, std::vector<double> &xyzrpy, int sol_num)
00384 {
00385 KDL::Frame frame_out;
00386 xyzrpy.resize(6);
00387 if(computeFK(angles,frame_num,&frame_out))
00388 {
00389
00390
00391 tf::Pose pose;
00392 tf::PoseKDLToTF(frame_out,pose);
00393 pose.getBasis().getRPY(xyzrpy[3],xyzrpy[4],xyzrpy[5],sol_num);
00394
00395 xyzrpy[0] = frame_out.p[0];
00396 xyzrpy[1] = frame_out.p[1];
00397 xyzrpy[2] = frame_out.p[2];
00398
00399 return true;
00400 }
00401
00402 return false;
00403 }
00404
00405 bool SBPLArmModel::computeEndEffPose(const std::vector<double> angles, double R_target[3][3], double* x, double* y, double* z, double* axis_angle)
00406 {
00407 KDL::Frame f_endeff;
00408
00409 if(computeFK(angles, planning_joint_, &f_endeff))
00410 {
00411 *x = f_endeff.p[0];
00412 *y = f_endeff.p[1];
00413 *z = f_endeff.p[2];
00414
00415 *axis_angle = frameToAxisAngle(f_endeff, R_target);
00416 return true;
00417 }
00418 return false;
00419 }
00420
00421 double SBPLArmModel::frameToAxisAngle(const KDL::Frame frame, const double R_target[3][3])
00422 {
00423 double R_endeff[3][3];
00424
00425
00426 for(unsigned int i = 0; i < 3; i++)
00427 for(unsigned int j = 0; j < 3; j++)
00428 R_endeff[i][j] = frame.M(i,j);
00429
00430
00431 return getAxisAngle(R_endeff, R_target);
00432 }
00433
00434 bool SBPLArmModel::computeIK(const std::vector<double> pose, const std::vector<double> start, std::vector<double> &solution)
00435 {
00436
00437 KDL::Frame frame_des;
00438
00439
00440 frame_des.p.x(pose[0]);
00441 frame_des.p.y(pose[1]);
00442 frame_des.p.z(pose[2]);
00443 if(pose.size() == 6)
00444 frame_des.M = KDL::Rotation::RPY(pose[3],pose[4],pose[5]);
00445 else
00446 {
00447
00448 frame_des.M = KDL::Rotation::Quaternion(pose[3],pose[4],pose[5],pose[6]);
00449 }
00450
00451
00452 frame_des.p = transform_inverse_ * frame_des.p;
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467 for(unsigned int i = 0; i < start.size(); i++)
00468 ik_jnt_pos_in_(i) = angles::normalize_angle(start[i]);
00469
00470
00471 if(pr2_arm_ik_solver_->CartToJntSearch(ik_jnt_pos_in_, frame_des, ik_jnt_pos_out_, 0.3) < 0)
00472 return false;
00473
00474 solution.resize(start.size());
00475 for(unsigned int i = 0; i < solution.size(); i++)
00476 solution[i] = ik_jnt_pos_out_(i);
00477
00478 return true;
00479 }
00480
00481 double SBPLArmModel::getAxisAngle(const double R1[3][3], const double R2[3][3])
00482 {
00483 short unsigned int x,y,k;
00484 double sum, R3[3][3], R1_T[3][3];
00485
00486
00487 for(x=0; x<3; x++)
00488 for(y=0; y<3; y++)
00489 R1_T[x][y] = R1[y][x];
00490
00491
00492 for (x=0; x<3; x++)
00493 {
00494 for (y=0; y<3; y++)
00495 {
00496 sum = 0.0;
00497 for (k=0; k<3; k++)
00498 sum += (R1_T[x][k] * R2[k][y]);
00499
00500 R3[x][y] = sum;
00501 }
00502 }
00503
00504 return acos(((R3[0][0] + R3[1][1] + R3[2][2]) - 1.0) / 2.0);
00505 }
00506
00507 bool SBPLArmModel::getJointPositions(const std::vector<double> angles, std::vector<std::vector<double> > &links, KDL::Frame &f_out)
00508 {
00509 KDL::Frame f;
00510
00511 links.resize(joint_indeces_.size());
00512
00513 for(int i = 0; i < int(joint_indeces_.size()); i++)
00514 {
00515 if(!computeFK(angles, joint_indeces_[i], &f))
00516 return false;
00517 links[i].resize(3,0);
00518 links[i][0] = f.p.x();
00519 links[i][1] = f.p.y();
00520 links[i][2] = f.p.z();
00521
00522
00523 if(i == 2)
00524 f_out = f;
00525 }
00526
00527 return true;
00528 }
00529
00530 bool SBPLArmModel::getJointPositions(const std::vector<double> angles, const double R_target[3][3], std::vector<std::vector<double> > &links, double *axis_angle)
00531 {
00532 KDL::Frame f_link_tip;
00533
00534 links.resize(joint_indeces_.size());
00535
00536 for(unsigned int i = 0; i < joint_indeces_.size(); ++i)
00537 {
00538
00539 if(!computeFK(angles, joint_indeces_[i], &f_link_tip))
00540 return false;
00541
00542 links[i].resize(3,0);
00543 links[i][0] = f_link_tip.p.x();
00544 links[i][1] = f_link_tip.p.y();
00545 links[i][2] = f_link_tip.p.z();
00546
00547
00548 if(joint_indeces_[i] == planning_joint_)
00549 *axis_angle = frameToAxisAngle(f_link_tip, R_target);
00550 }
00551 return true;
00552 }
00553
00554
00555 bool SBPLArmModel::computePlanningJointPos(const std::vector<double> angles, double* x, double* y, double* z)
00556 {
00557 KDL::Frame planning_joint_frame;
00558 if(!computeFK(angles, planning_joint_, &planning_joint_frame))
00559 {
00560 *x = planning_joint_frame.p.x();
00561 *y = planning_joint_frame.p.y();
00562 *z = planning_joint_frame.p.z();
00563 return true;
00564 }
00565
00566 return false;
00567 }
00568
00569
00570 bool SBPLArmModel::getPlanningJointPose(const std::vector<double> angles, double R_target[3][3], std::vector<double> &pose, double *axis_angle)
00571 {
00572 KDL::Frame planning_joint_frame;
00573 pose.resize(6);
00574
00575 if(computeFK(angles, planning_joint_, &planning_joint_frame))
00576 {
00577 pose[0] = planning_joint_frame.p.x();
00578 pose[1] = planning_joint_frame.p.y();
00579 pose[2] = planning_joint_frame.p.z();
00580
00581 planning_joint_frame.M.GetRPY(pose[3],pose[4],pose[5]);
00582
00583 *axis_angle = frameToAxisAngle(planning_joint_frame, R_target);
00584
00585 return true;
00586 }
00587
00588 return false;
00589 }
00590
00591 bool SBPLArmModel::getPlanningJointPose(const std::vector<double> angles, std::vector<double> &pose)
00592 {
00593 KDL::Frame planning_joint_frame;
00594 if(pose.size() < 6)
00595 pose.resize(6);
00596
00597 if(computeFK(angles, planning_joint_, &planning_joint_frame))
00598 {
00599 pose[0] = planning_joint_frame.p.x();
00600 pose[1] = planning_joint_frame.p.y();
00601 pose[2] = planning_joint_frame.p.z();
00602
00603 planning_joint_frame.M.GetRPY(pose[3],pose[4],pose[5]);
00604 return true;
00605 }
00606
00607 return false;
00608 }
00609
00610 void SBPLArmModel::RPY2Rot(double roll, double pitch, double yaw, double Rot[3][3])
00611 {
00612 double cosr, cosp, cosy, sinr, sinp, siny;
00613
00614 cosr = cos(roll);
00615 cosp = cos(pitch);
00616 cosy = cos(yaw);
00617 sinr = sin(roll);
00618 sinp = sin(pitch);
00619 siny = sin(yaw);
00620
00621 Rot[0][0] = cosp*cosy;
00622 Rot[0][1] = cosy*sinp*sinr - siny*cosr;
00623 Rot[0][2] = cosy*sinp*cosr + siny*sinr;
00624
00625 Rot[1][0] = siny*cosp;
00626 Rot[1][1] = siny*sinp*sinr + cosy*cosr;
00627 Rot[1][2] = siny*sinp*cosr - cosy*sinr;
00628
00629 Rot[2][0] = -sinp;
00630 Rot[2][1] = cosp*sinr;
00631 Rot[2][2] = cosp*cosr;
00632 }
00633
00635 void SBPLArmModel::getRPY(double Rot[3][3], double* roll, double* pitch, double* yaw, int solution_number)
00636 {
00637 double delta,rpy1[3],rpy2[3];
00638
00639
00640 if(fabs(Rot[0][2]) >= 1)
00641 {
00642 rpy1[2] = 0;
00643 rpy2[2] = 0;
00644
00645
00646 delta = atan2(Rot[0][0], Rot[2][0]);
00647 if(Rot[0][2] > 0)
00648 {
00649 rpy1[1] = M_PI / 2.0;
00650 rpy2[1] = M_PI / 2.0;
00651 rpy1[0] = rpy1[1] + delta;
00652 rpy2[0] = rpy2[1] + delta;
00653 }
00654 else
00655 {
00656 rpy1[1] = -M_PI / 2.0;
00657 rpy2[1] = -M_PI / 2.0;
00658 rpy1[0] = -rpy1[1] + delta;
00659 rpy2[0] = -rpy2[1] + delta;
00660 }
00661 }
00662 else
00663 {
00664 rpy1[1] = -asin(Rot[0][2]);
00665 rpy2[1] = M_PI - rpy1[1];
00666
00667
00668 rpy1[0] = atan2(Rot[1][2]/cos(rpy1[1]),
00669 Rot[2][2]/cos(rpy1[1]));
00670
00671 rpy2[0] = atan2(Rot[1][2]/cos(rpy2[1]),
00672 Rot[2][2]/cos(rpy2[1]));
00673
00674 rpy1[2] = atan2(Rot[0][1]/cos(rpy1[1]),
00675 Rot[0][0]/cos(rpy1[1]));
00676
00677 rpy2[2] = atan2(Rot[0][1]/cos(rpy2[1]),
00678 Rot[0][0]/cos(rpy2[1]));
00679 }
00680
00681 if (solution_number == 1)
00682 {
00683 *yaw = rpy1[2];
00684 *pitch = rpy1[1];
00685 *roll = rpy1[0];
00686 }
00687 else
00688 {
00689 *yaw = rpy2[2];
00690 *pitch = rpy2[1];
00691 *roll = rpy2[0];
00692 }
00693 }
00694
00695 bool SBPLArmModel::checkJointLimits(std::vector<double> angles, bool verbose)
00696 {
00697 std::vector<double> norm_angles(angles.size());
00698 for(int i = 0; i < int(angles.size()); ++i)
00699 {
00700 if(i==2)
00701 continue;
00702 norm_angles[i] = angles::normalize_angle(angles[i]);
00703 }
00704
00705
00706 if(angles[2] > joints_[2].max)
00707 norm_angles[2] = angles[2] + (2*-M_PI);
00708
00709 if(int(norm_angles.size()) < num_joints_)
00710 SBPL_FPRINTF(fOut_,"Joint array has %d joints. (should be %d joints)\n", int(norm_angles.size()),num_joints_);
00711
00712 for(int i = 0; i < num_joints_; ++i)
00713 {
00714 if(!joints_[i].continuous)
00715 {
00716 if(joints_[i].min > norm_angles[i] || norm_angles[i] > joints_[i].max)
00717 {
00718
00719
00720 return false;
00721 }
00722 }
00723 }
00724 return true;
00725 }
00726
00727 void SBPLArmModel::printArmDescription(FILE* fOut)
00728 {
00729 SBPL_FPRINTF(fOut, "\nSBPL Arm Description:\n");
00730 SBPL_FPRINTF(fOut, "# Joints: %d, # Links: %d\n",num_joints_,num_links_);
00731 SBPL_FPRINTF(fOut, "Root Frame: %s, Tip Frame: %s\n", chain_root_name_.c_str(),chain_tip_name_.c_str());
00732 SBPL_FPRINTF(fOut, "Joint Limits:\n");
00733 for(int i = 0; i < num_joints_; ++i)
00734 SBPL_FPRINTF(fOut, "%d: {%.3f, %0.3f}\n",i,joints_[i].min,joints_[i].max);
00735
00736 SBPL_FPRINTF(fOut,"Joints ");
00737 for(int i =0; i < num_joints_; ++i)
00738 {
00739 if(joints_[i].continuous)
00740 SBPL_FPRINTF(fOut, "%d ",i);
00741 }
00742 SBPL_FPRINTF(fOut, "are continuous.\n");
00743
00744 SBPL_FPRINTF(fOut, "Links:\n");
00745 for(int i = 0; i < num_links_; ++i)
00746 SBPL_FPRINTF(fOut, "(%d) radius: %0.3fm (%d cells) length: %0.3fm KDL chain index: %d\n",i,links_[i].radius,links_[i].radius_c, links_[i].length,links_[i].ind_chain);
00747
00748 SBPL_FPRINTF(fOut,"\nKDL Arm Chain:\n");
00749 SBPL_FPRINTF(fOut, "# segments: %d, # joints: %d\n", chain_.getNrOfSegments(), chain_.getNrOfJoints());
00750
00751 double jnt_pos = 0;
00752 for(unsigned int j = 0; j < chain_.getNrOfSegments(); ++j)
00753 {
00754 SBPL_FPRINTF(fOut, "frame %2d: segment: %0.3f %0.3f %0.3f joint: %0.3f %0.3f %0.3f joint_type: %s\n",j,
00755 chain_.getSegment(j).pose(jnt_pos).p.x(),
00756 chain_.getSegment(j).pose(jnt_pos).p.y(),
00757 chain_.getSegment(j).pose(jnt_pos).p.z(),
00758 chain_.getSegment(j).getJoint().pose(jnt_pos).p.x(),
00759 chain_.getSegment(j).getJoint().pose(jnt_pos).p.y(),
00760 chain_.getSegment(j).getJoint().pose(jnt_pos).p.z(),
00761 chain_.getSegment(j).getJoint().getTypeName().c_str());
00762 }
00763 }
00764
00765 void SBPLArmModel::getJointLimits(int joint_num, double* min, double *max)
00766 {
00767 *min = joints_[joint_num].min;
00768 *max = joints_[joint_num].max;
00769 }
00770
00771 void SBPLArmModel::setRefFrameTransform(KDL::Frame f, std::string &name)
00772 {
00773 reference_frame_ = name;
00774
00775 transform_ = f;
00776 transform_inverse_ = transform_.Inverse();
00777
00778 ROS_DEBUG("Transform %s to torso: x: %0.4f y: %0.4f z: %0.4f", name.c_str(),transform_.p.x(),transform_.p.y(),transform_.p.z());
00779 ROS_DEBUG("Inverse Transform torso to %s: x: %0.4f y: %0.4f z: %0.4f", name.c_str(),transform_inverse_.p.x(),transform_inverse_.p.y(),transform_inverse_.p.z());
00780 }
00781
00782 void SBPLArmModel::getArmChainRootLinkName(std::string &name)
00783 {
00784 name = chain_root_name_;
00785 }
00786