00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 #include <pr2_arm_kinematics/pr2_arm_kinematics_utils.h>
00038 #include <pr2_arm_kinematics/pr2_arm_kinematics_constants.h>
00039 
00040 namespace pr2_arm_kinematics
00041 {
00042 static const double IK_DEFAULT_TIMEOUT = 10.0;
00043 bool loadRobotModel(ros::NodeHandle node_handle, urdf::Model &robot_model, std::string &xml_string)
00044 {
00045   std::string urdf_xml,full_urdf_xml;
00046   node_handle.param("urdf_xml",urdf_xml,std::string("robot_description"));
00047   node_handle.searchParam(urdf_xml,full_urdf_xml);
00048   TiXmlDocument xml;
00049   ROS_DEBUG("Reading xml file from parameter server\n");
00050   std::string result;
00051   if (node_handle.getParam(full_urdf_xml, result))
00052     xml.Parse(result.c_str());
00053   else
00054   {
00055     ROS_FATAL("Could not load the xml from parameter server: %s\n", urdf_xml.c_str());
00056     return false;
00057   }
00058   xml_string = result;
00059   TiXmlElement *root_element = xml.RootElement();
00060   TiXmlElement *root = xml.FirstChildElement("robot");
00061   if (!root || !root_element)
00062   {
00063     ROS_FATAL("Could not parse the xml from %s\n", urdf_xml.c_str());
00064     exit(1);
00065   }
00066   robot_model.initXml(root);
00067   return true;
00068 }
00069 
00070 bool getKDLChain(const std::string &xml_string, const std::string &root_name, const std::string &tip_name, KDL::Chain &kdl_chain)
00071 {
00072   
00073   KDL::Tree tree;
00074   if (!kdl_parser::treeFromString(xml_string, tree))
00075   {
00076     ROS_ERROR("Could not initialize tree object");
00077     return false;
00078   }
00079   if (!tree.getChain(root_name, tip_name, kdl_chain))
00080   {
00081     ROS_ERROR_STREAM("Could not initialize chain object for base " << root_name << " tip " << tip_name);
00082     return false;
00083   }
00084   return true;
00085 }
00086 
00087 bool getKDLTree(const std::string &xml_string, const std::string &root_name, const std::string &tip_name, KDL::Tree &kdl_tree)
00088 {
00089   
00090   if (!kdl_parser::treeFromString(xml_string, kdl_tree))
00091   {
00092     ROS_ERROR("Could not initialize tree object");
00093     return false;
00094   }
00095   return true;
00096 }
00097 
00098 
00099 Eigen::Matrix4f KDLToEigenMatrix(const KDL::Frame &p)
00100 {
00101   Eigen::Matrix4f b = Eigen::Matrix4f::Identity();
00102   for(int i=0; i < 3; i++)
00103   {
00104     for(int j=0; j<3; j++)
00105     {
00106       b(i,j) = p.M(i,j);
00107     }
00108     b(i,3) = p.p(i);
00109   }
00110   return b;
00111 }
00112 
00113 double computeEuclideanDistance(const std::vector<double> &array_1, const KDL::JntArray &array_2)
00114 {
00115   double distance = 0.0;
00116   for(int i=0; i< (int) array_1.size(); i++)
00117   {
00118     distance += (array_1[i] - array_2(i))*(array_1[i] - array_2(i));
00119   }
00120   return sqrt(distance);
00121 }
00122 
00123 
00124 double distance(const urdf::Pose &transform)
00125 {
00126   return sqrt(transform.position.x*transform.position.x+transform.position.y*transform.position.y+transform.position.z*transform.position.z);
00127 }
00128 
00129 
00130 bool solveQuadratic(const double &a, const double &b, const double &c, double *x1, double *x2)
00131 {
00132   double discriminant = b*b-4*a*c;
00133   if(fabs(a) < IK_EPS)
00134   {
00135     *x1 = -c/b;
00136     *x2 = *x1;
00137     return true;
00138   }
00139   
00140   if (discriminant >= 0)
00141   {
00142     *x1 = (-b + sqrt(discriminant))/(2*a);
00143     *x2 = (-b - sqrt(discriminant))/(2*a);
00144     return true;
00145   }
00146   else if(fabs(discriminant) < IK_EPS)
00147   {
00148     *x1 = -b/(2*a);
00149     *x2 = -b/(2*a);
00150     return true;
00151   }
00152   else
00153   {
00154     *x1 = -b/(2*a);
00155     *x2 = -b/(2*a);
00156     return false;
00157   }
00158 }
00159 
00160 Eigen::Matrix4f matrixInverse(const Eigen::Matrix4f &g)
00161 {
00162   Eigen::Matrix4f result = g;
00163   Eigen::Matrix3f Rt = Eigen::Matrix3f::Identity();
00164 
00165   Eigen::Vector3f p = Eigen::Vector3f::Zero(3);
00166   Eigen::Vector3f pinv = Eigen::Vector3f::Zero(3);
00167 
00168   Rt(0,0) = g(0,0);
00169   Rt(1,1) = g(1,1);
00170   Rt(2,2) = g(2,2);
00171 
00172   Rt(0,1) = g(1,0);
00173   Rt(1,0) = g(0,1);
00174 
00175   Rt(0,2) = g(2,0);
00176   Rt(2,0) = g(0,2);
00177 
00178   Rt(1,2) = g(2,1);
00179   Rt(2,1) = g(1,2);
00180 
00181   p(0) = g(0,3);
00182   p(1) = g(1,3);
00183   p(2) = g(2,3);
00184 
00185   pinv = -Rt*p;
00186 
00187   result(0,0) = g(0,0);
00188   result(1,1) = g(1,1);
00189   result(2,2) = g(2,2);
00190 
00191   result(0,1) = g(1,0);
00192   result(1,0) = g(0,1);
00193 
00194   result(0,2) = g(2,0);
00195   result(2,0) = g(0,2);
00196 
00197   result(1,2) = g(2,1);
00198   result(2,1) = g(1,2);
00199 
00200   result(0,3) = pinv(0);
00201   result(1,3) = pinv(1);
00202   result(2,3) = pinv(2);
00203 
00204   return result;
00205 }
00206 
00207 
00208 bool solveCosineEqn(const double &a, const double &b, const double &c, double &soln1, double &soln2)
00209 {
00210   double theta1 = atan2(b,a);
00211   double denom  = sqrt(a*a+b*b);
00212 
00213   if(fabs(denom) < IK_EPS) 
00214   {
00215 #ifdef DEBUG
00216     std::cout << "denom: " << denom << std::endl;
00217 #endif
00218     return false;
00219   }
00220   double rhs_ratio = c/denom;
00221   if(rhs_ratio < -1 || rhs_ratio > 1)
00222   {
00223 #ifdef DEBUG
00224     std::cout << "rhs_ratio: " << rhs_ratio << std::endl;
00225 #endif
00226     return false;
00227   }
00228   double acos_term = acos(rhs_ratio);
00229   soln1 = theta1 + acos_term;
00230   soln2 = theta1 - acos_term;
00231 
00232   return true;
00233 }
00234 
00235 
00236 bool checkJointNames(const std::vector<std::string> &joint_names,
00237                      const moveit_msgs::KinematicSolverInfo &chain_info)
00238 {
00239   for(unsigned int i=0; i < chain_info.joint_names.size(); i++)
00240   {
00241     int index = -1;
00242     for(unsigned int j=0; j < joint_names.size(); j++)
00243     {
00244       if(chain_info.joint_names[i] == joint_names[j])
00245       {
00246         index = j;
00247         break;
00248       }
00249     }
00250     if(index < 0)
00251     {
00252       ROS_ERROR("Joint state does not contain joint state for %s.",chain_info.joint_names[i].c_str());
00253       return false;
00254     }
00255   }
00256   return true;
00257 }
00258 
00259 bool checkLinkNames(const std::vector<std::string> &link_names,
00260                     const moveit_msgs::KinematicSolverInfo &chain_info)
00261 {
00262   if(link_names.empty())
00263     return false;
00264   for(unsigned int i=0; i < link_names.size(); i++)
00265   {
00266     if(!checkLinkName(link_names[i],chain_info))
00267       return false;
00268   }
00269   return true;
00270 }
00271 
00272 bool checkLinkName(const std::string &link_name,
00273                    const moveit_msgs::KinematicSolverInfo &chain_info)
00274 {
00275   for(unsigned int i=0; i < chain_info.link_names.size(); i++)
00276   {
00277     if(link_name == chain_info.link_names[i])
00278       return true;
00279   }
00280   return false;
00281 }
00282 
00283 bool checkRobotState(moveit_msgs::RobotState &robot_state,
00284                      const moveit_msgs::KinematicSolverInfo &chain_info)
00285 {
00286   if((int) robot_state.joint_state.position.size() != (int) robot_state.joint_state.name.size())
00287   {
00288     ROS_ERROR("Number of joints in robot_state.joint_state does not match number of positions in robot_state.joint_state");
00289     return false;
00290   }
00291   if(!checkJointNames(robot_state.joint_state.name,chain_info))
00292   {
00293     ROS_ERROR("Robot state must contain joint state for every joint in the kinematic chain");
00294     return false;
00295   }
00296   return true;
00297 }
00298 
00299 bool checkFKService(moveit_msgs::GetPositionFK::Request &request,
00300                     moveit_msgs::GetPositionFK::Response &response,
00301                     const moveit_msgs::KinematicSolverInfo &chain_info)
00302 {
00303   if(!checkLinkNames(request.fk_link_names,chain_info))
00304   {
00305     ROS_ERROR("Link name in service request does not match links that kinematics can provide solutions for.");
00306     response.error_code.val = response.error_code.INVALID_LINK_NAME;
00307     return false;
00308   }
00309   if(!checkRobotState(request.robot_state,chain_info))
00310   {
00311     response.error_code.val = response.error_code.INVALID_ROBOT_STATE;
00312     return false;
00313   }
00314   return true;
00315 }
00316 
00317 bool checkIKService(moveit_msgs::GetPositionIK::Request &request,
00318                     moveit_msgs::GetPositionIK::Response &response,
00319                     const moveit_msgs::KinematicSolverInfo &chain_info)
00320 {
00321   if(!checkLinkName(request.ik_request.ik_link_name,chain_info))
00322   {
00323     ROS_ERROR("Link name in service request does not match links that kinematics can provide solutions for.");
00324     response.error_code.val = response.error_code.INVALID_LINK_NAME;
00325     return false;
00326   }
00327   if(!checkRobotState(request.ik_request.robot_state,chain_info))
00328   {
00329     response.error_code.val = response.error_code.INVALID_ROBOT_STATE;
00330     return false;
00331   }
00332   if(request.ik_request.timeout <= ros::Duration(0.0))
00333   {
00334     response.error_code.val = response.error_code.TIMED_OUT;
00335     return false;
00336   }
00337   return true;
00338 }
00339 
00340 bool convertPoseToRootFrame(const geometry_msgs::PoseStamped &pose_msg,
00341                             KDL::Frame &pose_kdl,
00342                             const std::string &root_frame,
00343                             tf::TransformListener& tf)
00344 {
00345   geometry_msgs::PoseStamped pose_stamped;
00346   if(!convertPoseToRootFrame(pose_msg, pose_stamped, root_frame,tf))
00347     return false;
00348   tf::poseMsgToKDL(pose_stamped.pose, pose_kdl);
00349   return true;
00350 }
00351 
00352 
00353 bool convertPoseToRootFrame(const geometry_msgs::PoseStamped &pose_msg,
00354                             geometry_msgs::PoseStamped &pose_msg_out,
00355                             const std::string &root_frame,
00356                             tf::TransformListener& tf)
00357 {
00358   geometry_msgs::PoseStamped pose_msg_in = pose_msg;
00359   ROS_DEBUG("Request:\nframe_id: %s\nPosition: %f %f %f\n:Orientation: %f %f %f %f\n",
00360             pose_msg_in.header.frame_id.c_str(),
00361             pose_msg_in.pose.position.x,
00362             pose_msg_in.pose.position.y,
00363             pose_msg_in.pose.position.z,
00364             pose_msg_in.pose.orientation.x,
00365             pose_msg_in.pose.orientation.y,
00366             pose_msg_in.pose.orientation.z,
00367             pose_msg_in.pose.orientation.w);
00368   pose_msg_out = pose_msg;
00369   tf::Stamped<tf::Pose> pose_stamped;
00370   poseStampedMsgToTF(pose_msg_in, pose_stamped);
00371 
00372   if (!tf.canTransform(root_frame, pose_stamped.frame_id_, pose_stamped.stamp_))
00373   {
00374     std::string err;
00375     if (tf.getLatestCommonTime(pose_stamped.frame_id_, root_frame, pose_stamped.stamp_, &err) != tf::NO_ERROR)
00376     {
00377       ROS_ERROR("pr2_arm_ik:: Cannot transform from '%s' to '%s'. TF said: %s",pose_stamped.frame_id_.c_str(),root_frame.c_str(), err.c_str());
00378       return false;
00379     }
00380   }
00381   try
00382   {
00383     tf.transformPose(root_frame, pose_stamped, pose_stamped);
00384   }
00385   catch(...)
00386   {
00387     ROS_ERROR("pr2_arm_ik:: Cannot transform from '%s' to '%s'",pose_stamped.frame_id_.c_str(),root_frame.c_str());
00388     return false;
00389   }
00390   tf::poseStampedTFToMsg(pose_stamped,pose_msg_out);
00391   return true;
00392 }
00393 
00394 
00395 
00396 int getJointIndex(const std::string &name,
00397                   const moveit_msgs::KinematicSolverInfo &chain_info)
00398 {
00399   for(unsigned int i=0; i < chain_info.joint_names.size(); i++)
00400   {
00401     if(chain_info.joint_names[i] == name)
00402     {
00403       return i;
00404     }
00405   }
00406   return -1;
00407 }
00408 
00409 void getKDLChainInfo(const KDL::Chain &chain,
00410                      moveit_msgs::KinematicSolverInfo &chain_info)
00411 {
00412   int i=0; 
00413   while(i < (int)chain.getNrOfSegments())
00414   {
00415     chain_info.link_names.push_back(chain.getSegment(i).getName());
00416     i++;
00417   }
00418 }
00419 
00420 int getKDLSegmentIndex(const KDL::Chain &chain,
00421                        const std::string &name)
00422 {
00423   int i=0; 
00424   while(i < (int)chain.getNrOfSegments())
00425   {
00426     if(chain.getSegment(i).getName() == name)
00427     {
00428       return i+1;
00429     }
00430     i++;
00431   }
00432   return -1;
00433 }
00434 
00435 
00436 }