00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "Rotation.h"
00015
00016 namespace O_SESSAME {
00017
00018
00019
00020 Rotation::Rotation() : m_RotationSense(RIGHT_HAND) { }
00021
00022
00023
00024 Rotation::~Rotation() { }
00025
00026
00027
00028
00029 Rotation::Rotation(const Matrix& _inMatrix) { Set(_inMatrix); }
00030
00031
00032
00033
00034 Rotation::Rotation(const DirectionCosineMatrix& _Matrix) { Set(_Matrix); }
00035
00036
00037
00038
00039
00040 Rotation::Rotation(const Vector& _Angles, const int& _Sequence) { Set(_Angles, _Sequence); }
00041
00042
00043
00044
00045
00046
00047
00048 Rotation::Rotation(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence) { Set(_Angle1, _Angle2, _Angle3, _Sequence); }
00049
00050
00051
00052
00053
00054 Rotation::Rotation(const Vector& _Axis, const Angle& _Angle) { Set(_Axis, _Angle); }
00055
00056
00057
00058
00059 Rotation::Rotation(const ModifiedRodriguezParameters& _MRP) { Set(_MRP); }
00060
00061
00062
00063
00064 Rotation::Rotation(const Quaternion& _quat) { Set(_quat); }
00065
00066
00067
00068
00069 void Rotation::Set(const Matrix& _inMatrix)
00070 {
00071 if((_inMatrix[MatrixRowsIndex].getIndexCount() == 3) && (_inMatrix[MatrixColsIndex].getIndexCount() == 3))
00072 {
00073 m_quaternion.Set(DirectionCosineMatrix(_inMatrix));
00074 }
00075 if((_inMatrix[MatrixRowsIndex].getIndexCount() == QUATERNION_SIZE) && (_inMatrix[MatrixColsIndex].getIndexCount() == 1))
00076 {
00077
00078 }
00079 return;
00080 }
00081
00082
00083
00084
00085 void Rotation::Set(const DirectionCosineMatrix& _DCM)
00086 {
00087 m_quaternion.Set(_DCM);
00088 return;
00089 }
00090
00091
00092
00093
00094
00095 void Rotation::Set(const Vector& _Angles, const int& _Sequence)
00096 {
00097 m_quaternion.Set(_Angles, _Sequence);
00098 return;
00099 }
00100
00101
00102
00103
00104
00105
00106
00107 void Rotation::Set(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence)
00108 {
00109 m_quaternion.Set(_Angle1, _Angle2, _Angle3, _Sequence);
00110 return;
00111 }
00112
00113
00114
00115
00116
00117 void Rotation::Set(const Vector& _Axis, const Angle& _Angle)
00118 {
00119 m_quaternion.Set(_Axis, _Angle);
00120 return;
00121 }
00122
00123
00124
00125
00126 void Rotation::Set(const ModifiedRodriguezParameters& _MRP)
00127 {
00128 m_quaternion.Set(_MRP);
00129 return;
00130 }
00131
00132
00133
00134
00135 void Rotation::Set(const Quaternion& _quat)
00136 {
00137 m_quaternion(1) = _quat(1);
00138 m_quaternion(2) = _quat(2);
00139 m_quaternion(3) = _quat(3);
00140 m_quaternion(4) = _quat(4);
00141 return;
00142 }
00143
00144
00145
00146
00147
00148 DirectionCosineMatrix Rotation::GetDCM() const
00149 {
00150 return DirectionCosineMatrix(m_quaternion);
00151 }
00152
00153
00154
00155
00156
00157 Vector Rotation::GetEulerAngles(const int& _Sequence) const
00158 {
00159 return m_quaternion.GetEulerAngles(_Sequence);
00160 }
00161
00162
00163
00164
00165 Vector Rotation::GetEulerAxisAngle() const
00166 {
00167 return m_quaternion.GetEulerAxisAngle();
00168 }
00169
00170
00171
00172
00173
00174 Vector Rotation::GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const
00175 {
00176 return m_quaternion.GetEulerAxisAngle(_EulerAxis, _EulerAngle);
00177 }
00178
00179
00180
00181
00182 ModifiedRodriguezParameters Rotation::GetMRP() const
00183 {
00184 return ModifiedRodriguezParameters(m_quaternion);
00185 }
00186
00187
00188
00189
00190 Quaternion Rotation::GetQuaternion() const
00191 {
00192 return m_quaternion;
00193 }
00194
00195
00196
00197
00198
00199
00200
00201 Vector Rotation::GetRotation(const RotationType& _type, const int& _Sequence) const
00202 {
00203 if(_type == DCM_Type)
00204 {
00205 Matrix tempMatrix = GetDCM();
00206 Vector tempVector(DCM_SIZE * DCM_SIZE);
00207
00208 for (int ii = VectorIndexBase; ii < DCM_SIZE + VectorIndexBase; ++ii)
00209 {
00210 tempVector(_(VectorIndexBase + DCM_SIZE*(ii-VectorIndexBase),VectorIndexBase + DCM_SIZE*ii-1)) = ~tempMatrix(ii, _);
00211 }
00212 return tempVector;
00213 }
00214 else if(_type == EulerAngle_Type)
00215 {
00216 return GetEulerAngles(_Sequence);
00217 }
00218 else if(_type == EulerAxisAngle_Type)
00219 {
00220 return GetEulerAxisAngle();
00221 }
00222 else if(_type == MRP_Type)
00223 {
00224 return (Vector)GetMRP();
00225 }
00226 else if(_type == Quaternion_Type)
00227 {
00228 return (Vector)GetQuaternion();
00229 }
00230
00231
00232 return (Vector)GetQuaternion();
00233 }
00234
00235
00236
00237
00238 Rotation Rotation::operator* (const Rotation& _rot2) const
00239 {
00240 return Rotation((*this).GetDCM() * _rot2.GetDCM());
00241 }
00242
00243
00244
00245 Vector Rotation::operator* (const Vector& _vec2) const
00246 {
00247 return ((*this).GetDCM() * _vec2);
00248 }
00249
00250
00251
00252
00253 Rotation Rotation::operator~ () const
00254 {
00255 Rotation rotOut(~((*this).GetDCM()));
00256 return rotOut;
00257 }
00258
00259
00260
00261 Rotation Rotation::operator+ (const Rotation& _rot2) const
00262 {
00263 Rotation rotOut(this->operator*(_rot2));
00264 return rotOut;
00265 }
00266
00267
00268
00269
00270
00271
00272 Rotation Rotation::operator- (const Rotation& _rot2) const
00273 {
00274 Rotation rotOut(this->operator*(~_rot2));
00275 return rotOut;
00276 }
00277
00278
00279
00280
00281
00282 DirectionCosineMatrix::DirectionCosineMatrix():Matrix(DCM_SIZE, DCM_SIZE)
00283 {
00284 (*this) = eye(DCM_SIZE);
00285 }
00286
00287
00288
00289 DirectionCosineMatrix::DirectionCosineMatrix(const DirectionCosineMatrix& _DCM):Matrix(DCM_SIZE, DCM_SIZE)
00290 {
00291 Set(_DCM);
00292 }
00293
00294
00295
00296 DirectionCosineMatrix::DirectionCosineMatrix(const Matrix& _DCM):Matrix(DCM_SIZE, DCM_SIZE)
00297 {
00298 Set(_DCM);
00299 }
00300
00301
00302
00303
00304
00305 DirectionCosineMatrix::DirectionCosineMatrix(const Vector& _EulerAngles, const int& _Sequence):Matrix(DCM_SIZE, DCM_SIZE)
00306 {
00307 Set(_EulerAngles, _Sequence);
00308 }
00309
00310
00311
00312
00313
00314
00315
00316 DirectionCosineMatrix::DirectionCosineMatrix(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence):Matrix(DCM_SIZE, DCM_SIZE)
00317 {
00318 Set(_Angle1, _Angle2, _Angle3, _Sequence);
00319 }
00320
00321
00322
00323
00324
00325 DirectionCosineMatrix::DirectionCosineMatrix(const Vector& _EulerAxis, const Angle& _EulerAngle):Matrix(DCM_SIZE, DCM_SIZE)
00326 {
00327 Set(_EulerAxis, _EulerAngle);
00328 }
00329
00330
00331
00332
00333 DirectionCosineMatrix::DirectionCosineMatrix(const ModifiedRodriguezParameters& _MRP):Matrix(DCM_SIZE, DCM_SIZE)
00334 {
00335 Set(_MRP);
00336 }
00337
00338
00339
00340
00341 DirectionCosineMatrix::DirectionCosineMatrix(const Quaternion& _quat):Matrix(DCM_SIZE, DCM_SIZE)
00342 {
00343 Set(_quat);
00344 }
00345
00346
00347 DirectionCosineMatrix::~DirectionCosineMatrix()
00348 {
00349 }
00350
00351
00352
00353
00354 void DirectionCosineMatrix::Set(const DirectionCosineMatrix& _DCM)
00355 {
00356 for (int ii = MatrixIndexBase; ii <= _DCM[MatrixRowsIndex].getIndexBound(); ++ii)
00357 for (int jj = MatrixIndexBase; jj <= _DCM[MatrixColsIndex].getIndexBound(); ++jj)
00358 (*this)(ii,jj) = _DCM(ii,jj);
00359 Normalize();
00360 return;
00361 }
00362
00363
00364
00365
00366 void DirectionCosineMatrix::Set(const Matrix& _DCM)
00367 {
00368 for (int ii = MatrixIndexBase; ii <= _DCM[MatrixRowsIndex].getIndexBound(); ++ii)
00369 for (int jj = MatrixIndexBase; jj <= _DCM[MatrixColsIndex].getIndexBound(); ++jj)
00370 (*this)(ii,jj) = _DCM(ii,jj);
00371 Normalize();
00372 return;
00373 }
00374
00375
00376
00377
00378
00379 void DirectionCosineMatrix::Set(const Vector& _EulerAngles, const int& _Sequence)
00380 {
00381 Set(_EulerAngles(VectorIndexBase+0), _EulerAngles(VectorIndexBase+1), _EulerAngles(VectorIndexBase+2), _Sequence);
00382 return;
00383 }
00384
00385
00386
00387
00388
00389
00390
00391 void DirectionCosineMatrix::Set(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence)
00392 {
00393 switch(_Sequence)
00394 {
00395 case 121: (*this) = R1(_Angle3) * R2(_Angle2) * R1(_Angle1); break;
00396 case 131: (*this) = R1(_Angle3) * R3(_Angle2) * R1(_Angle1); break;
00397 case 132: (*this) = R2(_Angle3) * R3(_Angle2) * R1(_Angle1); break;
00398 case 123: (*this) = R3(_Angle3) * R2(_Angle2) * R1(_Angle1); break;
00399 case 212: (*this) = R2(_Angle3) * R1(_Angle2) * R2(_Angle1); break;
00400 case 321: (*this) = R1(_Angle3) * R2(_Angle2) * R3(_Angle1); break;
00401 case 232: (*this) = R2(_Angle3) * R3(_Angle2) * R2(_Angle1); break;
00402 case 231: (*this) = R1(_Angle3) * R3(_Angle2) * R2(_Angle1); break;
00403 case 213: (*this) = R3(_Angle3) * R1(_Angle2) * R2(_Angle1); break;
00404 case 313: (*this) = R3(_Angle3) * R1(_Angle2) * R3(_Angle1); break;
00405 case 323: (*this) = R3(_Angle3) * R2(_Angle2) * R3(_Angle1); break;
00406 case 312: (*this) = R2(_Angle3) * R1(_Angle2) * R3(_Angle1); break;
00407 default: (*this) = eye(DCM_SIZE);
00408 }
00409 Normalize();
00410 return;
00411 }
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 void DirectionCosineMatrix::Set(const Vector& _EulerAxis, const Angle& _EulerAngle)
00430 {
00431
00432 double Phi = 1 - cos(_EulerAngle);
00433 double e1 = _EulerAxis(VectorIndexBase+0);
00434 double e2 = _EulerAxis(VectorIndexBase+1);
00435 double e3 = _EulerAxis(VectorIndexBase+2);
00436 double cosPhi = cos(_EulerAngle);
00437 double sinPhi = sin(_EulerAngle);
00438
00439
00440 (*this)(MatrixIndexBase+0,MatrixIndexBase+0) = e1 * e1 * Phi + cosPhi;
00441 (*this)(MatrixIndexBase+1,MatrixIndexBase+0) = e2 * e1 * Phi - e3 * sinPhi;
00442 (*this)(MatrixIndexBase+2,MatrixIndexBase+0) = e3 * e1 * Phi + e2 * sinPhi;
00443
00444
00445 (*this)(MatrixIndexBase+0,MatrixIndexBase+1) = e1 * e2 * Phi + e3 * sinPhi;
00446 (*this)(MatrixIndexBase+1,MatrixIndexBase+1) = e2 * e2 * Phi + cosPhi;
00447 (*this)(MatrixIndexBase+2,MatrixIndexBase+1) = e3 * e2 * Phi - e1 * sinPhi;
00448
00449
00450 (*this)(MatrixIndexBase+0,MatrixIndexBase+2) = e1 * e3 * Phi - e2 * sinPhi;
00451 (*this)(MatrixIndexBase+1,MatrixIndexBase+2) = e2 * e3 * Phi + e1 * sinPhi;
00452 (*this)(MatrixIndexBase+2,MatrixIndexBase+2) = e3 * e3 * Phi + cosPhi;
00453 Normalize();
00454 return;
00455 }
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 void DirectionCosineMatrix::Set(const ModifiedRodriguezParameters& _MRP)
00473 {
00474
00475 Matrix tempMatrix = (~(_MRP) * _MRP);
00476 double Sigma = 1 - tempMatrix(MatrixIndexBase,MatrixIndexBase);
00477 double sigma1 = _MRP(VectorIndexBase+0);
00478 double sigma2 = _MRP(VectorIndexBase+1);
00479 double sigma3 = _MRP(VectorIndexBase+2);
00480
00481
00482 (*this)(MatrixIndexBase+0,MatrixIndexBase+0) = 4*(sigma1*sigma1 - sigma2*sigma2 - sigma3*sigma3) + Sigma*Sigma;
00483 (*this)(MatrixIndexBase+1,MatrixIndexBase+0) = 8*sigma2*sigma1 - 4*sigma3*Sigma;
00484 (*this)(MatrixIndexBase+2,MatrixIndexBase+0) = 8*sigma3*sigma1 + 4*sigma2*Sigma;
00485
00486
00487 (*this)(MatrixIndexBase+0,MatrixIndexBase+1) = 8*sigma1*sigma2 + 4*sigma3*Sigma;
00488 (*this)(MatrixIndexBase+1,MatrixIndexBase+1) = 4*(-sigma1*sigma1 + sigma2*sigma2 - sigma3*sigma3) + Sigma*Sigma;
00489 (*this)(MatrixIndexBase+2,MatrixIndexBase+1) = 8*sigma3*sigma2 - 4*sigma1*Sigma;
00490
00491
00492 (*this)(MatrixIndexBase+0,MatrixIndexBase+2) = 8*sigma1*sigma3 - 4*sigma2 * Sigma;
00493 (*this)(MatrixIndexBase+1,MatrixIndexBase+2) = 8*sigma2*sigma3 + 4*sigma1*Sigma;
00494 (*this)(MatrixIndexBase+2,MatrixIndexBase+2) = 4*(-sigma1*sigma1 - sigma2*sigma2 + sigma3*sigma3) + Sigma*Sigma;
00495
00496
00497 (*this) /= pow(1 + tempMatrix(MatrixIndexBase,MatrixIndexBase), 2);
00498 Normalize();
00499 return;
00500 }
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516 void DirectionCosineMatrix::Set(const Quaternion& _qIn)
00517 {
00518
00519 double q1 = _qIn(VectorIndexBase+0);
00520 double q2 = _qIn(VectorIndexBase+1);
00521 double q3 = _qIn(VectorIndexBase+2);
00522 double q4 = _qIn(VectorIndexBase+3);
00523
00524
00525 (*this)(MatrixIndexBase+0,MatrixIndexBase+0) = q4*q4 + q1*q1 - q2*q2 - q3*q3;
00526
00527 (*this)(MatrixIndexBase+1,MatrixIndexBase+0) = 2 * (q1*q2 - q4*q3);
00528 (*this)(MatrixIndexBase+2,MatrixIndexBase+0) = 2 * (q1*q3 + q4*q2);
00529
00530
00531 (*this)(MatrixIndexBase+0,MatrixIndexBase+1) = 2 * (q1*q2 + q4*q3);
00532 (*this)(MatrixIndexBase+1,MatrixIndexBase+1) = q4*q4 - q1*q1 + q2*q2 -q3*q3;
00533
00534 (*this)(MatrixIndexBase+2,MatrixIndexBase+1) = 2 * (q2*q3 - q4*q1);
00535
00536
00537 (*this)(MatrixIndexBase+0,MatrixIndexBase+2) = 2 * (q1*q3 - q4*q2);
00538 (*this)(MatrixIndexBase+1,MatrixIndexBase+2) = 2 * (q2*q3 + q4*q1);
00539
00540 (*this)(MatrixIndexBase+2,MatrixIndexBase+2) = q4*q4 - q1*q1 - q2*q2 + q3*q3;
00541
00542 Normalize();
00543 return;
00544 }
00545
00546
00547
00548
00549
00550
00551 Vector DirectionCosineMatrix::GetEulerAngles(const int& _Sequence) const
00552
00553 {
00554 Vector eulerAngles(3);
00555
00556 switch(_Sequence)
00557 {
00558 case 321:
00559 eulerAngles(1) = atan2( ((*this)(1,2)),((*this)(1,1)) );
00560 eulerAngles(2) = asin(-(*this)(1,3));
00561 eulerAngles(3) = atan2( ((*this)(2,3)),((*this)(3,3)) );
00562 break;
00563 default:
00564 cout << "This angle sequence is currently not supported." << endl;
00565 }
00566
00567 return eulerAngles;
00568 }
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 void DirectionCosineMatrix::GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const
00584 {
00585 _EulerAngle = acos(0.5 * (trace(*this) - 1));
00586 if(sin(_EulerAngle) != 0)
00587 {
00588 _EulerAxis(VectorIndexBase + 0) = ((*this)(MatrixIndexBase+1,MatrixIndexBase+2)
00589 - (*this)(MatrixIndexBase+1,MatrixIndexBase+2))
00590 / (2 * sin(_EulerAngle));
00591 _EulerAxis(VectorIndexBase + 1) = ((*this)(MatrixIndexBase+2,MatrixIndexBase+0)
00592 - (*this)(MatrixIndexBase+0,MatrixIndexBase+2))
00593 / (2 * sin(_EulerAngle));
00594 _EulerAxis(VectorIndexBase + 2) = ((*this)(MatrixIndexBase+0,MatrixIndexBase+1)
00595 - (*this)(MatrixIndexBase+0,MatrixIndexBase+1))
00596 / (2 * sin(_EulerAngle));
00597 }
00598 else
00599 {
00600 _EulerAxis.setToValue(0.0);
00601 _EulerAxis(VectorIndexBase + 0) = 1;
00602 }
00603 return;
00604 }
00605
00606
00607
00608
00609
00610
00611 ModifiedRodriguezParameters DirectionCosineMatrix::GetMRP() const
00612 {
00613 return ModifiedRodriguezParameters(*this);
00614 }
00615
00616
00617
00618
00619
00620
00621 Quaternion DirectionCosineMatrix::GetQuaternion() const
00622 {
00623 return Quaternion(*this);
00624 }
00625
00626
00627
00628
00629
00630
00631 void DirectionCosineMatrix::Normalize()
00632 {
00633 double total = 0;
00634
00635 for (int ii = MatrixIndexBase; ii < MatrixIndexBase + DCM_SIZE; ++ii)
00636 {
00637 total = sqrt(pow((*this)(ii, MatrixIndexBase),2)
00638 + pow((*this)(ii, MatrixIndexBase+1),2)
00639 + pow((*this)(ii, MatrixIndexBase+2),2));
00640 for (int jj = MatrixIndexBase; jj < MatrixIndexBase + DCM_SIZE; ++jj)
00641 {
00642 (*this)(ii, jj) /= total;
00643 }
00644 }
00645 return;
00646 }
00647
00648
00649
00650
00651 DirectionCosineMatrix DirectionCosineMatrix::operator+ (const DirectionCosineMatrix& _DCM2) const
00652 {
00653 return DirectionCosineMatrix(Matrix::operator+(static_cast<Matrix>(_DCM2)));
00654 }
00655
00656
00657
00658
00659
00660 DirectionCosineMatrix DirectionCosineMatrix::operator- (const DirectionCosineMatrix& _DCM2) const
00661 {
00662 return DirectionCosineMatrix(Matrix::operator-(static_cast<Matrix>(_DCM2)));
00663 }
00664
00665
00666
00667
00668 DirectionCosineMatrix DirectionCosineMatrix::operator* (DirectionCosineMatrix _DCM2) const
00669 {
00670 return DirectionCosineMatrix(Matrix::operator*(static_cast<Matrix>(_DCM2)));
00671 }
00672
00673
00674
00675
00676 inline Vector DirectionCosineMatrix::operator* (const Vector& _vec) const
00677 {
00678 return Matrix::operator*(_vec);
00679 }
00680
00681
00682
00683
00684 DirectionCosineMatrix DirectionCosineMatrix::operator~ ()
00685 {
00686 return DirectionCosineMatrix(Matrix::operator~());
00687 }
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703 DirectionCosineMatrix R1(const Angle& _Angle)
00704 {
00705 DirectionCosineMatrix R1_Out;
00706 R1_Out(MatrixIndexBase+1, MatrixIndexBase+1) = cos(_Angle);
00707 R1_Out(MatrixIndexBase+1, MatrixIndexBase+2) = sin(_Angle);
00708 R1_Out(MatrixIndexBase+2, MatrixIndexBase+1) = -sin(_Angle);
00709 R1_Out(MatrixIndexBase+2, MatrixIndexBase+2) = cos(_Angle);
00710 return R1_Out;
00711 }
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727 DirectionCosineMatrix R2(const Angle& _Angle)
00728 {
00729 DirectionCosineMatrix R2_Out;
00730 R2_Out(MatrixIndexBase+0, MatrixIndexBase+0) = cos(_Angle);
00731 R2_Out(MatrixIndexBase+0, MatrixIndexBase+2) = -sin(_Angle);
00732 R2_Out(MatrixIndexBase+2, MatrixIndexBase+0) = sin(_Angle);
00733 R2_Out(MatrixIndexBase+2, MatrixIndexBase+2) = cos(_Angle);
00734 return R2_Out;
00735 }
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 DirectionCosineMatrix R3(const Angle& _Angle)
00752 {
00753 DirectionCosineMatrix R3_Out;
00754 R3_Out(MatrixIndexBase+0, MatrixIndexBase+0) = cos(_Angle);
00755 R3_Out(MatrixIndexBase+0, MatrixIndexBase+1) = sin(_Angle);
00756 R3_Out(MatrixIndexBase+1, MatrixIndexBase+0) = -sin(_Angle);
00757 R3_Out(MatrixIndexBase+1, MatrixIndexBase+1) = cos(_Angle);
00758 return R3_Out;
00759 }
00760
00761
00762
00763
00764
00765
00766 ModifiedRodriguezParameters::ModifiedRodriguezParameters():Vector(MRP_SIZE)
00767 {
00768 AutoSwitch();
00769 }
00770
00771
00772
00773
00774 ModifiedRodriguezParameters::ModifiedRodriguezParameters(const ModifiedRodriguezParameters& _MRP):Vector(MRP_SIZE)
00775 {
00776 Set(_MRP);
00777 AutoSwitch();
00778 }
00779
00780
00781
00782
00783
00784
00785 ModifiedRodriguezParameters::ModifiedRodriguezParameters(const double& _s1, const double& _s2, const double& _s3):Vector(MRP_SIZE)
00786 {
00787 Set(_s1,_s2,_s3);
00788 AutoSwitch();
00789 }
00790
00791
00792
00793
00794 ModifiedRodriguezParameters::ModifiedRodriguezParameters(const Vector& _sVector):Vector(MRP_SIZE)
00795 {
00796 Set(_sVector);
00797 AutoSwitch();
00798 }
00799
00800
00801
00802
00803 ModifiedRodriguezParameters::ModifiedRodriguezParameters(const DirectionCosineMatrix& _DCM):Vector(MRP_SIZE)
00804 {
00805 Set(_DCM);
00806 AutoSwitch();
00807 }
00808
00809
00810
00811
00812
00813 ModifiedRodriguezParameters::ModifiedRodriguezParameters(const Vector& _Angles, const int& _Sequence):Vector(MRP_SIZE)
00814 {
00815 Set(_Angles, _Sequence);
00816 AutoSwitch();
00817 }
00818
00819
00820
00821
00822
00823
00824 ModifiedRodriguezParameters::ModifiedRodriguezParameters(const Vector& _EulerAxis, const Angle& _EulerAngle):Vector(MRP_SIZE)
00825 {
00826 Set(_EulerAxis, _EulerAngle);
00827 AutoSwitch();
00828 }
00829
00830
00831
00832
00833 ModifiedRodriguezParameters::ModifiedRodriguezParameters(const Quaternion& _qIn):Vector(MRP_SIZE)
00834 {
00835 Set(_qIn);
00836 AutoSwitch();
00837 }
00838
00839
00840
00841
00842 void ModifiedRodriguezParameters::Set(const ModifiedRodriguezParameters& _MRP)
00843 {
00844 for(int ii = VectorIndexBase;ii < VectorIndexBase + MRP_SIZE; ++ii)
00845 (*this)(ii) = _MRP(ii);
00846 return;
00847 }
00848
00849
00850
00851
00852
00853
00854 void ModifiedRodriguezParameters::Set(const double& _s1, const double& _s2, const double& _s3)
00855 {
00856 (*this)(VectorIndexBase+0) = _s1;
00857 (*this)(VectorIndexBase+1) = _s2;
00858 (*this)(VectorIndexBase+2) = _s3;
00859 return;
00860 }
00861
00862
00863
00864
00865 void ModifiedRodriguezParameters::Set(const Vector& _sVector)
00866 {
00867 for(int ii = VectorIndexBase;ii < VectorIndexBase + MRP_SIZE; ++ii)
00868 (*this)(ii) = _sVector(ii);
00869 return;
00870 }
00871
00872
00873
00874
00875 void ModifiedRodriguezParameters::Set(const DirectionCosineMatrix& _DCM)
00876 {
00877 Set(_DCM.GetQuaternion());
00878 return;
00879 }
00880
00881
00882
00883
00884
00885 void ModifiedRodriguezParameters::Set(const Vector& _EulerAngles, const int& _Sequence)
00886 {
00887
00888 Set(DirectionCosineMatrix(_EulerAngles, _Sequence));
00889 return;
00890 }
00891
00892
00893
00894
00895
00896
00897
00898 void ModifiedRodriguezParameters::Set(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence)
00899 {
00900
00901 Set(DirectionCosineMatrix(_Angle1, _Angle2, _Angle3, _Sequence));
00902 return;
00903 }
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913 void ModifiedRodriguezParameters::Set(const Vector& _EulerAxis, const Angle& _EulerAngle)
00914 {
00915 (*this) = (ModifiedRodriguezParameters) (tan(0.25 * _EulerAngle) * _EulerAxis);
00916 return;
00917 }
00918
00919
00920
00921
00922
00923
00924
00925
00926 void ModifiedRodriguezParameters::Set(const Quaternion& _qIN)
00927 {
00928 double denom = (1+_qIN(VectorIndexBase+3));
00929 if(denom == 0)
00930 {
00931 denom = 2;
00932 (*this)(1) = (-_qIN(1) / denom);
00933 (*this)(2) = (-_qIN(2) / denom);
00934 (*this)(3) = (-_qIN(3) / denom);
00935 }
00936 else
00937 {
00938 (*this)(1) = (_qIN(1) / denom);
00939 (*this)(2) = (_qIN(2) / denom);
00940 (*this)(3) = (_qIN(3) / denom);
00941 }
00942 return;
00943 }
00944
00945
00946
00947
00948 DirectionCosineMatrix ModifiedRodriguezParameters::GetDCM() const
00949 {
00950 return DirectionCosineMatrix(*this);
00951 }
00952
00953
00954
00955
00956
00957 Vector ModifiedRodriguezParameters::GetEulerAngles(int _Sequence) const
00958 {
00959
00960 return Vector(MRP_SIZE);
00961 }
00962
00963
00964
00965
00966
00967 void ModifiedRodriguezParameters::GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const
00968 {
00969
00970 Quaternion qTemp(*this);
00971 qTemp.GetEulerAxisAngle(_EulerAxis, _EulerAngle);
00972 return;
00973 }
00974
00975
00976
00977
00978 Quaternion ModifiedRodriguezParameters::GetQuaternion() const
00979 {
00980 return Quaternion(*this);
00981 }
00982
00983
00984
00985
00986
00987 void ModifiedRodriguezParameters::Switch(int _SwitchThreshold)
00988 {
00989 if (norm2((Vector)*this) > _SwitchThreshold)
00990 (*this) = ShadowSet();
00991 return;
00992 }
00993
00994
00995
00996
00997
00998 void ModifiedRodriguezParameters::AutoSwitch(bool _SwitchBoolean)
00999 {
01000 m_AutoSwitch = _SwitchBoolean;
01001 return;
01002 }
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012 ModifiedRodriguezParameters ModifiedRodriguezParameters::ShadowSet() const
01013 {
01014 return (ModifiedRodriguezParameters)(-(*this)(_) / pow(norm2(*this),2));
01015 }
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026 ModifiedRodriguezParameters ModifiedRodriguezParameters::operator+ (const ModifiedRodriguezParameters& _MRP2) const
01027 {
01028 ModifiedRodriguezParameters MRPsum;
01029 ModifiedRodriguezParameters chk;
01030 MRPsum(_) = (1-pow(norm2(*this),2)) * _MRP2
01031 + (1-pow(norm2(_MRP2),2)) * (*this)
01032 - 2*crossP(_MRP2,(*this));
01033 MRPsum(_) = MRPsum / (1 + pow(norm2(*this),2) * pow(norm2(_MRP2),2)
01034 - 2 * (const_cast<ModifiedRodriguezParameters *>(this))->dot( chk ));
01035 return MRPsum;
01036 }
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047 ModifiedRodriguezParameters ModifiedRodriguezParameters::operator- (const ModifiedRodriguezParameters& _MRP2) const
01048 {
01049 ModifiedRodriguezParameters MRPsum;
01050 MRPsum(_) = (1-pow(norm2(_MRP2),2)) * (*this)
01051 - (1-pow(norm2(*this),2)) * _MRP2
01052 + 2*crossP((*this), _MRP2);
01053 MRPsum(_) = MRPsum / ( 1 + pow( norm2(_MRP2),2 ) * pow(norm2(*this),2) + 2 * _MRP2.dot(* ( const_cast<ModifiedRodriguezParameters *>(this) ) ) );
01054 return MRPsum;
01055 }
01056
01057
01058
01059
01060
01061
01062 Quaternion::Quaternion():Vector(QUATERNION_SIZE)
01063 {
01064
01065 (*this)(VectorIndexBase+3) = 1.0;
01066 }
01067
01068
01069
01070
01071
01072
01073
01074
01075 Quaternion::Quaternion(double _q1, double _q2, double _q3, double _q4):Vector(QUATERNION_SIZE)
01076 {
01077 Set(_q1, _q2, _q3, _q4);
01078 }
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096 Quaternion::Quaternion(const Vector& _qVector):Vector(QUATERNION_SIZE)
01097 {
01098 Set(_qVector);
01099 }
01100
01101
01102
01103
01104
01105
01106 Quaternion::Quaternion(const DirectionCosineMatrix& _DCM):Vector(QUATERNION_SIZE)
01107 {
01108 Set(_DCM);
01109 }
01110
01111
01112
01113
01114
01115 Quaternion::Quaternion(const Vector& _EulerAngles, const int& _Sequence):Vector(QUATERNION_SIZE)
01116 {
01117 Set(_EulerAngles, _Sequence);
01118 Normalize();
01119 }
01120
01121
01122
01123
01124
01125 Quaternion::Quaternion(const Vector& _EulerAxis, const Angle& _EulerAngle):Vector(QUATERNION_SIZE)
01126 {
01127 Set(_EulerAxis, _EulerAngle);
01128 }
01129
01130
01131
01132
01133 Quaternion::Quaternion(const ModifiedRodriguezParameters& _MRP):Vector(QUATERNION_SIZE)
01134 {
01135 Set(static_cast<ModifiedRodriguezParameters>(_MRP));
01136 }
01137
01138
01139
01140
01141 void Quaternion::Set(const Quaternion& _qIn)
01142 {
01143 (*this)(VectorIndexBase+0) = _qIn(MatrixIndexBase+0);
01144 (*this)(VectorIndexBase+1) = _qIn(MatrixIndexBase+1);
01145 (*this)(VectorIndexBase+2) = _qIn(MatrixIndexBase+2);
01146 (*this)(VectorIndexBase+3) = _qIn(MatrixIndexBase+3);
01147 Normalize();
01148 return;
01149 }
01150
01151
01152
01153
01154
01155
01156
01157 void Quaternion::Set(double _q1, double _q2, double _q3, double _q4)
01158 {
01159 (*this)(VectorIndexBase+0) = _q1;
01160 (*this)(VectorIndexBase+1) = _q2;
01161 (*this)(VectorIndexBase+2) = _q3;
01162 (*this)(VectorIndexBase+3) = _q4;
01163 Normalize();
01164 return;
01165 }
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190 void Quaternion::Set(const Vector& _qVector)
01191 {
01192 (*this)(VectorIndexBase+0) = _qVector(MatrixIndexBase+0);
01193 (*this)(VectorIndexBase+1) = _qVector(MatrixIndexBase+1);
01194 (*this)(VectorIndexBase+2) = _qVector(MatrixIndexBase+2);
01195 (*this)(VectorIndexBase+3) = _qVector(MatrixIndexBase+3);
01196 Normalize();
01197 return;
01198 }
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250 void Quaternion::Set(const DirectionCosineMatrix& _DCM)
01251 {
01252 Vector quaternionSquared(4);
01253 double DCMtrace = trace(_DCM);
01254 double maxQuaternionSquared;
01255
01256 quaternionSquared(4) = 0.25*(1 + DCMtrace);
01257 quaternionSquared(1) = 0.25*(1 + 2*_DCM(1,1) - DCMtrace);
01258 quaternionSquared(2) = 0.25*(1 + 2*_DCM(2,2) - DCMtrace);
01259 quaternionSquared(3) = 0.25*(1 + 2*_DCM(3,3) - DCMtrace);
01260
01261 maxQuaternionSquared = normInf(quaternionSquared);
01262
01263 if (maxQuaternionSquared == quaternionSquared(4))
01264 {
01265 (*this)(4) = sqrt(maxQuaternionSquared);
01266 (*this)(1) = (_DCM(2,3) - _DCM(3,2))/(4*(*this)(4));
01267 (*this)(2) = (_DCM(3,1) - _DCM(1,3))/(4*(*this)(4));
01268 (*this)(3) = (_DCM(1,2) - _DCM(2,1))/(4*(*this)(4));
01269 }
01270 else if (maxQuaternionSquared == quaternionSquared(1))
01271 {
01272 (*this)(1) = sqrt(maxQuaternionSquared);
01273 (*this)(2) = (_DCM(1,2) + _DCM(2,1))/(4*(*this)(1));
01274 (*this)(3) = (_DCM(3,1) + _DCM(1,3))/(4*(*this)(1));
01275 (*this)(4) = (_DCM(2,3) - _DCM(3,2))/(4*(*this)(1));
01276 }
01277 else if (maxQuaternionSquared == quaternionSquared(2))
01278 {
01279 (*this)(2) = sqrt(maxQuaternionSquared);
01280 (*this)(1) = (_DCM(1,2) + _DCM(2,1))/(4*(*this)(2));
01281 (*this)(3) = (_DCM(2,3) + _DCM(3,2))/(4*(*this)(2));
01282 (*this)(4) = (_DCM(3,1) - _DCM(1,3))/(4*(*this)(2));
01283 }
01284 else if (maxQuaternionSquared == quaternionSquared(3))
01285 {
01286 (*this)(3) = sqrt(maxQuaternionSquared);
01287 (*this)(1) = (_DCM(3,1) + _DCM(1,3))/(4*(*this)(3));
01288 (*this)(2) = (_DCM(2,3) + _DCM(3,2))/(4*(*this)(3));
01289 (*this)(4) = (_DCM(1,2) - _DCM(2,1))/(4*(*this)(3));
01290 }
01291
01292 Normalize();
01293 return;
01294 }
01295
01296
01297
01298
01299
01300 void Quaternion::Set(const Vector& _EulerAngles, const int& _Sequence)
01301 {
01302
01303 Set(DirectionCosineMatrix(_EulerAngles, _Sequence));
01304 Normalize();
01305 return;
01306 }
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316 void Quaternion::Set(const Vector& _EulerAxis, const Angle& _EulerAngle)
01317 {
01318 (*this)(_(VectorIndexBase+0,VectorIndexBase+2)) = _EulerAxis * sin(0.5 * _EulerAngle);
01319 (*this)(VectorIndexBase+3) = cos(0.5 * _EulerAngle);
01320 Normalize();
01321 return;
01322 }
01323
01324
01325
01326
01327
01328
01329
01330
01331 void Quaternion::Set(const ModifiedRodriguezParameters& _MRP)
01332 {
01333 Matrix tempMatrix = (~_MRP) * (_MRP);
01334 double sigmaSq = tempMatrix(MatrixIndexBase,MatrixIndexBase);
01335 double denom = 1 + sigmaSq;
01336 (*this)(1) = 2 * _MRP(1) / denom;
01337 (*this)(2) = 2 * _MRP(2) / denom;
01338 (*this)(3) = 2 * _MRP(3) / denom;
01339 (*this)(VectorIndexBase+3) = (1 - sigmaSq) /denom;
01340 Normalize();
01341 return;
01342 }
01343
01344
01345
01346
01347
01348 DirectionCosineMatrix Quaternion::GetDCM() const
01349 {
01350 return DirectionCosineMatrix(*this);
01351 }
01352
01353
01354
01355
01356
01357 Vector Quaternion::GetEulerAngles(const int& _Sequence) const
01358 {
01359 Vector returnVector(EULERANGLES_SIZE);
01360 DirectionCosineMatrix Rbi;
01361
01362 Rbi = DirectionCosineMatrix(*this);
01363
01364 switch(_Sequence){
01365 case 321:
01366 returnVector(1) = atan2(Rbi(1,2),Rbi(1,1));
01367 returnVector(2) = -asin(Rbi(1,3));
01368 returnVector(3) = atan2(Rbi(2,3),Rbi(3,3));
01369 }
01370
01371 return returnVector;
01372 }
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383 Vector Quaternion::GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const
01384 {
01385 Vector returnVector(EULERAXIS_SIZE + 1);
01386 _EulerAngle = 2.0 * acos((*this)(VectorIndexBase+3));
01387 _EulerAxis = (*this)(_(VectorIndexBase+0,VectorIndexBase+2)) * sin(0.5 * _EulerAngle);
01388 returnVector(_(VectorIndexBase,VectorIndexBase+EULERAXIS_SIZE-1)) = _EulerAxis;
01389 returnVector(VectorIndexBase + EULERAXIS_SIZE) = _EulerAngle;
01390 return returnVector;
01391 }
01392
01393
01394
01395
01396
01397 Vector Quaternion::GetEulerAxisAngle() const
01398 {
01399 Vector EulerAxis(EULERAXIS_SIZE);
01400 double EulerAngle;
01401 return GetEulerAxisAngle(EulerAxis, EulerAngle);
01402 }
01403
01404
01405
01406
01407
01408
01409 ModifiedRodriguezParameters Quaternion::GetMRP() const
01410 {
01411 return ModifiedRodriguezParameters(*this);
01412 }
01413
01414
01415
01416
01417 void Quaternion::Normalize()
01418 {
01419
01420 normalize(*this);
01421 return;
01422 }
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445 Quaternion Quaternion::operator+ (const Quaternion& _quat2) const
01446 {
01447 Matrix qSkewed(4,4);
01448
01449 qSkewed(_,MatrixIndexBase+0) = (*this);
01450
01451 qSkewed(MatrixIndexBase+0,MatrixIndexBase+1) = (*this)(VectorIndexBase+0);
01452 qSkewed(MatrixIndexBase+1,MatrixIndexBase+1) = (*this)(VectorIndexBase+2);
01453 qSkewed(MatrixIndexBase+2,MatrixIndexBase+1) = -(*this)(VectorIndexBase+1);
01454 qSkewed(MatrixIndexBase+3,MatrixIndexBase+1) = -(*this)(VectorIndexBase+3);
01455
01456 qSkewed(MatrixIndexBase+0,MatrixIndexBase+2) = -(*this)(VectorIndexBase+1);
01457 qSkewed(MatrixIndexBase+1,MatrixIndexBase+2) = (*this)(VectorIndexBase+2);
01458 qSkewed(MatrixIndexBase+2,MatrixIndexBase+2) = (*this)(VectorIndexBase+3);
01459 qSkewed(MatrixIndexBase+3,MatrixIndexBase+2) = -(*this)(VectorIndexBase+0);
01460
01461 qSkewed(MatrixIndexBase+0,MatrixIndexBase+3) = (*this)(VectorIndexBase+1);
01462 qSkewed(MatrixIndexBase+1,MatrixIndexBase+3) = -(*this)(VectorIndexBase+0);
01463 qSkewed(MatrixIndexBase+2,MatrixIndexBase+3) = (*this)(VectorIndexBase+3);
01464 qSkewed(MatrixIndexBase+3,MatrixIndexBase+3) = -(*this)(VectorIndexBase+2);
01465
01466 return Quaternion(qSkewed * _quat2);
01467 }
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490 Quaternion Quaternion::operator- (const Quaternion& _quat2) const
01491 {
01492 Matrix qSkewed(4,4);
01493
01494 qSkewed(MatrixIndexBase+0,MatrixIndexBase+0) = -_quat2(VectorIndexBase+0);
01495 qSkewed(MatrixIndexBase+1,MatrixIndexBase+0) = -_quat2(VectorIndexBase+1);
01496 qSkewed(MatrixIndexBase+2,MatrixIndexBase+0) = -_quat2(VectorIndexBase+2);
01497 qSkewed(MatrixIndexBase+3,MatrixIndexBase+0) = _quat2(VectorIndexBase+3);
01498
01499 qSkewed(MatrixIndexBase+0,MatrixIndexBase+1) = _quat2(VectorIndexBase+3);
01500 qSkewed(MatrixIndexBase+1,MatrixIndexBase+1) = -_quat2(VectorIndexBase+2);
01501 qSkewed(MatrixIndexBase+2,MatrixIndexBase+1) = _quat2(VectorIndexBase+1);
01502 qSkewed(MatrixIndexBase+3,MatrixIndexBase+1) = _quat2(VectorIndexBase+0);
01503
01504 qSkewed(MatrixIndexBase+0,MatrixIndexBase+2) = _quat2(VectorIndexBase+2);
01505 qSkewed(MatrixIndexBase+1,MatrixIndexBase+2) = _quat2(VectorIndexBase+3);
01506 qSkewed(MatrixIndexBase+2,MatrixIndexBase+2) = -_quat2(VectorIndexBase+0);
01507 qSkewed(MatrixIndexBase+3,MatrixIndexBase+2) = _quat2(VectorIndexBase+1);
01508
01509 qSkewed(MatrixIndexBase+0,MatrixIndexBase+3) = -_quat2(VectorIndexBase+1);
01510 qSkewed(MatrixIndexBase+1,MatrixIndexBase+3) = _quat2(VectorIndexBase+0);
01511 qSkewed(MatrixIndexBase+2,MatrixIndexBase+3) = _quat2(VectorIndexBase+3);
01512 qSkewed(MatrixIndexBase+3,MatrixIndexBase+3) = _quat2(VectorIndexBase+2);
01513
01514 return Quaternion((qSkewed) * (*this));
01515 }
01516 }
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616