00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "Kuka361Kinematics.hpp"
00025
00026 #define M_PI_T2 M_PI*2
00027
00028 namespace OCL{
00029 using namespace KDL;
00030
00031 void Kuka361Kinematics::calc_eq(const JntArray& q,JntArray& q_eq)
00032 {
00033
00034
00035
00036
00037
00038 for(unsigned int i=0;i<3;i++)
00039 q_eq(i)=q(i);
00040
00041 double c5 = cos( q( 4 ) );
00042 double s5 = sin( q( 4 ) );
00043 double c5_eq = ( c5 + 3. ) / 4;
00044
00045 double alpha;
00046 if ( q( 4 ) < -epsilon ){
00047 alpha = atan2( -s5, 0.8660254037844386 * ( c5 - 1. ) );
00048 q_eq( 4 ) = -2. * acos( c5_eq );
00049 }else{
00050 if ( q( 4 ) < epsilon ){
00051 alpha = M_PI_2;
00052 q_eq( 4 ) = 0.0;
00053 }else{
00054 alpha = atan2( s5, 0.8660254037844386 * ( 1. - c5 ) );
00055 q_eq( 4 ) = 2. * acos( c5_eq );
00056 }
00057 }
00058
00059 q_eq( 3 ) = q( 3 ) + alpha;
00060 q_eq( 5 ) = q( 5 ) - alpha;
00061 }
00062
00063 void Kuka361Kinematics::calc_eq(const JntArrayVel& q,JntArrayVel& q_eq)
00064 {
00065 this->calc_eq(q.q,q_eq.q);
00066
00067
00068
00069
00070 for(unsigned int i=0;i<3;i++)
00071 q_eq.qdot(i)=q.qdot(i);
00072
00073
00074 double c5 = cos( q.q( 4 ) );
00075 double s5 = sin( q.q( 4 ) );
00076
00077 if ( q.q( 4 ) < -epsilon ){
00078 q_eq.qdot( 4 ) = -2. * s5 * q.qdot( 4 ) / sqrt( ( 1. - c5 ) * ( c5 + 7. ) );
00079 }else{
00080 if ( q.q( 4 ) < epsilon ){
00081 q_eq.qdot( 4 ) = q.qdot( 4 );
00082 }else{
00083 q_eq.qdot( 4 ) = 2. * s5 * q.qdot( 4 ) / sqrt( ( 1. - c5 ) * ( c5 + 7. ) );
00084 }
00085 }
00086
00087 double alphadot = -3.46410161513775 / ( 7. + c5 ) * q.qdot( 4 );
00088 q_eq.qdot( 3 ) = q.qdot( 3 ) + alphadot;
00089 q_eq.qdot( 5 ) = q.qdot( 5 ) - alphadot;
00090 }
00091
00092 void Kuka361Kinematics::calc_eq_inv(const JntArray& q_eq,JntArray& q)
00093 {
00094 for(unsigned int i=0;i<3;i++)
00095 q(i)=q_eq(i);
00096
00097 double c5 = 4. * cos ( q_eq( 4 ) / 2. ) - 3.;
00098
00099 if (c5 > 1.) c5 = 1; else if (c5 <-1.) c5=-1.;
00100
00101 double alpha;
00102
00103 if ( q_eq( 4 ) < -epsilon ){
00104 q( 4 ) = -acos( c5 );
00105 double s5 = sin( q( 4 ) );
00106 alpha = atan2 ( -s5, 0.8660254037844386 * ( c5 - 1. ) );
00107 }else{
00108 if ( q_eq( 4 ) < epsilon ){
00109 alpha = M_PI_2;
00110 q( 4 ) = 0.0;
00111 }else{
00112 q( 4 ) = acos( c5 );
00113 double s5 = sin( q( 4 ) );
00114 alpha = atan2 ( s5, 0.8660254037844386 * ( 1. - c5 ) );
00115 }
00116 }
00117
00118 q( 3 ) = q_eq( 3 ) - alpha;
00119
00120 if ( q( 3 ) >= M_PI )
00121 q( 3 ) -= M_PI_T2;
00122 else if ( q( 3 ) <= -M_PI )
00123 q( 3 ) += M_PI_T2;
00124
00125 q( 5 ) = q_eq( 5 ) + alpha;
00126
00127 if ( q( 5 ) >= M_PI )
00128 q( 5 ) -= M_PI_T2;
00129 else if ( q( 5 ) <= -M_PI )
00130 q( 5 ) += M_PI_T2;
00131
00132 }
00133
00134 void Kuka361Kinematics::calc_eq_inv(const JntArrayVel& q_eq,JntArrayVel& q)
00135 {
00136 this->calc_eq_inv(q_eq.q,q.q);
00137
00138
00139
00140
00141
00142 double s5 = sin( q_eq.q( 4 ) );
00143 double c5 = 4. * cos ( q_eq.q( 4 ) / 2. ) - 3.;
00144
00145 if ( q_eq.q( 4 ) < -epsilon )
00146 {
00147 q.qdot( 4 ) = -sqrt( ( 1. - c5 ) * ( 7. + c5 ) ) * q_eq.qdot( 4 ) / 2. / s5;
00148 }
00149
00150 else
00151 {
00152 if ( q_eq.q( 4 ) < epsilon )
00153 {
00154 q.qdot( 4 ) = q_eq.qdot( 4 );
00155 }
00156
00157 else
00158 {
00159 q.qdot( 4 ) = sqrt( ( 1. - c5 ) * ( 7. + c5 ) ) * q_eq.qdot( 4 ) / 2. / s5;
00160 }
00161 }
00162 double alphadot = -3.46410161513775 / ( 7. + c5 ) * q.qdot( 4 );
00163
00164 q.qdot( 3 ) = q_eq.qdot( 3 ) - alphadot;
00165 q.qdot( 5 ) = q_eq.qdot( 5 ) + alphadot;
00166 for(unsigned int i=0;i<3;i++)
00167 q.qdot(i)=q_eq.qdot(i);
00168
00169 }
00170
00171
00172
00173 int Kuka361Kinematics::JntToCart(const JntArray& q, Frame& p_out,int segmentNr)
00174 {
00175
00176 if(segmentNr!=-1)
00177 return -1;
00178
00179
00180 JntArray q_eq(6);
00181 this->calc_eq(q,q_eq);
00182
00183
00184
00185 double c1 = cos( q_eq( 0 ) );
00186 double s1 = sin( q_eq( 0 ) );
00187 double c23 = cos( q_eq( 1 ) + q_eq( 2 ) );
00188 double s23 = sin( q_eq( 1 ) + q_eq( 2 ) );
00189 double c4 = cos( q_eq( 3 ) );
00190 double s4 = sin( q_eq( 3 ) );
00191 double c5 = cos( q_eq( 4 ) );
00192 double s5 = sin( q_eq( 4 ) );
00193 double c6 = cos( q_eq( 5 ) );
00194 double s6 = sin( q_eq( 5 ) );
00195 double s5c6 = s5 * c6;
00196 double s5s6 = s5 * s6;
00197 double c4s5 = c4 * s5;
00198 double s4s5 = s4 * s5;
00199 double c1c23 = c1 * c23;
00200 double c1s23 = c1 * s23;
00201 double s1c23 = s1 * c23;
00202 double s1s23 = s1 * s23;
00203
00204 p_out.M( 1, 0 ) = s4 * c5 * s6 - c4 * c6;
00205 p_out.M( 2, 0 ) = c4 * c5 * s6 + s4 * c6;
00206 p_out.M( 0, 0 ) = -s1c23 * p_out.M( 2, 0 ) - c1 * p_out.M( 1, 0 ) + s1s23 * s5s6;
00207 p_out.M( 1, 0 ) = c1c23 * p_out.M( 2, 0 ) - s1 * p_out.M( 1, 0 ) - c1s23 * s5s6;
00208 p_out.M( 2, 0 ) = - s23 * p_out.M( 2, 0 ) - c23 * s5s6;
00209
00210 p_out.M( 1, 1 ) = s4 * c5 * c6 + c4 * s6;
00211 p_out.M( 2, 1 ) = c4 * c5 * c6 - s4 * s6;
00212 p_out.M( 0, 1 ) = -s1c23 * p_out.M( 2, 1 ) - c1 * p_out.M( 1, 1 ) + s1s23 * s5c6;
00213 p_out.M( 1, 1 ) = c1c23 * p_out.M( 2, 1 ) - s1 * p_out.M( 1, 1 ) - c1s23 * s5c6;
00214 p_out.M( 2, 1 ) = - s23 * p_out.M( 2, 1 ) - c23 * s5c6;
00215
00216 p_out.M( 0, 2 ) = -s1c23 * c4s5 - c1 * s4s5 - s1s23 * c5;
00217 p_out.M( 1, 2 ) = c1c23 * c4s5 - s1 * s4s5 + c1s23 * c5;
00218 p_out.M( 2, 2 ) = - s23 * c4s5 + c23 * c5;
00219
00220
00221 double dWv = cos( q_eq( 1 ) ) * l2 + c23 * l3;
00222
00223 double dWh = sin( q_eq( 1 ) ) * l2 + s23 * l3;
00224
00225
00226 Vector P6 = p_out.M.UnitZ()*l6;
00227
00228
00229 Vector Pw(- s1 * dWh, c1 * dWh, l1 + dWv);
00230
00231
00232 p_out.p = P6+Pw;
00233
00234 return 0;
00235
00236 }
00237
00238 int Kuka361Kinematics::JntToCart(const JntArrayVel& q_in, FrameVel& out,int segmentNr)
00239 {
00240
00241 if(segmentNr!=-1)
00242 return -1;
00243
00244 JntArrayVel q_eq( 6 );
00245 this->calc_eq(q_in,q_eq);
00246
00247 double c1 = cos( q_eq.q( 0 ) );
00248 double s1 = sin( q_eq.q( 0 ) );
00249 double c23 = cos( q_eq.q( 1 ) + q_eq.q( 2 ) );
00250 double s23 = sin( q_eq.q( 1 ) + q_eq.q( 2 ) );
00251 double c4 = cos( q_eq.q( 3 ) );
00252 double s4 = sin( q_eq.q( 3 ) );
00253 double c5 = cos( q_eq.q( 4 ) );
00254 double s5 = sin( q_eq.q( 4 ) );
00255 double c4s5 = c4 * s5;
00256 double s4s5 = s4 * s5;
00257
00258 Frame pos;
00259 Twist vel;
00260 this->JntToCart(q_in.q,pos);
00261
00262
00263 double dWv = cos( q_eq.q( 1 ) ) * l2 + c23 * l3;
00264
00265 double dWh = sin( q_eq.q( 1 ) ) * l2 + s23 * l3;
00266
00267
00268 Vector Pw(- s1 * dWh, c1 * dWh, l1 + dWv);
00269
00270
00271 double Wwy = -s4 * q_eq.qdot( 4 ) + c4s5 * q_eq.qdot( 5 );
00272 double Wwz = q_eq.qdot( 3 ) + c5 * q_eq.qdot( 5 );
00273
00274 double Wx = -c4 * q_eq.qdot( 4 ) - s4s5 * q_eq.qdot( 5 ) - q_eq.qdot( 1 ) - q_eq.qdot( 2 );
00275 double Wy = c23 * Wwy + s23 * Wwz;
00276
00277 vel.rot.x(c1 * Wx - s1 * Wy);
00278 vel.rot.y(c1 * Wy + s1 * Wx);
00279 vel.rot.z(q_eq.qdot( 0 ) + c23 * Wwz - s23 * Wwy);
00280
00281
00282 double Vx = -dWh * q_eq.qdot( 0 );
00283 double Vy = dWv * q_eq.qdot( 1 ) + l3 * c23 * q_eq.qdot( 2 );
00284
00285 vel.vel.x(c1 * Vx - s1 * Vy - vel.rot.y()*Pw.z() + vel.rot.z()*Pw.y());
00286 vel.vel.y(c1 * Vy + s1 * Vx - vel.rot.z()*Pw.x() + vel.rot.x()*Pw.z());
00287 vel.vel.z(-dWh * q_eq.qdot( 1 ) - l3 * s23 * q_eq.qdot( 2 )
00288 - vel.rot.x()*Pw.y() + vel.rot.y()*Pw.x());
00289
00290 out=FrameVel(pos,vel);
00291
00292 return 0;
00293 }
00294
00295 int Kuka361Kinematics::CartToJnt(const JntArray& q_in, const Twist& v_in, JntArray& qdot_out)
00296 {
00297
00298
00299
00300
00301
00302 JntArrayVel q_eq(6);
00303 JntArrayVel q(6);
00304
00305 calc_eq(q_in,q_eq.q);
00306
00307
00308
00309 double c1 = cos( q_eq.q( 0 ) );
00310 double s1 = sin( q_eq.q( 0 ) );
00311 double s3 = sin( q_eq.q( 2 ) );
00312 double c23 = cos( q_eq.q( 1 ) + q_eq.q( 2 ) );
00313 double s23 = sin( q_eq.q( 1 ) + q_eq.q( 2 ) );
00314 double c4 = cos( q_eq.q( 3 ) );
00315 double s4 = sin( q_eq.q( 3 ) );
00316 double c5 = cos( q_eq.q( 4 ) );
00317 double s5 = sin( q_eq.q( 4 ) );
00318
00319
00320 double dWv = cos( q_eq.q( 1 ) ) * l2 + c23 * l3;
00321
00322 double dWh = sin( q_eq.q( 1 ) ) * l2 + s23 * l3;
00323
00324
00325 Vector Pw( - s1 * dWh, c1 * dWh, l1 + dWv);
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 Vector Vw(v_in.vel.x() + v_in.rot.y() * Pw.z() - v_in.rot.z() * Pw.y(),
00337 v_in.vel.y() + v_in.rot.z() * Pw.x() - v_in.rot.x() * Pw.z(),
00338 v_in.vel.z() + v_in.rot.x() * Pw.y() - v_in.rot.y() * Pw.x());
00339
00340
00341
00342
00343 q_eq.qdot( 0 ) = -( c1 * Vw.x() + s1 * Vw.y() ) / dWh;
00344
00345 double temp3 = c1 * Vw.y() - s1 * Vw.x();
00346
00347 q_eq.qdot( 1 ) = ( s23 * temp3 + c23 * Vw.z() ) / l2 / s3;
00348
00349 q_eq.qdot( 2 ) = -( dWh * temp3 + dWv * Vw.z() ) / l2 / l3 / s3;
00350
00351
00352 Vector Ww;
00353 Ww.x( c1 * v_in.rot.y() - s1 * v_in.rot.x());
00354 Ww.y(q_eq.qdot( 1 ) + q_eq.qdot( 2 ) + c1 * v_in.rot.x() + s1 * v_in.rot.y());
00355 Ww.z(c23 * Ww.x() - s23 * ( v_in.rot.z() - q_eq.qdot( 0 ) ));
00356
00357
00358 q_eq.qdot( 4 ) = -c4 * Ww.y() - s4 * Ww.z();
00359 q_eq.qdot( 5 ) = ( c4 * Ww.z() - s4 * Ww.y() ) / s5;
00360 q_eq.qdot( 3 ) = c23 * ( v_in.rot.z() - q_eq.qdot( 0 ) ) + s23 * Ww.x() - c5 * q_eq.qdot( 5 );
00361
00362
00363
00364
00365
00366
00367 calc_eq_inv(q_eq,q);
00368 qdot_out=q.qdot;
00369
00370 return 0;
00371 };
00372
00373 int Kuka361Kinematics::CartToJnt(const JntArray& q_init, const FrameVel& v_in, JntArrayVel& q_out)
00374 {
00375 return 0;
00376 };
00377
00378 int Kuka361Kinematics::JntToJac(const JntArray& q,Jacobian& J)
00379 {
00380
00381 double c5 = cos( q( 4 ) );
00382 double s5 = sin( q( 4 ) );
00383
00384 JntArray q_eq(6);
00385 calc_eq(q,q_eq);
00386
00387 double A;
00388 if ( q( 4 ) < -epsilon ){
00389 A = -2. * s5 / sqrt( ( 1. - c5 ) * ( c5 + 7. ) );
00390 }else{
00391 if ( q( 4 ) < epsilon ){
00392 A = 1.;
00393 }else{
00394 A = 2. * s5 / sqrt( ( 1. - c5 ) * ( c5 + 7. ) );
00395 }
00396 }
00397
00398 double B = 3.46410161513775 / ( 7. + c5 );
00399
00400 double c1 = cos( q_eq( 0 ) );
00401 double s1 = sin( q_eq( 0 ) );
00402 double c23 = cos( q_eq( 1 ) + q_eq( 2 ) );
00403 double s23 = sin( q_eq( 1 ) + q_eq( 2 ) );
00404 double c4 = cos( q_eq( 3 ) );
00405 double s4 = sin( q_eq( 3 ) );
00406 c5 = cos( q_eq( 4 ) );
00407 s5 = sin( q_eq( 4 ) );
00408 double c4s5 = c4 * s5;
00409 double s4s5 = s4 * s5;
00410 double c1c23 = c1 * c23;
00411 double c1s23 = c1 * s23;
00412 double s1c23 = s1 * c23;
00413 double s1s23 = s1 * s23;
00414
00415 double dWv = cos( q_eq( 1 ) ) * l2 + c23 * l3;
00416 double dWh = sin( q_eq( 1 ) ) * l2 + s23 * l3;
00417
00418 Vector Pw(-s1 * dWh, c1 * dWh, l1 + dWv);
00419
00420
00421
00422 J( 3 , 0 ) = J( 4 , 0 ) = J( 5 , 1 ) = J( 5 , 2 ) = 0.;
00423
00424 J( 3 , 1 ) = J( 3 , 2 ) = - c1;
00425 J( 3 , 3 ) = - s1s23;
00426 J( 3 , 4 ) = - c1 * c4 + s1c23 * s4;
00427 J( 3 , 5 ) = - s1 * ( c23 * c4s5 + s23 * c5 ) - c1 * s4s5;
00428
00429 J( 4 , 1 ) = J( 4 , 2 ) = - s1;
00430 J( 4 , 3 ) = c1s23;
00431 J( 4 , 4 ) = - s1 * c4 - c1c23 * s4;
00432 J( 4 , 5 ) = - s1 * s4s5 + c4s5 * c1c23 + c1s23 * c5;
00433
00434 J( 5 , 0 ) = 1.;
00435 J( 5 , 3 ) = c23;
00436 J( 5 , 4 ) = s23 * s4;
00437 J( 5 , 5 ) = c23 * c5 - s23 * c4s5;
00438
00439
00440 J( 0 , 0 ) = - c1 * dWh + Pw.y();
00441 J( 0 , 1 ) = J( 0 , 2 ) = s1 * Pw.z();
00442 J( 0 , 1 ) -= s1 * dWv;
00443 J( 0 , 2 ) -= s1c23 * l3;
00444 J( 0 , 3 ) = J( 5 , 3 ) * Pw.y() - J( 4 , 3 ) * Pw.z();
00445 J( 0 , 4 ) = J( 5 , 4 ) * Pw.y() - J( 4 , 4 ) * Pw.z();
00446 J( 0 , 5 ) = J( 5 , 5 ) * Pw.y() - J( 4 , 5 ) * Pw.z();
00447
00448 J( 1 , 0 ) = -s1 * dWh - Pw.x();
00449 J( 1 , 1 ) = J( 1 , 2 ) = -c1 * Pw.z();
00450 J( 1 , 1 ) += c1 * dWv;
00451 J( 1 , 2 ) += c1c23 * l3;
00452 J( 1 , 3 ) = J( 3 , 3 ) * Pw.z() - J( 5 , 3 ) * Pw.x();
00453 J( 1 , 4 ) = J( 3 , 4 ) * Pw.z() - J( 5 , 4 ) * Pw.x();
00454 J( 1 , 5 ) = J( 3 , 5 ) * Pw.z() - J( 5 , 5 ) * Pw.x();
00455
00456 J( 2 , 0 ) = 0.;
00457 J( 2 , 1 ) = J( 2 , 2 ) = c1 * Pw.y() - s1 * Pw.x();
00458 J( 2 , 1 ) -= dWh;
00459 J( 2 , 2 ) -= s23 * l3;
00460 J( 2 , 3 ) = J( 4 , 3 ) * Pw.x() - J( 3 , 3 ) * Pw.y();
00461 J( 2 , 4 ) = J( 4 , 4 ) * Pw.x() - J( 3 , 4 ) * Pw.y();
00462 J( 2 , 5 ) = J( 4 , 5 ) * Pw.x() - J( 3 , 5 ) * Pw.y();
00463
00464
00465
00466 for ( unsigned int i = 0;i < 6;i++ )
00467 {
00468 J( i , 4 ) = A * J( i , 4 ) + B * ( -J( i , 3 ) + J( i , 5 ) );
00469 }
00470
00471 return 0;
00472 }
00473 }
00474
00475