constrained_ik_plugin.cpp
Go to the documentation of this file.
00001 
00026 #include "constrained_ik/moveit_interface/constrained_ik_plugin.h"
00027 
00028 #include <ros/ros.h>
00029 #include <kdl_parser/kdl_parser.hpp>
00030 #include <tf_conversions/tf_kdl.h>
00031 #include <eigen_conversions/eigen_kdl.h>
00032 #include <pluginlib/class_list_macros.h>
00033 PLUGINLIB_EXPORT_CLASS(constrained_ik::ConstrainedIKPlugin, kinematics::KinematicsBase)
00034 
00035 using namespace KDL;
00036 using namespace tf;
00037 using namespace std;
00038 using namespace ros;
00039 
00040 namespace constrained_ik
00041 {
00042 
00043 ConstrainedIKPlugin::ConstrainedIKPlugin():active_(false), dimension_(0)
00044 {
00045 }
00046 
00047 bool ConstrainedIKPlugin::isActive() const
00048 {
00049   if(active_)
00050     return true;
00051   ROS_ERROR("kinematics not active");
00052   return false;
00053 }
00054 
00055 bool ConstrainedIKPlugin::initialize(const std::string& robot_description,
00056                                      const std::string& group_name,
00057                                      const std::string& base_name,
00058                                      const std::string& tip_name,
00059                                      double search_discretization)
00060 {
00061   setValues(robot_description, group_name, base_name, tip_name, search_discretization);
00062 
00063   // init robot model
00064   rdf_loader::RDFLoader rdf_loader(robot_description_);
00065   const boost::shared_ptr<srdf::Model> &srdf = rdf_loader.getSRDF();
00066   const boost::shared_ptr<urdf::ModelInterface>& urdf_model = rdf_loader.getURDF();
00067 
00068   if (!urdf_model || !srdf)
00069   {
00070     ROS_ERROR_STREAM("URDF and SRDF must be loaded for Constrained Ik solver to work.");
00071     return false;
00072   }
00073 
00074   // instatiating a robot model
00075   robot_model_ptr_.reset(new robot_model::RobotModel(urdf_model,srdf));
00076   if(!robot_model_ptr_)
00077   {
00078     ROS_ERROR_STREAM("Could not load URDF model from " << robot_description);
00079     active_ = false;
00080     return false;
00081   }
00082 
00083   const robot_model::JointModelGroup* joint_model_group = robot_model_ptr_->getJointModelGroup(group_name);
00084   if (!joint_model_group)
00085     return false;
00086 
00087   if (!joint_model_group->isChain())
00088   {
00089     ROS_ERROR_NAMED("clik", "Group '%s' is not a chain.", group_name.c_str());
00090     return false;
00091   }
00092 
00093   robot_state_.reset(new moveit::core::RobotState(robot_model_ptr_));
00094 
00095   // initializing planning scene
00096   planning_scene_.reset(new planning_scene::PlanningScene(robot_model_ptr_));
00097 
00098   //initialize kinematic solver with robot info
00099   if (!kin_.init(joint_model_group))
00100   {
00101     ROS_ERROR("Could not initialize BasicIK");
00102     active_ = false;
00103   }
00104   else
00105   {
00106     dimension_ = kin_.numJoints();
00107     kin_.getJointNames(joint_names_);
00108     kin_.getLinkNames(link_names_);
00109     active_ = true;
00110   }
00111 
00112   try
00113   {
00114     solver_.reset(new Constrained_IK());
00115     std::string constraint_param = "constrained_ik_solver/" + group_name + "/constraints";
00116     solver_->addConstraintsFromParamServer(constraint_param);
00117     solver_->init(kin_); // inside try because it has the potential to throw and error
00118   }
00119   catch (exception &e)
00120   {
00121     ROS_ERROR_STREAM("Caught exception from solver_: " << e.what());
00122     return false;
00123   }
00124 
00125   return active_;
00126 }
00127 
00128 bool ConstrainedIKPlugin::getPositionIK(const geometry_msgs::Pose &ik_pose,
00129                                         const std::vector<double> &ik_seed_state,
00130                                         std::vector<double> &solution,
00131                                         moveit_msgs::MoveItErrorCodes &error_code,
00132                                         const kinematics::KinematicsQueryOptions &options) const
00133 {
00134   //check that solver is ready and properly configured
00135   if(!active_)
00136   {
00137     ROS_ERROR("kinematics not active");
00138     error_code.val = error_code.NO_IK_SOLUTION;
00139     return false;
00140   }
00141   if(ik_seed_state.size() != dimension_)
00142   {
00143     ROS_ERROR("ik_seed_state does not have same dimension as solver");
00144     error_code.val = error_code.NO_IK_SOLUTION;
00145     return false;
00146   }
00147 
00148   //convert input parameters to required types
00149   KDL::Frame pose_desired;
00150   tf::poseMsgToKDL(ik_pose, pose_desired);
00151   Eigen::Affine3d goal;
00152   tf::transformKDLToEigen(pose_desired, goal);
00153 
00154   Eigen::VectorXd seed(dimension_), joint_angles(dimension_);
00155   for(size_t ii=0; ii < dimension_; ++ii)
00156   {
00157     seed(ii) = ik_seed_state[ii];
00158   }
00159 
00160   //Do IK and report results
00161   try
00162   {
00163     if(!solver_->calcInvKin(goal, seed, planning_scene_, joint_angles))
00164     {
00165       ROS_ERROR_STREAM("Unable to find IK solution.");
00166       error_code.val = error_code.NO_IK_SOLUTION;
00167       return false;
00168     }
00169   }
00170   catch (exception &e)
00171   {
00172     ROS_ERROR_STREAM("Caught exception from IK: " << e.what());
00173     error_code.val = error_code.NO_IK_SOLUTION;
00174     return false;
00175   }
00176   solution.resize(dimension_);
00177   for(size_t ii=0; ii < dimension_; ++ii)
00178   {
00179     solution[ii] = joint_angles(ii);
00180   }
00181 
00182   return true;
00183 
00184 }
00185 
00186 bool ConstrainedIKPlugin::searchPositionIK( const geometry_msgs::Pose &ik_pose,
00187                                             const std::vector<double> &ik_seed_state,
00188                                             double timeout,
00189                                             std::vector<double> &solution,
00190                                             moveit_msgs::MoveItErrorCodes &error_code,
00191                                             const kinematics::KinematicsQueryOptions &options) const
00192 {
00193     static IKCallbackFn solution_callback = 0;
00194     static std::vector<double> consistency_limits;
00195     return searchPositionIK(ik_pose, ik_seed_state, timeout, consistency_limits, solution, solution_callback, error_code);
00196 }
00197 
00198 bool ConstrainedIKPlugin::searchPositionIK( const geometry_msgs::Pose &ik_pose,
00199                                             const std::vector<double> &ik_seed_state,
00200                                             double timeout,
00201                                             const std::vector<double> &consistency_limits,
00202                                             std::vector<double> &solution,
00203                                             moveit_msgs::MoveItErrorCodes &error_code,
00204                                             const kinematics::KinematicsQueryOptions &options) const
00205 {
00206     static IKCallbackFn solution_callback = 0;
00207     return searchPositionIK(ik_pose, ik_seed_state, timeout, consistency_limits, solution, solution_callback, error_code);
00208 }
00209 
00210 bool ConstrainedIKPlugin::searchPositionIK( const geometry_msgs::Pose &ik_pose,
00211                                             const std::vector<double> &ik_seed_state,
00212                                             double timeout,
00213                                             std::vector<double> &solution,
00214                                             const IKCallbackFn &solution_callback,
00215                                             moveit_msgs::MoveItErrorCodes &error_code,
00216                                             const kinematics::KinematicsQueryOptions &options) const
00217 {
00218     static std::vector<double> consistency_limits;
00219     return searchPositionIK(ik_pose, ik_seed_state, timeout, consistency_limits, solution, solution_callback, error_code);
00220 }
00221 
00222 bool ConstrainedIKPlugin::searchPositionIK( const geometry_msgs::Pose &ik_pose,
00223                                             const std::vector<double> &ik_seed_state,
00224                                             double timeout,
00225                                             const std::vector<double> &consistency_limits,
00226                                             std::vector<double> &solution,
00227                                             const IKCallbackFn &solution_callback,
00228                                             moveit_msgs::MoveItErrorCodes &error_code,
00229                                             const kinematics::KinematicsQueryOptions &options) const
00230 {
00231 
00232   if(!active_)
00233   {
00234     ROS_ERROR("kinematics not active");
00235     error_code.val = error_code.FAILURE;
00236     return false;
00237   }
00238 
00239   KDL::Frame pose_desired;
00240   tf::poseMsgToKDL(ik_pose, pose_desired);
00241   Eigen::Affine3d goal;
00242   tf::transformKDLToEigen(pose_desired, goal);
00243 
00244   if(dimension_ != ik_seed_state.size()){
00245     ROS_ERROR("dimension_ and ik_seed_state are of different sizes");
00246     return(false);
00247   }
00248   Eigen::VectorXd seed(dimension_), joint_angles;
00249   for(size_t ii=0; ii < dimension_; ii++)
00250   {
00251     seed(ii) = ik_seed_state[ii];
00252   }
00253 
00254   //Do the IK
00255   bool success(true);
00256   try
00257   {
00258     if(!solver_->calcInvKin(goal, seed, planning_scene_, joint_angles))
00259     {
00260       ROS_ERROR_STREAM("Unable to find IK solution.");
00261       error_code.val = error_code.NO_IK_SOLUTION;
00262       success &= false;
00263     }
00264   }
00265   catch (exception &e)
00266   {
00267     ROS_ERROR_STREAM("Caught exception from IK: " << e.what());
00268     error_code.val = error_code.NO_IK_SOLUTION;
00269     success &= false;
00270   }
00271 
00272   solution.resize(dimension_);
00273   for(size_t ii=0; ii < dimension_; ++ii)
00274   {
00275     solution[ii] = joint_angles(ii);
00276   }
00277 
00278   // If there is a solution callback registered, check before returning
00279   if (solution_callback)
00280   {
00281     solution_callback(ik_pose, solution, error_code);
00282     if(error_code.val != error_code.SUCCESS)
00283       success &= false;
00284   }
00285   // Default: return successfully
00286   if (success)
00287     error_code.val = error_code.SUCCESS;
00288 
00289   return success;
00290 
00291 }
00292 
00293 bool ConstrainedIKPlugin::getPositionFK(const std::vector<std::string> &link_names,
00294                                         const std::vector<double> &joint_angles,
00295                                         std::vector<geometry_msgs::Pose> &poses) const
00296 {
00297   if(!active_)
00298   {
00299     ROS_ERROR("kinematics not active");
00300     return false;
00301   }
00302 
00303   Eigen::VectorXd jnt_pos_in;
00304   geometry_msgs::PoseStamped pose;
00305   tf::Stamped<tf::Pose> tf_pose;
00306 
00307   jnt_pos_in.resize(dimension_);
00308   for(int i=0; i < dimension_; i++)
00309   {
00310     jnt_pos_in(i) = joint_angles[i];
00311   }
00312 
00313   poses.resize(link_names.size());
00314 
00315   std::vector<KDL::Frame> kdl_poses;
00316   bool valid = kin_.linkTransforms(jnt_pos_in, kdl_poses, link_names);
00317   for(size_t ii=0; ii < kdl_poses.size(); ++ii)
00318   {
00319     tf::poseKDLToMsg(kdl_poses[ii],poses[ii]);
00320   }
00321   //TODO remove this printing
00322   ROS_INFO_STREAM("poses: ");
00323   for (size_t ii=0; ii<poses.size(); ++ii)
00324   {
00325     ROS_INFO_STREAM(poses[ii]);
00326   }
00327   return valid;
00328 }
00329 
00330 const std::vector<std::string>& ConstrainedIKPlugin::getJointNames() const
00331 {
00332   isActive();
00333   return joint_names_;
00334 }
00335 
00336 const std::vector<std::string>& ConstrainedIKPlugin::getLinkNames() const
00337 {
00338   isActive();
00339   return link_names_;
00340 }
00341 
00342 } //namespace constrained_ik_plugin


constrained_ik
Author(s): Chris Lewis , Jeremy Zoss , Dan Solomon
autogenerated on Sat Jun 8 2019 19:23:45