00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00065
00066 static const char rcsid[] = "$Id: invkine.cpp,v 1.8 2006/05/16 16:11:15 gourdeau Exp $";
00067
00068 #include <stdexcept>
00069 #include "robot.h"
00070
00071 #ifdef use_namespace
00072 namespace ROBOOP {
00073 using namespace NEWMAT;
00074 #endif
00075
00076 #define NITMAX 1000
00077 #ifdef USING_FLOAT //from newmat's include.h
00078 # define ITOL 1e-4
00079 #else
00080 # define ITOL 1e-6
00081 #endif
00082
00083 ReturnMatrix Robot_basic::inv_kin(const Matrix & Tobj, const int mj)
00085 {
00086 bool converge = false;
00087 return inv_kin(Tobj, mj, dof, converge);
00088 }
00089
00090
00091 ReturnMatrix Robot_basic::inv_kin(const Matrix & Tobj, const int mj, const int endlink, bool & converge)
00103 {
00104 ColumnVector qPrev, qout, dq, q_tmp;
00105 Matrix B, M;
00106 UpperTriangularMatrix U;
00107
00108 qPrev = get_available_q();
00109 qout = qPrev;
00110 q_tmp = qout;
00111
00112 converge = false;
00113 if(mj == 0) {
00114 Matrix Ipd, A, B(6,1);
00115 for(int j = 1; j <= NITMAX; j++) {
00116 Ipd = (kine(endlink)).i()*Tobj;
00117 B(1,1) = Ipd(1,4);
00118 B(2,1) = Ipd(2,4);
00119 B(3,1) = Ipd(3,4);
00120 B(4,1) = Ipd(3,2);
00121 B(5,1) = Ipd(1,3);
00122 B(6,1) = Ipd(2,1);
00123 A = jacobian(endlink,endlink);
00124 QRZ(A,U);
00125 QRZ(A,B,M);
00126 dq = U.i()*M;
00127
00128 while(dq.MaximumAbsoluteValue() > 1)
00129 dq /= 10;
00130
00131 for(int k = 1; k<= dq.nrows(); k++)
00132 qout(k)+=dq(k);
00133 set_q(qout);
00134
00135 if (dq.MaximumAbsoluteValue() < ITOL)
00136 {
00137 converge = true;
00138 break;
00139 }
00140 }
00141 } else {
00142 int adof=get_available_dof(endlink);
00143 Matrix A(12,adof);
00144 for(int j = 1; j <= NITMAX; j++) {
00145 B = (Tobj-kine(endlink)).SubMatrix(1,3,1,4).AsColumn();
00146 int k=1;
00147 for(int i = 1; i<=dof && k<=adof; i++) {
00148 if(links[i].immobile)
00149 continue;
00150 A.SubMatrix(1,12,k,k) = dTdqi(i).SubMatrix(1,3,1,4).AsColumn();
00151 k++;
00152 }
00153 QRZ(A,U);
00154 QRZ(A,B,M);
00155 dq = U.i()*M;
00156
00157 while(dq.MaximumAbsoluteValue() > 1)
00158 dq /= 10;
00159
00160 for(k = 1; k<=adof; k++)
00161 qout(k)+=dq(k);
00162 set_q(qout);
00163 if (dq.MaximumAbsoluteValue() < ITOL)
00164 {
00165 converge = true;
00166 break;
00167 }
00168 }
00169 }
00170
00171 if(converge)
00172 {
00173
00174 for(int i = 1; i <= dof; i++)
00175 {
00176 if(links[i].immobile)
00177 continue;
00178 if(links[i].get_joint_type() == 0) {
00179 qout(i) = fmod(qout(i), 2*M_PI);
00180 }
00181 }
00182 set_q(qPrev);
00183 qout.Release();
00184 return qout;
00185 }
00186 else
00187 {
00188 set_q(qPrev);
00189 q_tmp.Release();
00190 return q_tmp;
00191 }
00192 }
00193
00194
00195
00196 ReturnMatrix Robot::inv_kin(const Matrix & Tobj, const int mj)
00198 {
00199 bool converge = false;
00200 return inv_kin(Tobj, mj, dof, converge);
00201 }
00202
00203
00204 ReturnMatrix Robot::inv_kin(const Matrix & Tobj, const int mj, const int endlink, bool & converge)
00212 {
00213 switch (robotType) {
00214 case RHINO:
00215 return inv_kin_rhino(Tobj, converge);
00216 break;
00217 case PUMA:
00218 return inv_kin_puma(Tobj, converge);
00219 break;
00220 case SCHILLING:
00221 return inv_kin_schilling(Tobj, converge);
00222 break;
00223 default:
00224 return Robot_basic::inv_kin(Tobj, mj, endlink, converge);
00225 }
00226 }
00227
00228
00229 ReturnMatrix Robot::inv_kin_rhino(const Matrix & Tobj, bool & converge)
00235 {
00236 ColumnVector qout(5), q_actual;
00237 q_actual = get_q();
00238
00239 try
00240 {
00241 Real theta[6] , diff1, diff2, tmp,
00242 angle , L=0.0 , M=0.0 , K=0.0 , H=0.0 , G=0.0 ;
00243
00244
00245 theta[0] = atan2(Tobj(2,4),
00246 Tobj(1,4));
00247
00248 theta[1] = atan2(-Tobj(2,4),
00249 -Tobj(1,4)) ;
00250
00251 diff1 = fabs(q_actual(1)-theta[0]) ;
00252 if (diff1 > M_PI)
00253 diff1 = 2*M_PI - diff1;
00254
00255 diff2 = fabs(q_actual(1)-theta[1]);
00256 if (diff2 > M_PI)
00257 diff2 = 2*M_PI - diff2 ;
00258
00259
00260 if (diff1 < diff2)
00261 theta[1] = theta[0] ;
00262
00263 theta[5] = atan2(sin(theta[1])*Tobj(1,1) - cos(theta[1])*Tobj(2,1),
00264 sin(theta[1])*Tobj(1,2) - cos(theta[1])*Tobj(2,2));
00265
00266
00267 angle = atan2(-1*cos(theta[1])*Tobj(1,3) - sin(theta[1])*Tobj(2,3),
00268 -1*Tobj(3,3));
00269
00270 L = cos(theta[1])*Tobj(1,4) +
00271 sin(theta[1])*Tobj(2,4) +
00272 links[5].d*sin(angle) -
00273 links[4].a*cos(angle);
00274 M = links[1].d -
00275 Tobj(3,4) -
00276 links[5].d*cos(angle) -
00277 links[4].a*sin(angle);
00278 K = (L*L + M*M - links[3].a*links[3].a -
00279 links[2].a*links[2].a) /
00280 (2 * links[3].a * links[2].a);
00281
00282 tmp = 1-K*K;
00283 if (tmp < 0)
00284 throw out_of_range("sqrt of negative number not allowed.");
00285
00286 theta[0] = atan2( sqrt(tmp) , K );
00287 theta[3] = atan2( -sqrt(tmp) , K );
00288
00289 diff1 = fabs(q_actual(3)-theta[0]) ;
00290 if (diff1 > M_PI)
00291 diff1 = 2*M_PI - diff1 ;
00292
00293 diff2 = fabs(q_actual(3)-theta[3]);
00294 if (diff2 > M_PI)
00295 diff2 = 2*M_PI - diff2 ;
00296
00297 if (diff1 < diff2)
00298 theta[3] = theta[0] ;
00299
00300 H = cos(theta[3]) * links[3].a + links[2].a;
00301 G = sin(theta[3]) * links[3].a;
00302
00303 theta[2] = atan2( M , L ) - atan2( G , H );
00304 theta[4] = atan2( -1*cos(theta[1])*Tobj(1,3) - sin(theta[1])*Tobj(2,3) ,
00305 -1*Tobj(3,3)) - theta[2] - theta[3] ;
00306
00307 qout(1) = theta[1];
00308 qout(2) = theta[2];
00309 qout(3) = theta[3];
00310 qout(4) = theta[4];
00311 qout(5) = theta[5];
00312
00313 converge = true;
00314 }
00315 catch(std::out_of_range & e)
00316 {
00317 converge = false;
00318 qout = q_actual;
00319 }
00320
00321 qout.Release();
00322 return qout;
00323 }
00324
00325
00326 ReturnMatrix Robot::inv_kin_puma(const Matrix & Tobj, bool & converge)
00332 {
00333 ColumnVector qout(6), q_actual;
00334 q_actual = get_q();
00335
00336 try
00337 {
00338 Real theta[7] , diff1, diff2, tmp,
00339 A = 0.0 , B = 0.0 , C = 0.0 , D =0.0, Ro = 0.0,
00340 H = 0.0 , L = 0.0 , M = 0.0;
00341
00342
00343
00344 if (links[6].d)
00345 {
00346 ColumnVector tmpd6(3); Matrix tmp;
00347 tmpd6(1)=0; tmpd6(2)=0; tmpd6(3)=links[6].d;
00348 tmpd6 = Tobj.SubMatrix(1,3,1,3)*tmpd6;
00349 Tobj.SubMatrix(1,3,4,4) = Tobj.SubMatrix(1,3,4,4) - tmpd6;
00350 }
00351
00352 tmp = Tobj(2,4)*Tobj(2,4) + Tobj(1,4)*Tobj(1,4);
00353 if (tmp < 0)
00354 throw std::out_of_range("sqrt of negative number not allowed.");
00355
00356 Ro = sqrt(tmp);
00357 D = (links[2].d+links[3].d) / Ro;
00358
00359 tmp = 1-D*D;
00360 if (tmp < 0)
00361 throw std::out_of_range("sqrt of negative number not allowed.");
00362
00363
00364 theta[0] = atan2(Tobj(2,4),Tobj(1,4)) - atan2(D, sqrt(tmp));
00365
00366 theta[1] = atan2(Tobj(2,4),Tobj(1,4)) - atan2(D , -sqrt(tmp));
00367
00368 diff1 = fabs(q_actual(1)-theta[0]);
00369 if (diff1 > M_PI)
00370 diff1 = 2*M_PI - diff1;
00371
00372 diff2 = fabs(q_actual(1)-theta[1]);
00373 if (diff2 > M_PI)
00374 diff2 = 2*M_PI - diff2;
00375
00376
00377 if (diff1 < diff2)
00378 theta[1] = theta[0];
00379
00380 tmp = links[3].a*links[3].a + links[4].d*links[4].d;
00381 if (tmp < 0)
00382 throw std::out_of_range("sqrt of negative number not allowed.");
00383
00384 Ro = sqrt(tmp);
00385 B = atan2(links[4].d,links[3].a);
00386 C = Tobj(1,4)*Tobj(1,4) +
00387 Tobj(2,4)*Tobj(2,4) +
00388 (Tobj(3,4)-links[1].d)*(Tobj(3,4)-links[1].d) -
00389 (links[2].d + links[3].d)*(links[2].d + links[3].d) -
00390 links[2].a*links[2].a -
00391 links[3].a*links[3].a -
00392 links[4].d*links[4].d;
00393 A = C / (2*links[2].a);
00394
00395 tmp = 1-A/Ro*A/Ro;
00396 if (tmp < 0)
00397 throw std::out_of_range("sqrt of negative number not allowed.");
00398
00399 theta[0] = atan2(sqrt(tmp) , A/Ro) + B;
00400 theta[3] = atan2(-sqrt(tmp) , A/Ro) + B;
00401
00402 diff1 = fabs(q_actual(3)-theta[0]);
00403 if (diff1 > M_PI)
00404 diff1 = 2*M_PI - diff1 ;
00405
00406 diff2 = fabs(q_actual(3)-theta[3]);
00407 if (diff2 > M_PI)
00408 diff1 = 2*M_PI - diff2;
00409
00410
00411 if (diff1 < diff2)
00412 theta[3] = theta[0];
00413
00414 H = cos(theta[1])*Tobj(1,4) + sin(theta[1])*Tobj(2,4);
00415 L = sin(theta[3])*links[4].d + cos(theta[3])*links[3].a + links[2].a;
00416 M = cos(theta[3])*links[4].d - sin(theta[3])*links[3].a;
00417
00418 theta[2] = atan2( M , L ) - atan2(Tobj(3,4)-links[1].d , H );
00419
00420 theta[0] = atan2( -sin(theta[1])*Tobj(1,3) + cos(theta[1])*Tobj(2,3) ,
00421 cos(theta[2] + theta[3]) *
00422 (cos(theta[1]) * Tobj(1,3) + sin(theta[1])*Tobj(2,3))
00423 - (sin(theta[2]+theta[3])*Tobj(3,3)) );
00424
00425 theta[4] = atan2(-1*(-sin(theta[1])*Tobj(1,3) + cos(theta[1])*Tobj(2,3)),
00426 -cos(theta[2] + theta[3]) *
00427 (cos(theta[1]) * Tobj(1,3) + sin(theta[1])*Tobj(2,3))
00428 + (sin(theta[2]+theta[3])*Tobj(3,3)) );
00429
00430 diff1 = fabs(q_actual(4)-theta[0]);
00431 if (diff1 > M_PI)
00432 diff1 = 2*M_PI - diff1;
00433
00434 diff2 = fabs(q_actual(4)-theta[4]);
00435 if (diff2 > M_PI)
00436 diff2 = 2*M_PI - diff2;
00437
00438
00439 if (diff1 < diff2)
00440 theta[4] = theta[0];
00441
00442 theta[5] = atan2( cos(theta[4]) *
00443 ( cos(theta[2] + theta[3]) *
00444 (cos(theta[1]) * Tobj(1,3)
00445 + sin(theta[1])*Tobj(2,3))
00446 - (sin(theta[2]+theta[3])*Tobj(3,3)) ) +
00447 sin(theta[4])*(-sin(theta[1])*Tobj(1,3)
00448 + cos(theta[1])*Tobj(2,3)) ,
00449 sin(theta[2]+theta[3]) * (cos(theta[1]) * Tobj(1,3)
00450 + sin(theta[1])*Tobj(2,3) )
00451 + (cos(theta[2]+theta[3])*Tobj(3,3)) );
00452
00453 theta[6] = atan2( -sin(theta[4])
00454 * ( cos(theta[2] + theta[3]) *
00455 (cos(theta[1]) * Tobj(1,1)
00456 + sin(theta[1])*Tobj(2,1))
00457 - (sin(theta[2]+theta[3])*Tobj(3,1))) +
00458 cos(theta[4])*(-sin(theta[1])*Tobj(1,1)
00459 + cos(theta[1])*Tobj(2,1)),
00460 -sin(theta[4]) * ( cos(theta[2] + theta[3]) *
00461 (cos(theta[1]) * Tobj(1,2)
00462 + sin(theta[1])*Tobj(2,2))
00463 - (sin(theta[2]+theta[3])*Tobj(3,2))) +
00464 cos(theta[4])*(-sin(theta[1])*Tobj(1,2)
00465 + cos(theta[1])*Tobj(2,2)) );
00466
00467 qout(1) = theta[1];
00468 qout(2) = theta[2];
00469 qout(3) = theta[3];
00470 qout(4) = theta[4];
00471 qout(5) = theta[5];
00472 qout(6) = theta[6];
00473
00474 converge = true;
00475 }
00476 catch(std::out_of_range & e)
00477 {
00478 converge = false;
00479 qout = q_actual;
00480 }
00481
00482 qout.Release();
00483 return qout;
00484 }
00485
00486 ReturnMatrix Robot::inv_kin_schilling(const Matrix & Tobj, bool & converge)
00492 {
00493 ColumnVector qout(6), q_actual;
00494 q_actual = get_q();
00495
00496 try
00497 {
00498 Real theta[7], K=0.0, A=0.0, B=0.0, C=0.0, D=0.0, tmp=0.0, theta234 , diff1, diff2;
00499
00500 if (links[6].d)
00501 {
00502 ColumnVector tmpd6(3);
00503 Matrix tmp;
00504 tmpd6(1)=0;
00505 tmpd6(2)=0;
00506 tmpd6(3)=links[6].d;
00507 tmpd6 = Tobj.SubMatrix(1,3,1,3)*tmpd6;
00508 Tobj.SubMatrix(1,3,4,4) = Tobj.SubMatrix(1,3,4,4) - tmpd6;
00509 }
00510
00511 theta[1] = atan2(Tobj(2,4),Tobj(1,4));
00512
00513 theta[0] = atan2(-Tobj(2,4),-Tobj(1,4));
00514
00515 diff1 = fabs(q_actual(1)-theta[0]);
00516 if (diff1 > M_PI)
00517 diff1 = 2*M_PI - diff1;
00518
00519 diff2 = fabs(q_actual(1)-theta[1]);
00520 if (diff2 > M_PI)
00521 diff2 = 2*M_PI - diff2;
00522
00523
00524 if (diff1 < diff2)
00525 theta[1] = theta[0];
00526
00527
00528 theta234 = atan2( Tobj(3,3) , cos(theta[1])*Tobj(1,3) + sin(theta[1])*Tobj(2,3) );
00529
00530 theta[5] = atan2( (cos(theta234)*(cos(theta[1])*Tobj(1,3) +
00531 sin(theta[1])*Tobj(2,3)) + sin(theta234)*Tobj(3,3)),
00532 (sin(theta[1])*Tobj(1,3) - cos(theta[1])*Tobj(2,3)));
00533
00534 theta[6] = atan2( (-sin(theta234)*(cos(theta[1])*Tobj(1,1) +
00535 sin(theta[1])*Tobj(2,1)) + cos(theta234)*Tobj(3,1)),
00536 (-sin(theta234)*(cos(theta[1])*Tobj(1,2) + sin(theta[1])*Tobj(2,2)) +
00537 cos(theta234)*Tobj(3,2)));
00538
00539 A= cos(theta[1])*Tobj(1,4) + sin(theta[1])*Tobj(2,4) - links[1].a -
00540 links[4].a*cos(theta234);
00541
00542 B= Tobj(3,4) - links[1].d - links[4].a*sin(theta234);
00543
00544
00545 K= ( A*A + B*B - (links[3].a*links[3].a) - (links[2].a*links[2].a) ) /
00546 ( 2*links[2].a*links[3].a );
00547
00548 tmp = 1-K*K;
00549 if (tmp < 0)
00550 throw std::out_of_range("sqrt of negative number not allowed.");
00551
00552 theta[3] = atan2(sqrt(tmp),K);
00553 theta[0] = atan2(-sqrt(tmp),K);
00554
00555 diff1 = fabs(q_actual(3)-theta[0]);
00556 if (diff1 > M_PI)
00557 diff1 = 2*M_PI - diff1;
00558
00559 diff2 = fabs(q_actual(3)-theta[3]);
00560 if (diff2 > M_PI)
00561 diff2 = 2*M_PI - diff2;
00562
00563
00564 if (diff1 < diff2)
00565 theta[3] = theta[0];
00566
00567 C = cos(theta[3])*links[3].a + links[2].a;
00568 D = sin(theta[3])*links[3].a;
00569
00570 theta[2] = atan2(B,A) - atan2(D,C);
00571
00572 theta[4] = theta234 - theta[2] - theta[3];
00573
00574 qout(1) = theta[1];
00575 qout(2) = theta[2];
00576 qout(3) = theta[3];
00577 qout(4) = theta[4];
00578 qout(5) = theta[5];
00579 qout(6) = theta[6];
00580 converge = true;
00581 }
00582 catch(std::out_of_range & e)
00583 {
00584 converge = false;
00585 qout = q_actual;
00586 }
00587
00588 qout.Release();
00589 return qout;
00590 }
00591
00592
00593
00594
00595 ReturnMatrix mRobot::inv_kin(const Matrix & Tobj, const int mj)
00597 {
00598 bool converge = false;
00599 return inv_kin(Tobj, mj, dof, converge);
00600 }
00601
00602
00603 ReturnMatrix mRobot::inv_kin(const Matrix & Tobj, const int mj, const int endlink, bool & converge)
00611 {
00612 switch (robotType) {
00613 case RHINO:
00614 return inv_kin_rhino(Tobj, converge);
00615 break;
00616 case PUMA:
00617 return inv_kin_puma(Tobj, converge);
00618 break;
00619 case SCHILLING:
00620 return inv_kin_schilling(Tobj, converge);
00621 break;
00622 default:
00623 return Robot_basic::inv_kin(Tobj, mj, endlink, converge);
00624 }
00625 }
00626
00627
00628 ReturnMatrix mRobot::inv_kin_rhino(const Matrix & Tobj, bool & converge)
00634 {
00635 ColumnVector qout(5), q_actual;
00636 q_actual = get_q();
00637
00638 try
00639 {
00640 Real theta[6] , diff1, diff2, tmp,
00641 angle , L=0.0 , M=0.0 , K=0.0 , H=0.0 , G=0.0;
00642
00643 if (links[6].d > 0)
00644 {
00645 ColumnVector tmpd6(3);
00646 tmpd6(1)=0; tmpd6(2)=0; tmpd6(3)=links[6].d;
00647 tmpd6 = Tobj.SubMatrix(1,3,1,3)*tmpd6;
00648 Tobj.SubMatrix(1,3,4,4) = Tobj.SubMatrix(1,3,4,4) - tmpd6;
00649 }
00650
00651
00652 theta[0] = atan2(Tobj(2,4),
00653 Tobj(1,4));
00654
00655 theta[1] = atan2(-Tobj(2,4),
00656 -Tobj(1,4)) ;
00657
00658 diff1 = fabs(q_actual(1)-theta[0]) ;
00659 if (diff1 > M_PI)
00660 diff1 = 2*M_PI - diff1;
00661
00662 diff2 = fabs(q_actual(1)-theta[1]);
00663 if (diff2 > M_PI)
00664 diff2 = 2*M_PI - diff2 ;
00665
00666
00667 if (diff1 < diff2)
00668 theta[1] = theta[0] ;
00669
00670 theta[5] = atan2(sin(theta[1])*Tobj(1,1) - cos(theta[1])*Tobj(2,1),
00671 sin(theta[1])*Tobj(1,2) - cos(theta[1])*Tobj(2,2));
00672
00673
00674 angle = atan2(-1*cos(theta[1])*Tobj(1,3) - sin(theta[1])*Tobj(2,3),
00675 -1*Tobj(3,3));
00676
00677 L = cos(theta[1])*Tobj(1,4) +
00678 sin(theta[1])*Tobj(2,4) +
00679 links[5].d*sin(angle) -
00680 links[5].a*cos(angle);
00681 M = links[1].d -
00682 Tobj(3,4) -
00683 links[5].d*cos(angle) -
00684 links[5].a*sin(angle);
00685 K = (L*L + M*M - links[4].a*links[4].a -
00686 links[3].a*links[3].a) /
00687 (2 * links[4].a * links[4].a);
00688
00689 tmp = 1-K*K;
00690 if (tmp < 0)
00691 throw std::out_of_range("sqrt of negative number not allowed.");
00692
00693 theta[0] = atan2( sqrt(tmp) , K );
00694 theta[3] = atan2( -sqrt(tmp) , K );
00695
00696 diff1 = fabs(q_actual(3)-theta[0]) ;
00697 if (diff1 > M_PI)
00698 diff1 = 2*M_PI - diff1 ;
00699
00700 diff2 = fabs(q_actual(3)-theta[3]);
00701 if (diff2 > M_PI)
00702 diff2 = 2*M_PI - diff2 ;
00703
00704 if (diff1 < diff2)
00705 theta[3] = theta[0] ;
00706
00707 H = cos(theta[3]) * links[4].a + links[3].a;
00708 G = sin(theta[3]) * links[4].a;
00709
00710 theta[2] = atan2( M , L ) - atan2( G , H );
00711 theta[4] = atan2( -1*cos(theta[1])*Tobj(1,3) - sin(theta[1])*Tobj(2,3) ,
00712 -1*Tobj(3,3)) - theta[2] - theta[3] ;
00713
00714 qout(1) = theta[1];
00715 qout(2) = theta[2];
00716 qout(3) = theta[3];
00717 qout(4) = theta[4];
00718 qout(5) = theta[5];
00719
00720 converge = true;
00721 }
00722 catch(std::out_of_range & e)
00723 {
00724 converge = false;
00725 qout = q_actual;
00726 }
00727
00728 qout.Release();
00729 return qout;
00730 }
00731
00732
00733 ReturnMatrix mRobot::inv_kin_puma(const Matrix & Tobj, bool & converge)
00739 {
00740 ColumnVector qout(6), q_actual;
00741 q_actual = get_q();
00742
00743 try
00744 {
00745 Real theta[7] , diff1, diff2, tmp,
00746 A = 0.0 , B = 0.0 , C = 0.0 , D =0.0, Ro = 0.0,
00747 H = 0.0 , L = 0.0 , M = 0.0;
00748
00749
00750
00751 if (links[6].d)
00752 {
00753 ColumnVector tmpd6(3); Matrix tmp;
00754 tmpd6(1)=0; tmpd6(2)=0; tmpd6(3)=links[6].d;
00755 tmpd6 = Tobj.SubMatrix(1,3,1,3)*tmpd6;
00756 Tobj.SubMatrix(1,3,4,4) = Tobj.SubMatrix(1,3,4,4) - tmpd6;
00757 }
00758
00759 tmp = Tobj(2,4)*Tobj(2,4) + Tobj(1,4)*Tobj(1,4);
00760 if (tmp < 0)
00761 throw std::out_of_range("sqrt of negative number not allowed.");
00762
00763 Ro = sqrt(tmp);
00764 D = (links[2].d+links[3].d) / Ro;
00765
00766 tmp = 1-D*D;
00767 if (tmp < 0)
00768 throw std::out_of_range("sqrt of negative number not allowed.");
00769
00770
00771 theta[0] = atan2(Tobj(2,4),Tobj(1,4)) - atan2(D, sqrt(tmp));
00772
00773 theta[1] = atan2(Tobj(2,4),Tobj(1,4)) - atan2(D , -sqrt(tmp));
00774
00775 diff1 = fabs(q_actual(1)-theta[0]);
00776 if (diff1 > M_PI)
00777 diff1 = 2*M_PI - diff1;
00778
00779 diff2 = fabs(q_actual(1)-theta[1]);
00780 if (diff2 > M_PI)
00781 diff2 = 2*M_PI - diff2;
00782
00783
00784 if (diff1 < diff2)
00785 theta[1] = theta[0];
00786
00787 tmp = links[4].a*links[4].a + links[4].d*links[4].d;
00788 if (tmp < 0)
00789 throw std::out_of_range("sqrt of negative number not allowed.");
00790
00791 Ro = sqrt(tmp);
00792 B = atan2(links[4].d,links[4].a);
00793 C = Tobj(1,4)*Tobj(1,4) +
00794 Tobj(2,4)*Tobj(2,4) +
00795 (Tobj(3,4)-links[1].d)*(Tobj(3,4)-links[1].d) -
00796 (links[2].d + links[3].d)*(links[2].d + links[3].d) -
00797 links[3].a*links[3].a -
00798 links[4].a*links[4].a -
00799 links[4].d*links[4].d;
00800 A = C / (2*links[3].a);
00801
00802 tmp = 1-A/Ro*A/Ro;
00803 if (tmp < 0)
00804 throw std::out_of_range("sqrt of negative number not allowed.");
00805
00806 theta[0] = atan2(sqrt(tmp) , A/Ro) + B;
00807 theta[3] = atan2(-sqrt(tmp) , A/Ro) + B;
00808
00809 diff1 = fabs(q_actual(3)-theta[0]);
00810 if (diff1 > M_PI)
00811 diff1 = 2*M_PI - diff1 ;
00812
00813 diff2 = fabs(q_actual(3)-theta[3]);
00814 if (diff2 > M_PI)
00815 diff2 = 2*M_PI - diff2;
00816
00817
00818 if (diff1 < diff2)
00819 theta[3] = theta[0];
00820
00821 H = cos(theta[1])*Tobj(1,4) + sin(theta[1])*Tobj(2,4);
00822 L = sin(theta[3])*links[4].d + cos(theta[3])*links[4].a + links[3].a;
00823 M = cos(theta[3])*links[4].d - sin(theta[3])*links[4].a;
00824
00825 theta[2] = atan2( M , L ) - atan2(Tobj(3,4)-links[1].d , H );
00826
00827 theta[0] = atan2( -sin(theta[1])*Tobj(1,3) + cos(theta[1])*Tobj(2,3) ,
00828 cos(theta[2] + theta[3]) *
00829 (cos(theta[1]) * Tobj(1,3) + sin(theta[1])*Tobj(2,3))
00830 - (sin(theta[2]+theta[3])*Tobj(3,3)) );
00831
00832 theta[4] = atan2(-1*(-sin(theta[1])*Tobj(1,3) + cos(theta[1])*Tobj(2,3)),
00833 -cos(theta[2] + theta[3]) *
00834 (cos(theta[1]) * Tobj(1,3) + sin(theta[1])*Tobj(2,3))
00835 + (sin(theta[2]+theta[3])*Tobj(3,3)) );
00836
00837 diff1 = fabs(q_actual(4)-theta[0]);
00838 if (diff1 > M_PI)
00839 diff1 = 2*M_PI - diff1;
00840
00841 diff2 = fabs(q_actual(4)-theta[4]);
00842 if (diff2 > M_PI)
00843 diff2 = 2*M_PI - diff2;
00844
00845
00846 if (diff1 < diff2)
00847 theta[4] = theta[0];
00848
00849 theta[5] = atan2( cos(theta[4]) *
00850 ( cos(theta[2] + theta[3]) *
00851 (cos(theta[1]) * Tobj(1,3)
00852 + sin(theta[1])*Tobj(2,3))
00853 - (sin(theta[2]+theta[3])*Tobj(3,3)) ) +
00854 sin(theta[4])*(-sin(theta[1])*Tobj(1,3)
00855 + cos(theta[1])*Tobj(2,3)) ,
00856 sin(theta[2]+theta[3]) * (cos(theta[1]) * Tobj(1,3)
00857 + sin(theta[1])*Tobj(2,3) )
00858 + (cos(theta[2]+theta[3])*Tobj(3,3)) );
00859
00860 theta[6] = atan2( -sin(theta[4])
00861 * ( cos(theta[2] + theta[3]) *
00862 (cos(theta[1]) * Tobj(1,1)
00863 + sin(theta[1])*Tobj(2,1))
00864 - (sin(theta[2]+theta[3])*Tobj(3,1))) +
00865 cos(theta[4])*(-sin(theta[1])*Tobj(1,1)
00866 + cos(theta[1])*Tobj(2,1)),
00867 -sin(theta[4]) * ( cos(theta[2] + theta[3]) *
00868 (cos(theta[1]) * Tobj(1,2)
00869 + sin(theta[1])*Tobj(2,2))
00870 - (sin(theta[2]+theta[3])*Tobj(3,2))) +
00871 cos(theta[4])*(-sin(theta[1])*Tobj(1,2)
00872 + cos(theta[1])*Tobj(2,2)) );
00873
00874 qout(1) = theta[1];
00875 qout(2) = theta[2];
00876 qout(3) = theta[3];
00877 qout(4) = theta[4];
00878 qout(5) = theta[5];
00879 qout(6) = theta[6];
00880
00881 converge = true;
00882 }
00883 catch(std::out_of_range & e)
00884 {
00885 converge = false;
00886 qout = q_actual;
00887 }
00888
00889 qout.Release();
00890 return qout;
00891 }
00892
00893 ReturnMatrix mRobot::inv_kin_schilling(const Matrix & Tobj, bool & converge)
00899 {
00900 ColumnVector qout(6), q_actual;
00901 q_actual = get_q();
00902
00903 try
00904 {
00905 Real theta[7], K=0.0, A=0.0, B=0.0, C=0.0, D=0.0, tmp=0.0, theta234 , diff1, diff2;
00906
00907 if (links[6].d)
00908 {
00909 ColumnVector tmpd6(3);
00910 Matrix tmp;
00911 tmpd6(1)=0;
00912 tmpd6(2)=0;
00913 tmpd6(3)=links[6].d;
00914 tmpd6 = Tobj.SubMatrix(1,3,1,3)*tmpd6;
00915 Tobj.SubMatrix(1,3,4,4) = Tobj.SubMatrix(1,3,4,4) - tmpd6;
00916 }
00917
00918 theta[1] = atan2(Tobj(2,4),Tobj(1,4));
00919
00920 theta[0] = atan2(-Tobj(2,4),-Tobj(1,4));
00921
00922 diff1 = fabs(q_actual(1)-theta[0]);
00923 if (diff1 > M_PI)
00924 diff1 = 2*M_PI - diff1;
00925
00926 diff2 = fabs(q_actual(1)-theta[1]);
00927 if (diff2 > M_PI)
00928 diff2 = 2*M_PI - diff2;
00929
00930
00931 if (diff1 < diff2)
00932 theta[1] = theta[0];
00933
00934
00935 theta234 = atan2( Tobj(3,3) , cos(theta[1])*Tobj(1,3) + sin(theta[1])*Tobj(2,3) );
00936
00937 theta[5] = atan2( (cos(theta234)*(cos(theta[1])*Tobj(1,3) +
00938 sin(theta[1])*Tobj(2,3)) + sin(theta234)*Tobj(3,3)),
00939 (sin(theta[1])*Tobj(1,3) - cos(theta[1])*Tobj(2,3)));
00940
00941 theta[6] = atan2( (-sin(theta234)*(cos(theta[1])*Tobj(1,1) +
00942 sin(theta[1])*Tobj(2,1)) + cos(theta234)*Tobj(3,1)),
00943 (-sin(theta234)*(cos(theta[1])*Tobj(1,2) + sin(theta[1])*Tobj(2,2)) +
00944 cos(theta234)*Tobj(3,2)));
00945
00946 A= cos(theta[1])*Tobj(1,4) + sin(theta[1])*Tobj(2,4) - links[2].a -
00947 links[5].a*cos(theta234);
00948
00949 B= Tobj(3,4) - links[1].d - links[5].a*sin(theta234);
00950
00951
00952 K= ( A*A + B*B - (links[4].a*links[4].a) - (links[3].a*links[3].a) ) /
00953 ( 2*links[3].a*links[4].a );
00954
00955 tmp = 1-K*K;
00956 if (tmp < 0)
00957 throw std::out_of_range("sqrt of negative number not allowed.");
00958
00959 theta[3] = atan2(sqrt(tmp),K);
00960 theta[0] = atan2(-sqrt(tmp),K);
00961
00962 diff1 = fabs(q_actual(3)-theta[0]);
00963 if (diff1 > M_PI)
00964 diff1 = 2*M_PI - diff1;
00965
00966 diff2 = fabs(q_actual(3)-theta[3]);
00967 if (diff2 > M_PI)
00968 diff2 = 2*M_PI - diff2;
00969
00970
00971 if (diff1 < diff2)
00972 theta[3] = theta[0];
00973
00974 C = cos(theta[3])*links[4].a + links[3].a;
00975 D = sin(theta[3])*links[4].a;
00976
00977 theta[2] = atan2(B,A) - atan2(D,C);
00978
00979 theta[4] = theta234 - theta[2] - theta[3];
00980
00981 qout(1) = theta[1];
00982 qout(2) = theta[2];
00983 qout(3) = theta[3];
00984 qout(4) = theta[4];
00985 qout(5) = theta[5];
00986 qout(6) = theta[6];
00987
00988 converge = true;
00989 }
00990 catch(std::out_of_range & e)
00991 {
00992 converge = false;
00993 qout = q_actual;
00994 }
00995
00996 qout.Release();
00997 return qout;
00998 }
00999
01000
01001 ReturnMatrix mRobot_min_para::inv_kin(const Matrix & Tobj, const int mj)
01003 {
01004 bool converge = false;
01005 return inv_kin(Tobj, mj, dof, converge);
01006 }
01007
01008
01009 ReturnMatrix mRobot_min_para::inv_kin(const Matrix & Tobj, const int mj, const int endlink, bool & converge)
01017 {
01018 switch (robotType) {
01019 case RHINO:
01020 return inv_kin_rhino(Tobj, converge);
01021 break;
01022 case PUMA:
01023 return inv_kin_puma(Tobj, converge);
01024 break;
01025 default:
01026 return Robot_basic::inv_kin(Tobj, mj, endlink, converge);
01027 }
01028 }
01029
01030
01031 ReturnMatrix mRobot_min_para::inv_kin_rhino(const Matrix & Tobj, bool & converge)
01037 {
01038 ColumnVector qout(5), q_actual;
01039 q_actual = get_q();
01040
01041 try
01042 {
01043 Real theta[6] , diff1, diff2, tmp,
01044 angle , L=0.0 , M=0.0 , K=0.0 , H=0.0 , G=0.0 ;
01045
01046
01047 theta[0] = atan2(Tobj(2,4),
01048 Tobj(1,4));
01049
01050 theta[1] = atan2(-Tobj(2,4),
01051 -Tobj(1,4)) ;
01052
01053 diff1 = fabs(q_actual(1)-theta[0]) ;
01054 if (diff1 > M_PI)
01055 diff1 = 2*M_PI - diff1;
01056
01057 diff2 = fabs(q_actual(1)-theta[1]);
01058 if (diff2 > M_PI)
01059 diff2 = 2*M_PI - diff2 ;
01060
01061
01062 if (diff1 < diff2)
01063 theta[1] = theta[0] ;
01064
01065 theta[5] = atan2(sin(theta[1])*Tobj(1,1) - cos(theta[1])*Tobj(2,1),
01066 sin(theta[1])*Tobj(1,2) - cos(theta[1])*Tobj(2,2));
01067
01068
01069 angle = atan2(-1*cos(theta[1])*Tobj(1,3) - sin(theta[1])*Tobj(2,3),
01070 -1*Tobj(3,3));
01071
01072 L = cos(theta[1])*Tobj(1,4) +
01073 sin(theta[1])*Tobj(2,4) +
01074 links[5].d*sin(angle) -
01075 links[5].a*cos(angle);
01076 M = links[1].d -
01077 Tobj(3,4) -
01078 links[5].d*cos(angle) -
01079 links[5].a*sin(angle);
01080 K = (L*L + M*M - links[4].a*links[4].a -
01081 links[3].a*links[3].a) /
01082 (2 * links[4].a * links[4].a);
01083
01084 tmp = 1-K*K;
01085 if (tmp < 0)
01086 throw std::out_of_range("sqrt of negative number not allowed.");
01087
01088 theta[0] = atan2( sqrt(tmp) , K );
01089 theta[3] = atan2( -sqrt(tmp) , K );
01090
01091 diff1 = fabs(q_actual(3)-theta[0]) ;
01092 if (diff1 > M_PI)
01093 diff1 = 2*M_PI - diff1 ;
01094
01095 diff2 = fabs(q_actual(3)-theta[3]);
01096 if (diff2 > M_PI)
01097 diff2 = 2*M_PI - diff2 ;
01098
01099 if (diff1 < diff2)
01100 theta[3] = theta[0] ;
01101
01102 H = cos(theta[3]) * links[4].a + links[3].a;
01103 G = sin(theta[3]) * links[4].a;
01104
01105 theta[2] = atan2( M , L ) - atan2( G , H );
01106 theta[4] = atan2( -1*cos(theta[1])*Tobj(1,3) - sin(theta[1])*Tobj(2,3) ,
01107 -1*Tobj(3,3)) - theta[2] - theta[3] ;
01108
01109 qout(1) = theta[1];
01110 qout(2) = theta[2];
01111 qout(3) = theta[3];
01112 qout(4) = theta[4];
01113 qout(5) = theta[5];
01114
01115 converge = true;
01116 }
01117 catch(std::out_of_range & e)
01118 {
01119 converge = false;
01120 qout = q_actual;
01121 }
01122
01123 qout.Release();
01124 return qout;
01125 }
01126
01127
01128 ReturnMatrix mRobot_min_para::inv_kin_puma(const Matrix & Tobj, bool & converge)
01134 {
01135 ColumnVector qout(6), q_actual;
01136 q_actual = get_q();
01137
01138 try
01139 {
01140 Real theta[7] , diff1, diff2, tmp,
01141 A = 0.0 , B = 0.0 , C = 0.0 , D =0.0, Ro = 0.0,
01142 H = 0.0 , L = 0.0 , M = 0.0;
01143
01144
01145
01146 if (links[6].d > 0)
01147 {
01148 ColumnVector tmpd6(3); Matrix tmp;
01149 tmpd6(1)=0; tmpd6(2)=0; tmpd6(3)=links[6].d;
01150 tmpd6 = Tobj.SubMatrix(1,3,1,3)*tmpd6;
01151 Tobj.SubMatrix(1,3,4,4) = Tobj.SubMatrix(1,3,4,4) - tmpd6;
01152 }
01153
01154 tmp = Tobj(2,4)*Tobj(2,4) + Tobj(1,4)*Tobj(1,4);
01155 if (tmp < 0)
01156 throw std::out_of_range("sqrt of negative number not allowed.");
01157
01158 Ro = sqrt(tmp);
01159 D = (links[2].d+links[3].d) / Ro;
01160
01161 tmp = 1-D*D;
01162 if (tmp < 0)
01163 throw std::out_of_range("sqrt of negative number not allowed.");
01164
01165
01166 theta[0] = atan2(Tobj(2,4),Tobj(1,4)) - atan2(D, sqrt(tmp));
01167
01168 theta[1] = atan2(Tobj(2,4),Tobj(1,4)) - atan2(D , -sqrt(tmp));
01169
01170 diff1 = fabs(q_actual(1)-theta[0]);
01171 if (diff1 > M_PI)
01172 diff1 = 2*M_PI - diff1;
01173
01174 diff2 = fabs(q_actual(1)-theta[1]);
01175 if (diff2 > M_PI)
01176 diff2 = 2*M_PI - diff2;
01177
01178
01179 if (diff1 < diff2)
01180 theta[1] = theta[0];
01181
01182 tmp = links[4].a*links[4].a + links[4].d*links[4].d;
01183 if (tmp < 0)
01184 throw std::out_of_range("sqrt of negative number not allowed.");
01185
01186 Ro = sqrt(tmp);
01187 B = atan2(links[4].d,links[4].a);
01188 C = Tobj(1,4)*Tobj(1,4) +
01189 Tobj(2,4)*Tobj(2,4) +
01190 (Tobj(3,4)-links[1].d)*(Tobj(3,4)-links[1].d) -
01191 (links[2].d + links[3].d)*(links[2].d + links[3].d) -
01192 links[3].a*links[3].a -
01193 links[4].a*links[4].a -
01194 links[4].d*links[4].d;
01195 A = C / (2*links[3].a);
01196
01197 tmp = 1-A/Ro*A/Ro;
01198 if (tmp < 0)
01199 throw std::out_of_range("sqrt of negative number not allowed.");
01200
01201 theta[0] = atan2(sqrt(tmp) , A/Ro) + B;
01202 theta[3] = atan2(-sqrt(tmp) , A/Ro) + B;
01203
01204 diff1 = fabs(q_actual(3)-theta[0]);
01205 if (diff1 > M_PI)
01206 diff1 = 2*M_PI - diff1 ;
01207
01208 diff2 = fabs(q_actual(3)-theta[3]);
01209 if (diff2 > M_PI)
01210 diff2 = 2*M_PI - diff2;
01211
01212
01213 if (diff1 < diff2)
01214 theta[3] = theta[0];
01215
01216 H = cos(theta[1])*Tobj(1,4) + sin(theta[1])*Tobj(2,4);
01217 L = sin(theta[3])*links[4].d + cos(theta[3])*links[4].a + links[3].a;
01218 M = cos(theta[3])*links[4].d - sin(theta[3])*links[4].a;
01219
01220 theta[2] = atan2( M , L ) - atan2(Tobj(3,4)-links[1].d , H );
01221
01222 theta[0] = atan2( -sin(theta[1])*Tobj(1,3) + cos(theta[1])*Tobj(2,3) ,
01223 cos(theta[2] + theta[3]) *
01224 (cos(theta[1]) * Tobj(1,3) + sin(theta[1])*Tobj(2,3))
01225 - (sin(theta[2]+theta[3])*Tobj(3,3)) );
01226
01227 theta[4] = atan2(-1*(-sin(theta[1])*Tobj(1,3) + cos(theta[1])*Tobj(2,3)),
01228 -cos(theta[2] + theta[3]) *
01229 (cos(theta[1]) * Tobj(1,3) + sin(theta[1])*Tobj(2,3))
01230 + (sin(theta[2]+theta[3])*Tobj(3,3)) );
01231
01232 diff1 = fabs(q_actual(4)-theta[0]);
01233 if (diff1 > M_PI)
01234 diff1 = 2*M_PI - diff1;
01235
01236 diff2 = fabs(q_actual(4)-theta[4]);
01237 if (diff2 > M_PI)
01238 diff2 = 2*M_PI - diff2;
01239
01240
01241 if (diff1 < diff2)
01242 theta[4] = theta[0];
01243
01244 theta[5] = atan2( cos(theta[4]) *
01245 ( cos(theta[2] + theta[3]) *
01246 (cos(theta[1]) * Tobj(1,3)
01247 + sin(theta[1])*Tobj(2,3))
01248 - (sin(theta[2]+theta[3])*Tobj(3,3)) ) +
01249 sin(theta[4])*(-sin(theta[1])*Tobj(1,3)
01250 + cos(theta[1])*Tobj(2,3)) ,
01251 sin(theta[2]+theta[3]) * (cos(theta[1]) * Tobj(1,3)
01252 + sin(theta[1])*Tobj(2,3) )
01253 + (cos(theta[2]+theta[3])*Tobj(3,3)) );
01254
01255 theta[6] = atan2( -sin(theta[4])
01256 * ( cos(theta[2] + theta[3]) *
01257 (cos(theta[1]) * Tobj(1,1)
01258 + sin(theta[1])*Tobj(2,1))
01259 - (sin(theta[2]+theta[3])*Tobj(3,1))) +
01260 cos(theta[4])*(-sin(theta[1])*Tobj(1,1)
01261 + cos(theta[1])*Tobj(2,1)),
01262 -sin(theta[4]) * ( cos(theta[2] + theta[3]) *
01263 (cos(theta[1]) * Tobj(1,2)
01264 + sin(theta[1])*Tobj(2,2))
01265 - (sin(theta[2]+theta[3])*Tobj(3,2))) +
01266 cos(theta[4])*(-sin(theta[1])*Tobj(1,2)
01267 + cos(theta[1])*Tobj(2,2)) );
01268
01269 qout(1) = theta[1];
01270 qout(2) = theta[2];
01271 qout(3) = theta[3];
01272 qout(4) = theta[4];
01273 qout(5) = theta[5];
01274 qout(6) = theta[6];
01275
01276 converge = true;
01277 }
01278 catch(std::out_of_range & e)
01279 {
01280 converge = false;
01281 qout = q_actual;
01282 }
01283
01284 qout.Release();
01285 return qout;
01286 }
01287
01288
01289 ReturnMatrix mRobot_min_para::inv_kin_schilling(const Matrix & Tobj, bool & converge)
01295 {
01296 ColumnVector qout(6), q_actual;
01297 q_actual = get_q();
01298
01299 try
01300 {
01301 Real theta[7], K=0.0, A=0.0, B=0.0, C=0.0, D=0.0, tmp=0.0, theta234 , diff1, diff2;
01302
01303 if (links[6].d)
01304 {
01305 ColumnVector tmpd6(3);
01306 Matrix tmp;
01307 tmpd6(1)=0;
01308 tmpd6(2)=0;
01309 tmpd6(3)=links[6].d;
01310 tmpd6 = Tobj.SubMatrix(1,3,1,3)*tmpd6;
01311 Tobj.SubMatrix(1,3,4,4) = Tobj.SubMatrix(1,3,4,4) - tmpd6;
01312 }
01313
01314 theta[1] = atan2(Tobj(2,4),Tobj(1,4));
01315
01316 theta[0] = atan2(-Tobj(2,4),-Tobj(1,4));
01317
01318 diff1 = fabs(q_actual(1)-theta[0]);
01319 if (diff1 > M_PI)
01320 diff1 = 2*M_PI - diff1;
01321
01322 diff2 = fabs(q_actual(1)-theta[1]);
01323 if (diff2 > M_PI)
01324 diff2 = 2*M_PI - diff2;
01325
01326
01327 if (diff1 < diff2)
01328 theta[1] = theta[0];
01329
01330
01331 theta234 = atan2( Tobj(3,3) , cos(theta[1])*Tobj(1,3) + sin(theta[1])*Tobj(2,3) );
01332
01333 theta[5] = atan2( (cos(theta234)*(cos(theta[1])*Tobj(1,3) +
01334 sin(theta[1])*Tobj(2,3)) + sin(theta234)*Tobj(3,3)),
01335 (sin(theta[1])*Tobj(1,3) - cos(theta[1])*Tobj(2,3)));
01336
01337 theta[6] = atan2( (-sin(theta234)*(cos(theta[1])*Tobj(1,1) +
01338 sin(theta[1])*Tobj(2,1)) + cos(theta234)*Tobj(3,1)),
01339 (-sin(theta234)*(cos(theta[1])*Tobj(1,2) + sin(theta[1])*Tobj(2,2)) +
01340 cos(theta234)*Tobj(3,2)));
01341
01342 A= cos(theta[1])*Tobj(1,4) + sin(theta[1])*Tobj(2,4) - links[2].a -
01343 links[5].a*cos(theta234);
01344
01345 B= Tobj(3,4) - links[1].d - links[5].a*sin(theta234);
01346
01347
01348 K= ( A*A + B*B - (links[4].a*links[4].a) - (links[3].a*links[3].a) ) /
01349 ( 2*links[3].a*links[4].a );
01350
01351 tmp = 1-K*K;
01352 if (tmp < 0)
01353 throw std::out_of_range("sqrt of negative number not allowed.");
01354
01355 theta[3] = atan2(sqrt(tmp),K);
01356 theta[0] = atan2(-sqrt(tmp),K);
01357
01358 diff1 = fabs(q_actual(3)-theta[0]);
01359 if (diff1 > M_PI)
01360 diff1 = 2*M_PI - diff1;
01361
01362 diff2 = fabs(q_actual(3)-theta[3]);
01363 if (diff2 > M_PI)
01364 diff2 = 2*M_PI - diff2;
01365
01366
01367 if (diff1 < diff2)
01368 theta[3] = theta[0];
01369
01370 C = cos(theta[3])*links[4].a + links[3].a;
01371 D = sin(theta[3])*links[4].a;
01372
01373 theta[2] = atan2(B,A) - atan2(D,C);
01374
01375 theta[4] = theta234 - theta[2] - theta[3];
01376
01377 qout(1) = theta[1];
01378 qout(2) = theta[2];
01379 qout(3) = theta[3];
01380 qout(4) = theta[4];
01381 qout(5) = theta[5];
01382 qout(6) = theta[6];
01383
01384 converge = true;
01385 }
01386 catch(std::out_of_range & e)
01387 {
01388 converge = false;
01389 qout = q_actual;
01390 }
01391
01392 qout.Release();
01393 return qout;
01394 }
01395
01396
01397 #ifdef use_namespace
01398 }
01399 #endif