kdl_arm_kinematics_plugin.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 /*
00031  * Author: Sachin Chitta, David Lu!!, Ugo Cupcic
00032  */
00033 
00034 #include <arm_kinematics_constraint_aware/kdl_arm_kinematics_plugin.h>
00035 #include <kdl_conversions/kdl_msg.h>
00036 #include <pluginlib/class_list_macros.h>
00037 
00038 using namespace KDL;
00039 using namespace tf;
00040 using namespace std;
00041 using namespace ros;
00042  
00043 const double BOUNDS_EPSILON = .00001;
00044  
00045 //register KDLArmKinematics as a KinematicsBase implementation
00046 PLUGINLIB_DECLARE_CLASS(arm_kinematics_constraint_aware,KDLArmKinematicsPlugin, arm_kinematics_constraint_aware::KDLArmKinematicsPlugin, kinematics::KinematicsBase)
00047 
00048 namespace arm_kinematics_constraint_aware {
00049 
00050 KDLArmKinematicsPlugin::KDLArmKinematicsPlugin():active_(false)
00051 {
00052   srand ( time(NULL) );
00053 }
00054 
00055 bool KDLArmKinematicsPlugin::isActive()
00056 {
00057   if(active_)
00058     return true;
00059   return false;
00060 }
00061 
00062 double KDLArmKinematicsPlugin::genRandomNumber(const double &min, const double &max)
00063 {
00064   int rand_num = rand()%100+1;
00065   double result = min + (double)((max-min)*rand_num)/101.0;
00066   return result;
00067 }
00068 
00069 KDL::JntArray KDLArmKinematicsPlugin::getRandomConfiguration()
00070 {
00071   KDL::JntArray jnt_array;
00072   jnt_array.resize(dimension_);
00073   for(unsigned int i=0; i < dimension_; i++)
00074     jnt_array(i) = genRandomNumber(joint_min_(i),joint_max_(i));
00075   return jnt_array;
00076 }
00077 
00078 KDL::JntArray KDLArmKinematicsPlugin::getRandomConfiguration(const KDL::JntArray& seed_state,
00079                                                              const unsigned int& redundancy,
00080                                                              const double& consistency_limit)
00081 {
00082   KDL::JntArray jnt_array;
00083   jnt_array.resize(dimension_);
00084   for(unsigned int i=0; i < dimension_; i++) {
00085     if(i != redundancy) {
00086       jnt_array(i) = genRandomNumber(joint_min_(i),joint_max_(i));
00087     } else {
00088       double jmin = fmin(joint_min_(i), seed_state(i)-consistency_limit);
00089       double jmax = fmax(joint_max_(i), seed_state(i)+consistency_limit);
00090       jnt_array(i) = genRandomNumber(jmin, jmax);
00091     }
00092   }
00093   return jnt_array;
00094 }
00095 
00096 bool KDLArmKinematicsPlugin::checkConsistency(const KDL::JntArray& seed_state,
00097                                               const unsigned int& redundancy,
00098                                               const double& consistency_limit,
00099                                               const KDL::JntArray& solution) const
00100 {
00101   KDL::JntArray jnt_array;
00102   jnt_array.resize(dimension_);
00103   for(unsigned int i=0; i < dimension_; i++) {
00104     if(i == redundancy) {
00105       double jmin = fmin(joint_min_(i), seed_state(i)-consistency_limit);
00106       double jmax = fmax(joint_max_(i), seed_state(i)+consistency_limit);
00107       if(solution(i) < jmin || solution(i) > jmax) {
00108         return false;
00109       }
00110     }
00111   }
00112   return true;
00113 }
00114 
00115 bool KDLArmKinematicsPlugin::initialize(const std::string& group_name,
00116                                         const std::string& base_name,
00117                                         const std::string& tip_name,
00118                                         const double& search_discretization)
00119 {
00120   setValues(group_name, base_name, tip_name,search_discretization);
00121   // Get URDF XML
00122   std::string urdf_xml, full_urdf_xml;
00123   ros::NodeHandle node_handle;
00124   ros::NodeHandle private_handle("~"+group_name);
00125   ROS_INFO_STREAM("Private handle registered under " << private_handle.getNamespace());
00126   node_handle.param("urdf_xml",urdf_xml,std::string("robot_description"));
00127   node_handle.searchParam(urdf_xml,full_urdf_xml);
00128   ROS_DEBUG("Reading xml file from parameter server");
00129   std::string result;
00130   if (!node_handle.getParam(full_urdf_xml, result)) {
00131     ROS_FATAL("Could not load the xml from parameter server: %s", urdf_xml.c_str());
00132     return false;
00133   }
00134   // Load and Read Models
00135   if (!loadModel(result)) {
00136     ROS_FATAL("Could not load models!");
00137     return false;
00138   }
00139 
00140   // Get Solver Parameters
00141   int max_iterations;
00142   double epsilon;
00143 
00144   private_handle.param("max_solver_iterations", max_iterations, 500);
00145   private_handle.param("max_search_iterations", max_search_iterations_, 3);
00146   private_handle.param("epsilon", epsilon, 1e-5);
00147 
00148   // Build Solvers
00149   fk_solver_.reset(new KDL::ChainFkSolverPos_recursive(kdl_chain_));
00150   ik_solver_vel_.reset(new KDL::ChainIkSolverVel_pinv(kdl_chain_));
00151   ik_solver_pos_.reset(new KDL::ChainIkSolverPos_NR_JL(kdl_chain_, joint_min_, joint_max_,*fk_solver_, *ik_solver_vel_, max_iterations, epsilon));
00152   active_ = true;
00153   return true;
00154 }
00155 
00156 bool KDLArmKinematicsPlugin::loadModel(const std::string xml) 
00157 {
00158   urdf::Model robot_model;
00159   KDL::Tree tree;
00160 
00161   if (!robot_model.initString(xml)) {
00162     ROS_FATAL("Could not initialize robot model");
00163     return -1;
00164   }
00165   if (!kdl_parser::treeFromString(xml, tree)) {
00166     ROS_ERROR("Could not initialize tree object");
00167     return false;
00168   }
00169   if (!tree.getChain(base_name_, tip_name_, kdl_chain_)) {
00170     ROS_ERROR("Could not initialize chain object");
00171     return false;
00172   }
00173   if (!readJoints(robot_model)) {
00174     ROS_FATAL("Could not read information about the joints");
00175     return false;
00176   }
00177   return true;
00178 }
00179 
00180 bool KDLArmKinematicsPlugin::readJoints(urdf::Model &robot_model) 
00181 {
00182   dimension_ = 0;
00183   // get joint maxs and mins
00184   boost::shared_ptr<const urdf::Link> link = robot_model.getLink(tip_name_);
00185   boost::shared_ptr<const urdf::Joint> joint;
00186   while (link && link->name != base_name_) {
00187     joint = robot_model.getJoint(link->parent_joint->name);
00188     if (!joint) {
00189       ROS_ERROR("Could not find joint: %s",link->parent_joint->name.c_str());
00190       return false;
00191     }
00192     if (joint->type != urdf::Joint::UNKNOWN && joint->type != urdf::Joint::FIXED) {
00193       ROS_INFO( "adding joint: [%s]", joint->name.c_str() );
00194       dimension_++;
00195     }
00196     link = robot_model.getLink(link->getParent()->name);
00197   }
00198   joint_min_.resize(dimension_);
00199   joint_max_.resize(dimension_);
00200   chain_info_.joint_names.resize(dimension_);
00201   chain_info_.limits.resize(dimension_);
00202   link = robot_model.getLink(tip_name_);
00203   if(link)
00204     chain_info_.link_names.push_back(tip_name_);
00205 
00206   unsigned int i = 0;
00207   while (link && i < dimension_) {
00208     joint = robot_model.getJoint(link->parent_joint->name);
00209     if (joint->type != urdf::Joint::UNKNOWN && joint->type != urdf::Joint::FIXED) {
00210       ROS_INFO( "getting bounds for joint: [%s]", joint->name.c_str() );
00211 
00212       float lower, upper;
00213       int hasLimits;
00214       if ( joint->type != urdf::Joint::CONTINUOUS ) {
00215         if(joint->safety) {
00216           lower = joint->safety->soft_lower_limit+BOUNDS_EPSILON; 
00217           upper = joint->safety->soft_upper_limit-BOUNDS_EPSILON;
00218         } else {
00219           lower = joint->limits->lower+BOUNDS_EPSILON;
00220           upper = joint->limits->upper-BOUNDS_EPSILON;
00221         }
00222         hasLimits = 1;
00223       } else {
00224         lower = -M_PI;
00225         upper = M_PI;
00226         hasLimits = 0;
00227       }
00228       int index = dimension_ - i -1;
00229 
00230       joint_min_.data[index] = lower;
00231       joint_max_.data[index] = upper;
00232       chain_info_.joint_names[index] = joint->name;
00233       chain_info_.limits[index].joint_name = joint->name;
00234       chain_info_.limits[index].has_position_limits = hasLimits;
00235       chain_info_.limits[index].min_position = lower;
00236       chain_info_.limits[index].max_position = upper;
00237       i++;
00238     }
00239     link = robot_model.getLink(link->getParent()->name);
00240   }
00241   return true;
00242 }
00243 
00244 int KDLArmKinematicsPlugin::getJointIndex(const std::string &name) 
00245 {
00246   for (unsigned int i=0; i < chain_info_.joint_names.size(); i++) {
00247     if (chain_info_.joint_names[i] == name)
00248       return i;
00249   }
00250   return -1;
00251 }
00252 
00253 int KDLArmKinematicsPlugin::getKDLSegmentIndex(const std::string &name) 
00254 {
00255   int i=0; 
00256   while (i < (int)kdl_chain_.getNrOfSegments()) {
00257     if (kdl_chain_.getSegment(i).getName() == name) {
00258       return i+1;
00259     }
00260     i++;
00261   }
00262   return -1;
00263 }
00264 
00265 bool KDLArmKinematicsPlugin::getPositionIK(const geometry_msgs::Pose &ik_pose,
00266                                            const std::vector<double> &ik_seed_state,
00267                                            std::vector<double> &solution,
00268                                            int &error_code)
00269 {
00270   ros::WallTime n1 = ros::WallTime::now();
00271   if(!active_)
00272   {
00273     ROS_ERROR("kinematics not active");
00274     return false;
00275   }
00276   
00277   ROS_DEBUG_STREAM("getPositionIK1:Position request pose is " <<
00278                    ik_pose.position.x << " " <<
00279                    ik_pose.position.y << " " <<
00280                    ik_pose.position.z << " " <<
00281                    ik_pose.orientation.x << " " << 
00282                    ik_pose.orientation.y << " " << 
00283                    ik_pose.orientation.z << " " << 
00284                    ik_pose.orientation.w);
00285 
00286   KDL::Frame pose_desired;
00287   tf::poseMsgToKDL(ik_pose, pose_desired);
00288   //Do the inverse kinematics
00289   KDL::JntArray jnt_pos_in;
00290   KDL::JntArray jnt_pos_out;
00291   jnt_pos_in.resize(dimension_);
00292   for(unsigned int i=0; i < dimension_; i++)
00293   {
00294     jnt_pos_in(i) = ik_seed_state[i];
00295   }
00296   int ik_valid = ik_solver_pos_->CartToJnt(jnt_pos_in,pose_desired,jnt_pos_out);
00297   ROS_DEBUG_STREAM("IK success " << ik_valid << " time " << (ros::WallTime::now()-n1).toSec());
00298   if(ik_valid >= 0)
00299   {
00300     solution.resize(dimension_);
00301     for(unsigned int i=0; i < dimension_; i++)
00302     {
00303       solution[i] = jnt_pos_out(i);
00304     }
00305     error_code = kinematics::SUCCESS;
00306     return true;
00307   }
00308   else
00309   {
00310     ROS_DEBUG("An IK solution could not be found");   
00311     error_code = kinematics::NO_IK_SOLUTION;
00312     return false;
00313   }
00314 }
00315 
00316 bool KDLArmKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00317                                               const std::vector<double> &ik_seed_state,
00318                                               const double &timeout,
00319                                               std::vector<double> &solution,
00320                                               int &error_code)
00321 {
00322   ros::WallTime n1 = ros::WallTime::now();
00323   if(!active_)
00324   {
00325     ROS_ERROR("kinematics not active");
00326     error_code = kinematics::INACTIVE;
00327     return false;
00328   }
00329   KDL::Frame pose_desired;
00330   tf::poseMsgToKDL(ik_pose, pose_desired);
00331 
00332   ROS_DEBUG_STREAM("searchPositionIK1:Position request pose is " <<
00333                    ik_pose.position.x << " " <<
00334                    ik_pose.position.y << " " <<
00335                    ik_pose.position.z << " " <<
00336                    ik_pose.orientation.x << " " << 
00337                    ik_pose.orientation.y << " " << 
00338                    ik_pose.orientation.z << " " << 
00339                    ik_pose.orientation.w);
00340 
00341   //Do the IK
00342   KDL::JntArray jnt_pos_in;
00343   KDL::JntArray jnt_pos_out;
00344   jnt_pos_in.resize(dimension_);
00345   for(unsigned int i=0; i < dimension_; i++)
00346   {
00347     jnt_pos_in(i) = ik_seed_state[i];
00348   }
00349   for(int i=0; i < max_search_iterations_; i++)
00350   {
00351     for(unsigned int j=0; j < dimension_; j++)
00352     { 
00353       ROS_DEBUG_STREAM("seed state " << j << " " << jnt_pos_in(j));
00354     }
00355     int ik_valid = ik_solver_pos_->CartToJnt(jnt_pos_in,pose_desired,jnt_pos_out);                      
00356     ROS_DEBUG_STREAM("IK success " << ik_valid << " time " << (ros::WallTime::now()-n1).toSec());
00357     if(ik_valid >= 0) {                                                                                                       
00358       solution.resize(dimension_);
00359       for(unsigned int j=0; j < dimension_; j++) {
00360         solution[j] = jnt_pos_out(j);
00361       }
00362       error_code = kinematics::SUCCESS;
00363       ROS_DEBUG_STREAM("Solved after " << i+1 << " iterations");
00364       return true;
00365     }      
00366     jnt_pos_in = getRandomConfiguration();
00367   }
00368   ROS_DEBUG("An IK solution could not be found");   
00369   error_code = kinematics::NO_IK_SOLUTION;
00370   return false;
00371 }
00372 
00373 bool KDLArmKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00374                                               const std::vector<double> &ik_seed_state,
00375                                               const double &timeout,
00376                                               const unsigned int& redundancy,
00377                                               const double &consistency_limit,
00378                                               std::vector<double> &solution,
00379                                               int &error_code)
00380 {
00381   ros::WallTime n1 = ros::WallTime::now();
00382   if(!active_)
00383   {
00384     ROS_ERROR("kinematics not active");
00385     error_code = kinematics::INACTIVE;
00386     return false;
00387   }
00388   KDL::Frame pose_desired;
00389   tf::poseMsgToKDL(ik_pose, pose_desired);
00390 
00391   ROS_DEBUG_STREAM("searchPositionIK1:Position request pose is " <<
00392                    ik_pose.position.x << " " <<
00393                    ik_pose.position.y << " " <<
00394                    ik_pose.position.z << " " <<
00395                    ik_pose.orientation.x << " " << 
00396                    ik_pose.orientation.y << " " << 
00397                    ik_pose.orientation.z << " " << 
00398                    ik_pose.orientation.w);
00399 
00400   //Do the IK
00401   KDL::JntArray jnt_pos_in;
00402   KDL::JntArray jnt_pos_out;
00403   KDL::JntArray jnt_seed_state;
00404   jnt_seed_state.resize(dimension_);
00405   for(unsigned int i=0; i < dimension_; i++)
00406   {
00407     jnt_seed_state(i) = ik_seed_state[i];
00408   }
00409   jnt_pos_in = jnt_seed_state;
00410   for(int i=0; i < max_search_iterations_; i++)
00411   {
00412     for(unsigned int j=0; j < dimension_; j++)
00413     { 
00414       ROS_DEBUG_STREAM("seed state " << j << " " << jnt_pos_in(j));
00415     }
00416     int ik_valid = ik_solver_pos_->CartToJnt(jnt_pos_in,pose_desired,jnt_pos_out);
00417     ROS_DEBUG_STREAM("IK success " << ik_valid << " time " << (ros::WallTime::now()-n1).toSec());
00418     if(ik_valid >= 0 && checkConsistency(jnt_seed_state, redundancy, consistency_limit, jnt_pos_out)) {                                                                                                       
00419       solution.resize(dimension_);
00420       for(unsigned int j=0; j < dimension_; j++) {
00421         solution[j] = jnt_pos_out(j);
00422       }
00423       error_code = kinematics::SUCCESS;
00424       ROS_DEBUG_STREAM("Solved after " << i+1 << " iterations");
00425       return true;
00426     }      
00427     jnt_pos_in = getRandomConfiguration(jnt_seed_state, redundancy, consistency_limit);
00428   }
00429   ROS_DEBUG("An IK solution could not be found");   
00430   error_code = kinematics::NO_IK_SOLUTION;
00431   return false;
00432 }
00433 
00434 bool KDLArmKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00435                                               const std::vector<double> &ik_seed_state,
00436                                               const double &timeout,
00437                                               std::vector<double> &solution,
00438                                               const boost::function<void(const geometry_msgs::Pose &ik_pose,const std::vector<double> &ik_solution,int &error_code)> &desired_pose_callback,
00439                                               const boost::function<void(const geometry_msgs::Pose &ik_pose,const std::vector<double> &ik_solution,int &error_code)> &solution_callback,
00440                                               int &error_code)  
00441 {
00442   if(!active_)
00443   {
00444     ROS_ERROR("kinematics not active");
00445     error_code = kinematics::INACTIVE;
00446     return false;
00447   }
00448   KDL::Frame pose_desired;
00449   tf::poseMsgToKDL(ik_pose, pose_desired);
00450 
00451   ROS_DEBUG_STREAM("searchPositionIK2: Position request pose is " <<
00452                    ik_pose.position.x << " " <<
00453                    ik_pose.position.y << " " <<
00454                    ik_pose.position.z << " " <<
00455                    ik_pose.orientation.x << " " << 
00456                    ik_pose.orientation.y << " " << 
00457                    ik_pose.orientation.z << " " << 
00458                    ik_pose.orientation.w);
00459 
00460   //Do the IK
00461   KDL::JntArray jnt_pos_in;
00462   KDL::JntArray jnt_pos_out;
00463   jnt_pos_in.resize(dimension_);
00464   for(unsigned int i=0; i < dimension_; i++)
00465     jnt_pos_in(i) = ik_seed_state[i];
00466  
00467   if(!desired_pose_callback.empty())
00468     desired_pose_callback(ik_pose,ik_seed_state,error_code);
00469   
00470   if(error_code < 0)
00471   {
00472     ROS_DEBUG("Could not find inverse kinematics for desired end-effector pose since the pose may be in collision");
00473     return false;
00474   }
00475   for(int i=0; i < max_search_iterations_; i++)
00476   {
00477     //for(unsigned int j=0; j < dimension_; j++)
00478     //{ 
00479     //  ROS_DEBUG_STREAM("seed state " << j << " " << jnt_pos_in(j));
00480     //}
00481     int ik_valid = ik_solver_pos_->CartToJnt(jnt_pos_in,pose_desired,jnt_pos_out);                      
00482     jnt_pos_in = getRandomConfiguration();
00483     if(ik_valid < 0)                                                                                                       
00484       continue;
00485     std::vector<double> solution_local;
00486     solution_local.resize(dimension_);
00487     for(unsigned int j=0; j < dimension_; j++)
00488       solution_local[j] = jnt_pos_out(j);
00489     solution_callback(ik_pose,solution_local,error_code);
00490     if(error_code == kinematics::SUCCESS)
00491     {
00492       solution = solution_local;
00493       ROS_DEBUG_STREAM("Solved after " << i+1 << " iterations");
00494       return true;
00495     }
00496   }
00497   ROS_DEBUG("An IK that satisifes the constraints and is collision free could not be found");   
00498   error_code = kinematics::NO_IK_SOLUTION;
00499   return false;
00500 }
00501 
00502 bool KDLArmKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00503                                               const std::vector<double> &ik_seed_state,
00504                                               const double &timeout,
00505                                               const unsigned int& redundancy,
00506                                               const double& consistency_limit,
00507                                               std::vector<double> &solution,
00508                                               const boost::function<void(const geometry_msgs::Pose &ik_pose,const std::vector<double> &ik_solution,int &error_code)> &desired_pose_callback,
00509                                               const boost::function<void(const geometry_msgs::Pose &ik_pose,const std::vector<double> &ik_solution,int &error_code)> &solution_callback,
00510                                               int &error_code)  
00511 {
00512   if(!active_)
00513   {
00514     ROS_ERROR("kinematics not active");
00515     error_code = kinematics::INACTIVE;
00516     return false;
00517   }
00518   KDL::Frame pose_desired;
00519   tf::poseMsgToKDL(ik_pose, pose_desired);
00520 
00521   ROS_DEBUG_STREAM("searchPositionIK2: Position request pose is " <<
00522                    ik_pose.position.x << " " <<
00523                    ik_pose.position.y << " " <<
00524                    ik_pose.position.z << " " <<
00525                    ik_pose.orientation.x << " " << 
00526                    ik_pose.orientation.y << " " << 
00527                    ik_pose.orientation.z << " " << 
00528                    ik_pose.orientation.w);
00529 
00530   //Do the IK
00531   KDL::JntArray jnt_pos_in;
00532   KDL::JntArray jnt_pos_out;
00533   KDL::JntArray jnt_seed_state;
00534   jnt_seed_state.resize(dimension_);
00535   for(unsigned int i=0; i < dimension_; i++)
00536     jnt_seed_state(i) = ik_seed_state[i];
00537  
00538   jnt_pos_in = jnt_seed_state;
00539 
00540   if(!desired_pose_callback.empty())
00541     desired_pose_callback(ik_pose,ik_seed_state,error_code);
00542   
00543   if(error_code < 0)
00544   {
00545     ROS_DEBUG("Could not find inverse kinematics for desired end-effector pose since the pose may be in collision");
00546     return false;
00547   }
00548   for(int i=0; i < max_search_iterations_; i++)
00549   {
00550     //for(unsigned int j=0; j < dimension_; j++)
00551     //{ 
00552     //  ROS_DEBUG_STREAM("seed state " << j << " " << jnt_pos_in(j));
00553     //}
00554     int ik_valid = ik_solver_pos_->CartToJnt(jnt_pos_in,pose_desired,jnt_pos_out);                      
00555     jnt_pos_in = getRandomConfiguration(jnt_seed_state, redundancy, consistency_limit);
00556     if(ik_valid < 0 || !checkConsistency(jnt_seed_state, redundancy, consistency_limit, jnt_pos_out))
00557       continue;
00558     std::vector<double> solution_local;
00559     solution_local.resize(dimension_);
00560     for(unsigned int j=0; j < dimension_; j++)
00561       solution_local[j] = jnt_pos_out(j);
00562     solution_callback(ik_pose,solution_local,error_code);
00563     if(error_code == kinematics::SUCCESS)
00564     {
00565       solution = solution_local;
00566       ROS_DEBUG_STREAM("Solved after " << i+1 << " iterations");
00567       return true;
00568     }
00569   }
00570   ROS_DEBUG("An IK that satisifes the constraints and is collision free could not be found");   
00571   error_code = kinematics::NO_IK_SOLUTION;
00572   return false;
00573 }
00574 
00575 
00576 bool KDLArmKinematicsPlugin::getPositionFK(const std::vector<std::string> &link_names,
00577                                            const std::vector<double> &joint_angles,
00578                                            std::vector<geometry_msgs::Pose> &poses)
00579 {
00580   if(!active_)
00581   {
00582     ROS_ERROR("kinematics not active");
00583     return false;
00584   }
00585   
00586   KDL::Frame p_out;
00587   KDL::JntArray jnt_pos_in;
00588   geometry_msgs::PoseStamped pose;
00589   tf::Stamped<tf::Pose> tf_pose;
00590   
00591   jnt_pos_in.resize(dimension_);
00592   for(unsigned int i=0; i < dimension_; i++)
00593   {
00594     jnt_pos_in(i) = joint_angles[i];
00595   }
00596   
00597   poses.resize(link_names.size());
00598   
00599   bool valid = true;
00600   for(unsigned int i=0; i < poses.size(); i++)
00601   {
00602     ROS_DEBUG("End effector index: %d",getKDLSegmentIndex(link_names[i]));
00603     if(fk_solver_->JntToCart(jnt_pos_in,p_out,getKDLSegmentIndex(link_names[i])) >=0)
00604     {
00605       tf::poseKDLToMsg(p_out,poses[i]);
00606     }
00607     else
00608     {
00609       ROS_ERROR("Could not compute FK for %s",link_names[i].c_str());
00610       valid = false;
00611     }
00612   }
00613   return valid;
00614 }
00615 
00616 const std::vector<std::string>& KDLArmKinematicsPlugin::getJointNames() const
00617 {
00618   if(!active_)
00619   {
00620     ROS_ERROR("kinematics not active");
00621   }
00622   return chain_info_.joint_names;
00623 }
00624 
00625 const std::vector<std::string>& KDLArmKinematicsPlugin::getLinkNames() const
00626 {
00627   if(!active_)
00628   {
00629     ROS_ERROR("kinematics not active");
00630   }
00631   return chain_info_.link_names;
00632 }
00633 
00634 } // namespace


arm_kinematics_constraint_aware
Author(s): Sachin Chitta
autogenerated on Mon Dec 2 2013 12:38:08