Go to the documentation of this file.00001 #define IKFAST_HAS_LIBRARY
00002 #include "ikfast.h"
00003 using namespace ikfast;
00004
00005 #include <math.h>
00006 #include <stdio.h>
00007
00008 #define ZERO_THRESH 0.00000001
00009 #define SIGN(x) ( ( (x) > 0 ) - ( (x) < 0 ) )
00010 #define PI M_PI
00011 #define UR10_PARAMS
00012
00013 #ifdef UR10_PARAMS
00014 #define d1 0.1273
00015 #define a2 -0.612
00016 #define a3 -0.5723
00017 #define d4 0.163941
00018 #define d5 0.1157
00019 #define d6 0.0922
00020 #endif
00021
00022 namespace ur_kinematics {
00023
00024 void forward(const double* q, double* T) {
00025 double s1 = sin(*q), c1 = cos(*q); q++;
00026 double q234 = *q, s2 = sin(*q), c2 = cos(*q); q++;
00027 double s3 = sin(*q), c3 = cos(*q); q234 += *q; q++;
00028 q234 += *q; q++;
00029 double s5 = sin(*q), c5 = cos(*q); q++;
00030 double s6 = sin(*q), c6 = cos(*q);
00031 double s234 = sin(q234), c234 = cos(q234);
00032 *T = ((c1*c234-s1*s234)*s5)/2.0 - c5*s1 + ((c1*c234+s1*s234)*s5)/2.0; T++;
00033 *T = (c6*(s1*s5 + ((c1*c234-s1*s234)*c5)/2.0 + ((c1*c234+s1*s234)*c5)/2.0) -
00034 (s6*((s1*c234+c1*s234) - (s1*c234-c1*s234)))/2.0); T++;
00035 *T = (-(c6*((s1*c234+c1*s234) - (s1*c234-c1*s234)))/2.0 -
00036 s6*(s1*s5 + ((c1*c234-s1*s234)*c5)/2.0 + ((c1*c234+s1*s234)*c5)/2.0)); T++;
00037 *T = ((d5*(s1*c234-c1*s234))/2.0 - (d5*(s1*c234+c1*s234))/2.0 -
00038 d4*s1 + (d6*(c1*c234-s1*s234)*s5)/2.0 + (d6*(c1*c234+s1*s234)*s5)/2.0 -
00039 a2*c1*c2 - d6*c5*s1 - a3*c1*c2*c3 + a3*c1*s2*s3); T++;
00040 *T = c1*c5 + ((s1*c234+c1*s234)*s5)/2.0 + ((s1*c234-c1*s234)*s5)/2.0; T++;
00041 *T = (c6*(((s1*c234+c1*s234)*c5)/2.0 - c1*s5 + ((s1*c234-c1*s234)*c5)/2.0) +
00042 s6*((c1*c234-s1*s234)/2.0 - (c1*c234+s1*s234)/2.0)); T++;
00043 *T = (c6*((c1*c234-s1*s234)/2.0 - (c1*c234+s1*s234)/2.0) -
00044 s6*(((s1*c234+c1*s234)*c5)/2.0 - c1*s5 + ((s1*c234-c1*s234)*c5)/2.0)); T++;
00045 *T = ((d5*(c1*c234-s1*s234))/2.0 - (d5*(c1*c234+s1*s234))/2.0 + d4*c1 +
00046 (d6*(s1*c234+c1*s234)*s5)/2.0 + (d6*(s1*c234-c1*s234)*s5)/2.0 + d6*c1*c5 -
00047 a2*c2*s1 - a3*c2*c3*s1 + a3*s1*s2*s3); T++;
00048 *T = ((c234*c5-s234*s5)/2.0 - (c234*c5+s234*s5)/2.0); T++;
00049 *T = ((s234*c6-c234*s6)/2.0 - (s234*c6+c234*s6)/2.0 - s234*c5*c6); T++;
00050 *T = (s234*c5*s6 - (c234*c6+s234*s6)/2.0 - (c234*c6-s234*s6)/2.0); T++;
00051 *T = (d1 + (d6*(c234*c5-s234*s5))/2.0 + a3*(s2*c3+c2*s3) + a2*s2 -
00052 (d6*(c234*c5+s234*s5))/2.0 - d5*c234); T++;
00053 *T = 0.0; T++; *T = 0.0; T++; *T = 0.0; T++; *T = 1.0;
00054 }
00055
00056 int inverse(const double* T, double* q_sols, double q6_des) {
00057 int num_sols = 0;
00058 double T02 = -*T; T++; double T00 = *T; T++; double T01 = *T; T++; double T03 = -*T; T++;
00059 double T12 = -*T; T++; double T10 = *T; T++; double T11 = *T; T++; double T13 = -*T; T++;
00060 double T22 = *T; T++; double T20 = -*T; T++; double T21 = -*T; T++; double T23 = *T;
00061
00063 double q1[2];
00064 {
00065 double A = d6*T12 - T13;
00066 double B = d6*T02 - T03;
00067 double R = A*A + B*B;
00068 if(fabs(A) < ZERO_THRESH) {
00069 double div;
00070 if(fabs(fabs(d4) - fabs(B)) < ZERO_THRESH)
00071 div = -SIGN(d4)*SIGN(B);
00072 else
00073 div = -d4/B;
00074 double arcsin = asin(div);
00075 if(fabs(arcsin) < ZERO_THRESH)
00076 arcsin = 0.0;
00077 if(arcsin < 0.0)
00078 q1[0] = arcsin + 2.0*PI;
00079 else
00080 q1[0] = arcsin;
00081 q1[1] = PI - arcsin;
00082 }
00083 else if(fabs(B) < ZERO_THRESH) {
00084 double div;
00085 if(fabs(fabs(d4) - fabs(A)) < ZERO_THRESH)
00086 div = SIGN(d4)*SIGN(A);
00087 else
00088 div = d4/A;
00089 double arccos = acos(div);
00090 q1[0] = arccos;
00091 q1[1] = 2.0*PI - arccos;
00092 }
00093 else if(d4*d4 > R) {
00094 return num_sols;
00095 }
00096 else {
00097 double arccos = acos(d4 / sqrt(R)) ;
00098 double arctan = atan2(-B, A);
00099 double pos = arccos + arctan;
00100 double neg = -arccos + arctan;
00101 if(fabs(pos) < ZERO_THRESH)
00102 pos = 0.0;
00103 if(fabs(neg) < ZERO_THRESH)
00104 neg = 0.0;
00105 if(pos >= 0.0)
00106 q1[0] = pos;
00107 else
00108 q1[0] = 2.0*PI + pos;
00109 if(neg >= 0.0)
00110 q1[1] = neg;
00111 else
00112 q1[1] = 2.0*PI + neg;
00113 }
00114 }
00116
00118 double q5[2][2];
00119 {
00120 for(int i=0;i<2;i++) {
00121 double numer = (T03*sin(q1[i]) - T13*cos(q1[i])-d4);
00122 double div;
00123 if(fabs(fabs(numer) - fabs(d6)) < ZERO_THRESH)
00124 div = SIGN(numer) * SIGN(d6);
00125 else
00126 div = numer / d6;
00127 double arccos = acos(div);
00128 q5[i][0] = arccos;
00129 q5[i][1] = 2.0*PI - arccos;
00130 }
00131 }
00133
00134 {
00135 for(int i=0;i<2;i++) {
00136 for(int j=0;j<2;j++) {
00137 double c1 = cos(q1[i]), s1 = sin(q1[i]);
00138 double c5 = cos(q5[i][j]), s5 = sin(q5[i][j]);
00139 double q6;
00141 if(fabs(s5) < ZERO_THRESH)
00142 q6 = q6_des;
00143 else {
00144 q6 = atan2(SIGN(s5)*-(T01*s1 - T11*c1),
00145 SIGN(s5)*(T00*s1 - T10*c1));
00146 if(fabs(q6) < ZERO_THRESH)
00147 q6 = 0.0;
00148 if(q6 < 0.0)
00149 q6 += 2.0*PI;
00150 }
00152
00153 double q2[2], q3[2], q4[2];
00155 double c6 = cos(q6), s6 = sin(q6);
00156 double x04x = -s5*(T02*c1 + T12*s1) - c5*(s6*(T01*c1 + T11*s1) - c6*(T00*c1 + T10*s1));
00157 double x04y = c5*(T20*c6 - T21*s6) - T22*s5;
00158 double p13x = d5*(s6*(T00*c1 + T10*s1) + c6*(T01*c1 + T11*s1)) - d6*(T02*c1 + T12*s1) +
00159 T03*c1 + T13*s1;
00160 double p13y = T23 - d1 - d6*T22 + d5*(T21*c6 + T20*s6);
00161
00162 double c3 = (p13x*p13x + p13y*p13y - a2*a2 - a3*a3) / (2.0*a2*a3);
00163 if(fabs(fabs(c3) - 1.0) < ZERO_THRESH)
00164 c3 = SIGN(c3);
00165 else if(fabs(c3) > 1.0) {
00166
00167 continue;
00168 }
00169 double arccos = acos(c3);
00170 q3[0] = arccos;
00171 q3[1] = 2.0*PI - arccos;
00172 double denom = a2*a2 + a3*a3 + 2*a2*a3*c3;
00173 double s3 = sin(arccos);
00174 double A = (a2 + a3*c3), B = a3*s3;
00175 q2[0] = atan2((A*p13y - B*p13x) / denom, (A*p13x + B*p13y) / denom);
00176 q2[1] = atan2((A*p13y + B*p13x) / denom, (A*p13x - B*p13y) / denom);
00177 double c23_0 = cos(q2[0]+q3[0]);
00178 double s23_0 = sin(q2[0]+q3[0]);
00179 double c23_1 = cos(q2[1]+q3[1]);
00180 double s23_1 = sin(q2[1]+q3[1]);
00181 q4[0] = atan2(c23_0*x04y - s23_0*x04x, x04x*c23_0 + x04y*s23_0);
00182 q4[1] = atan2(c23_1*x04y - s23_1*x04x, x04x*c23_1 + x04y*s23_1);
00184 for(int k=0;k<2;k++) {
00185 if(fabs(q2[k]) < ZERO_THRESH)
00186 q2[k] = 0.0;
00187 else if(q2[k] < 0.0) q2[k] += 2.0*PI;
00188 if(fabs(q4[k]) < ZERO_THRESH)
00189 q4[k] = 0.0;
00190 else if(q4[k] < 0.0) q4[k] += 2.0*PI;
00191 q_sols[num_sols*6+0] = q1[i]; q_sols[num_sols*6+1] = q2[k];
00192 q_sols[num_sols*6+2] = q3[k]; q_sols[num_sols*6+3] = q4[k];
00193 q_sols[num_sols*6+4] = q5[i][j]; q_sols[num_sols*6+5] = q6;
00194 num_sols++;
00195 }
00196
00197 }
00198 }
00199 }
00200 return num_sols;
00201 }
00202 };
00203
00204 using namespace std;
00205 using namespace ur_kinematics;
00206
00207 #ifdef IKFAST_NAMESPACE
00208 namespace IKFAST_NAMESPACE {
00209 #endif
00210
00211 void to_mat44(double * mat4_4, const IkReal* eetrans, const IkReal* eerot)
00212 {
00213 for(int i=0; i< 3;++i){
00214 mat4_4[i*4+0] = eerot[i*3+0];
00215 mat4_4[i*4+1] = eerot[i*3+1];
00216 mat4_4[i*4+2] = eerot[i*3+2];
00217 mat4_4[i*4+3] = eetrans[i];
00218 }
00219 mat4_4[3*4+0] = 0;
00220 mat4_4[3*4+1] = 0;
00221 mat4_4[3*4+2] = 0;
00222 mat4_4[3*4+3] = 1;
00223
00224 }
00225
00226 void from_mat44(const double * mat4_4, IkReal* eetrans, IkReal* eerot)
00227 {
00228 for(int i=0; i< 3;++i){
00229 eerot[i*3+0] = mat4_4[i*4+0];
00230 eerot[i*3+1] = mat4_4[i*4+1];
00231 eerot[i*3+2] = mat4_4[i*4+2];
00232 eetrans[i] = mat4_4[i*4+3];
00233 }
00234 }
00235
00236
00237 IKFAST_API bool ComputeIk(const IkReal* eetrans, const IkReal* eerot, const IkReal* pfree, IkSolutionListBase<IkReal>& solutions) {
00238 if(!pfree) return false;
00239
00240 int n = GetNumJoints();
00241 double q_sols[8*6];
00242 double T[16];
00243 to_mat44(T, eetrans, eerot);
00244 int num_sols = 0;
00245 num_sols = inverse(T, q_sols,pfree[0]);
00246 for (int i=0; i < num_sols; ++i){
00247 std::vector<IkSingleDOFSolutionBase<IkReal> > vinfos(n);
00248 for (int j=0; j < n; ++j) vinfos[j].foffset = q_sols[i*n+j];
00249 std::vector<int> vfree(0);
00250 solutions.AddSolution(vinfos,vfree);
00251 }
00252
00253 return num_sols > 0;
00254 }
00255
00256 IKFAST_API void ComputeFk(const IkReal* j, IkReal* eetrans, IkReal* eerot)
00257 {
00258 double T[16];
00259 forward(j,T);
00260 from_mat44(T,eetrans,eerot);
00261 }
00262
00263 IKFAST_API int GetNumFreeParameters() { return 1; }
00264 IKFAST_API int* GetFreeParameters() { static int freeparams[] = {5}; return freeparams; }
00265 IKFAST_API int GetNumJoints() { return 6; }
00266
00267 IKFAST_API int GetIkRealSize() { return sizeof(IkReal); }
00268
00269 #ifdef IKFAST_NAMESPACE
00270 }
00271 #endif
00272
00273 #ifndef IKFAST_NO_MAIN
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 #endif