pr2_arm_ik.cpp
Go to the documentation of this file.
00001 //Software License Agreement (BSD License)
00002 
00003 //Copyright (c) 2008, Willow Garage, Inc.
00004 //All rights reserved.
00005 
00006 //Redistribution and use in source and binary forms, with or without
00007 //modification, are permitted provided that the following conditions
00008 //are met:
00009 
00010 // * Redistributions of source code must retain the above copyright
00011 //   notice, this list of conditions and the following disclaimer.
00012 // * Redistributions in binary form must reproduce the above
00013 //   copyright notice, this list of conditions and the following
00014 //   disclaimer in the documentation and/or other materials provided
00015 //   with the distribution.
00016 // * Neither the name of Willow Garage, Inc. nor the names of its
00017 //   contributors may be used to endorse or promote products derived
00018 //   from this software without specific prior written permission.
00019 
00020 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 //"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023 //FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024 //COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025 //INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026 //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028 //CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029 //LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00030 //ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031 //POSSIBILITY OF SUCH DAMAGE.
00032 
00033 #include <angles/angles.h>
00034 #include <pr2_arm_kinematics/pr2_arm_ik.h>
00035 
00036 /**** List of angles (for reference) *******
00037       th1 = shoulder/turret pan
00038       th2 = shoulder/turret lift/pitch
00039       th3 = shoulder/turret roll
00040       th4 = elbow pitch
00041       th5 = elbow roll 
00042       th6 = wrist pitch
00043       th7 = wrist roll 
00044 *****/
00045 using namespace angles;
00046 using namespace pr2_arm_kinematics;
00047 
00048 PR2ArmIK::PR2ArmIK()
00049 {
00050 }
00051 
00052 bool PR2ArmIK::init(const urdf::Model &robot_model, const std::string &root_name, const std::string &tip_name)
00053 {
00054   std::vector<urdf::Pose> link_offset;
00055   int num_joints = 0;
00056   boost::shared_ptr<const urdf::Link> link = robot_model.getLink(tip_name);
00057   while(link && num_joints < 7)
00058   {
00059     boost::shared_ptr<const urdf::Joint> joint = robot_model.getJoint(link->parent_joint->name);
00060     if(!joint)
00061     {
00062       ROS_ERROR("Could not find joint: %s",link->parent_joint->name.c_str());
00063       return false;
00064     }
00065     if(joint->type != urdf::Joint::UNKNOWN && joint->type != urdf::Joint::FIXED)
00066     {
00067       link_offset.push_back(link->parent_joint->parent_to_joint_origin_transform);
00068       angle_multipliers_.push_back(joint->axis.x*fabs(joint->axis.x) +  joint->axis.y*fabs(joint->axis.y) +  joint->axis.z*fabs(joint->axis.z));
00069       ROS_DEBUG("Joint axis: %d, %f, %f, %f",6-num_joints,joint->axis.x,joint->axis.y,joint->axis.z);
00070       if(joint->type != urdf::Joint::CONTINUOUS)
00071       {
00072         min_angles_.push_back(joint->safety->soft_lower_limit);
00073         max_angles_.push_back(joint->safety->soft_upper_limit);
00074         continuous_joint_.push_back(false);
00075       }
00076       else
00077       {
00078         min_angles_.push_back(-M_PI);
00079         max_angles_.push_back(M_PI);
00080         continuous_joint_.push_back(true);
00081       }
00082       addJointToChainInfo(link->parent_joint,solver_info_);
00083       num_joints++;
00084     }
00085     link = robot_model.getLink(link->getParent()->name);
00086   } 
00087 
00088   solver_info_.link_names.push_back(tip_name);
00089 
00090   //  solver_info_.link_names.push_back(tip_name);
00091   // We expect order from root to tip, so reverse the order
00092   std::reverse(angle_multipliers_.begin(),angle_multipliers_.end());
00093   std::reverse(min_angles_.begin(),min_angles_.end());
00094   std::reverse(max_angles_.begin(),max_angles_.end());
00095   std::reverse(link_offset.begin(),link_offset.end());
00096   std::reverse(solver_info_.limits.begin(),solver_info_.limits.end());
00097   std::reverse(solver_info_.joint_names.begin(),solver_info_.joint_names.end());
00098   std::reverse(solver_info_.link_names.begin(),solver_info_.link_names.end());
00099   std::reverse(continuous_joint_.begin(),continuous_joint_.end());
00100 
00101   if(num_joints != 7)
00102   {
00103     ROS_FATAL("PR2ArmIK:: Chain from %s to %s does not have 7 joints",root_name.c_str(),tip_name.c_str());
00104     return false;
00105   }
00106 
00107   torso_shoulder_offset_x_ = link_offset[0].position.x;
00108   torso_shoulder_offset_y_ = link_offset[0].position.y;
00109   torso_shoulder_offset_z_ = link_offset[0].position.z;
00110   shoulder_upperarm_offset_ = distance(link_offset[1]);
00111   upperarm_elbow_offset_ = distance(link_offset[3]);
00112   elbow_wrist_offset_ = distance(link_offset[5]);
00113   shoulder_elbow_offset_ = shoulder_upperarm_offset_ + upperarm_elbow_offset_;
00114   shoulder_wrist_offset_ = shoulder_upperarm_offset_+upperarm_elbow_offset_+elbow_wrist_offset_;
00115 
00116   Eigen::Matrix4f home = Eigen::Matrix4f::Identity();
00117   home(0,3) = shoulder_upperarm_offset_ +  upperarm_elbow_offset_ +  elbow_wrist_offset_;
00118   home_inv_ = home.inverse();
00119   grhs_ = home;
00120   gf_ = home_inv_;
00121   solution_.resize( NUM_JOINTS_ARM7DOF);
00122   return true;
00123 }
00124 
00125 void PR2ArmIK::addJointToChainInfo(boost::shared_ptr<const urdf::Joint> joint, kinematics_msgs::KinematicSolverInfo &info)
00126 {
00127   arm_navigation_msgs::JointLimits limit;
00128   info.joint_names.push_back(joint->name);//Joints are coming in reverse order
00129   limit.min_position = joint->safety->soft_lower_limit;
00130   limit.max_position = joint->safety->soft_upper_limit;
00131   if(joint->type != urdf::Joint::CONTINUOUS)
00132   {
00133     limit.min_position = joint->safety->soft_lower_limit;
00134     limit.max_position = joint->safety->soft_upper_limit;
00135     limit.has_position_limits = true;
00136   }
00137   else
00138   {
00139     limit.min_position = -M_PI;
00140     limit.max_position = M_PI;
00141     limit.has_position_limits = false;
00142   }
00143   limit.max_velocity = joint->limits->velocity;
00144   limit.has_velocity_limits = 1;
00145   info.limits.push_back(limit);
00146 }
00147 
00148 void PR2ArmIK::getSolverInfo(kinematics_msgs::KinematicSolverInfo &info)
00149 {
00150   info = solver_info_;
00151 }
00152 
00153 
00154 void PR2ArmIK::computeIKShoulderPan(const Eigen::Matrix4f &g_in, const double &t1_in, std::vector<std::vector<double> > &solution)
00155 {
00156 //t1 = shoulder/turret pan is specified
00157 //  solution_ik_.resize(0);
00158 
00159   Eigen::Matrix4f g = g_in;
00160 //First bring everything into the arm frame
00161   g(0,3) = g_in(0,3) - torso_shoulder_offset_x_;
00162   g(1,3) = g_in(1,3) - torso_shoulder_offset_y_;
00163   g(2,3) = g_in(2,3) - torso_shoulder_offset_z_;
00164 
00165   double t1 = angles::normalize_angle(t1_in);
00166   if(!checkJointLimits(t1,0))
00167     return;
00168 
00169 
00170   double cost1, cost2, cost3, cost4;
00171   double sint1, sint2, sint3, sint4;
00172 
00173   gf_ = g*home_inv_;
00174 
00175   cost1 = cos(t1);
00176   sint1 = sin(t1);
00177 
00178   double t2(0), t3(0), t4(0), t5(0), t6(0), t7(0);
00179 
00180   double at(0), bt(0), ct(0);
00181 
00182   double theta2[2],theta3[2],theta4[2],theta5[2],theta6[4],theta7[2]; 
00183 
00184   double sopx = shoulder_upperarm_offset_*cost1;
00185   double sopy = shoulder_upperarm_offset_*sint1;
00186   double sopz = 0;
00187 
00188   double x = g(0,3);
00189   double y = g(1,3);
00190   double z = g(2,3);
00191 
00192   double dx = x - sopx;
00193   double dy = y - sopy;
00194   double dz = z - sopz;
00195 
00196   double dd = dx*dx + dy*dy + dz*dz;
00197 
00198   double numerator = dd-shoulder_upperarm_offset_*shoulder_upperarm_offset_+2*shoulder_upperarm_offset_*shoulder_elbow_offset_-2*shoulder_elbow_offset_*shoulder_elbow_offset_+2*shoulder_elbow_offset_*shoulder_wrist_offset_-shoulder_wrist_offset_*shoulder_wrist_offset_;
00199   double denominator = 2*(shoulder_upperarm_offset_-shoulder_elbow_offset_)*(shoulder_elbow_offset_-shoulder_wrist_offset_);
00200 
00201   double acosTerm = numerator/denominator;
00202 
00203   if (acosTerm > 1.0 || acosTerm < -1.0)
00204     return;
00205 
00206   double acos_angle = acos(acosTerm);
00207  
00208   theta4[0] = acos_angle;
00209   theta4[1] = -acos_angle;
00210 
00211 #ifdef DEBUG
00212   std::cout << "ComputeIK::theta3:" << numerator << "," << denominator << "," << std::endl << theta4[0] << std::endl;
00213 #endif
00214 
00215   for(int jj =0; jj < 2; jj++)
00216   {
00217     t4 = theta4[jj];
00218     cost4 = cos(t4);
00219     sint4 = sin(t4);
00220 
00221 #ifdef DEBUG
00222     std::cout << "t4 " << t4 << std::endl;
00223 #endif
00224     if(std::isnan(t4))
00225       continue;
00226 
00227     if(!checkJointLimits(t4,3))
00228       continue;
00229 
00230     at = x*cost1+y*sint1-shoulder_upperarm_offset_;
00231     bt = -z;
00232     ct = -shoulder_upperarm_offset_ + shoulder_elbow_offset_ + (shoulder_wrist_offset_-shoulder_elbow_offset_)*cos(t4);
00233 
00234     if(!solveCosineEqn(at,bt,ct,theta2[0],theta2[1]))
00235       continue;
00236 
00237     for(int ii=0; ii < 2; ii++)
00238     {
00239       t2 = theta2[ii];
00240       if(!checkJointLimits(t2,1))
00241         continue;
00242 
00243 
00244 #ifdef DEBUG
00245       std::cout << "t2 " << t2 << std::endl; 
00246 #endif
00247       sint2 = sin(t2);
00248       cost2 = cos(t2);
00249 
00250       at = sint1*(shoulder_elbow_offset_ - shoulder_wrist_offset_)*sint2*sint4;
00251       bt = (-shoulder_elbow_offset_+shoulder_wrist_offset_)*cost1*sint4;
00252       ct = y - (shoulder_upperarm_offset_+cost2*(-shoulder_upperarm_offset_+shoulder_elbow_offset_+(-shoulder_elbow_offset_+shoulder_wrist_offset_)*cos(t4)))*sint1;
00253       if(!solveCosineEqn(at,bt,ct,theta3[0],theta3[1]))
00254         continue;
00255 
00256       for(int kk =0; kk < 2; kk++)
00257       {           
00258         t3 = theta3[kk];
00259 
00260         if(!checkJointLimits(angles::normalize_angle(t3),2))
00261           continue;
00262 
00263         sint3 = sin(t3);
00264         cost3 = cos(t3);
00265 #ifdef DEBUG
00266         std::cout << "t3 " << t3 << std::endl; 
00267 #endif
00268         if(fabs((shoulder_upperarm_offset_-shoulder_elbow_offset_+(shoulder_elbow_offset_-shoulder_wrist_offset_)*cost4)*sint2+(shoulder_elbow_offset_-shoulder_wrist_offset_)*cost2*cost3*sint4-z) > IK_EPS )
00269           continue;
00270 
00271         if(fabs((shoulder_elbow_offset_-shoulder_wrist_offset_)*sint1*sint3*sint4+cost1*(shoulder_upperarm_offset_+cost2*(-shoulder_upperarm_offset_+shoulder_elbow_offset_+(-shoulder_elbow_offset_+shoulder_wrist_offset_)*cost4)+(shoulder_elbow_offset_-shoulder_wrist_offset_)*cost3*sint2*sint4) - x) > IK_EPS)
00272           continue;
00273 
00274         grhs_(0,0) = cost4*(gf_(0,0)*cost1*cost2+gf_(1,0)*cost2*sint1-gf_(2,0)*sint2)-(gf_(2,0)*cost2*cost3 + cost3*(gf_(0,0)*cost1 + gf_(1,0)*sint1)*sint2 + (-(gf_(1,0)*cost1) + gf_(0,0)*sint1)*sint3)*sint4;
00275 
00276         grhs_(0,1) = cost4*(gf_(0,1)*cost1*cost2 + gf_(1,1)*cost2*sint1 - gf_(2,1)*sint2) - (gf_(2,1)*cost2*cost3 + cost3*(gf_(0,1)*cost1 + gf_(1,1)*sint1)*sint2 + (-(gf_(1,1)*cost1) + gf_(0,1)*sint1)*sint3)*sint4;
00277 
00278         grhs_(0,2) = cost4*(gf_(0,2)*cost1*cost2 + gf_(1,2)*cost2*sint1 - gf_(2,2)*sint2) - (gf_(2,2)*cost2*cost3 + cost3*(gf_(0,2)*cost1 + gf_(1,2)*sint1)*sint2 + (-(gf_(1,2)*cost1) + gf_(0,2)*sint1)*sint3)*sint4;
00279 
00280         grhs_(1,0) = cost3*(gf_(1,0)*cost1 - gf_(0,0)*sint1) + gf_(2,0)*cost2*sint3 + (gf_(0,0)*cost1 + gf_(1,0)*sint1)*sint2*sint3;
00281 
00282         grhs_(1,1) = cost3*(gf_(1,1)*cost1 - gf_(0,1)*sint1) + gf_(2,1)*cost2*sint3 + (gf_(0,1)*cost1 + gf_(1,1)*sint1)*sint2*sint3;
00283 
00284         grhs_(1,2) = cost3*(gf_(1,2)*cost1 - gf_(0,2)*sint1) + gf_(2,2)*cost2*sint3 + (gf_(0,2)*cost1 + gf_(1,2)*sint1)*sint2*sint3;
00285 
00286         grhs_(2,0) = cost4*(gf_(2,0)*cost2*cost3 + cost3*(gf_(0,0)*cost1 + gf_(1,0)*sint1)*sint2 + (-(gf_(1,0)*cost1) + gf_(0,0)*sint1)*sint3) + (gf_(0,0)*cost1*cost2 + gf_(1,0)*cost2*sint1 - gf_(2,0)*sint2)*sint4;
00287 
00288         grhs_(2,1) = cost4*(gf_(2,1)*cost2*cost3 + cost3*(gf_(0,1)*cost1 + gf_(1,1)*sint1)*sint2 + (-(gf_(1,1)*cost1) + gf_(0,1)*sint1)*sint3) + (gf_(0,1)*cost1*cost2 + gf_(1,1)*cost2*sint1 - gf_(2,1)*sint2)*sint4;
00289 
00290         grhs_(2,2) = cost4*(gf_(2,2)*cost2*cost3 + cost3*(gf_(0,2)*cost1 + gf_(1,2)*sint1)*sint2 + (-(gf_(1,2)*cost1) + gf_(0,2)*sint1)*sint3) + (gf_(0,2)*cost1*cost2 + gf_(1,2)*cost2*sint1 - gf_(2,2)*sint2)*sint4;
00291 
00292 
00293         double val1 = sqrt(grhs_(0,1)*grhs_(0,1)+grhs_(0,2)*grhs_(0,2));
00294         double val2 = grhs_(0,0);
00295 
00296         theta6[0] = atan2(val1,val2);
00297         theta6[1] = atan2(-val1,val2);
00298 
00299 //            theta6[3] = M_PI + theta6[0];
00300 //            theta6[4] = M_PI + theta6[1];
00301 
00302         for(int mm = 0; mm < 2; mm++)
00303         {
00304           t6 = theta6[mm];
00305           if(!checkJointLimits(angles::normalize_angle(t6),5))
00306             continue;
00307 
00308 #ifdef DEBUG
00309           std::cout << "t6 " << t6 << std::endl;
00310 #endif
00311           if(fabs(cos(t6) - grhs_(0,0)) > IK_EPS)
00312             continue;
00313 
00314           if(fabs(sin(t6)) < IK_EPS)
00315           {
00316             //                std::cout << "Singularity" << std::endl;
00317             theta5[0] = acos(grhs_(1,1))/2.0;
00318             theta7[0] = theta7[0];
00319             theta7[1] = M_PI+theta7[0];
00320             theta5[1] = theta7[1];
00321           }
00322           else
00323           {
00324             theta7[0] = atan2(grhs_(0,1),grhs_(0,2));
00325             theta5[0] = atan2(grhs_(1,0),-grhs_(2,0));
00326             theta7[1] = M_PI+theta7[0];
00327             theta5[1] = M_PI+theta5[0];
00328           }
00329 #ifdef DEBUG
00330           std::cout << "theta1: " << t1 << std::endl;
00331           std::cout << "theta2: " << t2 << std::endl;
00332           std::cout << "theta3: " << t3 << std::endl;
00333           std::cout << "theta4: " << t4 << std::endl;
00334           std::cout << "theta5: " << t5 << std::endl;
00335           std::cout << "theta6: " << t6 << std::endl;
00336           std::cout << "theta7: " << t7 << std::endl << std::endl << std::endl;
00337 #endif
00338           for(int lll =0; lll < 2; lll++)
00339           {
00340             t5 = theta5[lll];
00341             t7 = theta7[lll];
00342             if(!checkJointLimits(t5,4))
00343               continue;
00344             if(!checkJointLimits(t7,6))
00345               continue;
00346 
00347 #ifdef DEBUG
00348             std::cout << "t5" << t5 << std::endl;
00349             std::cout << "t7" << t7 << std::endl;
00350 #endif      
00351             if(fabs(sin(t6)*sin(t7)-grhs_(0,1)) > IK_EPS || fabs(cos(t7)*sin(t6)-grhs_(0,2)) > IK_EPS)
00352               continue;
00353 
00354             solution_[0] = normalize_angle(t1)*angle_multipliers_[0];
00355             solution_[1] = normalize_angle(t2)*angle_multipliers_[1];
00356             solution_[2] = normalize_angle(t3)*angle_multipliers_[2];
00357             solution_[3] = normalize_angle(t4)*angle_multipliers_[3];
00358             solution_[4] = normalize_angle(t5)*angle_multipliers_[4];
00359             solution_[5] = normalize_angle(t6)*angle_multipliers_[5];
00360             solution_[6] = normalize_angle(t7)*angle_multipliers_[6];
00361             solution.push_back(solution_);
00362 
00363 #ifdef DEBUG
00364             std::cout << "SOLN " << solution_[0] << " " << solution_[1] << " " <<  solution_[2] << " " << solution_[3] <<  " " << solution_[4] << " " << solution_[5] <<  " " << solution_[6] << std::endl << std::endl;
00365 #endif
00366           }
00367         }
00368       }
00369     }
00370   }
00371 }
00372 
00373 
00374 void PR2ArmIK::computeIKShoulderRoll(const Eigen::Matrix4f &g_in, const double &t3, std::vector<std::vector<double> > &solution)
00375 {
00376   //  ROS_INFO(" ");
00377   // solution_ik_.clear();
00378   //  ROS_INFO("Solution IK size: %d",solution_ik_.size());
00379   //  for(unsigned int i=0; i < solution_ik_.size(); i++)
00380   //  {
00381   //    solution_ik_[i].clear();
00382   //  }
00383   //  if(!solution_ik_.empty())
00384   //    solution_ik_.resize(0);
00385 //t3 = shoulder/turret roll is specified
00386   Eigen::Matrix4f g = g_in;
00387 //First bring everything into the arm frame
00388   g(0,3) = g_in(0,3) - torso_shoulder_offset_x_;
00389   g(1,3) = g_in(1,3) - torso_shoulder_offset_y_;
00390   g(2,3) = g_in(2,3) - torso_shoulder_offset_z_;
00391 
00392   if(!checkJointLimits(t3,2))
00393   {
00394     return;
00395   }
00396   double x = g(0,3);
00397   double y = g(1,3);
00398   double z = g(2,3);
00399   double cost1, cost2, cost3, cost4;
00400   double sint1, sint2, sint3, sint4;
00401 
00402   gf_ = g*home_inv_;
00403 
00404   cost3 = cos(t3);
00405   sint3 = sin(t3);
00406 
00407   double t1(0), t2(0), t4(0), t5(0), t6(0), t7(0);
00408 
00409   double at(0), bt(0), ct(0);
00410 
00411   double theta1[2],theta2[2],theta4[4],theta5[2],theta6[4],theta7[2];
00412 
00413   double c0 = -sin(-t3)*elbow_wrist_offset_;
00414   double c1 = -cos(-t3)*elbow_wrist_offset_;
00415 
00416   double d0 = 4*shoulder_upperarm_offset_*shoulder_upperarm_offset_*(upperarm_elbow_offset_*upperarm_elbow_offset_+c1*c1-z*z);
00417   double d1 = 8*shoulder_upperarm_offset_*shoulder_upperarm_offset_*upperarm_elbow_offset_*elbow_wrist_offset_;
00418   double d2 = 4*shoulder_upperarm_offset_*shoulder_upperarm_offset_*(elbow_wrist_offset_*elbow_wrist_offset_-c1*c1);
00419 
00420   double b0 = x*x+y*y+z*z-shoulder_upperarm_offset_*shoulder_upperarm_offset_-upperarm_elbow_offset_*upperarm_elbow_offset_-c0*c0-c1*c1;
00421   double b1 = -2*upperarm_elbow_offset_*elbow_wrist_offset_;
00422 
00423   if(!solveQuadratic(b1*b1-d2,2*b0*b1-d1,b0*b0-d0,&theta4[0],&theta4[1]))
00424   {
00425 #ifdef DEBUG
00426     printf("No solution to quadratic eqn\n");
00427 #endif
00428     return;
00429   }
00430   theta4[0] = acos(theta4[0]);
00431   theta4[2] = acos(theta4[1]);
00432   theta4[1] = -theta4[0];
00433   theta4[3] = -theta4[2];
00434 
00435   for(int jj = 0; jj < 4; jj++)
00436   {
00437     t4 = theta4[jj];
00438 
00439     if(!checkJointLimits(t4,3))
00440     {
00441       continue;
00442     }
00443     cost4 = cos(t4);
00444     sint4 = sin(t4);
00445 #ifdef DEBUG
00446     std::cout << "t4 " << t4 << std::endl;
00447 #endif
00448     if(std::isnan(t4))
00449       continue;
00450     at = cos(t3)*sin(t4)*(shoulder_elbow_offset_-shoulder_wrist_offset_);
00451     bt = (shoulder_upperarm_offset_-shoulder_elbow_offset_+(shoulder_elbow_offset_-shoulder_wrist_offset_)*cos(t4));
00452     ct = z;
00453 
00454     if(!solveCosineEqn(at,bt,ct,theta2[0],theta2[1]))
00455       continue;
00456 
00457     for(int ii=0; ii < 2; ii++)
00458     {
00459       t2 = theta2[ii];
00460 #ifdef DEBUG
00461       std::cout << "t2 " << t2 << std::endl;
00462 #endif
00463       if(!checkJointLimits(t2,1))
00464       {
00465         continue;
00466       }
00467 
00468 
00469       sint2 = sin(t2);
00470       cost2 = cos(t2);
00471 
00472       at = -y;
00473       bt = x;
00474       ct = (shoulder_elbow_offset_-shoulder_wrist_offset_)*sin(t3)*sin(t4);
00475       if(!solveCosineEqn(at,bt,ct,theta1[0],theta1[1]))
00476       {
00477 #ifdef DEBUG
00478         std::cout << "could not solve cosine equation for t1" << std::endl;
00479 #endif
00480         continue;
00481       }
00482 
00483       for(int kk =0; kk < 2; kk++)
00484       {           
00485         t1 = theta1[kk];
00486 #ifdef DEBUG
00487         std::cout << "t1 " << t1 << std::endl;
00488 #endif
00489         if(!checkJointLimits(t1,0))
00490         {
00491           continue;
00492         }
00493         sint1 = sin(t1);
00494         cost1 = cos(t1);
00495         if(fabs((shoulder_upperarm_offset_-shoulder_elbow_offset_+(shoulder_elbow_offset_-shoulder_wrist_offset_)*cost4)*sint2+(shoulder_elbow_offset_-shoulder_wrist_offset_)*cost2*cost3*sint4-z) > IK_EPS )
00496         {
00497 #ifdef DEBUG
00498           printf("z value not matched %f\n",fabs((shoulder_upperarm_offset_-shoulder_elbow_offset_+(shoulder_elbow_offset_-shoulder_wrist_offset_)*cost4)*sint2+(shoulder_elbow_offset_-shoulder_wrist_offset_)*cost2*cost3*sint4-z));
00499 #endif
00500           continue;
00501         }
00502         if(fabs((shoulder_elbow_offset_-shoulder_wrist_offset_)*sint1*sint3*sint4+cost1*(shoulder_upperarm_offset_+cost2*(-shoulder_upperarm_offset_+shoulder_elbow_offset_+(-shoulder_elbow_offset_+shoulder_wrist_offset_)*cost4)+(shoulder_elbow_offset_-shoulder_wrist_offset_)*cost3*sint2*sint4) - x) > IK_EPS)
00503         {
00504 #ifdef DEBUG
00505           printf("x value not matched by %f\n",fabs((shoulder_elbow_offset_-shoulder_wrist_offset_)*sint1*sint3*sint4+cost1*(shoulder_upperarm_offset_+cost2*(-shoulder_upperarm_offset_+shoulder_elbow_offset_+(-shoulder_elbow_offset_+shoulder_wrist_offset_)*cost4)+(shoulder_elbow_offset_-shoulder_wrist_offset_)*cost3*sint2*sint4) - x));
00506 #endif
00507           continue;
00508         }
00509         if(fabs(-(shoulder_elbow_offset_-shoulder_wrist_offset_)*cost1*sint3*sint4+sint1*(shoulder_upperarm_offset_+cost2*(-shoulder_upperarm_offset_+shoulder_elbow_offset_+(-shoulder_elbow_offset_+shoulder_wrist_offset_)*cost4)+(shoulder_elbow_offset_-shoulder_wrist_offset_)*cost3*sint2*sint4) - y) > IK_EPS)
00510         {
00511 #ifdef DEBUG
00512           printf("y value not matched\n");
00513 #endif
00514           continue;
00515         }
00516         grhs_(0,0) = cost4*(gf_(0,0)*cost1*cost2+gf_(1,0)*cost2*sint1-gf_(2,0)*sint2)-(gf_(2,0)*cost2*cost3 + cost3*(gf_(0,0)*cost1 + gf_(1,0)*sint1)*sint2 + (-(gf_(1,0)*cost1) + gf_(0,0)*sint1)*sint3)*sint4;
00517 
00518         grhs_(0,1) = cost4*(gf_(0,1)*cost1*cost2 + gf_(1,1)*cost2*sint1 - gf_(2,1)*sint2) - (gf_(2,1)*cost2*cost3 + cost3*(gf_(0,1)*cost1 + gf_(1,1)*sint1)*sint2 + (-(gf_(1,1)*cost1) + gf_(0,1)*sint1)*sint3)*sint4;
00519 
00520         grhs_(0,2) = cost4*(gf_(0,2)*cost1*cost2 + gf_(1,2)*cost2*sint1 - gf_(2,2)*sint2) - (gf_(2,2)*cost2*cost3 + cost3*(gf_(0,2)*cost1 + gf_(1,2)*sint1)*sint2 + (-(gf_(1,2)*cost1) + gf_(0,2)*sint1)*sint3)*sint4;
00521 
00522         grhs_(1,0) = cost3*(gf_(1,0)*cost1 - gf_(0,0)*sint1) + gf_(2,0)*cost2*sint3 + (gf_(0,0)*cost1 + gf_(1,0)*sint1)*sint2*sint3;
00523 
00524         grhs_(1,1) = cost3*(gf_(1,1)*cost1 - gf_(0,1)*sint1) + gf_(2,1)*cost2*sint3 + (gf_(0,1)*cost1 + gf_(1,1)*sint1)*sint2*sint3;
00525 
00526         grhs_(1,2) = cost3*(gf_(1,2)*cost1 - gf_(0,2)*sint1) + gf_(2,2)*cost2*sint3 + (gf_(0,2)*cost1 + gf_(1,2)*sint1)*sint2*sint3;
00527 
00528         grhs_(2,0) = cost4*(gf_(2,0)*cost2*cost3 + cost3*(gf_(0,0)*cost1 + gf_(1,0)*sint1)*sint2 + (-(gf_(1,0)*cost1) + gf_(0,0)*sint1)*sint3) + (gf_(0,0)*cost1*cost2 + gf_(1,0)*cost2*sint1 - gf_(2,0)*sint2)*sint4;
00529 
00530         grhs_(2,1) = cost4*(gf_(2,1)*cost2*cost3 + cost3*(gf_(0,1)*cost1 + gf_(1,1)*sint1)*sint2 + (-(gf_(1,1)*cost1) + gf_(0,1)*sint1)*sint3) + (gf_(0,1)*cost1*cost2 + gf_(1,1)*cost2*sint1 - gf_(2,1)*sint2)*sint4;
00531 
00532         grhs_(2,2) = cost4*(gf_(2,2)*cost2*cost3 + cost3*(gf_(0,2)*cost1 + gf_(1,2)*sint1)*sint2 + (-(gf_(1,2)*cost1) + gf_(0,2)*sint1)*sint3) + (gf_(0,2)*cost1*cost2 + gf_(1,2)*cost2*sint1 - gf_(2,2)*sint2)*sint4;
00533 
00534 
00535 
00536 
00537 
00538 
00539 
00540 
00541 
00542         double val1 = sqrt(grhs_(0,1)*grhs_(0,1)+grhs_(0,2)*grhs_(0,2));
00543         double val2 = grhs_(0,0);
00544 
00545         theta6[0] = atan2(val1,val2);
00546         theta6[1] = atan2(-val1,val2);
00547 
00548         for(int mm = 0; mm < 2; mm++)
00549         {
00550           t6 = theta6[mm];
00551 #ifdef DEBUG
00552           std::cout << "t6 " << t6 << std::endl;
00553 #endif
00554           if(!checkJointLimits(t6,5))
00555           {
00556             continue;
00557           }
00558 
00559 
00560           if(fabs(cos(t6) - grhs_(0,0)) > IK_EPS)
00561             continue;
00562 
00563           if(fabs(sin(t6)) < IK_EPS)
00564           {
00565             //                std::cout << "Singularity" << std::endl;
00566             theta5[0] = acos(grhs_(1,1))/2.0;
00567             theta7[0] = theta5[0];
00568 //            theta7[1] = M_PI+theta7[0];
00569 //            theta5[1] = theta7[1];
00570           }
00571           else
00572           {
00573             theta7[0] = atan2(grhs_(0,1)/sin(t6),grhs_(0,2)/sin(t6));
00574             theta5[0] = atan2(grhs_(1,0)/sin(t6),-grhs_(2,0)/sin(t6));
00575 //            theta7[1] = M_PI+theta7[0];
00576 //            theta5[1] = M_PI+theta5[0];
00577           }
00578           for(int lll =0; lll < 1; lll++)
00579           {
00580             t5 = theta5[lll];
00581             t7 = theta7[lll];
00582 
00583             if(!checkJointLimits(t5,4))
00584             {
00585               continue;
00586             }
00587             if(!checkJointLimits(t7,6))
00588             {
00589               continue;
00590             }
00591 
00592 
00593 #ifdef DEBUG
00594             std::cout << "t5 " << t5 << std::endl;
00595             std::cout << "t7 " << t7 << std::endl;
00596 #endif      
00597             //           if(fabs(sin(t6)*sin(t7)-grhs_(0,1)) > IK_EPS || fabs(cos(t7)*sin(t6)-grhs_(0,2)) > IK_EPS)
00598             //  continue;
00599 
00600 #ifdef DEBUG
00601             std::cout << "theta1: " << t1 << std::endl;
00602             std::cout << "theta2: " << t2 << std::endl;
00603             std::cout << "theta3: " << t3 << std::endl;
00604             std::cout << "theta4: " << t4 << std::endl;
00605             std::cout << "theta5: " << t5 << std::endl;
00606             std::cout << "theta6: " << t6 << std::endl;
00607             std::cout << "theta7: " << t7 << std::endl << std::endl << std::endl;
00608 #endif
00609 
00610 
00611             solution_[0] = normalize_angle(t1*angle_multipliers_[0]);
00612             solution_[1] = normalize_angle(t2*angle_multipliers_[1]);
00613             solution_[2] = t3*angle_multipliers_[2];
00614             solution_[3] = normalize_angle(t4*angle_multipliers_[3]);
00615             solution_[4] = normalize_angle(t5*angle_multipliers_[4]);
00616             solution_[5] = normalize_angle(t6*angle_multipliers_[5]);
00617             solution_[6] = normalize_angle(t7*angle_multipliers_[6]);
00618             solution.push_back(solution_);
00619 #ifdef DEBUG
00620             std::cout << "SOLN " << solution_[0] << " " << solution_[1] << " " <<  solution_[2] << " " << solution_[3] <<  " " << solution_[4] << " " << solution_[5] <<  " " << solution_[6] << std::endl << std::endl;
00621 #endif
00622           }
00623         }
00624       }
00625     }
00626   }
00627 }
00628 
00629 
00630 bool PR2ArmIK::checkJointLimits(const std::vector<double> &joint_values)
00631 {
00632   for(int i=0; i<NUM_JOINTS_ARM7DOF; i++)
00633   {
00634     if(!checkJointLimits(angles::normalize_angle(joint_values[i]*angle_multipliers_[i]),i))
00635     {
00636       return false;
00637     }
00638   }
00639   return true;
00640 }
00641 
00642 bool  PR2ArmIK::checkJointLimits(const double &joint_value, const int &joint_num)
00643 {
00644   double jv;
00645   if(continuous_joint_[joint_num])
00646     jv= angles::normalize_angle(joint_value*angle_multipliers_[joint_num]);
00647   else if (joint_num ==2)
00648     jv = joint_value*angle_multipliers_[joint_num];
00649   else
00650     jv= angles::normalize_angle(joint_value*angle_multipliers_[joint_num]);
00651 
00652   if(jv < min_angles_[joint_num] || jv > max_angles_[joint_num])
00653   {
00654     // ROS_INFO("Angle %d = %f out of range: (%f,%f)\n",joint_num,joint_value,min_angles_[joint_num],max_angles_[joint_num]);
00655     return false;
00656   }
00657   return true;
00658 }


pr2_arm_kinematics
Author(s): Sachin Chitta
autogenerated on Tue Apr 22 2014 19:33:02