wam_ikac.cpp
Go to the documentation of this file.
00001 
00002 
00003 // BETA VERSION, STILL BEING TESTED, BUT APPARENTLY ROBUST AND EFFICIENT.
00004 
00005 
00006 #include "wam_ikac.h"
00007 using namespace Eigen;
00008 using namespace std;
00009 
00010 WamIKAC::WamIKAC() {
00011   //init class attributes if necessary
00012   //this->loop_rate = 2;//in [Hz]
00013 
00014   this->currentjoints_.resize(7);
00015 
00016   //string for port names
00017   std::string port_name;
00018 
00019   // [init publishers]
00020   port_name = ros::names::append(ros::this_node::getName(), "ikjoints"); 
00021   this->ik_joints_publisher_ = this->nh_.advertise<sensor_msgs::JointState>(port_name, 5);
00022   this->ik_joints_msg.position.resize(7);
00023   
00024   // [init subscribers]
00025   port_name = ros::names::append(ros::this_node::getName(), "joint_states"); 
00026   this->joint_states_subscriber = this->nh_.subscribe(port_name, 5, &WamIKAC::joint_states_callback, this);
00027   
00028   // [init services]
00029   port_name = ros::names::append(ros::this_node::getName(), "wamik"); 
00030   this->wamik_server = this->nh_.advertiseService(port_name, &WamIKAC::wamikCallback, this);
00031   
00032   port_name = ros::names::append(ros::this_node::getName(), "wamik_from_pose");
00033   this->wamik_server_fromPose = this->nh_.advertiseService(port_name, &WamIKAC::wamikCallbackFromPose, this);
00034 
00035   // [init clients]
00036   port_name = ros::names::append(ros::this_node::getName(), "joints_move"); 
00037   joint_move_client = this->nh_.serviceClient<iri_wam_common_msgs::joints_move>(port_name);
00038   
00039   // [init action servers]
00040   
00041   // [init action clients] 
00042   
00043 }
00044 
00045 void WamIKAC::ikPub(void)
00046 {
00047   for (int i=0;i<7;i++){
00048     this->ik_joints_msg.position[i]=joints_(i);
00049   }
00050     this->ik_joints_publisher_.publish(this->ik_joints_msg);
00051 }
00052 
00053 /*  [subscriber callbacks] */
00054 void WamIKAC::joint_states_callback(const sensor_msgs::JointState::ConstPtr& msg) { 
00055 
00056   for(int i=0;i<7;i++)
00057     currentjoints_[i] = msg->position[i]; 
00058 
00059 }
00060 
00061 /*  [service callbacks] */
00062 bool WamIKAC::wamikCallbackFromPose(iri_wam_common_msgs::wamInverseKinematicsFromPose::Request &req, iri_wam_common_msgs::wamInverseKinematicsFromPose::Response &res){
00063 
00064   ROS_INFO("[WamIKAC] User Given Current Joints %s (j1, j2, j3, j4, j5, j6, j7): [ %f, %f, %f, %f, %f, %f, %f ]",
00065             req.current_joints.header.frame_id.c_str(), 
00066             req.current_joints.position[0], 
00067             req.current_joints.position[1],
00068             req.current_joints.position[2],
00069             req.current_joints.position[3],
00070             req.current_joints.position[4],
00071             req.current_joints.position[5],
00072             req.current_joints.position[6]);
00073   
00074   ROS_INFO("[WamIKAC] Received Pose from frame_id %s (x, y, z, qx, qy, qz, qw): [ %f, %f, %f, %f, %f, %f, %f ]",
00075             req.desired_pose.header.frame_id.c_str(), 
00076             req.desired_pose.pose.position.x, 
00077             req.desired_pose.pose.position.y,
00078             req.desired_pose.pose.position.z,
00079             req.desired_pose.pose.orientation.x,
00080             req.desired_pose.pose.orientation.y,
00081             req.desired_pose.pose.orientation.z,
00082             req.desired_pose.pose.orientation.w);
00083   
00084   // User defined current pose
00085   std::vector<double> currentjoints;
00086   for(int ii=0; ii<7; ii++)
00087     currentjoints[ii] = req.current_joints.position[ii]; 
00088 
00089   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);
00090   Matrix3f mat = quat.toRotationMatrix();
00091 
00092   std::vector <double> desired_pose(16,0);
00093   std::vector <double> desired_joints(7,0);
00094 
00095   // Desired pose as a Homogeneous Transformation
00096   desired_pose[3] = req.desired_pose.pose.position.x;
00097   desired_pose[7] = req.desired_pose.pose.position.y;
00098   desired_pose[11] = req.desired_pose.pose.position.z;
00099   desired_pose[15] = 1;
00100   for(int i=0; i<12; i++){
00101    if(i%4 != 3){
00102      desired_pose[i] = mat(i/4,i%4);
00103    }
00104   }
00105   ROS_INFO("[WamIKAC] 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",
00106             desired_pose[0], desired_pose[1], desired_pose[2], desired_pose[3],
00107             desired_pose[4], desired_pose[5], desired_pose[6], desired_pose[7],
00108             desired_pose[8], desired_pose[9], desired_pose[10], desired_pose[11],
00109             desired_pose[12], desired_pose[13], desired_pose[14], desired_pose[15]);
00110 
00111   if(!WamIKAC::ik(desired_pose, currentjoints, desired_joints)){
00112       ROS_ERROR("[WamIKAC] IK solution not found. Is pose out of configuration space?");
00113       return false;
00114   }else{
00115 
00116       ROS_INFO("[WamIKAC] 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));
00117     
00118       res.desired_joints.position.resize(7);
00119       joints_.resize(7);
00120       for(int i=0; i<7; i++){
00121         res.desired_joints.position[i] = desired_joints.at(i);
00122         joints_(i) = desired_joints.at(i);
00123       }
00124   }
00125   return true;
00126 }
00127 
00128 bool WamIKAC::wamikCallback(iri_wam_common_msgs::wamInverseKinematics::Request &req, iri_wam_common_msgs::wamInverseKinematics::Response &res){
00129 
00130   ROS_INFO("[WamIKAC] Received Pose from frame_id %s (x, y, z, qx, qy, qz, qw): [ %f, %f, %f, %f, %f, %f, %f ]",
00131             req.pose.header.frame_id.c_str(), 
00132             req.pose.pose.position.x, 
00133             req.pose.pose.position.y,
00134             req.pose.pose.position.z,
00135             req.pose.pose.orientation.x,
00136             req.pose.pose.orientation.y,
00137             req.pose.pose.orientation.z,
00138             req.pose.pose.orientation.w);
00139   
00140   Quaternion<float> quat( req.pose.pose.orientation.w, req.pose.pose.orientation.x, req.pose.pose.orientation.y, req.pose.pose.orientation.z);
00141   Matrix3f mat = quat.toRotationMatrix();
00142 
00143   std::vector <double> pose(16,0);
00144   std::vector <double> joints(7,0);
00145 
00146   pose[3] = req.pose.pose.position.x;
00147   pose[7] = req.pose.pose.position.y;
00148   pose[11] = req.pose.pose.position.z;
00149   pose[15] = 1;
00150   for(int i=0; i<12; i++){
00151    if(i%4 != 3){
00152      pose[i] = mat(i/4,i%4);
00153    }
00154   }
00155   ROS_INFO("[WamIKAC] 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",
00156             pose[0],pose[1],pose[2],pose[3],
00157             pose[4],pose[5],pose[6],pose[7],
00158             pose[8],pose[9],pose[10],pose[11],
00159             pose[12],pose[13],pose[14],pose[15]);
00160 
00161   if(!WamIKAC::ik(pose, currentjoints_, joints)){
00162       ROS_ERROR("[WamIKAC] IK solution not found. Is pose out of configuration space?");
00163       return false;
00164   }else{
00165 
00166       ROS_INFO("[WamIKAC] 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));
00167     
00168       res.joints.position.resize(7);
00169       joints_.resize(7);
00170       for(int i=0;i<7;i++){
00171         res.joints.position[i] = joints.at(i);
00172         joints_(i)=joints.at(i);
00173       }
00174   }
00175   return true;
00176 }
00177 
00178 /*  [action callbacks] */
00179 
00180 /*  [action requests] */
00181 
00182 
00183 bool WamIKAC::ik(vector<double> pose, vector<double> currentjoints, vector<double>& joints){
00184     //ik solver
00185 
00186   MatrixXd posec(4,4);
00187   VectorXd cjoints(7),nextangles(7),qoptim(7);
00188   for(int i=0;i<16;i++)
00189      posec(i/4,i%4) = pose.at(i); 
00190 
00191 /* Convert current joints to a eigen vector structure*/
00192   for(int i=0;i<7;i++)
00193      cjoints(i) = currentjoints.at(i);
00194 
00195         clock_t start,end;
00196         start=clock();
00197         joints.resize(7);
00198 
00199         MatrixXd A(4,4);
00200         double i=0;
00201         bool initfound=false;
00202         bool breakloop=false;
00203         
00204         clock_t t1,t2,t3;
00205         t1=clock();
00206         
00207         /*T0 is the objective position*/
00208         MatrixXd T0(4,4);
00209         T0=posec;
00210         MatrixXd qsol(8,7);
00211         VectorXd sol(8);        
00212         qsol.fill(0.0);
00213         sol.fill(0.0);
00214         double q10=cjoints(0);
00215         double step;
00216         MatrixXd qaux;
00217         Vector3f Xw;
00218 
00219         double potq=10000.;
00220         //int basicelements=4;
00221         step=0.0005;
00222         ROS_DEBUG("WAM_IKAC: Beta Version, still being tested but apparently working correctly");
00223         ROS_DEBUG("Solution found is that which minimizes a weighted norm of the joints variation, to insert another criterion, modify the function WamIKAC::potentialfunction");
00224         ROS_DEBUG("Variation on q0 at each step for obtaining first solution : %e",step);
00225         ROS_DEBUG("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));
00226         //std::cout<<"q1 iteration step:\n"<<step<<std::endl;   
00227         //std::cin>>step;
00228         /* Look for the initial solution */
00229 
00230 //q10=-2.44;
00231 //      WamIKAC::exactikine(T0,q10,qsol,sol);
00232 //      WamIKAC::filtersols(qsol,sol);
00233 //std::cout<<"q10="<<q10<<std::endl<<"qsol=\n"<<qsol<<std::endl<<"sol \n"<<sol.transpose()<<std::endl;  
00234         
00235         
00236         while (!initfound & !breakloop){
00237                 /* q10 is the joint 1 value used to find a solution*/
00238                 WamIKAC::getq1(cjoints,i,q10,step);
00239         
00240                 if (abs(q10)<2.6){
00241                 //std::cout<<"provant q10="<<q10<<std::endl;
00242                 /* qsol is the solution matrix (up to 8 solutions) found with q10, sol is a vector indicating which solutions are valid
00243                 posec is the objective homogeneous transformation*/
00244                       WamIKAC::exactikine(T0,q10,qsol,sol);
00245                       
00246                       //std::cout<<"q10="<<q10<<std::endl;
00247                       //std::cout<<"qsol="<<qsol<<std::endl;
00248       //                std::cout<<"sol exactikine"<<sol<<std::endl;
00249                       /* we eliminate solutions which are not valid*/
00250                       WamIKAC::filtersols(qsol,sol);
00251                       if (sol.sum()!=0.){
00252                               WamIKAC::basicsols(qsol,qaux,sol);
00253                               //ROS_INFO("LOOP BREAK, SOLUTION FOUND");
00254                               //std::cout<<"sol="<<std::endl<<sol.transpose()<<std::endl;
00255                               initfound=true;
00256                       }
00257                 }else{
00258                   if (i*step+cjoints(0)>2.6 && -i*step+cjoints(0)<-2.6){
00259                     breakloop=true;
00260                     ROS_INFO("LOOP BREAK,q1 steps OUT OF RANGE");
00261                   }
00262                 }
00263 
00264                 /* we take the one with best (q) evaluation function over the rows of qsol */
00265                 
00266                 i=i+1.;
00267                 /* add possibility of not finding a solution, add i limits*/
00268         }
00269 //std::cout<<"initfound="<<initfound<<std::endl;
00270 //std::cout<<"firstsol="<<std::endl<<qaux<<std::endl;
00271 
00272 
00273         if (initfound){
00274                 t2=clock();
00275                 /* Rotate solutions to optimize*/
00276                 /* perform optimization */
00277                 WamIKAC::optimizesol(qaux,T0,qoptim,potq,cjoints);      
00278                 t3=clock();
00279                 double dif1, dif2;
00280                 dif1=((double)t2 - (double)t1)/((double)CLOCKS_PER_SEC);
00281                 dif2=((double)t3 - (double)t2)/((double)CLOCKS_PER_SEC);
00282 
00283                 //std::cout<<"initial solution time="<<dif1<<std::endl<<"Optimization time="<<dif2<<std::endl<<"Best potential value="<<potq<<std::endl;
00284                                   joints.clear();
00285                   joints.resize(7);
00286                   for(int i=0;i<7;i++)
00287                      joints[i] = qoptim(i);
00288                  end=clock();
00289 
00290                 double dif;
00291 
00292                 dif = ((double)end-(double)start)/((double)CLOCKS_PER_SEC);
00293         
00294                 MatrixXd T01,T12,T23,T34,T45,T56,T67,T07;
00295                 double PI=3.14159265;
00296                 WamIKAC::DHmatrix(-PI/2,0.,0.,qoptim(0),T01),
00297                 WamIKAC::DHmatrix(PI/2,0.,0.,qoptim(1),T12),
00298                 WamIKAC::DHmatrix(-PI/2,0.045,0.55,qoptim(2),T23),
00299                 WamIKAC::DHmatrix(PI/2,-0.045,0.,qoptim(3),T34);
00300                 WamIKAC::DHmatrix(-PI/2,0.,0.3,qoptim(4),T45);
00301                 WamIKAC::DHmatrix(PI/2,0.,0.,qoptim(5),T56);
00302                 WamIKAC::DHmatrix(0.,0.,0.06,qoptim(6),T67);
00303         
00304         
00305                 T07=T01*T12*T23*T34*T45*T56*T67;
00306 
00307                 ROS_DEBUG("ELAPSED TIME IS  %.5lf seconds ", dif );
00308                   return true;
00309         } else{
00310                   for(int i=0;i<7;i++)
00311                      joints[i] = cjoints(i);
00312                 ROS_DEBUG("SOLUTION NOT FOUND, robot not moving ");
00313                 return false;
00314         }    
00315 
00316 
00317 }
00318 
00319 
00320 
00321 
00322 
00323 void WamIKAC::filtersols(MatrixXd qsol,VectorXd& sol){
00324 // INPUT: qsol, Nx7 MatrixXd, where each row is a solution of the WAM inverse kinematics, not concerning joint limits
00325 // OUPUT: the same Nx7 matrix, plus a N-dimentional VectorXd "sol", whose ith value is 1 if the ith row of qsol respects joint limits, 0 otherwise
00326         MatrixXd Qlim(7,2);
00327         Qlim << -2.6, 2.6,
00328                 -2.0, 2.0,
00329                 -2.8, 2.8,
00330                 -0.9, 3.1,
00331                 -4.76,1.24,
00332                 -1.6, 1.6,
00333                 -2.2, 2.2;
00334         sol.resize(qsol.rows());
00335         sol.fill(1.0);
00336 
00337         for (int i=0;i<qsol.rows();i++){
00338                 for (int j=0;j<7;j++){
00339                         if ((qsol(i,j)<Qlim(j,0))|(qsol(i,j)>Qlim(j,1))){
00340                                 sol(i)=0.0;
00341         
00342                         }       
00343                 }
00344 
00345         }
00346         
00347         
00348 }
00349 
00350 void WamIKAC::DHmatrix(double alpha, double a, double d,double& theta, MatrixXd& T){
00351 // INPUT: alpha, a, d Denavit Hartenberg parameters, and theta, the rotation angle of a wam link (standard notation).
00352 // OUTPUT: T, the D-H matrix (MatrixXd) calculated with those parameters and theta.
00353 
00354 T.resize(4,4);
00355 T.fill(0.0);
00356 T(0,0)= cos(theta); 
00357 T(0,1)=-sin(theta)*cos(alpha);
00358 T(0,2)=sin(theta)*sin(alpha);
00359 T(0,3)=a*cos(theta);
00360 T(1,0)=sin(theta);
00361 T(1,1)=cos(theta)*cos(alpha); 
00362 T(1,2)=-cos(theta)*sin(alpha); 
00363 T(1,3)=a*sin(theta); 
00364 T(2,1)=sin(alpha); 
00365 T(2,2)=cos(alpha);
00366 T(2,3)=d; 
00367 T(3,3)=1;
00368 
00369 }
00370 
00371 
00372 
00373 void WamIKAC::exactikine(MatrixXd T0, double q10, MatrixXd& qsol,VectorXd&sol){
00374 // INPUT: T0=MatrixXd, the desired homogeneous transformation.
00375 //        q10=double, a fixed value for the first joint.
00376 // OUTPUT: qsol=MatrixXd, a 8x7 matrix, each row corresponds to a solution of the inverse kinematics for the desired goal.
00377 //         sol=vector, indicating wether solution has been found or not for the fixed q1. Note it does not consider joint limits!
00378 
00379         /*DEFINITION DHs*/
00380         double L=0.06;
00381         double a=0.3;
00382         double b=0.045;
00383         double c=0.55;
00384         double s3;
00385         double c3;
00386         double PI=3.14159265;
00387         
00388         qsol.resize(8,7);
00389 
00390         MatrixXd q2sol2(2,2);
00391         VectorXd Pw1(4);
00392         MatrixXd Pw(1,4);
00393         VectorXd q3(2);
00394         MatrixXd Pw3(4,2);
00395         MatrixXd q4sol4(2,2);
00396         MatrixXd T12,T23,T34,T01,T04;
00397         MatrixXd qout(8,7);
00398         qout.fill(0.0);
00399 
00400         int k;
00401         Vector2d q5;
00402         Vector2d q6;
00403         Vector2d q7;
00404 
00405 
00406         Pw=T0.block<4,1>(0,3)-L*T0.block<4,1>(0,2);
00407         
00408 
00409         double aux1=pow(Pw(0,0),2)+pow(Pw(1,0),2)+pow(Pw(2,0),2)-pow(a,2)-2*pow(b,2)-pow(c,2);
00410         double aux2=2*a*b+2*b*c;
00411         double aux3=2*a*c-2*pow(b,2);
00412 
00413         WamIKAC::soltrig(aux1, aux2, aux3,q4sol4);
00414 
00415         WamIKAC::DHmatrix(-PI/2,0.,0.,q10,T01);
00416         
00417         Pw1=T01.inverse()*Pw;
00418 
00419         Pw3.fill(0.0);
00420                 for (int i4=0;i4<2;i4++){
00421                         Pw3(0,i4)=a*sin(q4sol4(i4,0))-b*cos(q4sol4(i4,0));              
00422                         Pw3(1,i4)=-a*cos(q4sol4(i4,0))-b*sin(q4sol4(i4,0));
00423                         Pw3(2,i4)=0.;
00424                         Pw3(3,i4)=1.;
00425 
00426                         aux1=11.0/20.0-Pw3(1,i4);
00427                         aux2=Pw1(0);
00428                         aux3=-Pw1(1);
00429                         WamIKAC::soltrig(aux1, aux2, aux3, q2sol2);
00430                         //std::cout<<"q2sol2="<<q2sol2<<std::endl;
00431                                 for(int i2=0;i2<2;i2++){
00432                                         s3=Pw1(2)/(Pw3(0,i4)+9/200);
00433                                         c3=(cos(q2sol2(i2,0))*Pw1(0)+sin(q2sol2(i2,0))*Pw1(1))/(Pw3(0,i4)+9/200);
00434                                         q3(i2)=atan2(s3,c3);
00435                                         WamIKAC::DHmatrix(PI/2,0.,0.,q2sol2(i2,0),T12);
00436                                         WamIKAC::DHmatrix(-PI/2,0.045,0.55,q3(i2),T23);
00437                                         WamIKAC::DHmatrix(PI/2,-0.045,0.,q4sol4(i4,0),T34);
00438                                         T04=T01*T12*T23*T34;
00439                                         WamIKAC::sphericalikine(T0,T04,q5,q6,q7);
00440                                         /*We write all the posible solutions in a 8x7 matrix, each row of it is a solution set. the vector sol indicates wether solutions have been found*/
00441                                         for (int i5=0;i5<2;i5++){
00442                                                 k=i4*4+i2*2+i5;
00443                                                 qsol(k,0)=q10;
00444                                                 qsol(k,1)=q2sol2(i2,0);
00445                                                 qsol(k,2)=q3(i2);
00446                                                 qsol(k,3)=q4sol4(i4,0);
00447                                                 qsol(k,4)=q5(i5);
00448                                                 qsol(k,5)=q6(i5);
00449                                                 qsol(k,6)=q7(i5);
00450 
00451                                                 sol(k)=q4sol4(i4,1)*q2sol2(i2,1);
00452                                         }
00453 
00454                                 }
00455 
00456                 }
00457 
00458         
00459         
00460 }
00461 
00462 
00463 
00464 void WamIKAC::basicsols(MatrixXd qsol,MatrixXd& qaux,VectorXd sol){
00465 // INPUT:  qsol=a 8x7 matrix (MatrixXd), each row corresponds to a solution of the inverse kinematics for the desired goal.
00466 //         sol=vector, indicating wether solution has been found or not for the fixed q1. Suposed to consider joint limits.
00467            
00468 // OUTPUT: qaux=a Nx7 matrix (MatrixXd), each row corresponds to a solution of the inverse kinematics for the desired goal of those in qsol. With the 
00469 //      consideration that qaux only has one row for each pair of q2, q4 which gives a solution of the inverse kinematics for a given q1 
00470 //      (note there will usualy be 2 solutions for the spherical wrist for each of these couples {q2,q4}
00471 
00472         MatrixXd qauxiliar2;
00473         qauxiliar2.resize(4,7);
00474         qauxiliar2.fill(-99.9999);
00475         int nbasics=0;
00476         for (int i=0;i<qsol.rows()/2;i++){
00477 //      std::cout<<"i="<<i<<" nbasics="<<nbasics<<std::endl;
00478                 if (sol(2*i)>0.0){
00479                         qauxiliar2.row(nbasics)=qsol.row(2*i);
00480                         nbasics=nbasics+1;
00481 
00482                 }else if (sol(2*i+1)>0.0){
00483                         qauxiliar2.row(nbasics)=qsol.row(2*i+1);
00484                         nbasics=nbasics+1;
00485                 }
00486         }
00487 
00488         qaux.resize(nbasics,7);
00489 
00490         for (int j=0;j<nbasics;j++){
00491                 qaux.row(j)=qauxiliar2.row(j);
00492         }
00493                 
00494 
00495 }
00496 
00497 
00498 
00499 
00500 
00501 void WamIKAC::optimizesol(MatrixXd q, MatrixXd T0, VectorXd& qoutput,double& potact,VectorXd qref){
00502 // INPUT q=qaux in basicsol function.
00503 //       T0=desired goal
00504 // OUPUT qoutput=the best solution, according to a desired optimization function, obtained by rotating the basic solutions around Origin-Wrist axis.
00505 //       potact=the value of the potential function for the solution chosen.
00506 
00507         /* q is the initial guess*/
00508         VectorXd PLa,PJa,qelbows;
00509         MatrixXd PL(3,q.rows()); //each column corresponds to one basic solution
00510         MatrixXd PJ(3,q.rows());
00511 
00512         int IMAX;
00513 
00514         IMAX=50;
00515         ROS_INFO("Rotations for each solution: %d",IMAX);
00516 
00517         for (int ia=0;ia<q.rows();ia++){
00518                 qelbows=q.row(ia);
00519                 WamIKAC::initialelbows(qelbows,T0,PLa,PJa);
00520                 PL.col(ia)=PLa;
00521                 PJ.col(ia)=PJa;
00522         }
00523 
00524         double L=0.06;
00525         MatrixXd T04;
00526         Matrix3d Mrot,Rn,I3;
00527         double phi,qn4,qn3,qn2,qn1,s3,c3,eps1,eps3,potq;
00528         Vector2d qn5,qn6,qn7;
00529         double PI=3.14159265;
00530         Vector3d v,CJ,CL,VLJ;
00531         VectorXd qn4b,sol,qbest;
00532         MatrixXd Pw,T01,T12,T23,T34,Qaux;
00533         MatrixXd Qglobal(4*q.rows(),7); 
00534         qoutput=q.row(0);
00535         Pw=T0.block<3,1>(0,3)-L*T0.block<3,1>(0,2);
00536         double aux0=Pw.norm();
00537         v=Pw/aux0;      
00538 
00539         /*Compute q4*/
00540         WamIKAC::skewop(Mrot,v);
00541         I3.setIdentity();
00542 
00543         for (int i=0;i<IMAX;i++){
00544                 phi=2*PI*double(i)/double(IMAX)*pow(-1,double(i));
00545                 Rn=I3+sin(phi)*Mrot+(1-cos(phi))*Mrot*Mrot;
00546 
00547                 Qglobal.fill(-9.9);
00548                 for (int nconfig=0;nconfig<q.rows();nconfig++){
00549                         qn4=q(nconfig,3);
00550                         CJ=Rn*PJ.block<3,1>(0,nconfig);
00551                         CL=Rn*PL.block<3,1>(0,nconfig);
00552                         Qaux.resize(4,7);
00553                         Qaux.fill(-9.9);
00554                         if (CL(2)/0.55>-0.4161){
00555                                 /*Calculacte q2*/
00556                                 qn2=acos(CL(2)/0.55);
00557                                 /*Calculate q1*/
00558                                 qn1=atan2(CL(1),CL(0));
00559                                 /*Calculate q3*/
00560                                 VLJ=(CJ-CL)/0.045;
00561                                 s3=VLJ(1)*cos(qn1)-VLJ(0)*sin(qn1);
00562                                 if (sin(qn2)<0.001){
00563                                     c3=(VLJ(1)*sin(qn1)+VLJ(0)*cos(qn1))/cos(qn2);
00564                                 }else{
00565                                     c3=-VLJ(2)/sin(qn2);
00566                                 }
00567                                 qn3=atan2(s3,c3);
00568                                 WamIKAC::DHmatrix(-PI/2,0,0,qn1,T01),
00569                                 WamIKAC::DHmatrix(PI/2,0,0,qn2,T12),
00570                                 WamIKAC::DHmatrix(-PI/2,0.045,0.55,qn3,T23),
00571                                 WamIKAC::DHmatrix(PI/2,-0.045,0,qn4,T34);
00572                                 T04=T01*T12*T23*T34;
00573                                 WamIKAC::sphericalikine(T0,T04,qn5,qn6,qn7);
00574                                 eps1 = copysign(1.0, qn1);
00575                                 eps3 = copysign(1.0, qn3);                      
00576                                 Qaux<<qn1,qn2,qn3,qn4,qn5(0),qn6(0),qn7(0),
00577                                         qn1,qn2,qn3,qn4,qn5(1),qn6(1),qn7(1),
00578                                         qn1-eps1*PI,-qn2,qn3-eps3*PI,qn4,qn5(0),qn6(0),qn7(0),
00579                                         qn1-eps1*PI,-qn2,qn3-eps3*PI,qn4,qn5(1),qn6(1),qn7(1);
00580 
00581                         }
00582                         Qglobal.row(4*nconfig)=Qaux.row(0);
00583                         Qglobal.row(4*nconfig+1)=Qaux.row(1);
00584                         Qglobal.row(4*nconfig+2)=Qaux.row(2);
00585                         Qglobal.row(4*nconfig+3)=Qaux.row(3);
00586                 }
00587 
00588                 WamIKAC::filtersols(Qglobal,sol);
00589 
00590                 WamIKAC::bestsol(Qglobal,sol,qref,qbest,potq);
00591 
00592                 // if the potential found is better than the best we had, we update the solution:
00593                 if (potq<potact){
00594                         qoutput=qbest;
00595                         potact=potq;
00596 
00597                 }
00598         }
00599 }
00600 
00601 
00602 
00603 
00604 void WamIKAC::skewop(Matrix3d& M,Vector3d v){
00605 M.fill(0.0);
00606 M(0,1)=-v(2);
00607 M(1,0)=v(2);
00608 M(0,2)=v(1);
00609 M(2,0)=-v(1);
00610 M(1,2)=-v(0);
00611 M(2,1)=v(0);
00612 }
00613 
00614 void WamIKAC::getq1(VectorXd cjoints,float i,double& q10,double step){
00615 q10=cjoints(0)+i*step*pow(-1,i);        
00616 }
00617 
00618 
00619 
00620 
00621 
00622 void WamIKAC::bestsol(MatrixXd qsol,VectorXd sol,VectorXd qref,VectorXd& q,double& potbest){
00623   
00624   
00625         potbest=10000; /*high initial potential value*/
00626         double potq;
00627         VectorXd qact;
00628         
00629         for(int i=1;i<qsol.rows();i++){
00630                 if (sol(i)!=0.0){
00631                         qact=qsol.block<1,7>(i,0);
00632                         WamIKAC::potentialfunction(qref,qact,potq);
00633                         if (potq<potbest){
00634                                 q=qact;
00635                                 potbest=potq;
00636                         }
00637                 }
00638         }
00639 }
00640 
00641 
00642 
00643 
00644 void WamIKAC::potentialfunction(VectorXd qref,VectorXd& q, double& potq){
00645 // INPUT: qref: taken as the current joint state of the robot
00646 //        q: the joint state q to be evaluated  
00647 // OUTPUT:   potq: the potential of the joint position q
00648         MatrixXd W(7,7);
00649         W.fill(0.0);
00650         W(0,0)=2.5;
00651         W(1,1)=2.0;
00652         W(2,2)=2.0;
00653         W(3,3)=1.5;
00654         W(4,4)=1.0;
00655         W(5,5)=1.0;
00656         W(6,6)=1.0;
00657 
00658         VectorXd qdif(7);
00659         
00660         qdif=q-qref;
00661         potq=qdif.transpose()*W*qdif;
00662 
00663 }
00664 
00665 
00666 
00667 
00668 
00669 void WamIKAC::sphericalikine(MatrixXd T0,MatrixXd T4, Vector2d& q5,Vector2d& q6,Vector2d& q7){
00670         MatrixXd Taux;
00671         Taux=T4.inverse()*T0;
00672         q5(0)=atan(Taux(1,2)/Taux(0,2));
00673 
00674         if (q5(0)>1.3-3.14159265){
00675         q5(1)=q5(0)-3.14159265;
00676         }else{
00677         q5(1)=q5(0)+3.14159265;
00678         }
00679 
00680         for (int i5=0;i5<2;i5++){
00681         q6(i5)=atan2(Taux(0,2)*cos(q5(i5))+Taux(1,2)*sin(q5(i5)),Taux(2,2));
00682         q7(i5)=atan2(-Taux(0,0)*sin(q5(i5))+Taux(1,0)*cos(q5(i5)),-Taux(0,1)*sin(q5(i5))+Taux(1,1)*cos(q5(i5)));
00683         }
00684 }
00685 
00686 
00687 
00688 void WamIKAC::initialelbows(VectorXd q,MatrixXd T0,VectorXd& PL,VectorXd& PJ){
00689         const double pi=3.14159265;
00690         MatrixXd T01,T12,T23,T02,T03;
00691         WamIKAC::DHmatrix(-pi/2,0,0,q(0),T01);
00692         WamIKAC::DHmatrix(pi/2,0,0,q(1),T12);
00693         WamIKAC::DHmatrix(-pi/2,0.045,0.55,q(2),T23);
00694         T02=T01*T12;
00695         T03=T02*T23;
00696         VectorXd aux(4),PLaux(4);
00697         aux(0)=0.0;
00698         aux(1)=0.0;
00699         aux(2)=0.55;
00700         aux(3)=1.0;
00701         PLaux=T02*aux;
00702         PL=PLaux.block<3,1>(0,0);
00703         PJ=T03.block<3,1>(0,3);
00704 
00705 }
00706 
00707 
00708 
00709 void WamIKAC::soltrig(double a, double b, double c, MatrixXd& q2sol2){
00710 /*solves the equation a = b*sin(x)+c*cos(x) */
00711 //std::cout<<"b"<<b<<std::endl;
00712         if (abs(b)<0.00000001 && abs(a/c)<1.0){
00713                 q2sol2(0,1)=1.;
00714                 q2sol2(1,1)=1.;
00715                 q2sol2(0,0)=acos(a/c);
00716                 q2sol2(1,0)=-acos(a/c);
00717     
00718 
00719         }else if (pow(c,2.)*pow(b,2)-pow(b,2.)*pow(a,2.)+pow(b,4.)<=0.00000001){
00720           
00721                 q2sol2(0,1)=0.;
00722                 q2sol2(1,1)=0.;
00723                 q2sol2(0,0)=-99.9999;
00724                 q2sol2(1,0)=-99.9999;
00725 
00726                 
00727         }else{
00728         
00729                 q2sol2(0,1)=1.;
00730                 q2sol2(1,1)=1.;
00731 
00732                 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.)));
00733 
00734                 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.)));
00735         }
00736 }
00737 
00738 
00739 
00740 
00741 int main(int argc, char** argv) {
00742     ros::init(argc, argv, "wam_ik");
00743     WamIKAC wam_ikac;
00744     ros::Rate loop_rate(10);
00745     while(ros::ok()){
00746       ros::spinOnce();
00747       loop_rate.sleep(); 
00748     }
00749 
00750 }


iri_wam_ik
Author(s): Adria Colomer
autogenerated on Fri Dec 6 2013 20:07:41