eus_kinematics_plugin.cpp
Go to the documentation of this file.
00001 
00007 // #include <moveit/pr2_arm_kinematics/pr2_arm_kinematics_plugin.h>
00008 #include <geometry_msgs/PoseStamped.h>
00009 #include <kdl_parser/kdl_parser.hpp>
00010 #include <tf_conversions/tf_kdl.h>
00011 #include <ros/ros.h>
00012 #include <algorithm>
00013 #include <numeric>
00014 #include <moveit/kinematics_base/kinematics_base.h>
00015 #include <urdf/model.h>
00016 #include <moveit_msgs/GetPositionIK.h>
00017 #include <boost/shared_ptr.hpp>
00018 
00019 
00020 #define ARRAY_LENGTH(array) (int(sizeof(array) / sizeof(array[0])))
00021 
00022 using namespace KDL;
00023 using namespace tf;
00024 using namespace std;
00025 using namespace ros;
00026 
00027 namespace eus_kinematics {
00028 
00029   class EusKinematicsPlugin : public kinematics::KinematicsBase
00030   {
00031     std::vector<std::string> joint_names_;
00032     std::vector<double> joint_min_vector_;
00033     std::vector<double> joint_max_vector_;
00034     std::vector<bool> joint_has_limits_vector_;
00035     std::vector<std::string> link_names_;
00036     size_t num_joints_;
00037     bool active_; // Internal variable that indicates whether solvers are configured and ready
00038 
00039     const std::vector<std::string>& getJointNames() const { return joint_names_; }
00040     const std::vector<std::string>& getLinkNames() const { return link_names_; }
00041 
00042     boost::shared_ptr<ros::ServiceClient> ik_service_client;
00043 
00044   public:
00045 
00049     EusKinematicsPlugin():active_(false){}
00050 
00060     // Returns the first IK solution that is within joint limits, this is called by get_ik() service
00061     bool getPositionIK(const geometry_msgs::Pose &ik_pose,
00062                        const std::vector<double> &ik_seed_state,
00063                        std::vector<double> &solution,
00064                        moveit_msgs::MoveItErrorCodes &error_code,
00065                        const kinematics::KinematicsQueryOptions &options = kinematics::KinematicsQueryOptions()) const;
00066 
00075     bool searchPositionIK(const geometry_msgs::Pose &ik_pose,
00076                           const std::vector<double> &ik_seed_state,
00077                           double timeout,
00078                           std::vector<double> &solution,
00079                           moveit_msgs::MoveItErrorCodes &error_code,
00080                           const kinematics::KinematicsQueryOptions &options = kinematics::KinematicsQueryOptions()) const;
00081 
00091     bool searchPositionIK(const geometry_msgs::Pose &ik_pose,
00092                           const std::vector<double> &ik_seed_state,
00093                           double timeout,
00094                           const std::vector<double> &consistency_limits,
00095                           std::vector<double> &solution,
00096                           moveit_msgs::MoveItErrorCodes &error_code,
00097                           const kinematics::KinematicsQueryOptions &options = kinematics::KinematicsQueryOptions()) const;
00098 
00107     bool searchPositionIK(const geometry_msgs::Pose &ik_pose,
00108                           const std::vector<double> &ik_seed_state,
00109                           double timeout,
00110                           std::vector<double> &solution,
00111                           const IKCallbackFn &solution_callback,
00112                           moveit_msgs::MoveItErrorCodes &error_code,
00113                           const kinematics::KinematicsQueryOptions &options = kinematics::KinematicsQueryOptions()) const;
00114 
00125     bool searchPositionIK(const geometry_msgs::Pose &ik_pose,
00126                           const std::vector<double> &ik_seed_state,
00127                           double timeout,
00128                           const std::vector<double> &consistency_limits,
00129                           std::vector<double> &solution,
00130                           const IKCallbackFn &solution_callback,
00131                           moveit_msgs::MoveItErrorCodes &error_code,
00132                           const kinematics::KinematicsQueryOptions &options = kinematics::KinematicsQueryOptions()) const;
00133 
00145     bool getPositionFK(const std::vector<std::string> &link_names,
00146                        const std::vector<double> &joint_angles,
00147                        std::vector<geometry_msgs::Pose> &poses) const;
00148 
00149   private:
00150 
00151     bool initialize(const std::string &robot_description,
00152                     const std::string& group_name,
00153                     const std::string& base_name,
00154                     const std::string& tip_name,
00155                     double search_discretization);
00156 
00157     int ComputeIkEus(const geometry_msgs::Pose ik_pose, std::vector<double> &result_angle) const;
00158     void ComputeFkEus(void) const;
00159 
00160   }; // end class
00161 
00162   bool EusKinematicsPlugin::initialize(const std::string &robot_description,
00163                                        const std::string& group_name,
00164                                        const std::string& base_name,
00165                                        const std::string& tip_name,
00166                                        double search_discretization)
00167   {
00168     setValues(robot_description, group_name, base_name, tip_name, search_discretization);
00169 
00170     ros::NodeHandle node_handle(group_name);
00171 
00172     ik_service_client = boost::make_shared<ros::ServiceClient>(node_handle.serviceClient<moveit_msgs::GetPositionIK>("eus_ik_request"));
00173     ROS_INFO_STREAM("service client started. service name: " << ik_service_client->getService());
00174       
00175     std::string robot;
00176     node_handle.param("robot",robot,std::string());
00177 
00178     urdf::Model robot_model;
00179     std::string xml_string;
00180 
00181     std::string urdf_xml,full_urdf_xml;
00182     node_handle.param("urdf_xml",urdf_xml,robot_description);
00183     node_handle.searchParam(urdf_xml,full_urdf_xml);
00184 
00185     ROS_DEBUG_STREAM("Reading xml file from parameter server");
00186     if (!node_handle.getParam(full_urdf_xml, xml_string))
00187       {
00188         ROS_FATAL_STREAM("Could not load the xml from parameter server " << urdf_xml.c_str());
00189         return false;
00190       }
00191 
00192     node_handle.param(full_urdf_xml,xml_string,std::string());
00193     robot_model.initString(xml_string);
00194 
00195     ROS_DEBUG_STREAM("Reading joints and links from URDF");
00196 
00197     boost::shared_ptr<urdf::Link> link = boost::const_pointer_cast<urdf::Link>(robot_model.getLink(tip_frame_));
00198     while(link->name != base_frame_)
00199       {
00200         ROS_DEBUG_STREAM("Link " << link->name.c_str());
00201         link_names_.push_back(link->name);
00202         boost::shared_ptr<urdf::Joint> joint = link->parent_joint;
00203         if(joint)
00204           {
00205             if (joint->type != urdf::Joint::UNKNOWN && joint->type != urdf::Joint::FIXED)
00206               {
00207                 ROS_DEBUG_STREAM("Adding joint " << joint->name );
00208 
00209                 joint_names_.push_back(joint->name);
00210                 float lower, upper;
00211                 int hasLimits;
00212                 if ( joint->type != urdf::Joint::CONTINUOUS )
00213                   {
00214                     if(joint->safety)
00215                       {
00216                         lower = joint->safety->soft_lower_limit;
00217                         upper = joint->safety->soft_upper_limit;
00218                       } else {
00219                       lower = joint->limits->lower;
00220                       upper = joint->limits->upper;
00221                     }
00222                     hasLimits = 1;
00223                   }
00224                 else
00225                   {
00226                     lower = -M_PI;
00227                     upper = M_PI;
00228                     hasLimits = 0;
00229                   }
00230                 if(hasLimits)
00231                   {
00232                     joint_has_limits_vector_.push_back(true);
00233                     joint_min_vector_.push_back(lower);
00234                     joint_max_vector_.push_back(upper);
00235                   }
00236                 else
00237                   {
00238                     joint_has_limits_vector_.push_back(false);
00239                     joint_min_vector_.push_back(-M_PI);
00240                     joint_max_vector_.push_back(M_PI);
00241                   }
00242               }
00243           } else
00244           {
00245             ROS_WARN_STREAM("no joint corresponding to " << link->name.c_str());
00246           }
00247         link = link->getParent();
00248       }
00249 
00250     num_joints_ = joint_names_.size();
00251 
00252     if(joint_names_.size() != num_joints_)
00253       {
00254         ROS_FATAL_STREAM("Joint numbers mismatch: URDF has " << joint_names_.size() << " and EusIK has " << num_joints_);
00255         return false;
00256       }
00257 
00258     std::reverse(link_names_.begin(),link_names_.end());
00259     std::reverse(joint_names_.begin(),joint_names_.end());
00260     std::reverse(joint_min_vector_.begin(),joint_min_vector_.end());
00261     std::reverse(joint_max_vector_.begin(),joint_max_vector_.end());
00262     std::reverse(joint_has_limits_vector_.begin(), joint_has_limits_vector_.end());
00263 
00264     ROS_INFO_STREAM("eus_kinematics_plugin was called for plannning group " << getGroupName());
00265     for(size_t i=0; i <num_joints_; ++i)
00266       ROS_INFO_STREAM(joint_names_[i] << " " << joint_min_vector_[i] << " " << joint_max_vector_[i] << " " << joint_has_limits_vector_[i]);
00267 
00268     active_ = true;
00269     return true;
00270   }
00271 
00272   bool EusKinematicsPlugin::getPositionIK(const geometry_msgs::Pose &ik_pose,
00273                                           const std::vector<double> &ik_seed_state,
00274                                           std::vector<double> &solution,
00275                                           moveit_msgs::MoveItErrorCodes &error_code,
00276                                           const kinematics::KinematicsQueryOptions &options) const
00277   {
00278     ROS_DEBUG_STREAM("getPositionIK");
00279 
00280     if(!active_)
00281       {
00282         ROS_ERROR_STREAM("Kinematics not active");
00283         error_code.val = error_code.NO_IK_SOLUTION;
00284         return false;
00285       }
00286 
00287     error_code.val = ComputeIkEus(ik_pose, solution);
00288 
00289     ROS_INFO_STREAM("ComputeIKEus() was called.");
00290 
00291     if(error_code.val != 1)
00292       {
00293         ROS_DEBUG_STREAM("No IK solution");
00294         return false;
00295       }
00296         
00297     // All elements of solution obey limits
00298     // for(int i = 0; i < int(num_joints_); i++)
00299     //   {
00300     //  solution.push_back(sol[i]);
00301     //   }
00302     //ROS_DEBUG_STREAM("Solution: " << *sol);
00303 
00304     return true;
00305   }
00306 
00307   bool EusKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00308                                              const std::vector<double> &ik_seed_state,
00309                                              double timeout,
00310                                              std::vector<double> &solution,
00311                                              moveit_msgs::MoveItErrorCodes &error_code,
00312                                              const kinematics::KinematicsQueryOptions &options) const
00313   {
00314     static IKCallbackFn solution_callback = 0;
00315     static std::vector<double> consistency_limits;
00316     return searchPositionIK(ik_pose, ik_seed_state, timeout, consistency_limits, solution, solution_callback, error_code);
00317   }
00318 
00319   bool EusKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00320                                              const std::vector<double> &ik_seed_state,
00321                                              double timeout,
00322                                              const std::vector<double> &consistency_limits,
00323                                              std::vector<double> &solution,
00324                                              moveit_msgs::MoveItErrorCodes &error_code,
00325                                              const kinematics::KinematicsQueryOptions &options) const
00326   {
00327     static IKCallbackFn solution_callback = 0;
00328     return searchPositionIK(ik_pose, ik_seed_state, timeout, consistency_limits, solution, solution_callback, error_code);
00329   }
00330 
00331   bool EusKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00332                                              const std::vector<double> &ik_seed_state,
00333                                              double timeout,
00334                                              std::vector<double> &solution,
00335                                              const IKCallbackFn &solution_callback,
00336                                              moveit_msgs::MoveItErrorCodes &error_code,
00337                                              const kinematics::KinematicsQueryOptions &options) const
00338   {
00339     static std::vector<double> consistency_limits;
00340     return searchPositionIK(ik_pose, ik_seed_state, timeout, consistency_limits, solution, solution_callback, error_code);
00341   }
00342 
00343   bool EusKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00344                                              const std::vector<double> &ik_seed_state,
00345                                              double timeout,
00346                                              const std::vector<double> &consistency_limits,
00347                                              std::vector<double> &solution,
00348                                              const IKCallbackFn &solution_callback,
00349                                              moveit_msgs::MoveItErrorCodes &error_code,
00350                                              const kinematics::KinematicsQueryOptions &options) const
00351   {
00352     return EusKinematicsPlugin::getPositionIK(ik_pose, ik_seed_state, solution, error_code, options);
00353   }
00354 
00355   bool EusKinematicsPlugin::getPositionFK(const std::vector<std::string> &link_names,
00356                                           const std::vector<double> &joint_angles,
00357                                           std::vector<geometry_msgs::Pose> &poses) const
00358   {
00359     KDL::Frame p_out;
00360     if(link_names.size() == 0) {
00361       ROS_WARN_STREAM("Link names with nothing");
00362       return false;
00363     }
00364 
00365     if(link_names.size()!=1 || link_names[0]!=tip_frame_){
00366       ROS_ERROR_STREAM("Can compute FK for " << tip_frame_.c_str() << " only");
00367       return false;
00368     }
00369 
00370     bool valid = true;
00371 
00372     double eerot[9],eetrans[3];
00373 
00374     ComputeFkEus();
00375     ROS_DEBUG_STREAM("ComputeFKEus() was called. angle: " << angle << " trans: " << eetrans << " rot: " << eerot);
00376 
00377     for(int i=0; i<3;++i)
00378       p_out.p.data[i] = eetrans[i];
00379 
00380     for(int i=0; i<9;++i)
00381       p_out.M.data[i] = eerot[i];
00382 
00383     poses.resize(1);
00384     tf::poseKDLToMsg(p_out,poses[0]);
00385 
00386     return valid;
00387   }
00388 
00389   int EusKinematicsPlugin::ComputeIkEus(const geometry_msgs::Pose ik_pose, std::vector<double> &result_angle) const
00390   {
00391     moveit_msgs::GetPositionIK ik_srv;
00392     geometry_msgs::PoseStamped ik_pose_st;
00393 
00394     ik_pose_st.pose = ik_pose;
00395 
00396     ik_srv.request.ik_request.group_name = getGroupName();
00397     ik_srv.request.ik_request.robot_state.joint_state.name = joint_names_;
00398     ik_srv.request.ik_request.pose_stamped = ik_pose_st;
00399 
00400     ROS_INFO_STREAM("service was called. service name: " << ik_service_client->getService() << "ik_request:");
00401     ROS_INFO_STREAM(ik_srv.request.ik_request);
00402     if (ik_service_client->call(ik_srv))
00403       {
00404         result_angle = ik_srv.response.solution.joint_state.position;
00405         ROS_INFO_STREAM("service succeeded. solution:");
00406         ROS_INFO_STREAM(ik_srv.response.solution);
00407       }
00408     else
00409       {
00410         ROS_ERROR_STREAM("service failed. service name: " << ik_service_client->getService());
00411       }
00412 
00413     return ik_srv.response.error_code.val;
00414   }
00415 
00416   void EusKinematicsPlugin::ComputeFkEus(void) const
00417   {
00418     return;
00419   }
00420 
00421 } // namespace
00422 
00423 //register EusKinematicsPlugin as a KinematicsBase implementation
00424 #include <pluginlib/class_list_macros.h>
00425 PLUGINLIB_EXPORT_CLASS(eus_kinematics::EusKinematicsPlugin, kinematics::KinematicsBase);


moveit_eus_ik_plugin
Author(s): murooka
autogenerated on Wed Sep 16 2015 10:56:25