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 <moveit/pr2_arm_kinematics/pr2_arm_kinematics_plugin.h>
00038 #include <geometry_msgs/PoseStamped.h>
00039 #include <kdl_parser/kdl_parser.hpp>
00040 #include <tf_conversions/tf_kdl.h>
00041 #include <ros/ros.h>
00042 #include <algorithm>
00043 #include <numeric>
00044 
00045 #include <pluginlib/class_list_macros.h>
00046 
00047 using namespace KDL;
00048 using namespace tf;
00049 using namespace std;
00050 using namespace ros;
00051 
00052 
00053 PLUGINLIB_EXPORT_CLASS(pr2_arm_kinematics::PR2ArmKinematicsPlugin, kinematics::KinematicsBase);
00054 
00055 namespace pr2_arm_kinematics {
00056 
00057 PR2ArmKinematicsPlugin::PR2ArmKinematicsPlugin():active_(false){}
00058 
00059 bool PR2ArmKinematicsPlugin::isActive()
00060 {
00061   if(active_)
00062     return true;
00063   return false;
00064 }
00065 
00066 bool PR2ArmKinematicsPlugin::initialize(const std::string& robot_description,
00067                                         const std::string& group_name,
00068                                         const std::string& base_frame,
00069                                         const std::string& tip_frame,
00070                                         double search_discretization)
00071 {
00072   setValues(robot_description, group_name, base_frame, tip_frame, search_discretization);
00073   urdf::Model robot_model;
00074   std::string xml_string;
00075   ros::NodeHandle private_handle("~/"+group_name);
00076   dimension_ = 7;
00077   while(!loadRobotModel(private_handle,robot_model,xml_string) && private_handle.ok())
00078   {
00079     ROS_ERROR("Could not load robot model. Are you sure the robot model is on the parameter server?");
00080     ros::Duration(0.5).sleep();
00081   }
00082 
00083   ROS_DEBUG("Loading KDL Tree");
00084   if(!getKDLChain(xml_string,base_frame_,tip_frame_,kdl_chain_))
00085   {
00086     active_ = false;
00087     ROS_ERROR("Could not load kdl tree");
00088   }
00089   ROS_DEBUG("Advertising services");
00090   jnt_to_pose_solver_.reset(new KDL::ChainFkSolverPos_recursive(kdl_chain_));
00091   private_handle.param<int>("free_angle",free_angle_,2);
00092 
00093   pr2_arm_ik_solver_.reset(new pr2_arm_kinematics::PR2ArmIKSolver(robot_model, base_frame_,tip_frame_, search_discretization_,free_angle_));
00094   if(!pr2_arm_ik_solver_->active_)
00095   {
00096     ROS_ERROR("Could not load ik");
00097     active_ = false;
00098   }
00099   else
00100   {
00101 
00102     pr2_arm_ik_solver_->getSolverInfo(ik_solver_info_);
00103     pr2_arm_kinematics::getKDLChainInfo(kdl_chain_,fk_solver_info_);
00104     fk_solver_info_.joint_names = ik_solver_info_.joint_names;
00105 
00106     for(unsigned int i=0; i < ik_solver_info_.joint_names.size(); i++)
00107     {
00108       ROS_DEBUG("PR2Kinematics:: joint name: %s",ik_solver_info_.joint_names[i].c_str());
00109     }
00110     for(unsigned int i=0; i < ik_solver_info_.link_names.size(); i++)
00111     {
00112       ROS_DEBUG("PR2Kinematics can solve IK for %s",ik_solver_info_.link_names[i].c_str());
00113     }
00114     for(unsigned int i=0; i < fk_solver_info_.link_names.size(); i++)
00115     {
00116       ROS_DEBUG("PR2Kinematics can solve FK for %s",fk_solver_info_.link_names[i].c_str());
00117     }
00118     ROS_DEBUG("PR2KinematicsPlugin::active for %s",group_name.c_str());
00119     active_ = true;
00120   }
00121   pr2_arm_ik_solver_->setFreeAngle(2);
00122   return active_;
00123 }
00124 
00125 bool PR2ArmKinematicsPlugin::getPositionIK(const geometry_msgs::Pose &ik_pose,
00126                                            const std::vector<double> &ik_seed_state,
00127                                            std::vector<double> &solution,
00128                                            moveit_msgs::MoveItErrorCodes &error_code,
00129                                            const kinematics::KinematicsQueryOptions &options) const
00130 {
00131   if(!active_)
00132   {
00133     ROS_ERROR("kinematics not active");
00134     error_code.val = error_code.NO_IK_SOLUTION;
00135     return false;
00136   }
00137 
00138   KDL::Frame pose_desired;
00139   tf::poseMsgToKDL(ik_pose, pose_desired);
00140 
00141   
00142   KDL::JntArray jnt_pos_in;
00143   KDL::JntArray jnt_pos_out;
00144   jnt_pos_in.resize(dimension_);
00145   for(int i=0; i < dimension_; i++)
00146   {
00147     jnt_pos_in(i) = ik_seed_state[i];
00148   }
00149 
00150   int ik_valid = pr2_arm_ik_solver_->CartToJnt(jnt_pos_in,
00151                                                pose_desired,
00152                                                jnt_pos_out);
00153   if(ik_valid == pr2_arm_kinematics::NO_IK_SOLUTION)
00154   {
00155     error_code.val = error_code.NO_IK_SOLUTION;
00156     return false;
00157   }
00158 
00159   if(ik_valid >= 0)
00160   {
00161     solution.resize(dimension_);
00162     for(int i=0; i < dimension_; i++)
00163     {
00164       solution[i] = jnt_pos_out(i);
00165     }
00166     error_code.val = error_code.SUCCESS;
00167     return true;
00168   }
00169   else
00170   {
00171     ROS_DEBUG("An IK solution could not be found");
00172     error_code.val = error_code.NO_IK_SOLUTION;
00173     return false;
00174   }
00175 }
00176 
00177 bool PR2ArmKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00178                                               const std::vector<double> &ik_seed_state,
00179                                               double timeout,
00180                                               std::vector<double> &solution,
00181                                               moveit_msgs::MoveItErrorCodes &error_code,
00182                                               const kinematics::KinematicsQueryOptions &options) const
00183 {
00184   static IKCallbackFn solution_callback = 0;
00185   static std::vector<double> consistency_limits;
00186   return searchPositionIK(ik_pose, ik_seed_state, timeout, consistency_limits, solution, solution_callback, error_code);
00187 }
00188 
00189 bool PR2ArmKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00190                                               const std::vector<double> &ik_seed_state,
00191                                               double timeout,
00192                                               const std::vector<double> &consistency_limits,
00193                                               std::vector<double> &solution,
00194                                               moveit_msgs::MoveItErrorCodes &error_code,
00195                                               const kinematics::KinematicsQueryOptions &options) const
00196 {
00197   static IKCallbackFn solution_callback = 0;
00198   return searchPositionIK(ik_pose, ik_seed_state, timeout, consistency_limits, solution, solution_callback, error_code);
00199 }
00200 
00201 bool PR2ArmKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00202                                               const std::vector<double> &ik_seed_state,
00203                                               double timeout,
00204                                               std::vector<double> &solution,
00205                                               const IKCallbackFn &solution_callback,
00206                                               moveit_msgs::MoveItErrorCodes &error_code,
00207                                               const kinematics::KinematicsQueryOptions &options) const
00208 {
00209   static std::vector<double> consistency_limits;
00210   return searchPositionIK(ik_pose, ik_seed_state, timeout, consistency_limits, solution, solution_callback, error_code);
00211 }
00212 
00213 bool PR2ArmKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00214                                               const std::vector<double> &ik_seed_state,
00215                                               double timeout,
00216                                               const std::vector<double> &consistency_limits,
00217                                               std::vector<double> &solution,
00218                                               const IKCallbackFn &solution_callback,
00219                                               moveit_msgs::MoveItErrorCodes &error_code,
00220                                               const kinematics::KinematicsQueryOptions &options) const
00221 {
00222   if(!active_)
00223   {
00224     ROS_ERROR("kinematics not active");
00225     error_code.val = error_code.FAILURE;
00226     return false;
00227   }
00228   if(!consistency_limits.empty() && consistency_limits.size() != dimension_)
00229   {
00230     ROS_ERROR("Consistency limits should be of size: %d",dimension_);
00231     error_code.val = error_code.FAILURE;
00232     return false;
00233   }
00234 
00235   KDL::Frame pose_desired;
00236   tf::poseMsgToKDL(ik_pose, pose_desired);
00237 
00238   
00239   KDL::JntArray jnt_pos_in;
00240   KDL::JntArray jnt_pos_out;
00241   jnt_pos_in.resize(dimension_);
00242   for(int i=0; i < dimension_; i++)
00243   {
00244     jnt_pos_in(i) = ik_seed_state[i];
00245   }
00246 
00247   int ik_valid;
00248   if(consistency_limits.empty())
00249   {
00250     ik_valid = pr2_arm_ik_solver_->CartToJntSearch(jnt_pos_in,
00251                                                    pose_desired,
00252                                                    jnt_pos_out,
00253                                                    timeout,
00254                                                    error_code,
00255                                                    solution_callback ?
00256                                                    boost::bind(solution_callback, _1, _2, _3):
00257                                                    IKCallbackFn());
00258   }
00259   else
00260   {
00261     ik_valid = pr2_arm_ik_solver_->CartToJntSearch(jnt_pos_in,
00262                                                    pose_desired,
00263                                                    jnt_pos_out,
00264                                                    timeout,
00265                                                    consistency_limits[free_angle_],
00266                                                    error_code,
00267                                                    solution_callback ?
00268                                                    boost::bind(solution_callback, _1, _2, _3):
00269                                                    IKCallbackFn());
00270   }
00271 
00272   if(ik_valid == pr2_arm_kinematics::NO_IK_SOLUTION)
00273     return false;
00274 
00275   if(ik_valid >= 0)
00276   {
00277     solution.resize(dimension_);
00278     for(int i=0; i < dimension_; i++)
00279     {
00280       solution[i] = jnt_pos_out(i);
00281     }
00282     return true;
00283   }
00284   else
00285   {
00286     ROS_DEBUG("An IK solution could not be found");
00287     return false;
00288   }
00289 }
00290 
00291 bool PR2ArmKinematicsPlugin::getPositionFK(const std::vector<std::string> &link_names,
00292                                            const std::vector<double> &joint_angles,
00293                                            std::vector<geometry_msgs::Pose> &poses) const
00294 {
00295   if(!active_)
00296   {
00297     ROS_ERROR("kinematics not active");
00298     return false;
00299   }
00300 
00301   KDL::Frame p_out;
00302   KDL::JntArray jnt_pos_in;
00303   geometry_msgs::PoseStamped pose;
00304   tf::Stamped<tf::Pose> tf_pose;
00305 
00306   jnt_pos_in.resize(dimension_);
00307   for(int i=0; i < dimension_; i++)
00308   {
00309     jnt_pos_in(i) = joint_angles[i];
00310     
00311   }
00312 
00313   poses.resize(link_names.size());
00314 
00315   bool valid = true;
00316   for(unsigned int i=0; i < poses.size(); i++)
00317   {
00318     
00319     if(jnt_to_pose_solver_->JntToCart(jnt_pos_in,p_out,pr2_arm_kinematics::getKDLSegmentIndex(kdl_chain_,link_names[i])) >= 0)
00320     {
00321       tf::poseKDLToMsg(p_out,poses[i]);
00322     }
00323     else
00324     {
00325       ROS_ERROR("Could not compute FK for %s",link_names[i].c_str());
00326       valid = false;
00327     }
00328   }
00329   return valid;
00330 }
00331 
00332 const std::vector<std::string>& PR2ArmKinematicsPlugin::getJointNames() const
00333 {
00334   if(!active_)
00335   {
00336     ROS_ERROR("kinematics not active");
00337   }
00338   return ik_solver_info_.joint_names;
00339 }
00340 
00341 const std::vector<std::string>& PR2ArmKinematicsPlugin::getLinkNames() const
00342 {
00343   if(!active_)
00344   {
00345     ROS_ERROR("kinematics not active");
00346   }
00347   return fk_solver_info_.link_names;
00348 }
00349 
00350 }