ur_kin.cpp
Go to the documentation of this file.
00001 #include <ur_kinematics/ur_kin.h>
00002 
00003 namespace ur_kinematics {
00004 
00005   void forward(const double* q, double* T) {
00006     double s1 = sin(*q), c1 = cos(*q); q++;
00007     double q234 = *q, s2 = sin(*q), c2 = cos(*q); q++;
00008     double s3 = sin(*q), c3 = cos(*q); q234 += *q; q++;
00009     q234 += *q; q++;
00010     double s5 = sin(*q), c5 = cos(*q); q++;
00011     double s6 = sin(*q), c6 = cos(*q); 
00012     double s234 = sin(q234), c234 = cos(q234);
00013     *T = ((c1*c234-s1*s234)*s5)/2.0 - c5*s1 + ((c1*c234+s1*s234)*s5)/2.0; T++;
00014     *T = (c6*(s1*s5 + ((c1*c234-s1*s234)*c5)/2.0 + ((c1*c234+s1*s234)*c5)/2.0) - 
00015           (s6*((s1*c234+c1*s234) - (s1*c234-c1*s234)))/2.0); T++;
00016     *T = (-(c6*((s1*c234+c1*s234) - (s1*c234-c1*s234)))/2.0 - 
00017           s6*(s1*s5 + ((c1*c234-s1*s234)*c5)/2.0 + ((c1*c234+s1*s234)*c5)/2.0)); T++;
00018     *T = ((d5*(s1*c234-c1*s234))/2.0 - (d5*(s1*c234+c1*s234))/2.0 - 
00019           d4*s1 + (d6*(c1*c234-s1*s234)*s5)/2.0 + (d6*(c1*c234+s1*s234)*s5)/2.0 - 
00020           a2*c1*c2 - d6*c5*s1 - a3*c1*c2*c3 + a3*c1*s2*s3); T++;
00021     *T = c1*c5 + ((s1*c234+c1*s234)*s5)/2.0 + ((s1*c234-c1*s234)*s5)/2.0; T++;
00022     *T = (c6*(((s1*c234+c1*s234)*c5)/2.0 - c1*s5 + ((s1*c234-c1*s234)*c5)/2.0) + 
00023           s6*((c1*c234-s1*s234)/2.0 - (c1*c234+s1*s234)/2.0)); T++;
00024     *T = (c6*((c1*c234-s1*s234)/2.0 - (c1*c234+s1*s234)/2.0) - 
00025           s6*(((s1*c234+c1*s234)*c5)/2.0 - c1*s5 + ((s1*c234-c1*s234)*c5)/2.0)); T++;
00026     *T = ((d5*(c1*c234-s1*s234))/2.0 - (d5*(c1*c234+s1*s234))/2.0 + d4*c1 + 
00027           (d6*(s1*c234+c1*s234)*s5)/2.0 + (d6*(s1*c234-c1*s234)*s5)/2.0 + d6*c1*c5 - 
00028           a2*c2*s1 - a3*c2*c3*s1 + a3*s1*s2*s3); T++;
00029     *T = ((c234*c5-s234*s5)/2.0 - (c234*c5+s234*s5)/2.0); T++;
00030     *T = ((s234*c6-c234*s6)/2.0 - (s234*c6+c234*s6)/2.0 - s234*c5*c6); T++;
00031     *T = (s234*c5*s6 - (c234*c6+s234*s6)/2.0 - (c234*c6-s234*s6)/2.0); T++;
00032     *T = (d1 + (d6*(c234*c5-s234*s5))/2.0 + a3*(s2*c3+c2*s3) + a2*s2 - 
00033          (d6*(c234*c5+s234*s5))/2.0 - d5*c234); T++;
00034     *T = 0.0; T++; *T = 0.0; T++; *T = 0.0; T++; *T = 1.0;
00035   }
00036 
00037   void forward_all(const double* q, double* T1, double* T2, double* T3, 
00038                                     double* T4, double* T5, double* T6) {
00039     double s1 = sin(*q), c1 = cos(*q); q++; // q1
00040     double q23 = *q, q234 = *q, s2 = sin(*q), c2 = cos(*q); q++; // q2
00041     double s3 = sin(*q), c3 = cos(*q); q23 += *q; q234 += *q; q++; // q3
00042     q234 += *q; q++; // q4
00043     double s5 = sin(*q), c5 = cos(*q); q++; // q5
00044     double s6 = sin(*q), c6 = cos(*q); // q6
00045     double s23 = sin(q23), c23 = cos(q23);
00046     double s234 = sin(q234), c234 = cos(q234);
00047 
00048     if(T1 != NULL) {
00049       *T1 = c1; T1++;
00050       *T1 = 0; T1++;
00051       *T1 = s1; T1++;
00052       *T1 = 0; T1++;
00053       *T1 = s1; T1++;
00054       *T1 = 0; T1++;
00055       *T1 = -c1; T1++;
00056       *T1 = 0; T1++;
00057       *T1 =       0; T1++;
00058       *T1 = 1; T1++;
00059       *T1 = 0; T1++;
00060       *T1 =d1; T1++;
00061       *T1 =       0; T1++;
00062       *T1 = 0; T1++;
00063       *T1 = 0; T1++;
00064       *T1 = 1; T1++;
00065     }
00066 
00067     if(T2 != NULL) {
00068       *T2 = c1*c2; T2++;
00069       *T2 = -c1*s2; T2++;
00070       *T2 = s1; T2++;
00071       *T2 =a2*c1*c2; T2++;
00072       *T2 = c2*s1; T2++;
00073       *T2 = -s1*s2; T2++;
00074       *T2 = -c1; T2++;
00075       *T2 =a2*c2*s1; T2++;
00076       *T2 =         s2; T2++;
00077       *T2 = c2; T2++;
00078       *T2 = 0; T2++;
00079       *T2 =   d1 + a2*s2; T2++;
00080       *T2 =               0; T2++;
00081       *T2 = 0; T2++;
00082       *T2 = 0; T2++;
00083       *T2 =                 1; T2++;
00084     }
00085 
00086     if(T3 != NULL) {
00087       *T3 = c23*c1; T3++;
00088       *T3 = -s23*c1; T3++;
00089       *T3 = s1; T3++;
00090       *T3 =c1*(a3*c23 + a2*c2); T3++;
00091       *T3 = c23*s1; T3++;
00092       *T3 = -s23*s1; T3++;
00093       *T3 = -c1; T3++;
00094       *T3 =s1*(a3*c23 + a2*c2); T3++;
00095       *T3 =         s23; T3++;
00096       *T3 = c23; T3++;
00097       *T3 = 0; T3++;
00098       *T3 =     d1 + a3*s23 + a2*s2; T3++;
00099       *T3 =                    0; T3++;
00100       *T3 = 0; T3++;
00101       *T3 = 0; T3++;
00102       *T3 =                                     1; T3++;
00103     }
00104 
00105     if(T4 != NULL) {
00106       *T4 = c234*c1; T4++;
00107       *T4 = s1; T4++;
00108       *T4 = s234*c1; T4++;
00109       *T4 =c1*(a3*c23 + a2*c2) + d4*s1; T4++;
00110       *T4 = c234*s1; T4++;
00111       *T4 = -c1; T4++;
00112       *T4 = s234*s1; T4++;
00113       *T4 =s1*(a3*c23 + a2*c2) - d4*c1; T4++;
00114       *T4 =         s234; T4++;
00115       *T4 = 0; T4++;
00116       *T4 = -c234; T4++;
00117       *T4 =                  d1 + a3*s23 + a2*s2; T4++;
00118       *T4 =                         0; T4++;
00119       *T4 = 0; T4++;
00120       *T4 = 0; T4++;
00121       *T4 =                                                  1; T4++;
00122     }
00123 
00124     if(T5 != NULL) {
00125       *T5 = s1*s5 + c234*c1*c5; T5++;
00126       *T5 = -s234*c1; T5++;
00127       *T5 = c5*s1 - c234*c1*s5; T5++;
00128       *T5 =c1*(a3*c23 + a2*c2) + d4*s1 + d5*s234*c1; T5++;
00129       *T5 = c234*c5*s1 - c1*s5; T5++;
00130       *T5 = -s234*s1; T5++;
00131       *T5 = - c1*c5 - c234*s1*s5; T5++;
00132       *T5 =s1*(a3*c23 + a2*c2) - d4*c1 + d5*s234*s1; T5++;
00133       *T5 =                           s234*c5; T5++;
00134       *T5 = c234; T5++;
00135       *T5 = -s234*s5; T5++;
00136       *T5 =                          d1 + a3*s23 + a2*s2 - d5*c234; T5++;
00137       *T5 =                                                   0; T5++;
00138       *T5 = 0; T5++;
00139       *T5 = 0; T5++;
00140       *T5 =                                                                                 1; T5++;
00141     }
00142 
00143     if(T6 != NULL) {
00144       *T6 =   c6*(s1*s5 + c234*c1*c5) - s234*c1*s6; T6++;
00145       *T6 = - s6*(s1*s5 + c234*c1*c5) - s234*c1*c6; T6++;
00146       *T6 = c5*s1 - c234*c1*s5; T6++;
00147       *T6 =d6*(c5*s1 - c234*c1*s5) + c1*(a3*c23 + a2*c2) + d4*s1 + d5*s234*c1; T6++;
00148       *T6 = - c6*(c1*s5 - c234*c5*s1) - s234*s1*s6; T6++;
00149       *T6 = s6*(c1*s5 - c234*c5*s1) - s234*c6*s1; T6++;
00150       *T6 = - c1*c5 - c234*s1*s5; T6++;
00151       *T6 =s1*(a3*c23 + a2*c2) - d4*c1 - d6*(c1*c5 + c234*s1*s5) + d5*s234*s1; T6++;
00152       *T6 =                                       c234*s6 + s234*c5*c6; T6++;
00153       *T6 = c234*c6 - s234*c5*s6; T6++;
00154       *T6 = -s234*s5; T6++;
00155       *T6 =                                                      d1 + a3*s23 + a2*s2 - d5*c234 - d6*s234*s5; T6++;
00156       *T6 =                                                                                                   0; T6++;
00157       *T6 = 0; T6++;
00158       *T6 = 0; T6++;
00159       *T6 =                                                                                                                                            1; T6++;
00160     }
00161   }
00162 
00163   int inverse(const double* T, double* q_sols, double q6_des) {
00164     int num_sols = 0;
00165     double T02 = -*T; T++; double T00 =  *T; T++; double T01 =  *T; T++; double T03 = -*T; T++; 
00166     double T12 = -*T; T++; double T10 =  *T; T++; double T11 =  *T; T++; double T13 = -*T; T++; 
00167     double T22 =  *T; T++; double T20 = -*T; T++; double T21 = -*T; T++; double T23 =  *T;
00168 
00170     double q1[2];
00171     {
00172       double A = d6*T12 - T13;
00173       double B = d6*T02 - T03;
00174       double R = A*A + B*B;
00175       if(fabs(A) < ZERO_THRESH) {
00176         double div;
00177         if(fabs(fabs(d4) - fabs(B)) < ZERO_THRESH)
00178           div = -SIGN(d4)*SIGN(B);
00179         else
00180           div = -d4/B;
00181         double arcsin = asin(div);
00182         if(fabs(arcsin) < ZERO_THRESH)
00183           arcsin = 0.0;
00184         if(arcsin < 0.0)
00185           q1[0] = arcsin + 2.0*PI;
00186         else
00187           q1[0] = arcsin;
00188         q1[1] = PI - arcsin;
00189       }
00190       else if(fabs(B) < ZERO_THRESH) {
00191         double div;
00192         if(fabs(fabs(d4) - fabs(A)) < ZERO_THRESH)
00193           div = SIGN(d4)*SIGN(A);
00194         else
00195           div = d4/A;
00196         double arccos = acos(div);
00197         q1[0] = arccos;
00198         q1[1] = 2.0*PI - arccos;
00199       }
00200       else if(d4*d4 > R) {
00201         return num_sols;
00202       }
00203       else {
00204         double arccos = acos(d4 / sqrt(R)) ;
00205         double arctan = atan2(-B, A);
00206         double pos = arccos + arctan;
00207         double neg = -arccos + arctan;
00208         if(fabs(pos) < ZERO_THRESH)
00209           pos = 0.0;
00210         if(fabs(neg) < ZERO_THRESH)
00211           neg = 0.0;
00212         if(pos >= 0.0)
00213           q1[0] = pos;
00214         else
00215           q1[0] = 2.0*PI + pos;
00216         if(neg >= 0.0)
00217           q1[1] = neg; 
00218         else
00219           q1[1] = 2.0*PI + neg;
00220       }
00221     }
00223 
00225     double q5[2][2];
00226     {
00227       for(int i=0;i<2;i++) {
00228         double numer = (T03*sin(q1[i]) - T13*cos(q1[i])-d4);
00229         double div;
00230         if(fabs(fabs(numer) - fabs(d6)) < ZERO_THRESH)
00231           div = SIGN(numer) * SIGN(d6);
00232         else
00233           div = numer / d6;
00234         double arccos = acos(div);
00235         q5[i][0] = arccos;
00236         q5[i][1] = 2.0*PI - arccos;
00237       }
00238     }
00240 
00241     {
00242       for(int i=0;i<2;i++) {
00243         for(int j=0;j<2;j++) {
00244           double c1 = cos(q1[i]), s1 = sin(q1[i]);
00245           double c5 = cos(q5[i][j]), s5 = sin(q5[i][j]);
00246           double q6;
00248           if(fabs(s5) < ZERO_THRESH)
00249             q6 = q6_des;
00250           else {
00251             q6 = atan2(SIGN(s5)*-(T01*s1 - T11*c1), 
00252                        SIGN(s5)*(T00*s1 - T10*c1));
00253             if(fabs(q6) < ZERO_THRESH)
00254               q6 = 0.0;
00255             if(q6 < 0.0)
00256               q6 += 2.0*PI;
00257           }
00259 
00260           double q2[2], q3[2], q4[2];
00262           double c6 = cos(q6), s6 = sin(q6);
00263           double x04x = -s5*(T02*c1 + T12*s1) - c5*(s6*(T01*c1 + T11*s1) - c6*(T00*c1 + T10*s1));
00264           double x04y = c5*(T20*c6 - T21*s6) - T22*s5;
00265           double p13x = d5*(s6*(T00*c1 + T10*s1) + c6*(T01*c1 + T11*s1)) - d6*(T02*c1 + T12*s1) + 
00266                         T03*c1 + T13*s1;
00267           double p13y = T23 - d1 - d6*T22 + d5*(T21*c6 + T20*s6);
00268 
00269           double c3 = (p13x*p13x + p13y*p13y - a2*a2 - a3*a3) / (2.0*a2*a3);
00270           if(fabs(fabs(c3) - 1.0) < ZERO_THRESH)
00271             c3 = SIGN(c3);
00272           else if(fabs(c3) > 1.0) {
00273             // TODO NO SOLUTION
00274             continue;
00275           }
00276           double arccos = acos(c3);
00277           q3[0] = arccos;
00278           q3[1] = 2.0*PI - arccos;
00279           double denom = a2*a2 + a3*a3 + 2*a2*a3*c3;
00280           double s3 = sin(arccos);
00281           double A = (a2 + a3*c3), B = a3*s3;
00282           q2[0] = atan2((A*p13y - B*p13x) / denom, (A*p13x + B*p13y) / denom);
00283           q2[1] = atan2((A*p13y + B*p13x) / denom, (A*p13x - B*p13y) / denom);
00284           double c23_0 = cos(q2[0]+q3[0]);
00285           double s23_0 = sin(q2[0]+q3[0]);
00286           double c23_1 = cos(q2[1]+q3[1]);
00287           double s23_1 = sin(q2[1]+q3[1]);
00288           q4[0] = atan2(c23_0*x04y - s23_0*x04x, x04x*c23_0 + x04y*s23_0);
00289           q4[1] = atan2(c23_1*x04y - s23_1*x04x, x04x*c23_1 + x04y*s23_1);
00291           for(int k=0;k<2;k++) {
00292             if(fabs(q2[k]) < ZERO_THRESH)
00293               q2[k] = 0.0;
00294             else if(q2[k] < 0.0) q2[k] += 2.0*PI;
00295             if(fabs(q4[k]) < ZERO_THRESH)
00296               q4[k] = 0.0;
00297             else if(q4[k] < 0.0) q4[k] += 2.0*PI;
00298             q_sols[num_sols*6+0] = q1[i];    q_sols[num_sols*6+1] = q2[k]; 
00299             q_sols[num_sols*6+2] = q3[k];    q_sols[num_sols*6+3] = q4[k]; 
00300             q_sols[num_sols*6+4] = q5[i][j]; q_sols[num_sols*6+5] = q6; 
00301             num_sols++;
00302           }
00303 
00304         }
00305       }
00306     }
00307     return num_sols;
00308   }
00309 };
00310 
00311 
00312 #define IKFAST_HAS_LIBRARY
00313 #include <ur_kinematics/ikfast.h>
00314 using namespace ikfast;
00315 
00316 // check if the included ikfast version matches what this file was compiled with
00317 #define IKFAST_COMPILE_ASSERT(x) extern int __dummy[(int)x]
00318 IKFAST_COMPILE_ASSERT(IKFAST_VERSION==61);
00319 
00320 #ifdef IKFAST_NAMESPACE
00321 namespace IKFAST_NAMESPACE {
00322 #endif
00323 
00324 void to_mat44(double * mat4_4, const IkReal* eetrans, const IkReal* eerot)
00325 {
00326     for(int i=0; i< 3;++i){
00327         mat4_4[i*4+0] = eerot[i*3+0];
00328         mat4_4[i*4+1] = eerot[i*3+1];
00329         mat4_4[i*4+2] = eerot[i*3+2];
00330         mat4_4[i*4+3] = eetrans[i];
00331     }
00332     mat4_4[3*4+0] = 0;
00333     mat4_4[3*4+1] = 0;
00334     mat4_4[3*4+2] = 0;
00335     mat4_4[3*4+3] = 1;
00336 }
00337 
00338 void from_mat44(const double * mat4_4, IkReal* eetrans, IkReal* eerot)
00339 {
00340     for(int i=0; i< 3;++i){
00341         eerot[i*3+0] = mat4_4[i*4+0];
00342         eerot[i*3+1] = mat4_4[i*4+1];
00343         eerot[i*3+2] = mat4_4[i*4+2];
00344         eetrans[i] = mat4_4[i*4+3];
00345     }
00346 }
00347 
00348 
00349 IKFAST_API bool ComputeIk(const IkReal* eetrans, const IkReal* eerot, const IkReal* pfree, IkSolutionListBase<IkReal>& solutions) {
00350   if(!pfree) return false;
00351 
00352   int n = GetNumJoints();
00353   double q_sols[8*6];
00354   double T[16];
00355 
00356   to_mat44(T, eetrans, eerot);
00357 
00358   int num_sols = ur_kinematics::inverse(T, q_sols,pfree[0]);
00359 
00360   std::vector<int> vfree(0);
00361 
00362   for (int i=0; i < num_sols; ++i){
00363     std::vector<IkSingleDOFSolutionBase<IkReal> > vinfos(n);
00364     for (int j=0; j < n; ++j) vinfos[j].foffset = q_sols[i*n+j];
00365     solutions.AddSolution(vinfos,vfree);
00366   }
00367   return num_sols > 0;
00368 }
00369 
00370 IKFAST_API void ComputeFk(const IkReal* j, IkReal* eetrans, IkReal* eerot)
00371 {
00372     double T[16];
00373     ur_kinematics::forward(j,T);
00374     from_mat44(T,eetrans,eerot);
00375 }
00376 
00377 IKFAST_API int GetNumFreeParameters() { return 1; }
00378 IKFAST_API int* GetFreeParameters() { static int freeparams[] = {5}; return freeparams; }
00379 IKFAST_API int GetNumJoints() { return 6; }
00380 
00381 IKFAST_API int GetIkRealSize() { return sizeof(IkReal); }
00382 
00383 #ifdef IKFAST_NAMESPACE
00384 } // end namespace
00385 #endif
00386 
00387 #ifndef IKFAST_NO_MAIN
00388 
00389 using namespace std;
00390 using namespace ur_kinematics;
00391 
00392 int main(int argc, char* argv[])
00393 {
00394   double q[6] = {0.0, 0.0, 1.0, 0.0, 1.0, 0.0};
00395   double* T = new double[16];
00396   forward(q, T);
00397   for(int i=0;i<4;i++) {
00398     for(int j=i*4;j<(i+1)*4;j++)
00399       printf("%1.3f ", T[j]);
00400     printf("\n");
00401   }
00402   double q_sols[8*6];
00403   int num_sols;
00404   num_sols = inverse(T, q_sols);
00405   for(int i=0;i<num_sols;i++) 
00406     printf("%1.6f %1.6f %1.6f %1.6f %1.6f %1.6f\n", 
00407        q_sols[i*6+0], q_sols[i*6+1], q_sols[i*6+2], q_sols[i*6+3], q_sols[i*6+4], q_sols[i*6+5]);
00408   for(int i=0;i<=4;i++)
00409     printf("%f ", PI/2.0*i);
00410   printf("\n");
00411   return 0;
00412 }
00413 #endif


ur_kinematics
Author(s): Kelsey Hawkins
autogenerated on Fri Aug 28 2015 13:31:18