00001
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
00036
00037 #include <math.h>
00038 #include "math\math2.h"
00039 #include "math\vector4.h"
00040 #include "Passive.h"
00041 #include "debug/debug.h"
00042
00043
00044
00045
00046
00047 CPassive::CPassive():CJoints()
00048 {
00049 solution = new Configuration[MAX_SOLUTION];
00050 }
00051
00052 CPassive::CPassive(FrameManager* frameManager)
00053 :CJoints(frameManager)
00054 {
00055 solution = new Configuration[MAX_SOLUTION];
00056 }
00057
00058 CPassive::~CPassive()
00059 {
00060 delete[] solution;
00061 }
00062
00063
00064
00065
00066
00067
00068
00069 void CPassive::SetRobot(R_OpenChain *robot)
00070 {
00071 CJoints::SetRobot(robot);
00072 Frame *frame = frameManager->GetFrameRef(robot->GetToolFrame(0));
00073 if (frame != NULL)
00074 effectFrame.SetValues(*(frame));
00075 else
00076 effectFrame.SetValues(Frame::Identity());
00077 }
00078
00079
00080
00081
00082
00083
00084 void CPassive::SetLastJoint(unsigned int joint)
00085 {
00086 CJoints::SetLastJoint(joint);
00087 for (int i=0; i<MAX_SOLUTION; i++)
00088 {
00089 solution[i].SetNumDOF(jointNum);
00090 }
00091 solutionNum = 0;
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 void CPassive::SetEndEffectFrame(Frame &frame)
00107 {
00108 effectFrame.SetValues(frame);
00109
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 void CPassive::SetDesireEndEffect(Frame &frame)
00126 {
00127 desireEffect.SetValues(frame);
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 void CPassive::SetFirstFrame(Frame &frame)
00144 {
00145 firstFrame.SetValues(frame);
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 bool CPassive::GetRandomConfiguration(Configuration &conf)
00162 {
00163 conf.SetLength(jointNum);
00164 if (jointNum==0)
00165 return true;
00166
00167 for( int i = 0; i < jointNum; i++ )
00168 {
00169 double max = links[firstJoint+i]->JointMax() ;
00170 double min = links[firstJoint+i]->JointMin() ;
00171 double random = 2*( double( rand() ) / RAND_MAX ) - 1;
00172 double jointvalue = ( max - min ) * random;
00173
00174
00175 if ( jointvalue < min )
00176 {
00177 jointvalue += (max - min);
00178 }
00179 else if ( jointvalue > max )
00180 {
00181 jointvalue -= (max - min);
00182 }
00183
00184 conf[ i ] = jointvalue;
00185 }
00186
00187 return true;
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 bool CPassive::GetConfiguration(Configuration &conf)
00204 {
00205 conf.SetLength(jointNum);
00206 if (jointNum==0)
00207 return true;
00208
00209 if (!Inverse())
00210 return false;
00211
00212 int random = solutionNum*rand() / (RAND_MAX+2);
00213
00214 for (int i=0; i<jointNum; i++)
00215 conf[i] = (solution[random])[i];
00216 return true;
00217 }
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 bool CPassive::GetConfiguration(Configuration &conf, Configuration ¤t, double dist)
00236 {
00237 conf.SetLength(jointNum);
00238 if (jointNum==0)
00239 return true;
00240
00241 bool bFind;
00242 int i, j;
00243 if (!Inverse())
00244 {
00245 return false;
00246 }
00247
00248
00249
00250
00251
00252
00253 for (i=0; i<solutionNum; i++)
00254 {
00255 bFind = true;
00256
00257 for (j=0; j<jointNum; j++)
00258 {
00259 if (Distance(links[firstJoint+j],solution[i][j], current[j])>dist)
00260 {
00261 bFind = false;
00262 break;
00263 }
00264 }
00265 if (bFind)
00266 {
00267 for (j=0; j<jointNum; j++)
00268 conf[j] = (solution[i])[j];
00269 break;
00270 }
00271 }
00272 return bFind;
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 bool CPassive::GetConfiguration(Configuration &conf, Configuration ¤t)
00291 {
00292 conf.SetLength(jointNum);
00293 if (jointNum==0)
00294 return true;
00295
00296 int i, j;
00297 if (!Inverse())
00298 {
00299 return false;
00300 }
00301
00302
00303
00304
00305
00306
00307 int minDist = 0;
00308 int minSolution = 0;
00309 for (j=0; j<jointNum; j++)
00310 {
00311 double dist = Distance(links[firstJoint+j], solution[0][j], current[j]);
00312 minDist += dist*dist;
00313 }
00314
00315 for (i=1; i<solutionNum; i++)
00316 {
00317 double currDist=0;
00318 for (j=0; j<jointNum; j++)
00319 {
00320 double dist = Distance(links[firstJoint+j], solution[i][j], current[j]);
00321 currDist += dist*dist;
00322 }
00323
00324 if (currDist < minDist)
00325 {
00326 minDist = currDist;
00327 minSolution = i;
00328 }
00329 }
00330
00331 for (j=0; j<jointNum; j++)
00332 {
00333 conf[j] = (solution[minSolution])[j];
00334 }
00335
00336 return true;
00337 }
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 bool CPassive::ResolveJoints(DH_Parameter type)
00354 {
00355 return false;
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 bool CPassive::ResolveJoints(DH_Parameter type1, DH_Parameter type2)
00373 {
00374 double a1, alpha1, d1, theta1;
00375 double a2, alpha2, d2, theta2;
00376
00377 DH_Link *link1 = (DH_Link *) links[firstJoint];
00378 DH_Link *link2 = (DH_Link *) links[firstJoint+1];
00379
00380 a1 = link1->GetA();
00381 a2 = link2->GetA();
00382
00383 d1 = link1->GetD();
00384 d2 = link2->GetD();
00385
00386 alpha1 = link1->GetAlpha();
00387 alpha2 = link2->GetAlpha();
00388
00389 theta1 = link1->GetTheta();
00390 theta2 = link2->GetTheta();
00391
00392 double x, y, z;
00393 double Xe, Ye, Ze;
00394 double Xo, Yo, Zo;
00395
00396
00397 Xe = desireEffect(0, 3);
00398 Ye = desireEffect(1, 3);
00399 Ze = desireEffect(2, 3);
00400
00401
00402 x = effectFrame(0, 3);
00403 y = effectFrame(1, 3);
00404 z = effectFrame(2, 3);
00405
00406 Vector4 firstPos(a1, -sin(alpha1)*d1, cos(alpha1)*d1);
00407 Vector4 firstPos0= firstFrame * firstPos;
00408 Xo = firstPos0[0];
00409 Yo = firstPos0[1];
00410 Zo = firstPos0[2];
00411
00412
00413
00414
00415 double a, b, c, d;
00416
00417 double solu[2];
00418 int num;
00419
00420 solutionNum = 0;
00421
00422
00423 if ((type1==DH_THETA)&& (type2==DH_THETA))
00424 {
00425 a = (Xe-Xo)*(Xe-Xo)+(Ye-Yo)*(Ye-Yo)-a1*a1-a2*a2;
00426 b = -2*a1*a2;
00427
00428 double cos2, sin2;
00429 cos2 = a/b;
00430 if (fabs(cos2)>1)
00431 {
00432 if (IsZero(fabs(cos2)-1))
00433 {
00434 cos2 = cos2/fabs(cos2);
00435 sin2 = 0;
00436 }
00437 else
00438 {
00439 return false;
00440 }
00441 }
00442 else
00443 {
00444 sin2 = sqrt(1-cos2*cos2);
00445 }
00446
00447 sin2 = sqrt(1-cos2*cos2);
00448
00449 solution[0][1] = M_PI-atan2(sin2, cos2);
00450 solution[1][1] = atan2(sin2, cos2)-M_PI;
00451
00452 solutionNum = 2;
00453
00454 Vector4 end2First(Xe, Ye, Ze);
00455 Vector4 end2First0 = firstFrame.Inverse() * end2First;
00456 Xo = end2First0[0];
00457 Yo = end2First0[1];
00458 Zo = end2First0[2];
00459
00460 for (int i=0; i<2; i++)
00461 {
00462 cos2 = cos(solution[i][1]);
00463 sin2 = sin(solution[i][1]);
00464
00465 a = cos(alpha1)*Yo+sin(alpha1)*Zo;
00466 b = Xo-a1;
00467 c = sin2*x - cos2*y;
00468 d = a2 + cos2*x - sin2*y;
00469
00470 Solution(a, b, c, d, solu[0]);
00471 solution[i][0] = solu[0];
00472 }
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 }
00531
00532
00533 else if((type1==DH_D)&& (type2==DH_D))
00534 {
00535 a = cos(theta1)*(Xe-a1)
00536 +sin(theta1)*(cos(alpha1)*Ye+sin(alpha1)*Ze)
00537 -cos(theta2)*x+sin(theta2)*y-a2;
00538
00539 if (!IsZero(a))
00540 return false;
00541
00542
00543 a=sin(alpha2);
00544 b=-(-sin(theta1)*(Xe-a1)
00545 +cos(theta1)*(cos(alpha1)*Ye+sin(alpha1)*Ze)
00546 -sin(theta2)*cos(alpha2)*x
00547 -cos(theta2)*cos(alpha2)*y+sin(alpha2)*z
00548 );
00549
00550 if (!IsZero(a))
00551 return false;
00552 solution[0][1]=d2=b/a;
00553
00554
00555 solution[0][0]=(-sin(theta2)*sin(alpha2)*x
00556 -cos(theta2)*sin(alpha2)*y
00557 -sin(alpha1)*Ye
00558 +cos(alpha1)*Ze
00559 -cos(alpha2)*z
00560 -cos(alpha2)*d2
00561 );
00562
00563 solutionNum = 1;
00564 }
00565
00566
00567 else if((type1==DH_THETA)&& (type2==DH_D))
00568 {
00569
00570 a=(Xe-a1);
00571 b=(cos(alpha1)*Ye+sin(alpha1)*Ze);
00572 c=-(-cos(theta2)*x+sin(theta2)*y-a2);
00573
00574 Solution(a, b, c, solu, num);
00575 if (num==1)
00576 {
00577 solutionNum = 1;
00578 solution[0][0] = solu[0];
00579 }
00580 else if (num==2)
00581 {
00582 solutionNum = 2;
00583 solution[0][0] = solu[0];
00584 solution[1][0] = solu[1];
00585 }
00586 else
00587 {
00588 return false;
00589 }
00590
00591
00592 for (int i=0; i<solutionNum; i++)
00593 {
00594 theta1 = solution[i][0];
00595
00596 a=sin(alpha2);
00597 b=-(-sin(theta1)*(Xe-a1)
00598 +cos(theta1)*(cos(alpha1)*Ye+sin(alpha1)*Ze)
00599 -sin(theta2)*cos(alpha2)*x
00600 -cos(theta2)*cos(alpha2)*y
00601 +sin(alpha2)*z
00602 );
00603
00604
00605 if (!IsZero(a))
00606 {
00607 solutionNum = 0;
00608 return false;
00609 }
00610 else
00611 {
00612 solution[i][1] = b/a;
00613 }
00614 }
00615
00616 }
00617
00618
00619 else
00620 {
00621
00622 a=cos(alpha2)*y;
00623 b=cos(alpha2)*x;
00624 c=-sin(theta1)*(Xe-a1)
00625 +cos(theta1)*(cos(alpha1)*Ye+sin(alpha1)*Ze)
00626 +sin(alpha2)*z+sin(alpha2)*d2;
00627
00628 Solution(a, b, c, solu, num);
00629 if (num==1)
00630 {
00631 solutionNum = 1;
00632 solution[0][1] = solu[0];
00633 }
00634 else if (num==2)
00635 {
00636 solutionNum = 2;
00637 solution[0][1] = solu[0];
00638 solution[1][1] = solu[1];
00639 }
00640 else
00641 {
00642 return false;
00643 }
00644
00645
00646 for (int i=0; i<solutionNum; i++)
00647 {
00648 theta2 = solution[i][1];
00649
00650 solution[i][0]=(-sin(theta2)*sin(alpha2)*x
00651 -cos(theta2)*sin(alpha2)*y
00652 -sin(alpha1)*Ye+cos(alpha1)*Ze
00653 -cos(alpha2)*z
00654 -cos(alpha2)*d2
00655 );
00656 }
00657 }
00658
00659 return true;
00660 }
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676 bool CPassive::ResolveJoints(DH_Parameter type1, DH_Parameter type2, DH_Parameter type3)
00677 {
00678 double a1, alpha1, d1, theta1;
00679 double a2, alpha2, d2, theta2;
00680
00681 DH_Link *link1 = (DH_Link *) links[firstJoint];
00682 DH_Link *link2 = (DH_Link *) links[firstJoint+1];
00683 DH_Link *link3 = (DH_Link *) links[firstJoint+2];
00684
00685 a1 = link1->GetA();
00686 a2 = link2->GetA();
00687
00688 d1 = link1->GetD();
00689 d2 = link2->GetD();
00690
00691 alpha1 = link1->GetAlpha();
00692 alpha2 = link2->GetAlpha();
00693
00694 theta1 = link1->GetTheta();
00695 theta2 = link2->GetTheta();
00696
00697 double x, y, z;
00698 double Xw, Yw, Zw;
00699 double Xo, Yo, Zo;
00700
00701 Frame desireWrist = desireEffect * effectFrame.Inverse();
00702 Xw = desireWrist(0, 3);
00703 Yw = desireWrist(1, 3);
00704 Zw = desireWrist(2, 3);
00705
00706 link3->SetJointVariable(0);
00707 Frame wristFrame = link3->GetFrame();
00708 x = wristFrame(0, 3);
00709 y = wristFrame(1, 3);
00710 z = wristFrame(2, 3);
00711
00712 Vector4 firstPos(a1, -sin(alpha1)*d1, cos(alpha1)*d1);
00713 Vector4 firstPos0= firstFrame * firstPos;
00714 Xo = firstPos0[0];
00715 Yo = firstPos0[1];
00716 Zo = firstPos0[2];
00717
00718
00719
00720
00721 #if 0
00722 Log("passive.log", \
00723 "desireEffect:\n \
00724 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00725 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00726 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n", \
00727 desireEffect(0, 0), desireEffect(0, 1), desireEffect(0, 2), desireEffect(0, 3), \
00728 desireEffect(1, 0), desireEffect(1, 1), desireEffect(1, 2), desireEffect(1, 3), \
00729 desireEffect(2, 0), desireEffect(2, 1), desireEffect(2, 2), desireEffect(2, 3) \
00730 );
00731 Log("passive.log", \
00732 "desireWrist:\n \
00733 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00734 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00735 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n", \
00736 desireWrist(0, 0), desireWrist(0, 1), desireWrist(0, 2), desireWrist(0, 3), \
00737 desireWrist(1, 0), desireWrist(1, 1), desireWrist(1, 2), desireWrist(1, 3), \
00738 desireWrist(2, 0), desireWrist(2, 1), desireWrist(2, 2), desireWrist(2, 3) \
00739 );
00740 Log("passive.log", \
00741 "wristFrame:\n \
00742 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00743 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00744 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n", \
00745 wristFrame(0, 0), wristFrame(0, 1), wristFrame(0, 2), wristFrame(0, 3),
00746 wristFrame(1, 0), wristFrame(1, 1), wristFrame(1, 2), wristFrame(1, 3),
00747 wristFrame(2, 0), wristFrame(2, 1), wristFrame(2, 2), wristFrame(2, 3)
00748 );
00749 Log("passive.log", \
00750 "firstFrame:\n \
00751 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00752 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00753 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n", \
00754 firstFrame(0, 0), firstFrame(0, 1), firstFrame(0, 2), firstFrame(0, 3),
00755 firstFrame(1, 0), firstFrame(1, 1), firstFrame(1, 2), firstFrame(1, 3),
00756 firstFrame(2, 0), firstFrame(2, 1), firstFrame(2, 2), firstFrame(2, 3)
00757 );
00758 #endif
00759
00760 double a, b, c, d;
00761 double solu[2];
00762
00763 solutionNum = 0;
00764
00765 if ((type1==DH_THETA)&& (type2==DH_THETA) && (type3==DH_THETA))
00766 {
00767 a = (Xw-Xo)*(Xw-Xo)+(Yw-Yo)*(Yw-Yo)-a1*a1-a2*a2;
00768 b = -2*a1*a2;
00769
00770 double cos2, sin2;
00771 cos2 = a/b;
00772 if (fabs(cos2)>1)
00773 {
00774 if (IsZero(fabs(cos2)-1))
00775 {
00776 cos2 = cos2/fabs(cos2);
00777 sin2 = 0;
00778 }
00779 else
00780 {
00781 return false;
00782 }
00783 }
00784 else
00785 {
00786 sin2 = sqrt(1-cos2*cos2);
00787 }
00788
00789 solution[0][1] = M_PI-atan2(sin2, cos2);
00790 solution[1][1] = atan2(sin2, cos2)-M_PI;
00791
00792 solutionNum = 2;
00793
00794 Vector4 end2First(Xw, Yw, Zw);
00795 Vector4 end2First0 = firstFrame.Inverse() * end2First;
00796 Xo = end2First0[0];
00797 Yo = end2First0[1];
00798 Zo = end2First0[2];
00799
00800 for (int i=0; i<2; i++)
00801 {
00802 cos2 = cos(solution[i][1]);
00803 sin2 = sin(solution[i][1]);
00804
00805 a = cos(alpha1)*Yo+sin(alpha1)*Zo;
00806 b = Xo-a1;
00807 c = sin2*x - cos2*y;
00808 d = a2 + cos2*x - sin2*y;
00809
00810 Solution(a, b, c, d, solu[0]);
00811 solution[i][0] = solu[0];
00812
00813
00814 link1->SetJointVariable(Rad2Deg(solution[i][0]));
00815 link2->SetJointVariable(Rad2Deg(solution[i][1]));
00816 link3->SetJointVariable(0);
00817 Frame currWristFrame = firstFrame*link1->GetFrame()*link2->GetFrame()*link3->GetFrame();
00818 Frame link3Frame = currWristFrame.Inverse() * desireWrist;
00819
00820 #if 0
00821 Log("passive.log", \
00822 "currWristFrame:\n \
00823 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00824 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00825 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n", \
00826 currWristFrame(0, 0), currWristFrame(0, 1), currWristFrame(0, 2), currWristFrame(0, 3),
00827 currWristFrame(1, 0), currWristFrame(1, 1), currWristFrame(1, 2), currWristFrame(1, 3),
00828 currWristFrame(2, 0), currWristFrame(2, 1), currWristFrame(2, 2), currWristFrame(2, 3)
00829 );
00830 Log("passive.log", \
00831 "link3Frame:\n \
00832 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00833 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00834 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n", \
00835 link3Frame(0, 0), link3Frame(0, 1), link3Frame(0, 2), link3Frame(0, 3),
00836 link3Frame(1, 0), link3Frame(1, 1), link3Frame(1, 2), link3Frame(1, 3),
00837 link3Frame(2, 0), link3Frame(2, 1), link3Frame(2, 2), link3Frame(2, 3)
00838 );
00839 #endif
00840
00841 Solution(link3Frame, solu[0]);
00842 solution[i][2] = solu[0];
00843 #if 0
00844 Log("passive.log", "The solution we get is %f\n==========", solu[0]);
00845 #endif
00846 }
00847
00848 }
00849 else
00850 {
00851
00852 assert(false);
00853 }
00854 return true;
00855 }
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877 bool CPassive::Inverse()
00878 {
00879
00880 if ((jointNum>3) || (jointNum<=0))
00881 {
00882 return false;
00883 }
00884
00885 DH_Parameter type1, type2, type3;
00886
00887 DH_Link *link1, *link2, *link3;
00888
00889 link1 = (DH_Link *) links[firstJoint];
00890 type1 = link1->GetJointType();
00891 if ((type1 == DH_ALPHA) || (type1 == DH_A))
00892 {
00893 return false;
00894 }
00895
00896 if (jointNum > 1)
00897 {
00898 link2 = (DH_Link *)links[firstJoint+1];
00899 type2 = link2->GetJointType();
00900
00901 if ((type2 == DH_ALPHA) || (type2 == DH_A))
00902 {
00903 return false;
00904 }
00905 }
00906
00907 if (jointNum > 2)
00908 {
00909 link3 = (DH_Link *)links[firstJoint+2];
00910 type3 = link3->GetJointType();
00911
00912 if ((type2 == DH_ALPHA) || (type2 == DH_A))
00913 {
00914 return false;
00915 }
00916 }
00917
00918 bool bResolved;
00919 if (jointNum==1)
00920 {
00921 bResolved = ResolveJoints(type1);
00922 }
00923 else if (jointNum==2)
00924 {
00925 bResolved = ResolveJoints(type1, type2);
00926 }
00927 else if (jointNum==3)
00928 {
00929 bResolved = ResolveJoints(type1, type2, type3);
00930 }
00931
00932 if (bResolved)
00933 {
00934 for (int i=0; i<solutionNum; i++)
00935 for (int j=0; j<jointNum; j++)
00936 solution[i][j] = Rad2Deg(solution[i][j]);
00937 }
00938
00939 return bResolved;
00940 }
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958 bool __inline CPassive::Solution(double a, double b, double c, double solution[2], int &num)
00959 {
00960 if ((a==0) && (b==0))
00961 {
00962 num = 0;
00963 return false;
00964 }
00965
00966 if ((a*a+b*b)<(c*c))
00967 {
00968 return false;
00969 }
00970 else if ((a*a+b*b)==(c*c))
00971 {
00972 num = 1;
00973 if (c>0)
00974 solution[0] = atan2(b,a);
00975 else
00976 solution[0] = atan2(b,a)+M_PI;
00977 }
00978 else
00979 {
00980 num = 2;
00981 solution[0] = atan2(b,a)+atan2(sqrt(a*a+b*b-c*c), c);
00982 solution[1] = atan2(b,a)-atan2(sqrt(a*a+b*b-c*c), c);
00983 }
00984 return true;
00985 }
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003 bool __inline CPassive::Solution(double a, double b, double c, double d, double &solution)
01004 {
01005 if ((a==0) && (b==0))
01006 {
01007 return false;
01008 }
01009
01010 solution = atan2(a*d-b*c, a*c+b*d);
01011 return true;
01012 }
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029 bool __inline CPassive::Solution(Frame &rotated, double &solution)
01030 {
01031 double temp;
01032 temp = rotated.values[0][0] + rotated.values[1][1] + rotated.values[2][2] - 1;
01033
01034 assert( fabs(temp) <= (2+ROUNDING_ERROR) );
01035
01036 solution = acos(temp/2);
01037 if ((rotated.values[1][0] - rotated.values[0][1]) < 0)
01038 solution = -solution;
01039 return true;
01040 }