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
00060
00061
00062
00063
00064 #include "robot.h"
00065 #include <sstream>
00066
00067 using namespace std;
00068
00069 #ifdef use_namespace
00070 namespace ROBOOP {
00071 using namespace NEWMAT;
00072 #endif
00073
00074 static const char rcsid[] __UNUSED__ = "$Id: invkine.cpp,v 1.29 2007/11/16 16:46:45 ejt Exp $";
00075
00076 #define NITMAX 1000
00077 #ifdef USING_FLOAT //from newmat's include.h
00078 # define ITOL 1e-4f
00079 #else
00080 # define ITOL 1e-6
00081 #endif
00082
00083 ReturnMatrix Robot_basic::inv_kin(const Matrix & Tobj, const int mj)
00084
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)
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 {
00104 ColumnVector qout, dq, q_tmp;
00105 UpperTriangularMatrix U;
00106
00107 qout = get_available_q();
00108 if(qout.nrows()==0) {
00109 converge=true;
00110 return qout;
00111 }
00112 q_tmp = qout;
00113
00114 converge = false;
00115 if(mj == 0) {
00116 Matrix Ipd, A, B(6,1), M;
00117 for(int j = 1; j <= NITMAX; j++) {
00118 Ipd = (kine(endlink)).i()*Tobj;
00119 B(1,1) = Ipd(1,4);
00120 B(2,1) = Ipd(2,4);
00121 B(3,1) = Ipd(3,4);
00122 B(4,1) = Ipd(3,2);
00123 B(5,1) = Ipd(1,3);
00124 B(6,1) = Ipd(2,1);
00125 A = jacobian(endlink,endlink);
00126 QRZ(A,U);
00127 QRZ(A,B,M);
00128 dq = U.i()*M;
00129
00130 while(dq.MaximumAbsoluteValue() > 1)
00131 dq /= 10;
00132
00133 for(int k = 1; k<= dq.nrows(); k++)
00134 qout(k)+=dq(k);
00135 set_q(qout);
00136
00137 if (dq.MaximumAbsoluteValue() < ITOL)
00138 {
00139 converge = true;
00140 break;
00141 }
00142 }
00143 } else {
00144 int adof=get_available_dof(endlink);
00145 Matrix A(12,adof),B,M;
00146 for(int j = 1; j <= NITMAX; j++) {
00147 B = (Tobj-kine(endlink)).SubMatrix(1,3,1,4).AsColumn();
00148 int k=1;
00149 for(int i = 1; i<=dof && k<=adof; i++) {
00150 if(links[i].immobile)
00151 continue;
00152 A.SubMatrix(1,12,k,k) = dTdqi(i,endlink).SubMatrix(1,3,1,4).AsColumn();
00153 k++;
00154 }
00155 if(A.ncols()==0) {
00156 converge=true;
00157 break;
00158 }
00159 QRZ(A,U);
00160 QRZ(A,B,M);
00161 dq = U.i()*M;
00162
00163 while(dq.MaximumAbsoluteValue() > 1)
00164 dq /= 10;
00165
00166 for(k = 1; k<=adof; k++)
00167 qout(k)+=dq(k);
00168 set_q(qout);
00169 if (dq.MaximumAbsoluteValue() < ITOL)
00170 {
00171 converge = true;
00172 break;
00173 }
00174 }
00175 }
00176
00177 if(converge)
00178 {
00179
00180 int j=1;
00181 for(int i = 1; i <= dof; i++)
00182 {
00183 if(links[i].immobile)
00184 continue;
00185 if(links[i].get_joint_type() == 0) {
00186 while(qout(j) >= M_PI)
00187 qout(j) -= 2*M_PI;
00188 while(qout(j) <= -M_PI)
00189 qout(j) += 2*M_PI;
00190 }
00191 j++;
00192 }
00193 set_q(qout);
00194 qout.Release();
00195 return qout;
00196 }
00197 else
00198 {
00199 set_q(q_tmp);
00200 q_tmp.Release();
00201 return q_tmp;
00202 }
00203 }
00204
00205
00206
00207
00208 #define DEBUG_ET ;
00209
00210
00211
00212 ReturnMatrix Robot_basic::inv_kin_pos(const ColumnVector & Pobj, const int mj, const int endlink, const ColumnVector& , bool & converge)
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 {
00226 ColumnVector qout, dq, q_tmp;
00227 UpperTriangularMatrix U;
00228
00229 DEBUG_ET;
00230
00231 qout = get_available_q();
00232 if(qout.nrows()==0) {
00233 converge=true;
00234 return qout;
00235 }
00236 q_tmp = qout;
00237
00238 ColumnVector PHobj(4);
00239 if(Pobj.nrows()!=4) {
00240 PHobj.SubMatrix(1,Pobj.nrows(),1,1)=Pobj;
00241 PHobj.SubMatrix(Pobj.nrows()+1,4,1,1)=1;
00242 } else {
00243 PHobj=Pobj;
00244 }
00245
00246 DEBUG_ET;
00247 converge = false;
00248 if(mj == 0) {
00249 DEBUG_ET;
00250 Matrix Ipd, A, B(3,1),M;
00251 for(int j = 1; j <= NITMAX; j++) {
00252 Ipd = (kine(endlink)).i()*PHobj;
00253 B(1,1) = Ipd(1,1);
00254 B(2,1) = Ipd(2,1);
00255 B(3,1) = Ipd(3,1);
00256 A = jacobian(endlink,endlink);
00257 A = A.SubMatrix(1,3,1,A.ncols());
00258
00259
00260 int removeCount=0;
00261 for(int k=1; k<= A.ncols(); k++)
00262 if(A.SubMatrix(1,3,k,k).MaximumAbsoluteValue()<ITOL)
00263 removeCount++;
00264 Matrix A2(3,A.ncols()-removeCount);
00265 if(removeCount==0)
00266 A2=A;
00267 else
00268 for(int k=1,m=1; k<= A.ncols(); k++) {
00269 if(A.SubMatrix(1,3,k,k).MaximumAbsoluteValue()<ITOL)
00270 continue;
00271 A2.SubMatrix(1,3,m,m)=A.SubMatrix(1,3,k,k);
00272 m++;
00273 }
00274
00275 if(A2.ncols()==0) {
00276 converge=true;
00277 break;
00278 }
00279 {
00280 stringstream ss;
00281 ss << "A2-pre:\n";
00282 for(int r=1; r<=A2.nrows(); r++) {
00283 for(int c=1; c<=A2.ncols(); c++) {
00284 ss << A2(r,c) << ' ';
00285 }
00286 ss << '\n';
00287 }
00288 QRZ(A2,U);
00289
00290
00291
00292
00293
00294
00295
00296 QRZ(A2,B,M);
00297
00298 }
00299 DEBUG_ET;
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 DEBUG_ET;
00323 dq = U.i()*M;
00324
00325 DEBUG_ET;
00326 while(dq.MaximumAbsoluteValue() > 1)
00327 dq /= 10;
00328
00329 for(int k = 1,m=1; m<= dq.nrows(); k++)
00330 if(A.SubMatrix(1,3,k,k).MaximumAbsoluteValue()>=ITOL)
00331 qout(k)+=dq(m++);
00332 set_q(qout);
00333
00334 if (dq.MaximumAbsoluteValue() < ITOL)
00335 {
00336 converge = true;
00337 break;
00338 }
00339 }
00340 } else {
00341 int adof=get_available_dof(endlink);
00342 Matrix A(3,adof),Rcur,B,M;
00343 ColumnVector pcur;
00344 bool used[adof];
00345 for(int j = 1; j <= NITMAX; j++) {
00346 kine(Rcur,pcur,endlink);
00347 B = (PHobj.SubMatrix(1,3,1,1)-pcur);
00348 int k=1,m=1;
00349 for(int i = 1; m<=adof; i++) {
00350 if(links[i].immobile)
00351 continue;
00352 Matrix Atmp=dTdqi(i,endlink).SubMatrix(1,3,4,4);
00353 used[m]=(Atmp.MaximumAbsoluteValue()>=ITOL);
00354 if(!used[m++])
00355 continue;
00356 A.SubMatrix(1,3,k,k) = Atmp;
00357 k++;
00358 }
00359 Matrix A2=A.SubMatrix(1,3,1,k-1);
00360 if(A2.ncols()==0) {
00361 converge=true;
00362 break;
00363 }
00364 QRZ(A2,U);
00365 QRZ(A2,B,M);
00366 dq = U.i()*M;
00367
00368 while(dq.MaximumAbsoluteValue() > 1)
00369 dq /= 10;
00370
00371 for(k = m = 1; k<=adof; k++)
00372 if(used[k])
00373 qout(k)+=dq(m++);
00374 set_q(qout);
00375
00376 if (dq.MaximumAbsoluteValue() < ITOL)
00377 {
00378 converge = true;
00379 break;
00380 }
00381 }
00382 }
00383 DEBUG_ET;
00384
00385 if(converge)
00386 {
00387 DEBUG_ET;
00388
00389 int j=1;
00390 for(int i = 1; i <= dof; i++)
00391 {
00392 if(links[i].immobile)
00393 continue;
00394 unsigned int * test=(unsigned int*)&qout(j);
00395 if(((*test)&(255U<<23))==(255U<<23)) {
00396
00397 set_q(q_tmp);
00398 q_tmp.Release();
00399 return q_tmp;
00400 }
00401
00402
00403
00404
00405
00406
00407
00408
00409 j++;
00410 }
00411 DEBUG_ET;
00412 set_q(qout);
00413 qout.Release();
00414 DEBUG_ET;
00415 return qout;
00416 }
00417 else
00418 {
00419 DEBUG_ET;
00420 set_q(q_tmp);
00421 q_tmp.Release();
00422 DEBUG_ET;
00423 return q_tmp;
00424 }
00425 }
00426
00427 ReturnMatrix Robot_basic::inv_kin_orientation(const Matrix & Robj, const int mj, const int endlink, bool & converge)
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 {
00440 ColumnVector qout, dq, q_tmp;
00441 UpperTriangularMatrix U;
00442
00443 qout = get_available_q();
00444 if(qout.nrows()==0) {
00445 converge=true;
00446 return qout;
00447 }
00448 q_tmp = qout;
00449
00450 Matrix RHobj(4,3);
00451 RHobj.SubMatrix(1,3,1,3)=Robj;
00452 RHobj.SubMatrix(4,4,1,3)=0;
00453
00454 converge = false;
00455 if(mj == 0) {
00456 Matrix Ipd, A, B(3,1),M;
00457 for(int j = 1; j <= NITMAX; j++) {
00458 Ipd = kine(endlink).i()*RHobj;
00459 B(1,1) = Ipd(3,2);
00460 B(2,1) = Ipd(1,3);
00461 B(3,1) = Ipd(2,1);
00462 A = jacobian(endlink,endlink);
00463 A = A.SubMatrix(4,6,1,A.ncols());
00464
00465
00466 int removeCount=0;
00467 for(int k=1; k<= A.ncols(); k++)
00468 if(A.SubMatrix(1,3,k,k).MaximumAbsoluteValue()<ITOL)
00469 removeCount++;
00470 Matrix A2(3,A.ncols()-removeCount);
00471 if(removeCount==0)
00472 A2=A;
00473 else
00474 for(int k=1,m=1; k<= A.ncols(); k++) {
00475 if(A.SubMatrix(1,3,k,k).MaximumAbsoluteValue()<ITOL)
00476 continue;
00477 A2.SubMatrix(1,3,m,m)=A.SubMatrix(1,3,k,k);
00478 m++;
00479 }
00480
00481 if(A2.ncols()==0) {
00482 converge=true;
00483 break;
00484 }
00485 QRZ(A2,U);
00486 QRZ(A2,B,M);
00487 dq = U.i()*M;
00488
00489 while(dq.MaximumAbsoluteValue() > 1)
00490 dq /= 10;
00491
00492 for(int k = 1,m=1; m<= dq.nrows(); k++)
00493 if(A.SubMatrix(1,3,k,k).MaximumAbsoluteValue()>=ITOL)
00494 qout(k)+=dq(m++);
00495 set_q(qout);
00496
00497 if (dq.MaximumAbsoluteValue() < ITOL)
00498 {
00499 converge = true;
00500 break;
00501 }
00502 }
00503 } else {
00504 int adof=get_available_dof(endlink);
00505 Matrix A(9,adof),Rcur,B,M;
00506 ColumnVector pcur;
00507 bool used[adof];
00508 for(int j = 1; j <= NITMAX; j++) {
00509 kine(Rcur,pcur,endlink);
00510 B = (Robj-Rcur).AsColumn();
00511 int k=1,m=1;
00512 for(int i = 1; m<=adof; i++) {
00513 if(links[i].immobile)
00514 continue;
00515 Matrix Atmp=dTdqi(i,endlink).SubMatrix(1,3,1,3).AsColumn();
00516 used[m]=(Atmp.MaximumAbsoluteValue()>=ITOL);
00517 if(!used[m++])
00518 continue;
00519 A.SubMatrix(1,9,k,k) = Atmp;
00520 k++;
00521 }
00522 Matrix A2=A.SubMatrix(1,9,1,k-1);
00523 if(A2.ncols()==0) {
00524 converge=true;
00525 break;
00526 }
00527 QRZ(A2,U);
00528 QRZ(A2,B,M);
00529 dq = U.i()*M;
00530
00531 while(dq.MaximumAbsoluteValue() > 1)
00532 dq /= 10;
00533
00534 for(k = m = 1; k<=adof; k++)
00535 if(used[k])
00536 qout(k)+=dq(m++);
00537 set_q(qout);
00538
00539 if (dq.MaximumAbsoluteValue() < ITOL)
00540 {
00541 converge = true;
00542 break;
00543 }
00544 }
00545 }
00546
00547 if(converge)
00548 {
00549
00550 int j=1;
00551 for(int i = 1; i <= dof; i++)
00552 {
00553 if(links[i].immobile)
00554 continue;
00555 if(links[i].get_joint_type() == 0) {
00556 while(qout(j) >= M_PI)
00557 qout(j) -= 2*M_PI;
00558 while(qout(j) <= -M_PI)
00559 qout(j) += 2*M_PI;
00560 }
00561 j++;
00562 }
00563 set_q(qout);
00564 qout.Release();
00565 return qout;
00566 }
00567 else
00568 {
00569 set_q(q_tmp);
00570 q_tmp.Release();
00571 return q_tmp;
00572 }
00573 }
00574
00575
00576
00577 ReturnMatrix Robot::inv_kin(const Matrix & Tobj, const int mj)
00578
00579 {
00580 bool converge = false;
00581 return inv_kin(Tobj, mj, dof, converge);
00582 }
00583
00584
00585 ReturnMatrix Robot::inv_kin(const Matrix & Tobj, const int mj, const int endlink, bool & converge)
00586
00587
00588
00589
00590
00591
00592
00593 {
00594 switch (robotType) {
00595 case RHINO:
00596 return inv_kin_rhino(Tobj, converge);
00597 case PUMA:
00598 return inv_kin_puma(Tobj, converge);
00599 case ERS_LEG:
00600 case ERS2XX_HEAD:
00601 case ERS7_HEAD:
00602
00603 case PANTILT:
00604 case GOOSENECK:
00605 return inv_kin_goose_neck(Tobj);
00606 case CRABARM:
00607 default:
00608 return Robot_basic::inv_kin(Tobj, mj, endlink, converge);
00609 }
00610 }
00611
00612 ReturnMatrix Robot::inv_kin_pos(const ColumnVector & Pobj, const int mj, const int endlink, const ColumnVector& Plink, bool & converge)
00613
00614
00615
00616
00617
00618
00619
00620 {
00621 switch (robotType) {
00622 case ERS_LEG:
00623 case ERS2XX_HEAD:
00624 case ERS7_HEAD:
00625 return inv_kin_ers_pos(Pobj, endlink, Plink, converge);
00626 case RHINO:
00627 case PUMA:
00628
00629 case PANTILT:
00630 return inv_kin_pan_tilt(Pobj, converge);
00631 case GOOSENECK:
00632 return inv_kin_goose_neck_pos(Pobj);
00633 case CRABARM:
00634 default:
00635 return Robot_basic::inv_kin_pos(Pobj, mj, endlink, Plink, converge);
00636 }
00637 }
00638
00639 ReturnMatrix Robot::inv_kin_orientation(const Matrix & Robj, const int mj, const int endlink, bool & converge)
00640
00641
00642
00643
00644
00645
00646
00647 {
00648 switch (robotType) {
00649 case ERS_LEG:
00650 case ERS2XX_HEAD:
00651 case ERS7_HEAD:
00652 case RHINO:
00653 case PUMA:
00654
00655 case PANTILT:
00656 case GOOSENECK:
00657
00658 case CRABARM:
00659 default:
00660 return Robot_basic::inv_kin_orientation(Robj, mj, endlink, converge);
00661 }
00662 }
00663
00664 ReturnMatrix Robot::inv_kin_rhino(const Matrix & Tobj, bool & converge)
00665
00666
00667
00668
00669
00670 {
00671 ColumnVector qout(5), q_actual;
00672 q_actual = get_q();
00673
00674 try
00675 {
00676 Real theta[6] , diff1, diff2, tmp,
00677 angle , L=0.0 , M=0.0 , K=0.0 , H=0.0 , Gl=0.0 ;
00678
00679
00680 theta[0] = atan2(Tobj(2,4),
00681 Tobj(1,4));
00682
00683 theta[1] = atan2(-Tobj(2,4),
00684 -Tobj(1,4)) ;
00685
00686 diff1 = fabs(q_actual(1)-theta[0]) ;
00687 if (diff1 > M_PI)
00688 diff1 = 2*M_PI - diff1;
00689
00690 diff2 = fabs(q_actual(1)-theta[1]);
00691 if (diff2 > M_PI)
00692 diff1 = 2*M_PI - diff2 ;
00693
00694
00695 if (diff1 < diff2)
00696 theta[1] = theta[0] ;
00697
00698 theta[5] = atan2(sin(theta[1])*Tobj(1,1) - cos(theta[1])*Tobj(2,1),
00699 sin(theta[1])*Tobj(1,2) - cos(theta[1])*Tobj(2,2));
00700
00701
00702 angle = atan2(-1*cos(theta[1])*Tobj(1,3) - sin(theta[1])*Tobj(2,3),
00703 -1*Tobj(3,3));
00704
00705 L = cos(theta[1])*Tobj(1,4) +
00706 sin(theta[1])*Tobj(2,4) +
00707 links[5].d*sin(angle) -
00708 links[4].a*cos(angle);
00709 M = links[1].d -
00710 Tobj(3,4) -
00711 links[5].d*cos(angle) -
00712 links[4].a*sin(angle);
00713 K = (L*L + M*M - links[3].a*links[3].a -
00714 links[2].a*links[2].a) /
00715 (2 * links[3].a * links[2].a);
00716
00717 tmp = 1-K*K;
00718 if (tmp < 0)
00719 throw std::out_of_range("sqrt of negative number not allowed.");
00720
00721 theta[0] = atan2( sqrt(tmp) , K );
00722 theta[3] = atan2( -sqrt(tmp) , K );
00723
00724 diff1 = fabs(q_actual(3)-theta[0]) ;
00725 if (diff1 > M_PI)
00726 diff1 = 2*M_PI - diff1 ;
00727
00728 diff2 = fabs(q_actual(3)-theta[3]);
00729 if (diff2 > M_PI)
00730 diff1 = 2*M_PI - diff2 ;
00731
00732 if (diff1 < diff2)
00733 theta[3] = theta[0] ;
00734
00735 H = cos(theta[3]) * links[3].a + links[2].a;
00736 Gl = sin(theta[3]) * links[3].a;
00737
00738 theta[2] = atan2( M , L ) - atan2( Gl , H );
00739 theta[4] = atan2( -1*cos(theta[1])*Tobj(1,3) - sin(theta[1])*Tobj(2,3) ,
00740 -1*Tobj(3,3)) - theta[2] - theta[3] ;
00741
00742 qout(1) = theta[1];
00743 qout(2) = theta[2];
00744 qout(3) = theta[3];
00745 qout(4) = theta[4];
00746 qout(5) = theta[5];
00747 set_q(qout);
00748
00749 converge = true;
00750 }
00751 catch(std::out_of_range & e)
00752 {
00753 converge = false;
00754 set_q(q_actual);
00755 qout = q_actual;
00756 }
00757
00758 qout.Release();
00759 return qout;
00760 }
00761
00762
00763 ReturnMatrix Robot::inv_kin_puma(const Matrix & Tobj, bool & converge)
00764
00765
00766
00767
00768
00769 {
00770 ColumnVector qout(6), q_actual;
00771 q_actual = get_q();
00772
00773 try
00774 {
00775 Real theta[7] , diff1, diff2, tmp,
00776 A = 0.0 , B = 0.0 , Cl = 0.0 , D =0.0, Ro = 0.0,
00777 H = 0.0 , L = 0.0 , M = 0.0;
00778
00779
00780
00781 if (links[6].d)
00782 {
00783 ColumnVector tmpd6(3);
00784 tmpd6(1)=0; tmpd6(2)=0; tmpd6(3)=links[6].d;
00785 tmpd6 = Tobj.SubMatrix(1,3,1,3)*tmpd6;
00786 Tobj.SubMatrix(1,3,4,4) = Tobj.SubMatrix(1,3,4,4) - tmpd6;
00787 }
00788
00789 tmp = Tobj(2,4)*Tobj(2,4) + Tobj(1,4)*Tobj(1,4);
00790 if (tmp < 0)
00791 throw std::out_of_range("sqrt of negative number not allowed.");
00792
00793 Ro = sqrt(tmp);
00794 D = (links[2].d+links[3].d) / Ro;
00795
00796 tmp = 1-D*D;
00797 if (tmp < 0)
00798 throw std::out_of_range("sqrt of negative number not allowed.");
00799
00800
00801 theta[0] = atan2(Tobj(2,4),Tobj(1,4)) - atan2(D, sqrt(tmp));
00802
00803 theta[1] = atan2(Tobj(2,4),Tobj(1,4)) - atan2(D , -sqrt(tmp));
00804
00805 diff1 = fabs(q_actual(1)-theta[0]);
00806 if (diff1 > M_PI)
00807 diff1 = 2*M_PI - diff1;
00808
00809 diff2 = fabs(q_actual(1)-theta[1]);
00810 if (diff2 > M_PI)
00811 diff1 = 2*M_PI - diff2;
00812
00813
00814 if (diff1 < diff2)
00815 theta[1] = theta[0];
00816
00817 tmp = links[3].a*links[3].a + links[4].d*links[4].d;
00818 if (tmp < 0)
00819 throw std::out_of_range("sqrt of negative number not allowed.");
00820
00821 Ro = sqrt(tmp);
00822 B = atan2(links[4].d,links[3].a);
00823 Cl = Tobj(1,4)*Tobj(1,4) +
00824 Tobj(2,4)*Tobj(2,4) +
00825 Tobj(3,4)*Tobj(3,4) -
00826 (links[2].d + links[3].d)*(links[2].d + links[3].d) -
00827 links[2].a*links[2].a -
00828 links[3].a*links[3].a -
00829 links[4].d*links[4].d;
00830 A = Cl / (2*links[2].a);
00831
00832 tmp = 1-A/Ro*A/Ro;
00833 if (tmp < 0)
00834 throw std::out_of_range("sqrt of negative number not allowed.");
00835
00836 theta[0] = atan2(sqrt(tmp) , A/Ro) + B;
00837 theta[3] = atan2(-sqrt(tmp) , A/Ro) + B;
00838
00839 diff1 = fabs(q_actual(3)-theta[0]);
00840 if (diff1 > M_PI)
00841 diff1 = 2*M_PI - diff1 ;
00842
00843 diff2 = fabs(q_actual(3)-theta[3]);
00844 if (diff2 > M_PI)
00845 diff1 = 2*M_PI - diff2;
00846
00847
00848 if (diff1 < diff2)
00849 theta[3] = theta[0];
00850
00851 H = cos(theta[1])*Tobj(1,4) + sin(theta[1])*Tobj(2,4);
00852 L = sin(theta[3])*links[4].d + cos(theta[3])*links[3].a + links[2].a;
00853 M = cos(theta[3])*links[4].d - sin(theta[3])*links[3].a;
00854
00855 theta[2] = atan2( M , L ) - atan2(Tobj(3,4) , H );
00856
00857 theta[0] = atan2( -sin(theta[1])*Tobj(1,3) + cos(theta[1])*Tobj(2,3) ,
00858 cos(theta[2] + theta[3]) *
00859 (cos(theta[1]) * Tobj(1,3) + sin(theta[1])*Tobj(2,3))
00860 - (sin(theta[2]+theta[3])*Tobj(3,3)) );
00861
00862 theta[4] = atan2(-1*(-sin(theta[1])*Tobj(1,3) + cos(theta[1])*Tobj(2,3)),
00863 -cos(theta[2] + theta[3]) *
00864 (cos(theta[1]) * Tobj(1,3) + sin(theta[1])*Tobj(2,3))
00865 + (sin(theta[2]+theta[3])*Tobj(3,3)) );
00866
00867 diff1 = fabs(q_actual(4)-theta[0]);
00868 if (diff1 > M_PI)
00869 diff1 = 2*M_PI - diff1;
00870
00871 diff2 = fabs(q_actual(4)-theta[4]);
00872 if (diff2 > M_PI)
00873 diff1 = 2*M_PI - diff2;
00874
00875
00876 if (diff1 < diff2)
00877 theta[4] = theta[0];
00878
00879 theta[5] = atan2( cos(theta[4]) *
00880 ( cos(theta[2] + theta[3]) *
00881 (cos(theta[1]) * Tobj(1,3)
00882 + sin(theta[1])*Tobj(2,3))
00883 - (sin(theta[2]+theta[3])*Tobj(3,3)) ) +
00884 sin(theta[4])*(-sin(theta[1])*Tobj(1,3)
00885 + cos(theta[1])*Tobj(2,3)) ,
00886 sin(theta[2]+theta[3]) * (cos(theta[1]) * Tobj(1,3)
00887 + sin(theta[1])*Tobj(2,3) )
00888 + (cos(theta[2]+theta[3])*Tobj(3,3)) );
00889
00890 theta[6] = atan2( -sin(theta[4])
00891 * ( cos(theta[2] + theta[3]) *
00892 (cos(theta[1]) * Tobj(1,1)
00893 + sin(theta[1])*Tobj(2,1))
00894 - (sin(theta[2]+theta[3])*Tobj(3,1))) +
00895 cos(theta[4])*(-sin(theta[1])*Tobj(1,1)
00896 + cos(theta[1])*Tobj(2,1)),
00897 -sin(theta[4]) * ( cos(theta[2] + theta[3]) *
00898 (cos(theta[1]) * Tobj(1,2)
00899 + sin(theta[1])*Tobj(2,2))
00900 - (sin(theta[2]+theta[3])*Tobj(3,2))) +
00901 cos(theta[4])*(-sin(theta[1])*Tobj(1,2)
00902 + cos(theta[1])*Tobj(2,2)) );
00903
00904 qout(1) = theta[1];
00905 qout(2) = theta[2];
00906 qout(3) = theta[3];
00907 qout(4) = theta[4];
00908 qout(5) = theta[5];
00909 qout(6) = theta[6];
00910 set_q(qout);
00911
00912 converge = true;
00913 }
00914 catch(std::out_of_range & e)
00915 {
00916 converge = false;
00917 set_q(q_actual);
00918 qout = q_actual;
00919 }
00920
00921 qout.Release();
00922 return qout;
00923 }
00924
00925 ReturnMatrix Robot::inv_kin_pan_tilt(const ColumnVector & Pobj, bool & converge)
00926
00927
00928
00929
00930
00931 {
00932
00933 ColumnVector qout, qtmp,
00934 xyz1, xyz2,
00935 xyz0 = Pobj;
00936 Matrix M01,
00937 M12;
00938
00939 qtmp = get_q();
00940 M01 = convertFrame(1,2);
00941
00942 xyz1 = M01*xyz0;
00943
00944 qtmp(2)=atan2(xyz1(2),xyz1(1));
00945 set_q(qtmp);
00946 M12 = convertFrame(2,3);
00947
00948 xyz2 = M12*xyz1;
00949
00950 qtmp(3)=atan2(xyz2(2),xyz2(1));
00951 set_q(qtmp);
00952
00953
00954
00955 if( qtmp(2) < links[2].get_theta_min() )
00956 qtmp(2) = links[2].get_theta_min();
00957 if( qtmp(2) > links[2].get_theta_max() )
00958 qtmp(2) = links[2].get_theta_max();
00959 if( qtmp(3) < links[3].get_theta_min() )
00960 qtmp(3) = links[3].get_theta_min();
00961 if( qtmp(3) > links[3].get_theta_max() )
00962 qtmp(3) = links[3].get_theta_max();
00963
00964
00965 qout = qtmp;
00966 converge=true;
00967 return qout;
00968 }
00969
00970 ReturnMatrix Robot::inv_kin_goose_neck(const Matrix & Tobj)
00971
00972
00973 {
00974
00975 ColumnVector qout, Pobj(3);
00976 Real phi;
00977 Pobj(1) = Tobj(1,4);
00978 Pobj(2) = Tobj(2,4);
00979 Pobj(3) = Tobj(3,4);
00980 phi = atan2(Tobj(3,3),Tobj(1,3));
00981 qout = goose_neck_angles(Pobj, phi);
00982 return qout;
00983 }
00984
00985 ReturnMatrix Robot::inv_kin_goose_neck_pos(const ColumnVector & Pobj)
00986
00987
00988 {
00989
00990 ColumnVector qout;
00991 qout = goose_neck_angles(Pobj, -1.57079632679);
00992 return qout;
00993 }
00994
00995
00996
00997
00998
00999
01000
01001 ReturnMatrix Robot::goose_neck_angles(const ColumnVector & Pobj, Real phi)
01002
01003
01004 {
01005 Real c2,
01006 qp, q1, q2, q3,
01007
01008 K1, K2,
01009 L1=links[2].get_a(),
01010 L2=links[3].get_a(),