arm_kinematics.cpp
Go to the documentation of this file.
00001 // bsd license blah blah
00002 
00003 #include <string>
00004 #include <exception>
00005 #include <math.h>
00006 
00007 #include <ros/ros.h>
00008 #include <urdf/model.h>
00009 #include <tf/transform_listener.h>
00010 #include <tf_conversions/tf_kdl.h>
00011 #include <tf/transform_datatypes.h>
00012 #include <kdl_parser/kdl_parser.hpp>
00013 #include <kdl/jntarray.hpp>
00014 #include <kdl/chainiksolverpos_nr_jl.hpp>
00015 #include <kdl/chainiksolvervel_wdls.hpp>
00016 #include <kdl/chainfksolverpos_recursive.hpp>
00017 #include <kinematics_msgs/GetPositionFK.h>
00018 #include <kinematics_msgs/GetPositionIK.h>
00019 #include <kinematics_msgs/GetKinematicSolverInfo.h>
00020 #include <kinematics_msgs/KinematicSolverInfo.h>
00021 #include <kdl_arm_kinematics/GetWeightedIK.h>
00022 
00023 using std::string;
00024 
00025 class Kinematics
00026 {
00027 public:
00028   class InitFailed : public std::runtime_error
00029   {
00030   public:
00031     InitFailed(const string &what)
00032       : std::runtime_error(what) {}
00033   };
00034   
00035   Kinematics();
00036 
00037 private:
00038   ros::NodeHandle nh, nh_private;
00039   std::string root_name, tip_name;
00040   KDL::JntArray joint_min, joint_max;
00041   KDL::Chain chain;
00042   unsigned int num_joints;
00043   int max_iterations;
00044   double epsilon;
00045   Eigen::MatrixXd default_weight_ts;
00046   Eigen::MatrixXd default_weight_js;
00047   double default_lambda;
00048 
00049   ros::ServiceServer ik_service,ik_solver_info_service;
00050   ros::ServiceServer fk_service,fk_solver_info_service;
00051   ros::ServiceServer weighted_ik_service;
00052 
00053   tf::TransformListener tf_listener;
00054 
00055   kinematics_msgs::KinematicSolverInfo info;
00056 
00057   void parseWeightParams(ros::NodeHandle &nh);
00058   bool loadModel(const std::string xml);
00059   bool readJoints(urdf::Model &robot_model);
00060   int getJointIndex(const std::string &name);
00061   int getKDLSegmentIndex(const std::string &name);
00062   bool solveCartToJnt(const KDL::JntArray &q_init, const KDL::Frame &q_in, KDL::JntArray &q_out,
00063     const KDL::Frame &tool_frame = KDL::Frame::Identity());
00064   bool solveCartToJnt(const KDL::JntArray &q_init, const KDL::Frame &q_in, KDL::JntArray &q_out,
00065     const KDL::Frame &tool_frame, const Eigen::MatrixXd &weight_ts,
00066     const Eigen::MatrixXd &weight_js, const double lambda);
00067   double calculateEps(const KDL::Frame &f, const KDL::Frame &ref,
00068     const Eigen::MatrixXd &weight=Eigen::MatrixXd::Identity(6,6));
00069   void initializeWeights(const kdl_arm_kinematics::KDLWeights &msg,
00070     Eigen::MatrixXd &weight_ts, Eigen::MatrixXd &weight_js, double &lambda);
00071 
00077   bool getPositionIK(kinematics_msgs::GetPositionIK::Request &request,
00078     kinematics_msgs::GetPositionIK::Response &response);
00079 
00085   bool getIKSolverInfo(kinematics_msgs::GetKinematicSolverInfo::Request &request,
00086     kinematics_msgs::GetKinematicSolverInfo::Response &response);
00087 
00093   bool getFKSolverInfo(kinematics_msgs::GetKinematicSolverInfo::Request &request,
00094     kinematics_msgs::GetKinematicSolverInfo::Response &response);
00095 
00101   bool getPositionFK(kinematics_msgs::GetPositionFK::Request &request,
00102     kinematics_msgs::GetPositionFK::Response &response);
00103 
00104   bool getWeightedIK(kdl_arm_kinematics::GetWeightedIK::Request &request,
00105     kdl_arm_kinematics::GetWeightedIK::Response &response);
00106 };
00107 
00108 
00109 
00110 Kinematics::Kinematics()
00111   : nh(),
00112     nh_private ("~"),
00113     default_weight_ts(Eigen::MatrixXd::Identity(6,6)),
00114     default_lambda(0.1)
00115 {
00116   // Get URDF XML
00117   std::string urdf_xml, full_urdf_xml;
00118   nh_private.param("robot_description_name",urdf_xml,std::string("robot_description"));
00119   nh.searchParam(urdf_xml,full_urdf_xml);
00120   ROS_DEBUG("Reading xml file from parameter server");
00121   std::string result;
00122   if (!nh.getParam(full_urdf_xml, result))
00123     throw Kinematics::InitFailed("Could not load the xml from parameter server: " + urdf_xml);
00124 
00125   // Get Root and Tip From Parameter Service
00126   if (!nh_private.getParam("root_name", root_name))
00127     throw Kinematics::InitFailed("GenericIK: No root name found on parameter server");
00128 
00129   if (!nh_private.getParam("tip_name", tip_name))
00130     throw Kinematics::InitFailed("GenericIK: No tip name found on parameter server");
00131 
00132   // Load and Read Models
00133   if (!loadModel(result))
00134     throw Kinematics::InitFailed("Could not load models!");
00135 
00136   default_weight_js = Eigen::MatrixXd::Identity(chain.getNrOfJoints(), chain.getNrOfJoints());
00137   parseWeightParams(nh_private);
00138 
00139   nh_private.param("maxIterations", max_iterations, 100);
00140   nh_private.param("epsilon", epsilon, 1e-2);
00141 
00142   ROS_INFO("Advertising services");
00143   fk_service = nh_private.advertiseService("get_fk", &Kinematics::getPositionFK,this);
00144   ik_service = nh_private.advertiseService("get_ik", &Kinematics::getPositionIK,this);
00145   ik_solver_info_service = nh_private.advertiseService("get_ik_solver_info", &Kinematics::getIKSolverInfo,this);
00146   fk_solver_info_service = nh_private.advertiseService("get_fk_solver_info", &Kinematics::getFKSolverInfo,this);
00147   weighted_ik_service = nh_private.advertiseService("get_weighted_ik", &Kinematics::getWeightedIK, this);
00148 }
00149 
00150 void Kinematics::parseWeightParams(ros::NodeHandle &nh)
00151 {
00152   ros::NodeHandle weights_nh(nh, "weights");
00153   
00154   if(weights_nh.hasParam("lambda"))
00155   {
00156     weights_nh.getParam("lambda", default_lambda);
00157     ROS_INFO("Setting lambda to %lf", default_lambda);
00158   }
00159 
00160   if(weights_nh.hasParam("weight_ts"))
00161   {
00162     ros::NodeHandle weight_ts_nh(weights_nh, "weight_ts");
00163     double value;
00164     
00165     if(weight_ts_nh.getParam("x", value))
00166     {
00167       ROS_INFO("Reading weight_ts/x: %lf", value);
00168       default_weight_ts(0,0) = value;
00169     }
00170 
00171     if(weight_ts_nh.getParam("y", value))
00172     {
00173       ROS_INFO("Reading weight_ts/y: %lf", value);    
00174       default_weight_ts(1,1) = value;
00175     }
00176 
00177     if(weight_ts_nh.getParam("z", value))
00178     {
00179       ROS_INFO("Reading weight_ts/z: %lf", value);    
00180       default_weight_ts(2,2) = value;
00181     }
00182 
00183     if(weight_ts_nh.getParam("roll", value))
00184     {
00185       ROS_INFO("Reading weight_ts/roll: %lf", value);
00186       default_weight_ts(3,3) = value;
00187     }
00188 
00189     if(weight_ts_nh.getParam("pitch", value))
00190     {
00191       ROS_INFO("Reading weight_ts/pitch: %lf", value);    
00192       default_weight_ts(4,4) = value;
00193     }
00194 
00195     if(weight_ts_nh.getParam("yaw", value))
00196     {
00197       ROS_INFO("Reading weight_ts/yaw: %lf", value);
00198       default_weight_ts(5,5) = value;
00199     }
00200   }
00201 
00202   if(weights_nh.hasParam("weight_js"))
00203   {
00204     ros::NodeHandle weight_js_nh(weights_nh, "weight_js");
00205     double value;
00206 
00207     for (unsigned int i=0; i < info.joint_names.size(); i++)
00208     {
00209       if(weight_js_nh.getParam(info.joint_names[i], value))
00210       {
00211         ROS_INFO("Setting weight for joint '%s' to %lf", info.joint_names[i].c_str(), value);
00212         default_weight_js(i, i) = value;
00213       }
00214     }
00215   }
00216 }
00217 
00218 bool Kinematics::loadModel(const std::string xml) {
00219   urdf::Model robot_model;
00220   KDL::Tree tree;
00221 
00222   if (!robot_model.initString(xml)) {
00223     ROS_FATAL("Could not initialize robot model");
00224     return -1;
00225   }
00226   if (!kdl_parser::treeFromString(xml, tree)) {
00227     ROS_ERROR("Could not initialize tree object");
00228     return false;
00229   }
00230   if (!tree.getChain(root_name, tip_name, chain)) {
00231     ROS_ERROR("Could not initialize chain object");
00232     return false;
00233   }
00234 
00235   if (!readJoints(robot_model)) {
00236     ROS_FATAL("Could not read information about the joints");
00237     return false;
00238   }
00239 
00240   return true;
00241 }
00242 
00243 bool Kinematics::readJoints(urdf::Model &robot_model) {
00244   num_joints = 0;
00245   // get joint maxs and mins
00246   boost::shared_ptr<const urdf::Link> link = robot_model.getLink(tip_name);
00247   boost::shared_ptr<const urdf::Joint> joint;
00248 
00249   while (link && link->name != root_name) {
00250     joint = robot_model.getJoint(link->parent_joint->name);
00251     if (!joint) {
00252       ROS_ERROR("Could not find joint: %s",link->parent_joint->name.c_str());
00253       return false;
00254     }
00255     if (joint->type != urdf::Joint::UNKNOWN && joint->type != urdf::Joint::FIXED) {
00256       ROS_INFO( "adding joint: [%s]", joint->name.c_str() );
00257       num_joints++;
00258     }
00259     link = robot_model.getLink(link->getParent()->name);
00260   }
00261 
00262   joint_min.resize(num_joints);
00263   joint_max.resize(num_joints);
00264   info.joint_names.resize(num_joints);
00265   info.link_names.clear();
00266   info.limits.resize(num_joints);
00267 
00268   link = robot_model.getLink(tip_name);
00269   unsigned int i = 0;
00270   while (link && i < num_joints) {
00271     joint = robot_model.getJoint(link->parent_joint->name);
00272     info.link_names.push_back(link->name);
00273     if (joint->type != urdf::Joint::UNKNOWN && joint->type != urdf::Joint::FIXED) {
00274       ROS_INFO( "getting bounds for joint: [%s]", joint->name.c_str() );
00275 
00276       float lower, upper;
00277       int hasLimits;
00278       if ( joint->type != urdf::Joint::CONTINUOUS ) {
00279         lower = joint->limits->lower;
00280         upper = joint->limits->upper;
00281         hasLimits = 1;
00282       } else {
00283         lower = -M_PI;
00284         upper = M_PI;
00285         hasLimits = 0;
00286       }
00287       int index = num_joints - i -1;
00288 
00289       joint_min.data[index] = lower;
00290       joint_max.data[index] = upper;
00291       info.joint_names[index] = joint->name;
00292       info.limits[index].joint_name = joint->name;
00293       info.limits[index].has_position_limits = hasLimits;
00294       info.limits[index].min_position = lower;
00295       info.limits[index].max_position = upper;
00296       i++;
00297     }
00298     link = robot_model.getLink(link->getParent()->name);
00299   }
00300   return true;
00301 }
00302 
00303 
00304 int Kinematics::getJointIndex(const std::string &name) {
00305   for (unsigned int i=0; i < info.joint_names.size(); i++) {
00306     if (info.joint_names[i] == name)
00307       return i;
00308   }
00309   return -1;
00310 }
00311 
00312 int Kinematics::getKDLSegmentIndex(const std::string &name) {
00313   int i=0; 
00314   while (i < (int)chain.getNrOfSegments()) {
00315     if (chain.getSegment(i).getName() == name) {
00316       return i+1;
00317     }
00318     i++;
00319   }
00320   return -1;
00321 }
00322 
00323 bool Kinematics::solveCartToJnt(const KDL::JntArray &q_init, const KDL::Frame &q_in, KDL::JntArray &q_out,
00324   const KDL::Frame &tool_frame)
00325 {
00326   return solveCartToJnt(q_init, q_in, q_out, tool_frame,
00327     default_weight_ts, default_weight_js, default_lambda);
00328 }
00329 
00330 bool Kinematics::solveCartToJnt(const KDL::JntArray &q_init, const KDL::Frame &p_in, KDL::JntArray &q_out,
00331   const KDL::Frame &tool_frame, const Eigen::MatrixXd &weight_ts, const Eigen::MatrixXd &weight_js,
00332   const double lambda)
00333 {
00334   KDL::Frame f;
00335   KDL::JntArray delta_q;
00336   KDL::Twist delta_twist;  
00337   int i;
00338   double err;
00339 
00340   KDL::Chain chain_with_tool(chain);
00341   chain_with_tool.addSegment(KDL::Segment(KDL::Joint(KDL::Joint::None), tool_frame));
00342   
00343   KDL::ChainFkSolverPos_recursive fk_solver(chain_with_tool);
00344   KDL::ChainIkSolverVel_wdls ik_solver(chain_with_tool);
00345 
00346   ik_solver.setWeightTS(weight_ts);
00347   ik_solver.setWeightJS(weight_js);
00348   ik_solver.setLambda(lambda);
00349   
00350   q_out = q_init;
00351 
00352   for(i=0;i<max_iterations;i++)
00353   {
00354     fk_solver.JntToCart(q_out, f);
00355 
00356     err = calculateEps(f, p_in, weight_ts);
00357 
00358     if(isnan(err))
00359     {
00360       ROS_WARN("NaN in IK");
00361       return false;
00362     }
00363 
00364     if( err < epsilon )
00365       break;
00366 
00367     delta_twist = diff(f, p_in);
00368     ik_solver.CartToJnt(q_out, delta_twist, delta_q);
00369     KDL::Add(q_out, delta_q, q_out);
00370 
00371     for(unsigned int j=0; j<joint_min.rows(); j++)
00372     {
00373       if(q_out(j) < joint_min(j))
00374         q_out(j) = joint_min(j);
00375     }
00376 
00377     for(unsigned int j=0; j<joint_max.rows(); j++)
00378     {
00379       if(q_out(j) > joint_max(j))
00380         q_out(j) = joint_max(j);
00381     }
00382   }
00383 
00384   ROS_INFO("IK terminating after %d iterations and error %lf", i, err);
00385   
00386   if(i < max_iterations)
00387     return true;
00388   return false;
00389 }
00390 
00391 double Kinematics::calculateEps(const KDL::Frame &f, const KDL::Frame &ref, const Eigen::MatrixXd &weight)
00392 {
00393   double f_roll, f_pitch, f_yaw;
00394   double ref_roll, ref_pitch, ref_yaw;
00395   f.M.GetRPY(f_roll, f_pitch, f_yaw);
00396   ref.M.GetRPY(ref_roll, ref_pitch, ref_yaw);
00397 
00398   double x_diff = f.p.x() - ref.p.x();
00399   double y_diff = f.p.y() - ref.p.y();
00400   double z_diff = f.p.z() - ref.p.z();
00401   double roll_diff = f_roll - ref_roll;
00402   double pitch_diff = f_pitch - ref_pitch;
00403   double yaw_diff = f_yaw - ref_yaw;
00404 
00405   return (x_diff * x_diff * weight(0, 0)) +
00406     (y_diff * y_diff * weight(1, 1)) +
00407     (z_diff * z_diff * weight(2, 2)) +
00408     (roll_diff * roll_diff * weight(3, 3)) +
00409     (pitch_diff * pitch_diff * weight(4, 4)) +
00410     (yaw_diff * yaw_diff * weight(5, 5));
00411 }
00412 
00413 void Kinematics::initializeWeights(const kdl_arm_kinematics::KDLWeights &msg,
00414     Eigen::MatrixXd &weight_ts, Eigen::MatrixXd &weight_js, double &lambda)
00415 {
00416   if(msg.mode == kdl_arm_kinematics::KDLWeights::INVALID_MODE)
00417   {
00418     return;
00419   }
00420   if(msg.mode & kdl_arm_kinematics::KDLWeights::SET_TS)
00421   {
00422     for(int i=0, a=0; i<6; i++)
00423     {
00424       for(int j=0; j<6; j++, a++)
00425         weight_ts(i, j) = msg.weight_ts[a];
00426     }
00427   }
00428   if(msg.mode & kdl_arm_kinematics::KDLWeights::SET_JS)
00429   {
00430     int dim = sqrt(msg.weight_js.size());
00431     weight_js = Eigen::MatrixXd(dim, dim);
00432     for(int i=0, a=0; i<dim; i++)
00433     {
00434       for(int j=0; j<dim; j++, a++)
00435         weight_js(i, j) = msg.weight_js[a];
00436     }
00437   }
00438   if(msg.mode & kdl_arm_kinematics::KDLWeights::SET_LAMBDA)
00439     lambda = msg.lambda;
00440 }
00441 
00442 bool Kinematics::getPositionIK(kinematics_msgs::GetPositionIK::Request &request,
00443                                kinematics_msgs::GetPositionIK::Response &response) {
00444 
00445   geometry_msgs::PoseStamped pose_msg_in = request.ik_request.pose_stamped;
00446   tf::Stamped<tf::Pose> transform;
00447   tf::Stamped<tf::Pose> transform_root;
00448   tf::poseStampedMsgToTF( pose_msg_in, transform );
00449 
00450   //Do the IK
00451   KDL::JntArray jnt_pos_in;
00452   KDL::JntArray jnt_pos_out;
00453   jnt_pos_in.resize(num_joints);
00454 
00455   if(request.ik_request.ik_seed_state.joint_state.name.size() < num_joints ||
00456      request.ik_request.ik_seed_state.joint_state.position.size() < num_joints)
00457   {
00458     ROS_ERROR("Invalid seed state. It must contain states for all joints used by the IK solver.");
00459     return false;
00460   }
00461   for (unsigned int i=0; i < num_joints; i++) {
00462     int tmp_index = getJointIndex(request.ik_request.ik_seed_state.joint_state.name[i]);
00463     if (tmp_index >=0) {
00464       jnt_pos_in(tmp_index) = request.ik_request.ik_seed_state.joint_state.position[i];
00465     } else {
00466       ROS_ERROR("i: %d, No joint index for %s",i,request.ik_request.ik_seed_state.joint_state.name[i].c_str());
00467       return false;
00468     }
00469   }
00470 
00471   //Convert F to our root_frame
00472   try {
00473     tf_listener.transformPose(root_name, transform, transform_root);
00474   } catch (...) {
00475     ROS_ERROR("Could not transform IK pose to frame: %s", root_name.c_str());
00476     response.error_code.val = response.error_code.FRAME_TRANSFORM_FAILURE;
00477     return false;
00478   }
00479 
00480   KDL::Frame F_dest;
00481   tf::TransformTFToKDL(transform_root, F_dest);
00482 
00483   if (solveCartToJnt(jnt_pos_in, F_dest, jnt_pos_out))
00484   {
00485     response.solution.joint_state.name = info.joint_names;
00486     response.solution.joint_state.position.resize(num_joints);
00487     for (unsigned int i=0; i < num_joints; i++)
00488     {
00489       response.solution.joint_state.position[i] = jnt_pos_out(i);
00490       ROS_INFO("IK Solution: %s %d: %f",response.solution.joint_state.name[i].c_str(),i,jnt_pos_out(i));
00491     }
00492     response.error_code.val = response.error_code.SUCCESS;
00493     return true;
00494   } else {
00495     ROS_INFO("An IK solution could not be found");
00496     response.error_code.val = response.error_code.NO_IK_SOLUTION;
00497     return true;
00498   }
00499 }
00500 
00501 bool Kinematics::getIKSolverInfo(kinematics_msgs::GetKinematicSolverInfo::Request &request,
00502                                  kinematics_msgs::GetKinematicSolverInfo::Response &response) {
00503   response.kinematic_solver_info = info;
00504   return true;
00505 }
00506 
00507 bool Kinematics::getFKSolverInfo(kinematics_msgs::GetKinematicSolverInfo::Request &request,
00508                                  kinematics_msgs::GetKinematicSolverInfo::Response &response) {
00509   response.kinematic_solver_info = info;
00510   return true;
00511 }
00512 
00513 bool Kinematics::getPositionFK(kinematics_msgs::GetPositionFK::Request &request,
00514                                kinematics_msgs::GetPositionFK::Response &response) {
00515   KDL::Frame p_out;
00516   KDL::JntArray jnt_pos_in;
00517   geometry_msgs::PoseStamped pose;
00518   tf::Stamped<tf::Pose> tf_pose;
00519 
00520   KDL::ChainFkSolverPos_recursive fk_solver(chain);
00521 
00522   jnt_pos_in.resize(num_joints);
00523   for (unsigned int i=0; i < num_joints; i++) {
00524     int tmp_index = getJointIndex(request.robot_state.joint_state.name[i]);
00525     if (tmp_index >=0)
00526       jnt_pos_in(tmp_index) = request.robot_state.joint_state.position[i];
00527   }
00528 
00529   response.pose_stamped.resize(request.fk_link_names.size());
00530   response.fk_link_names.resize(request.fk_link_names.size());
00531 
00532   for (unsigned int i=0; i < request.fk_link_names.size(); i++) {
00533     int segmentIndex = getKDLSegmentIndex(request.fk_link_names[i]);
00534     ROS_DEBUG("End effector index: %d",segmentIndex);
00535     ROS_DEBUG("Chain indices: %d",chain.getNrOfSegments());
00536     if (fk_solver.JntToCart(jnt_pos_in,p_out,segmentIndex) >=0) {
00537       tf_pose.frame_id_ = root_name;
00538       tf_pose.stamp_ = ros::Time();
00539       tf::PoseKDLToTF(p_out,tf_pose);
00540       try {
00541         tf_listener.transformPose(request.header.frame_id,tf_pose,tf_pose);
00542       } catch (...) {
00543         ROS_ERROR("Could not transform FK pose to frame: %s",request.header.frame_id.c_str());
00544         response.error_code.val = arm_navigation_msgs::ArmNavigationErrorCodes::FRAME_TRANSFORM_FAILURE;
00545         return false;
00546       }
00547       tf::poseStampedTFToMsg(tf_pose,pose);
00548       response.pose_stamped[i] = pose;
00549       response.fk_link_names[i] = request.fk_link_names[i];
00550       response.error_code.val = response.error_code.SUCCESS;
00551     } else {
00552       ROS_ERROR("Could not compute FK for %s",request.fk_link_names[i].c_str());
00553       response.error_code.val = arm_navigation_msgs::ArmNavigationErrorCodes::NO_FK_SOLUTION;
00554     }
00555   }
00556   return true;
00557 }
00558 
00559 bool Kinematics::getWeightedIK(kdl_arm_kinematics::GetWeightedIK::Request &request,
00560   kdl_arm_kinematics::GetWeightedIK::Response &response)
00561 {
00562   geometry_msgs::PoseStamped pose_msg_in = request.pose;
00563   tf::Stamped<tf::Pose> transform;
00564   tf::Stamped<tf::Pose> transform_root;
00565   tf::poseStampedMsgToTF( pose_msg_in, transform );
00566 
00567   //Do the IK
00568   KDL::JntArray jnt_pos_in;
00569   KDL::JntArray jnt_pos_out;
00570   jnt_pos_in.resize(num_joints);
00571 
00572   if(request.ik_seed.name.size() < num_joints ||
00573      request.ik_seed.position.size() < num_joints)
00574   {
00575     ROS_ERROR("Invalid seed state. It must contain states for all joints used by the IK solver.");
00576     return false;
00577   }
00578   for (unsigned int i=0; i < num_joints; i++)
00579   {
00580     int tmp_index = getJointIndex(request.ik_seed.name[i]);
00581     if (tmp_index >=0)
00582       jnt_pos_in(tmp_index) = request.ik_seed.position[i];
00583     else
00584     {
00585       ROS_ERROR("i: %d, No joint index for %s",i,request.ik_seed.name[i].c_str());
00586       return false;
00587     }
00588   }
00589 
00590   //Convert F to our root_frame
00591   try
00592   {
00593     tf_listener.transformPose(root_name, transform, transform_root);
00594   }
00595   catch (...)
00596   {
00597     ROS_ERROR("Could not transform IK pose to frame: %s", root_name.c_str());
00598     response.error_code.val = response.error_code.FRAME_TRANSFORM_FAILURE;
00599     return false;
00600   }
00601 
00602   KDL::Frame F_dest;
00603   tf::TransformTFToKDL(transform_root, F_dest);
00604 
00605   KDL::Frame tool;
00606   tf::PoseMsgToKDL(request.tool_frame, tool);
00607 
00609   Eigen::MatrixXd weight_ts(default_weight_ts);
00610   Eigen::MatrixXd weight_js(default_weight_js);
00611   double lambda = default_lambda;
00612 
00613   initializeWeights(request.weights, weight_ts, weight_js, lambda);
00614   
00615   if (solveCartToJnt(jnt_pos_in, F_dest, jnt_pos_out, tool, weight_ts, weight_js, lambda))
00616   {
00617     response.solution.name = info.joint_names;
00618     response.solution.position.resize(num_joints);
00619     for (unsigned int i=0; i < num_joints; i++)
00620     {
00621       response.solution.position[i] = jnt_pos_out(i);
00622       ROS_INFO("IK Solution: %s %d: %f",response.solution.name[i].c_str(),i,jnt_pos_out(i));
00623     }
00624     response.error_code.val = response.error_code.SUCCESS;
00625     return true;
00626   } else {
00627     ROS_INFO("An IK solution could not be found");
00628     response.error_code.val = response.error_code.NO_IK_SOLUTION;
00629     return true;
00630   }
00631 }
00632 
00633 int main(int argc, char **argv) {
00634   ros::init(argc, argv, "arm_kinematics");
00635   try
00636   {
00637     Kinematics k;
00638     ros::spin();
00639   }
00640   catch(Kinematics::InitFailed &e)
00641   {
00642     ROS_ERROR("Could not initialize kinematics node: %s", e.what());
00643     return -1;
00644   }
00645 
00646   return 0;
00647 }
00648 


kdl_arm_kinematics
Author(s): David Lu!!, Lorenz Moesenlechner
autogenerated on Sun Jan 26 2014 12:29:39