00001 
00002 
00003 #include "kuka_ikac.h"
00004 using namespace Eigen;
00005 using namespace std;
00006 
00007 KukaIKAC::KukaIKAC() {
00008   
00009   
00010 
00011   this->currentjoints_.resize(7);
00012 
00013   
00014   std::string port_name;
00015 
00016   
00017   port_name = ros::names::append(ros::this_node::getName(), "ikjoints"); 
00018   this->ik_joints_publisher_ = this->nh_.advertise<sensor_msgs::JointState>(port_name, 5);
00019   this->ik_joints_msg.position.resize(7);
00020   
00021   
00022   port_name = ros::names::append(ros::this_node::getName(), "joint_states"); 
00023   this->joint_states_subscriber = this->nh_.subscribe(port_name, 5, &KukaIKAC::joint_states_callback, this);
00024   
00025   
00026   port_name = ros::names::append(ros::this_node::getName(), "wamik"); 
00027   this->kukaik_server = this->nh_.advertiseService(port_name, &KukaIKAC::kukaikCallback, this);
00028   
00029   port_name = ros::names::append(ros::this_node::getName(), "wamik_from_pose");
00030   this->kukaik_server_fromPose = this->nh_.advertiseService(port_name, &KukaIKAC::kukaikCallbackFromPose, this);
00031 
00032   
00033   port_name = ros::names::append(ros::this_node::getName(), "joints_move"); 
00034   joint_move_client = this->nh_.serviceClient<iri_wam_common_msgs::joints_move>(port_name);
00035   
00036   
00037   
00038   
00039  
00040   
00041 
00042 
00043 
00044 
00045   double PI=3.14159265;
00046   
00047   d1=0.3100;
00048   d3=0.4000;
00049   d5=0.3900;
00050   d7=0.0785; 
00051   
00052   
00053   checksol_=1;
00054   
00055   
00056   DHparam_.resize(7,3);  
00057   DHparam_ << 0.0,  PI/2.0, d1,
00058                     0.0, -PI/2.0, 0.0,
00059                     0.0, -PI/2.0, d3,
00060                     0.0,  PI/2.0, 0.0,
00061                     0.0,  PI/2.0, d5,
00062                     0.0, -PI/2.0, 0.0,
00063                     0.0, 0.0, d7; 
00064             
00065   
00066   Qlim_.resize(7,2);
00067   Qlim_ << -2.97, 2.97,
00068           -0.47, 3.49,
00069           -2.97, 2.97,
00070           -2.09, 2.09,
00071           -2.97, 2.97,
00072           -2.09, 2.09,
00073           -2.97, 2.97;
00074           
00075   
00076   step_ = 0.0005;
00077   
00078   
00079   
00080   IMAX_ = 100;
00081   
00082 }
00083 
00084 void KukaIKAC::ikPub(void)
00085 {
00086   for (int i=0;i<7;i++){
00087     this->ik_joints_msg.position[i]=joints_(i);
00088   }
00089     this->ik_joints_publisher_.publish(this->ik_joints_msg);
00090 }
00091 
00092 
00093 void KukaIKAC::joint_states_callback(const sensor_msgs::JointState::ConstPtr& msg) { 
00094 
00095   for(int i=0;i<7;i++)
00096     currentjoints_[i] = msg->position[i]; 
00097 
00098 }
00099 
00100 
00101 bool KukaIKAC::kukaikCallbackFromPose(iri_wam_common_msgs::wamInverseKinematicsFromPose::Request &req, iri_wam_common_msgs::wamInverseKinematicsFromPose::Response &res){
00102 
00103   ROS_INFO("[KukaIKAC] User Given Current Joints %s (j1, j2, j3, j4, j5, j6, j7): [ %f, %f, %f, %f, %f, %f, %f ]",
00104             req.current_joints.header.frame_id.c_str(), 
00105             req.current_joints.position[0], 
00106             req.current_joints.position[1],
00107             req.current_joints.position[2],
00108             req.current_joints.position[3],
00109             req.current_joints.position[4],
00110             req.current_joints.position[5],
00111             req.current_joints.position[6]);
00112   
00113   ROS_INFO("[KukaIKAC] Received Pose from frame_id %s (x, y, z, qx, qy, qz, qw): [ %f, %f, %f, %f, %f, %f, %f ]",
00114             req.desired_pose.header.frame_id.c_str(), 
00115             req.desired_pose.pose.position.x, 
00116             req.desired_pose.pose.position.y,
00117             req.desired_pose.pose.position.z,
00118             req.desired_pose.pose.orientation.x,
00119             req.desired_pose.pose.orientation.y,
00120             req.desired_pose.pose.orientation.z,
00121             req.desired_pose.pose.orientation.w);
00122   
00123   
00124   std::vector<double> currentjoints;
00125   for(int ii=0; ii<7; ii++)
00126     currentjoints[ii] = req.current_joints.position[ii]; 
00127 
00128   Quaternion<float> quat( req.desired_pose.pose.orientation.w, req.desired_pose.pose.orientation.x, req.desired_pose.pose.orientation.y, req.desired_pose.pose.orientation.z);
00129   Matrix3f mat = quat.toRotationMatrix();
00130 
00131   std::vector <double> desired_pose(16,0);
00132   std::vector <double> desired_joints(7,0);
00133 
00134   
00135   desired_pose[3] = req.desired_pose.pose.position.x;
00136   desired_pose[7] = req.desired_pose.pose.position.y;
00137   desired_pose[11] = req.desired_pose.pose.position.z;
00138   desired_pose[15] = 1;
00139   for(int i=0; i<12; i++){
00140    if(i%4 != 3){
00141      desired_pose[i] = mat(i/4,i%4);
00142    }
00143   }
00144   ROS_INFO("[KukaIKAC] Received HRt:\n [ \t%f %f %f %f\n\t %f %f %f %f\n\t %f %f %f %f\n\t %f %f %f %f\n",
00145             desired_pose[0], desired_pose[1], desired_pose[2], desired_pose[3],
00146             desired_pose[4], desired_pose[5], desired_pose[6], desired_pose[7],
00147             desired_pose[8], desired_pose[9], desired_pose[10], desired_pose[11],
00148             desired_pose[12], desired_pose[13], desired_pose[14], desired_pose[15]);
00149 
00150   if(!KukaIKAC::ik(desired_pose, currentjoints, desired_joints)){
00151       ROS_ERROR("[KukaIKAC] IK solution not found. Is pose out of configuration space?");
00152       return false;
00153   }else{
00154 
00155       ROS_INFO("[KukaIKAC] Service computed joints:\n %f %f %f %f %f %f %f\n", desired_joints.at(0), desired_joints.at(1), desired_joints.at(2), desired_joints.at(3), desired_joints.at(4), desired_joints.at(5), desired_joints.at(6));
00156     
00157       res.desired_joints.position.resize(7);
00158       joints_.resize(7);
00159       for(int i=0; i<7; i++){
00160         res.desired_joints.position[i] = desired_joints.at(i);
00161         joints_(i) = desired_joints.at(i);
00162       }
00163   }
00164   return true;
00165 }
00166 
00167 bool KukaIKAC::kukaikCallback(iri_wam_common_msgs::wamInverseKinematics::Request &req, iri_wam_common_msgs::wamInverseKinematics::Response &res){
00168 
00169   ROS_INFO("[KukaIKAC] Received Pose from frame_id %s (x, y, z, qx, qy, qz, qw): [ %f, %f, %f, %f, %f, %f, %f ]",
00170             req.pose.header.frame_id.c_str(), 
00171             req.pose.pose.position.x, 
00172             req.pose.pose.position.y,
00173             req.pose.pose.position.z,
00174             req.pose.pose.orientation.x,
00175             req.pose.pose.orientation.y,
00176             req.pose.pose.orientation.z,
00177             req.pose.pose.orientation.w);
00178   
00179   Quaternion<float> quat( req.pose.pose.orientation.w, req.pose.pose.orientation.x, req.pose.pose.orientation.y, req.pose.pose.orientation.z);
00180   Matrix3f mat = quat.toRotationMatrix();
00181 
00182   std::vector <double> pose(16,0);
00183   std::vector <double> joints(7,0);
00184 
00185   pose[3] = req.pose.pose.position.x;
00186   pose[7] = req.pose.pose.position.y;
00187   pose[11] = req.pose.pose.position.z;
00188   pose[15] = 1;
00189   for(int i=0; i<12; i++){
00190    if(i%4 != 3){
00191      pose[i] = mat(i/4,i%4);
00192    }
00193   }
00194   ROS_INFO("[KukaIKAC] Received HRt:\n [ \t%f %f %f %f\n\t %f %f %f %f\n\t %f %f %f %f\n\t %f %f %f %f\n",
00195             pose[0],pose[1],pose[2],pose[3],
00196             pose[4],pose[5],pose[6],pose[7],
00197             pose[8],pose[9],pose[10],pose[11],
00198             pose[12],pose[13],pose[14],pose[15]);
00199 
00200   if(!KukaIKAC::ik(pose, currentjoints_, joints)){
00201       ROS_ERROR("[KukaIKAC] IK solution not found. Is pose out of configuration space?");
00202       return false;
00203   }else{
00204 
00205       ROS_INFO("[KukaIKAC] Service computed joints:\n %f %f %f %f %f %f %f\n", joints.at(0), joints.at(1), joints.at(2), joints.at(3), joints.at(4), joints.at(5), joints.at(6));
00206     
00207       res.joints.position.resize(7);
00208       joints_.resize(7);
00209       for(int i=0;i<7;i++){
00210         res.joints.position[i] = joints.at(i);
00211         joints_(i)=joints.at(i);
00212       }
00213       res.joints.position[1] = joints.at(1)+1.57079;
00214       joints_(1) = joints.at(1)+1.57079;
00215   }
00216   return true;
00217 }
00218 
00219 
00220 
00221 
00222 
00223 
00224 bool KukaIKAC::ik(vector<double> pose, vector<double> currentjoints, vector<double>& joints){
00225     
00226     
00227     
00228 
00229 
00230   MatrixXd T0(4,4);
00231   VectorXd cjoints(7), nextangles(7), qoptim(7);
00232   for(int i=0;i<16;i++)
00233      T0(i/4,i%4) = pose.at(i); 
00234 
00235   for(int i=0;i<7;i++)
00236      cjoints(i) = currentjoints.at(i);
00237 
00238         joints.resize(7);
00239         MatrixXd A(4,4);
00240         
00241         double i=0;
00242         bool initfound=false;
00243         bool breakloop=false;
00244         
00245         MatrixXd qsol(8,7);
00246         VectorXd sol(8);        
00247         qsol.fill(0.0);
00248         sol.fill(0.0);
00249         double q10=cjoints(0);
00250         MatrixXd qaux;
00251         Vector3f Xw;
00252         
00253         double potq=100000.;
00254         
00255         printf("Solution found is that which minimizes a weighted norm of the joints variation, to insert another criterion, modify the function KukaIKAC::potentialfunction \n");
00256         printf("Variation on q0 at each step for obtaining first solution : %e", step_);
00257         printf(" \n Initial joints:\n %f %f %f %f %f %f %f\n", currentjoints.at(0), currentjoints.at(1), currentjoints.at(2), currentjoints.at(3), currentjoints.at(4), currentjoints.at(5), currentjoints.at(6));
00258 
00259         
00260         
00261         while (!initfound & !breakloop){
00262                 
00263     KukaIKAC::getq1(cjoints,i,q10);
00264                 
00265                 if (q10<Qlim_(0,1) && q10>Qlim_(0,0)){
00266                 
00267 
00268                       KukaIKAC::exactikine(T0,q10,cjoints,qsol,sol);
00269                       
00270                       KukaIKAC::filtersols(qsol,sol);
00271                       if (sol.sum()!=0.){ 
00272 
00273                               KukaIKAC::basicsols(qsol,qaux,sol);
00274                               initfound=true;
00275                       }
00276                 }else{
00277                   if (i*step_+cjoints(0)>Qlim_(0,1) && -i*step_+cjoints(0)<Qlim_(0,0)){
00278                     breakloop=true; 
00279                     printf("LOOP BREAK,q1 steps OUT OF RANGE \n");
00280                   }
00281                 }       
00282                 i=i+1.;
00283         }
00284 
00285 
00286 
00287         if (initfound){
00288 
00289                 
00290                 KukaIKAC::optimizesol(qaux,T0,qoptim,potq,cjoints);     
00291                   joints.clear();
00292                   joints.resize(7);
00293                   for(int i=0;i<7;i++)
00294                      joints[i] = qoptim(i);
00295                   
00296                   std::cout<<"\n best solution is: \n"<<qoptim.transpose();
00297 
00298 
00299                 if (checksol_==1){
00300                   MatrixXd T01,T12,T23,T34,T45,T56,T67,T07;
00301                   KukaIKAC::DHmatrix(DHparam_(0,1),DHparam_(0,0),DHparam_(0,2),qoptim(0),T01),
00302                   KukaIKAC::DHmatrix(DHparam_(1,1),DHparam_(1,0),DHparam_(1,2),qoptim(1),T12),
00303                   KukaIKAC::DHmatrix(DHparam_(2,1),DHparam_(2,0),DHparam_(2,2),qoptim(2),T23),
00304                   KukaIKAC::DHmatrix(DHparam_(3,1),DHparam_(3,0),DHparam_(3,2),qoptim(3),T34);
00305                   KukaIKAC::DHmatrix(DHparam_(4,1),DHparam_(4,0),DHparam_(4,2),qoptim(4),T45);
00306                   KukaIKAC::DHmatrix(DHparam_(5,1),DHparam_(5,0),DHparam_(5,2),qoptim(5),T56);
00307                   KukaIKAC::DHmatrix(DHparam_(6,1),DHparam_(6,0),DHparam_(6,2),qoptim(6),T67);
00308                   T07=T01*T12*T23*T34*T45*T56*T67;
00309                   std::cout<<"\n Result matrix error T0-Tout= \n"<<T0-T07<<std::endl;
00310                 }
00311 
00312 
00313                 return true;
00314         } else{
00315                   for(int i=0;i<7;i++)
00316                      joints[i] = cjoints(i);
00317                 printf("SOLUTION NOT FOUND, robot not moving \n ");
00318                 return false;
00319         }    
00320 
00321 
00322 }
00323 
00324 
00325 
00326 
00327 
00328 void KukaIKAC::filtersols(MatrixXd qsol,VectorXd& sol){
00329 
00330 
00331         sol.resize(qsol.rows());
00332         sol.fill(1.0);
00333         for (int i=0;i<qsol.rows();i++){
00334                 for (int j=0;j<7;j++){
00335                         if ((qsol(i,j)<Qlim_(j,0))|(qsol(i,j)>Qlim_(j,1))){
00336                                 sol(i)=0.0;
00337                         }       
00338                 }
00339         }
00340 }
00341 
00342 void KukaIKAC::DHmatrix(double alpha, double a, double d,double& theta, MatrixXd& T){
00343 
00344 
00345 T.resize(4,4);
00346 T.fill(0.0);
00347 T(0,0)= cos(theta); 
00348 T(0,1)=-sin(theta)*cos(alpha);
00349 T(0,2)=sin(theta)*sin(alpha);
00350 T(0,3)=a*cos(theta);
00351 T(1,0)=sin(theta);
00352 T(1,1)=cos(theta)*cos(alpha); 
00353 T(1,2)=-cos(theta)*sin(alpha); 
00354 T(1,3)=a*sin(theta); 
00355 T(2,1)=sin(alpha); 
00356 T(2,2)=cos(alpha);
00357 T(2,3)=d; 
00358 T(3,3)=1;
00359 
00360 }
00361 
00362 
00363 
00364 void KukaIKAC::exactikine(MatrixXd T0, double q10, VectorXd cjoints, MatrixXd& qsol,VectorXd&sol){
00365 
00366 
00367 
00368 
00369 
00370 
00371 
00372         double q30=cjoints(2);
00373         double c4,aux1,aux2,aux3,signq4;
00374         double PI=3.14159265;
00375         qsol.resize(8,7);
00376         MatrixXd q4sol4(2,2);
00377         MatrixXd q2sol2(2,2);
00378         MatrixXd Pw(4,1),Pwaux(3,1);
00379         MatrixXd T12,T23,T34,T01,T04;
00380         VectorXd q3(2);
00381         Vector2d q5;
00382         Vector2d q6;
00383         Vector2d q7;
00384 
00385         MatrixXd qout(8,7);
00386         qout.fill(0.0);
00387         int k;
00388 
00389         
00390         Pw=T0.block<4,1>(0,3)-d7*T0.block<4,1>(0,2);
00391         Pwaux=Pw.block<3,1>(0,0);
00392         Pwaux(2,0)=Pw(2,0)-d1;
00393         
00394         
00395         c4=(Pwaux.squaredNorm()-pow(d3,2.0)-pow(d5,2.0))/(2*d3*d5);
00396         if (abs(c4)<=1.0){
00397           q4sol4(0,1)=1.0;
00398           q4sol4(1,1)=1.0;
00399           q4sol4(0,0)=acos(c4);
00400           q4sol4(1,0)=-acos(c4);
00401         }else{
00402           q4sol4.fill(0.0);
00403           q4sol4(0,0)=-99.9999;
00404           q4sol4(1,0)=-99.9999;
00405         }
00406         
00407         KukaIKAC::DHmatrix(DHparam_(0,1),DHparam_(0,0),DHparam_(0,2),q10,T01);
00408                 for (int i4=0;i4<2;i4++){ 
00409 
00410 
00411                         aux1=c4*d5+d3;
00412                         aux2=-cos(q10)*Pw(0,0)-sin(q10)*Pw(1,0);
00413                         aux3=Pw(2,0)-d1;        
00414                         KukaIKAC::soltrig(aux1, aux2, aux3, q2sol2);
00415                         KukaIKAC::DHmatrix(DHparam_(3,1),DHparam_(3,0),DHparam_(3,2),q4sol4(i4,0),T34);
00416                         signq4=q4sol4(i4,0)/abs(q4sol4(i4,0));
00417                                 for(int i2=0;i2<2;i2++){
00418                                         if (abs(cos(q4sol4(i4,0))-1.0)>0.000001){
00419                                           q3(i2)=pi2pi(0.5*PI*(-signq4+1.0)+atan2(-sin(q10)*Pw(0,0)+cos(q10)*Pw(1,0),sin(q10)*cos(q2sol2(i2,0))*Pw(1,0)+cos(q10)*cos(q2sol2(i2,0))*Pw(0,0)+sin(q2sol2(i2,0))*(Pw(2,0)-d1)));
00420                                         }else{ 
00421                                           q3(i2)=q30;             
00422                                         }
00423                                         KukaIKAC::DHmatrix(DHparam_(1,1),DHparam_(1,0),DHparam_(1,2),q2sol2(i2,0),T12);
00424                                         KukaIKAC::DHmatrix(DHparam_(2,1),DHparam_(2,0),DHparam_(2,2),q3(i2),T23);
00425                                         T04=T01*T12*T23*T34;
00426                                         KukaIKAC::sphericalikine(T0,T04,cjoints,q5,q6,q7);
00427                                         
00428                                         for (int i5=0;i5<2;i5++){
00429                                                 k=i4*4+i2*2+i5;
00430                                                 qsol(k,0)=q10;
00431                                                 qsol(k,1)=q2sol2(i2,0);
00432                                                 qsol(k,2)=q3(i2);
00433                                                 qsol(k,3)=q4sol4(i4,0);
00434                                                 qsol(k,4)=q5(i5);
00435                                                 qsol(k,5)=q6(i5);
00436                                                 qsol(k,6)=q7(i5);
00437                                                 sol(k)=q4sol4(i4,1)*q2sol2(i2,1);
00438                                         }
00439                                 }
00440                 }
00441 }
00442 
00443 
00444 
00445 void KukaIKAC::basicsols(MatrixXd qsol,MatrixXd& qaux,VectorXd sol){
00446 
00447 
00448            
00449 
00450 
00451 
00452 
00453         MatrixXd qauxiliar2;
00454         qauxiliar2.resize(4,7);
00455         qauxiliar2.fill(-99.9999);
00456         int nbasics=0;
00457         for (int i=0;i<qsol.rows()/2;i++){
00458                 if (sol(2*i)>0.0){
00459                         qauxiliar2.row(nbasics)=qsol.row(2*i);
00460                         nbasics=nbasics+1;
00461 
00462                 }else if (sol(2*i+1)>0.0){
00463                         qauxiliar2.row(nbasics)=qsol.row(2*i+1);
00464                         nbasics=nbasics+1;
00465                 }
00466         }
00467         qaux.resize(nbasics,7);
00468 
00469         for (int j=0;j<nbasics;j++){
00470                 qaux.row(j)=qauxiliar2.row(j);
00471         }
00472 }
00473 
00474 
00475 
00476 
00477 
00478 void KukaIKAC::optimizesol(MatrixXd q, MatrixXd T0, VectorXd& qoutput,double& potact,VectorXd qref){
00479 
00480 
00481 
00482 
00483         
00484         VectorXd PJa,qelbows;
00485         MatrixXd PJ(3,q.rows()); 
00486 
00487         printf("Rotations for each solution: %d",IMAX_);
00488 
00489         for (int ia=0;ia<q.rows();ia++){
00490                 qelbows=q.row(ia);
00491                 KukaIKAC::initialelbows(qelbows,T0,PJa); 
00492                 PJ.col(ia)=PJa;
00493         }
00494         
00495         double L=d7;
00496         MatrixXd T04;
00497         Matrix3d Mrot,Rn,I3;
00498         double phi,qn4,qn3,qn2,qn1,eps1,eps3,potq;
00499         Vector2d qn5,qn6,qn7;
00500         double PI=3.14159265;
00501         Vector3d v,CJ;
00502         VectorXd qn4b,sol,qbest;
00503         MatrixXd Pw,Pw2,Paux,T01,T12,T23,T34,Qaux;
00504         MatrixXd Qglobal(4*q.rows(),7); 
00505         qoutput=q.row(0);
00506         VectorXd offshoulder(3,1);
00507         offshoulder << 0.0,0.0,d1;
00508         Pw=T0.block<3,1>(0,3)-L*T0.block<3,1>(0,2);
00509         Pw2=T0.block<3,1>(0,3)-L*T0.block<3,1>(0,2)-offshoulder;
00510         double aux0=Pw2.norm();
00511         v=Pw2/aux0;     
00512         
00513         KukaIKAC::skewop(Mrot,v);
00514         I3.setIdentity();
00515         double signq4;
00516         
00517         for (int i=0;i<IMAX_;i++){
00518                 phi=2*PI*double(i)/double(IMAX_)*pow(-1,double(i));
00519                 Rn=I3+sin(phi)*Mrot+(1-cos(phi))*Mrot*Mrot;
00520 
00521                 Qglobal.fill(-9.9);
00522                 for (int nconfig=0;nconfig<q.rows();nconfig++){
00523                         qn4=q(nconfig,3);
00524                         Paux=PJ.block<3,1>(0,nconfig);
00525                         Paux(2)=Paux(2)-d1;
00526                         CJ=Rn*Paux;
00527                         CJ(2)=CJ(2)+d1;
00528                         Qaux.resize(4,7);
00529                         Qaux.fill(-9.9);
00530 
00531                                 
00532                                 qn2=atan2(CJ(2)-d1,sqrt(pow(CJ(0),2.0)+pow(CJ(1),2.0)))-PI/2;
00533                                 
00534                                 qn1=atan2(CJ(1),CJ(0));
00535                                 
00536                                 signq4=qn4/abs(qn4);
00537                                 qn3=pi2pi(0.5*PI*(-signq4+1.0)+atan2(-sin(qn1)*Pw(0,0)+cos(qn1)*Pw(1,0),sin(qn1)*cos(qn2)*Pw(1,0)+cos(qn1)*cos(qn2)*Pw(0,0)+sin(qn2)*(Pw(2,0)-d1)));
00538                                 KukaIKAC::DHmatrix(DHparam_(0,1),DHparam_(0,0),DHparam_(0,2),qn1,T01);
00539                                 KukaIKAC::DHmatrix(DHparam_(1,1),DHparam_(1,0),DHparam_(1,2),qn2,T12);
00540                                 KukaIKAC::DHmatrix(DHparam_(2,1),DHparam_(2,0),DHparam_(2,2),qn3,T23);
00541                                 KukaIKAC::DHmatrix(DHparam_(3,1),DHparam_(3,0),DHparam_(3,2),qn4,T34);
00542                                 T04=T01*T12*T23*T34;
00543                                 
00544                                 KukaIKAC::sphericalikine(T0,T04,qref,qn5,qn6,qn7);
00545                                 eps1 = copysign(1.0, qn1);
00546                                 eps3 = copysign(1.0, qn3);                      
00547                                 Qaux<<qn1,qn2,qn3,qn4,qn5(0),qn6(0),qn7(0), 
00548                                         qn1,qn2,qn3,qn4,qn5(1),qn6(1),qn7(1),
00549                                         qn1-eps1*PI,-qn2,qn3-eps3*PI,qn4,qn5(0),qn6(0),qn7(0),
00550                                         qn1-eps1*PI,-qn2,qn3-eps3*PI,qn4,qn5(1),qn6(1),qn7(1);
00551 
00552 
00553                         Qglobal.row(4*nconfig)=Qaux.row(0);
00554                         Qglobal.row(4*nconfig+1)=Qaux.row(1);
00555                         Qglobal.row(4*nconfig+2)=Qaux.row(2);
00556                         Qglobal.row(4*nconfig+3)=Qaux.row(3);
00557                 }
00558                 
00559                 KukaIKAC::filtersols(Qglobal,sol);
00560                 
00561                 KukaIKAC::bestsol(Qglobal,sol,qref,qbest,potq);
00562 
00563                 
00564                 if (potq<potact){
00565                         qoutput=qbest;
00566                         potact=potq;
00567 
00568                 }
00569         }
00570 }
00571 
00572 
00573 
00574 
00575 void KukaIKAC::skewop(Matrix3d& M,Vector3d v){ 
00576 M.fill(0.0);
00577 M(0,1)=-v(2);
00578 M(1,0)=v(2);
00579 M(0,2)=v(1);
00580 M(2,0)=-v(1);
00581 M(1,2)=-v(0);
00582 M(2,1)=v(0);
00583 }
00584 
00585 void KukaIKAC::getq1(VectorXd cjoints,float i,double& q10){
00586 q10=cjoints(0)+i*step_*pow(-1,i);       
00587 }
00588 
00589 double KukaIKAC::pi2pi(double x){ 
00590   double PI=3.14159265; 
00591  while (x>PI || x<-PI){
00592     if (x>PI){
00593       x=x-2*PI;
00594     }
00595     if (x<-PI){
00596       x=x+2*PI;
00597     } 
00598   }
00599 return x;
00600 }
00601 
00602 
00603 
00604 void KukaIKAC::bestsol(MatrixXd qsol,VectorXd sol,VectorXd qref,VectorXd& q,double& potbest){
00605   
00606         potbest=100000; 
00607         double potq;
00608         VectorXd qact;
00609         for(int i=1;i<qsol.rows();i++){
00610                 if (sol(i)!=0.0){
00611                         qact=qsol.block<1,7>(i,0);
00612                         KukaIKAC::potentialfunction(qref,qact,potq);
00613                         if (potq<potbest){
00614                                 q=qact;
00615                                 potbest=potq;
00616                         }
00617                 }
00618         }
00619 }
00620 
00621 
00622 
00623 
00624 void KukaIKAC::potentialfunction(VectorXd qref,VectorXd& q, double& potq){
00625   
00626 
00627 
00628 
00629 
00630 
00631 
00632 
00633 
00634 
00635         MatrixXd W(7,7);
00636         W.fill(0.0);
00637         W(0,0)=2.5;
00638         W(1,1)=2.0;
00639         W(2,2)=2.0;
00640         W(3,3)=1.5;
00641         W(4,4)=1.0;
00642         W(5,5)=1.0;
00643         W(6,6)=1.0;
00644 
00645         VectorXd qdif(7);
00646         
00647         qdif=q-qref;
00648         potq=qdif.transpose()*W*qdif;
00649 
00650 }
00651 
00652 
00653 
00654 
00655 
00656 void KukaIKAC::sphericalikine(MatrixXd T0,MatrixXd T4, VectorXd cjoints, Vector2d& q5,Vector2d& q6,Vector2d& q7){
00657         
00658   
00659   MatrixXd Taux;
00660         Taux=T4.inverse()*T0;
00661         
00662         double c6,s6,q57;
00663         c6=Taux(2,2);
00664         double  pi=3.14159265;
00665         if (abs(c6)<0.99999){
00666          q7(0)=atan2(-Taux(2,1),Taux(2,0));
00667          q5(0)=atan2(-Taux(1,2),-Taux(0,2));
00668          s6=Taux(0,3)/(-cos(q5(0))*d7);
00669          q6(0)=atan2(s6,c6);
00670          q5(1)=pi2pi(q5(0)+pi);
00671          q6(1)=-q6(0);  
00672          q7(1)=pi2pi(q7(0)+pi);
00673         }else if(abs(c6<1.0) && abs(c6)>0.99999){
00674          
00675          q57=atan2(Taux(1,0),Taux(0,0));
00676          q5(0)=cjoints(4);
00677          q7(0)=q57-q5(0);       
00678          q6(0)=0.0;
00679          q5(1)=pi2pi(q5(0)+pi);
00680          q6(1)=0.0;     
00681          q7(1)=pi2pi(q7(0)+pi);
00682         }else{
00683          q5(0)=-99.9999;
00684          q5(1)=-99.9999;
00685          q6(0)=-99.9999;
00686          q6(1)=-99.9999;
00687          q7(0)=-99.9999;
00688          q7(1)=-99.9999;
00689          std::cout<<"\n no solution spherical---------------------\n";
00690         }
00691 
00692 }
00693 
00694 
00695 
00696 void KukaIKAC::initialelbows(VectorXd q,MatrixXd T0,VectorXd& PJ){
00697         MatrixXd T01,T12,T23,T02,T03;
00698         KukaIKAC::DHmatrix(DHparam_(0,1),DHparam_(0,0),DHparam_(0,2),q(0),T01);
00699         KukaIKAC::DHmatrix(DHparam_(1,1),DHparam_(1,0),DHparam_(1,2),q(1),T12);
00700         KukaIKAC::DHmatrix(DHparam_(2,1),DHparam_(2,0),DHparam_(2,2),q(2),T23);
00701         T02=T01*T12;
00702         T03=T02*T23;
00703         VectorXd aux(4),PLaux(4);
00704         aux(0)=0.0;
00705         aux(1)=0.0;
00706         aux(2)=d3;
00707         aux(3)=1.0;
00708         PLaux=T02*aux;
00709         PJ=PLaux.block<3,1>(0,0);
00710 
00711 }
00712 
00713 
00714 
00715 void KukaIKAC::soltrig(double a, double b, double c, MatrixXd& q2sol2){
00716 
00717 
00718         if (abs(b)<0.00000001 && abs(a/c)<1.0){
00719                 q2sol2(0,1)=1.;
00720                 q2sol2(1,1)=1.;
00721                 q2sol2(0,0)=acos(a/c);
00722                 q2sol2(1,0)=-acos(a/c);
00723     
00724 
00725         }else if (pow(c,2.)*pow(b,2)-pow(b,2.)*pow(a,2.)+pow(b,4.)<=0.00000001){
00726           
00727                 q2sol2(0,1)=0.;
00728                 q2sol2(1,1)=0.;
00729                 q2sol2(0,0)=-99.9999;
00730                 q2sol2(1,0)=-99.9999;
00731 
00732                 
00733         }else{
00734         
00735                 q2sol2(0,1)=1.;
00736                 q2sol2(1,1)=1.;
00737                 q2sol2(0,0)=atan2(-(-a+c*(a*c+sqrt(pow(c,2.)*pow(b,2.)-pow(b,2.)*pow(a,2.)+pow(b,4.)))/(pow(c,2.)+pow(b,2.)))/b,(a*c+sqrt(pow(c,2.)*pow(b,2.)-pow(b,2.)*pow(a,2.)+pow(b,4.)))/(pow(c,2.)+pow(b,2.)));
00738                 q2sol2(1,0)=atan2(-(-a-c*(-a*c+sqrt(pow(c,2.)*pow(b,2.)-pow(b,2.)*pow(a,2.)+pow(b,4.)))/(pow(c,2.)+pow(b,2.)))/b,-(-a*c+sqrt(pow(c,2.)*pow(b,2.)-pow(b,2.)*pow(a,2.)+pow(b,4.)))/(pow(c,2.)+pow(b,2.)));
00739         }
00740 }
00741 
00742 
00743 int main(int argc, char** argv) {
00744     ros::init(argc, argv, "wam_ik");
00745     KukaIKAC kuka_ikac;
00746     ros::Rate loop_rate(10);
00747     while(ros::ok()){
00748       ros::spinOnce();
00749       loop_rate.sleep(); 
00750     }
00751 
00752 }