00001
00002
00010
00011
00013
00014 #include "Rotation.h"
00015
00016 namespace O_SESSAME {
00020 Rotation::Rotation() : m_RotationSense(RIGHT_HAND) { }
00021
00024 Rotation::~Rotation() { }
00025
00029 Rotation::Rotation(const Matrix& _inMatrix) { Set(_inMatrix); }
00030
00034 Rotation::Rotation(const DirectionCosineMatrix& _Matrix) { Set(_Matrix); }
00035
00040 Rotation::Rotation(const Vector& _Angles, const int& _Sequence) { Set(_Angles, _Sequence); }
00041
00048 Rotation::Rotation(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence) { Set(_Angle1, _Angle2, _Angle3, _Sequence); }
00049
00054 Rotation::Rotation(const Vector& _Axis, const Angle& _Angle) { Set(_Axis, _Angle); }
00055
00059 Rotation::Rotation(const ModifiedRodriguezParameters& _MRP) { Set(_MRP); }
00060
00064 Rotation::Rotation(const Quaternion& _quat) { Set(_quat); }
00065
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
00085 void Rotation::Set(const DirectionCosineMatrix& _DCM)
00086 {
00087 m_quaternion.Set(_DCM);
00088 return;
00089 }
00090
00095 void Rotation::Set(const Vector& _Angles, const int& _Sequence)
00096 {
00097 m_quaternion.Set(_Angles, _Sequence);
00098 return;
00099 }
00100
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
00117 void Rotation::Set(const Vector& _Axis, const Angle& _Angle)
00118 {
00119 m_quaternion.Set(_Axis, _Angle);
00120 return;
00121 }
00122
00126 void Rotation::Set(const ModifiedRodriguezParameters& _MRP)
00127 {
00128 m_quaternion.Set(_MRP);
00129 return;
00130 }
00131
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
00148 DirectionCosineMatrix Rotation::GetDCM() const
00149 {
00150 return DirectionCosineMatrix(m_quaternion);
00151 }
00152
00157 Vector Rotation::GetEulerAngles(const int& _Sequence) const
00158 {
00159 return m_quaternion.GetEulerAngles(_Sequence);
00160 }
00161
00165 Vector Rotation::GetEulerAxisAngle() const
00166 {
00167 return m_quaternion.GetEulerAxisAngle();
00168 }
00169
00174 Vector Rotation::GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const
00175 {
00176 return m_quaternion.GetEulerAxisAngle(_EulerAxis, _EulerAngle);
00177 }
00178
00182 ModifiedRodriguezParameters Rotation::GetMRP() const
00183 {
00184 return ModifiedRodriguezParameters(m_quaternion);
00185 }
00186
00190 Quaternion Rotation::GetQuaternion() const
00191 {
00192 return m_quaternion;
00193 }
00194
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
00238 Rotation Rotation::operator* (const Rotation& _rot2) const
00239 {
00240 return Rotation((*this).GetDCM() * _rot2.GetDCM());
00241 }
00245 Vector Rotation::operator* (const Vector& _vec2) const
00246 {
00247 return ((*this).GetDCM() * _vec2);
00248 }
00249
00253 Rotation Rotation::operator~ () const
00254 {
00255 Rotation rotOut(~((*this).GetDCM()));
00256 return rotOut;
00257 }
00261 Rotation Rotation::operator+ (const Rotation& _rot2) const
00262 {
00263 Rotation rotOut(this->operator*(_rot2));
00264 return rotOut;
00265 }
00271 Rotation Rotation::operator- (const Rotation& _rot2) const
00272 {
00273 Rotation rotOut(this->operator*(~_rot2));
00274 return rotOut;
00275 }
00277
00281 DirectionCosineMatrix::DirectionCosineMatrix():Matrix(DCM_SIZE, DCM_SIZE)
00282 {
00283 (*this) = eye(DCM_SIZE);
00284 }
00288 DirectionCosineMatrix::DirectionCosineMatrix(const DirectionCosineMatrix& _DCM):Matrix(DCM_SIZE, DCM_SIZE)
00289 {
00290 Set(_DCM);
00291 }
00295 DirectionCosineMatrix::DirectionCosineMatrix(const Matrix& _DCM):Matrix(DCM_SIZE, DCM_SIZE)
00296 {
00297 Set(_DCM);
00298 }
00299
00304 DirectionCosineMatrix::DirectionCosineMatrix(const Vector& _EulerAngles, const int& _Sequence):Matrix(DCM_SIZE, DCM_SIZE)
00305 {
00306 Set(_EulerAngles, _Sequence);
00307 }
00308
00315 DirectionCosineMatrix::DirectionCosineMatrix(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence):Matrix(DCM_SIZE, DCM_SIZE)
00316 {
00317 Set(_Angle1, _Angle2, _Angle3, _Sequence);
00318 }
00319
00324 DirectionCosineMatrix::DirectionCosineMatrix(const Vector& _EulerAxis, const Angle& _EulerAngle):Matrix(DCM_SIZE, DCM_SIZE)
00325 {
00326 Set(_EulerAxis, _EulerAngle);
00327 }
00328
00332 DirectionCosineMatrix::DirectionCosineMatrix(const ModifiedRodriguezParameters& _MRP):Matrix(DCM_SIZE, DCM_SIZE)
00333 {
00334 Set(_MRP);
00335 }
00340 DirectionCosineMatrix::DirectionCosineMatrix(const Quaternion& _quat):Matrix(DCM_SIZE, DCM_SIZE)
00341 {
00342 Set(_quat);
00343 }
00346 DirectionCosineMatrix::~DirectionCosineMatrix()
00347 {
00348 }
00349
00353 void DirectionCosineMatrix::Set(const DirectionCosineMatrix& _DCM)
00354 {
00355 for (int ii = MatrixIndexBase; ii <= _DCM[MatrixRowsIndex].getIndexBound(); ++ii)
00356 for (int jj = MatrixIndexBase; jj <= _DCM[MatrixColsIndex].getIndexBound(); ++jj)
00357 (*this)(ii,jj) = _DCM(ii,jj);
00358 Normalize();
00359 return;
00360 }
00361
00365 void DirectionCosineMatrix::Set(const Matrix& _DCM)
00366 {
00367 for (int ii = MatrixIndexBase; ii <= _DCM[MatrixRowsIndex].getIndexBound(); ++ii)
00368 for (int jj = MatrixIndexBase; jj <= _DCM[MatrixColsIndex].getIndexBound(); ++jj)
00369 (*this)(ii,jj) = _DCM(ii,jj);
00370 Normalize();
00371 return;
00372 }
00373
00378 void DirectionCosineMatrix::Set(const Vector& _EulerAngles, const int& _Sequence)
00379 {
00380 Set(_EulerAngles(VectorIndexBase+0), _EulerAngles(VectorIndexBase+1), _EulerAngles(VectorIndexBase+2), _Sequence);
00381 return;
00382 }
00383
00390 void DirectionCosineMatrix::Set(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence)
00391 {
00392 switch(_Sequence)
00393 {
00394 case 121: (*this) = R1(_Angle3) * R2(_Angle2) * R1(_Angle1); break;
00395 case 131: (*this) = R1(_Angle3) * R3(_Angle2) * R1(_Angle1); break;
00396 case 132: (*this) = R2(_Angle3) * R3(_Angle2) * R1(_Angle1); break;
00397 case 123: (*this) = R3(_Angle3) * R2(_Angle2) * R1(_Angle1); break;
00398 case 212: (*this) = R2(_Angle3) * R1(_Angle2) * R2(_Angle1); break;
00399 case 321: (*this) = R1(_Angle3) * R2(_Angle2) * R3(_Angle1); break;
00400 case 232: (*this) = R2(_Angle3) * R3(_Angle2) * R2(_Angle1); break;
00401 case 231: (*this) = R1(_Angle3) * R3(_Angle2) * R2(_Angle1); break;
00402 case 213: (*this) = R3(_Angle3) * R1(_Angle2) * R2(_Angle1); break;
00403 case 313: (*this) = R3(_Angle3) * R1(_Angle2) * R3(_Angle1); break;
00404 case 323: (*this) = R3(_Angle3) * R2(_Angle2) * R3(_Angle1); break;
00405 case 312: (*this) = R2(_Angle3) * R1(_Angle2) * R3(_Angle1); break;
00406 default: (*this) = eye(DCM_SIZE);
00407 }
00408 Normalize();
00409 return;
00410 }
00411
00428 void DirectionCosineMatrix::Set(const Vector& _EulerAxis, const Angle& _EulerAngle)
00429 {
00430
00431 double Phi = 1 - cos(_EulerAngle);
00432 double e1 = _EulerAxis(VectorIndexBase+0);
00433 double e2 = _EulerAxis(VectorIndexBase+1);
00434 double e3 = _EulerAxis(VectorIndexBase+2);
00435 double cosPhi = cos(_EulerAngle);
00436 double sinPhi = sin(_EulerAngle);
00437
00438
00439 (*this)(MatrixIndexBase+0,MatrixIndexBase+0) = e1 * e1 * Phi + cosPhi;
00440 (*this)(MatrixIndexBase+1,MatrixIndexBase+0) = e2 * e1 * Phi - e3 * sinPhi;
00441 (*this)(MatrixIndexBase+2,MatrixIndexBase+0) = e3 * e1 * Phi + e2 * sinPhi;
00442
00443
00444 (*this)(MatrixIndexBase+0,MatrixIndexBase+1) = e1 * e2 * Phi + e3 * sinPhi;
00445 (*this)(MatrixIndexBase+1,MatrixIndexBase+1) = e2 * e2 * Phi + cosPhi;
00446 (*this)(MatrixIndexBase+2,MatrixIndexBase+1) = e3 * e2 * Phi - e1 * sinPhi;
00447
00448
00449 (*this)(MatrixIndexBase+0,MatrixIndexBase+2) = e1 * e3 * Phi - e2 * sinPhi;
00450 (*this)(MatrixIndexBase+1,MatrixIndexBase+2) = e2 * e3 * Phi + e1 * sinPhi;
00451 (*this)(MatrixIndexBase+2,MatrixIndexBase+2) = e3 * e3 * Phi + cosPhi;
00452 Normalize();
00453 return;
00454 }
00455
00471 void DirectionCosineMatrix::Set(const ModifiedRodriguezParameters& _MRP)
00472 {
00473
00474 Matrix tempMatrix = (~(_MRP) * _MRP);
00475 double Sigma = 1 - tempMatrix(MatrixIndexBase,MatrixIndexBase);
00476 double sigma1 = _MRP(VectorIndexBase+0);
00477 double sigma2 = _MRP(VectorIndexBase+1);
00478 double sigma3 = _MRP(VectorIndexBase+2);
00479
00480
00481 (*this)(MatrixIndexBase+0,MatrixIndexBase+0) = 4*(sigma1*sigma1 - sigma2*sigma2 - sigma3*sigma3) + Sigma*Sigma;
00482 (*this)(MatrixIndexBase+1,MatrixIndexBase+0) = 8*sigma2*sigma1 - 4*sigma3*Sigma;
00483 (*this)(MatrixIndexBase+2,MatrixIndexBase+0) = 8*sigma3*sigma1 + 4*sigma2*Sigma;
00484
00485
00486 (*this)(MatrixIndexBase+0,MatrixIndexBase+1) = 8*sigma1*sigma2 + 4*sigma3*Sigma;
00487 (*this)(MatrixIndexBase+1,MatrixIndexBase+1) = 4*(-sigma1*sigma1 + sigma2*sigma2 - sigma3*sigma3) + Sigma*Sigma;
00488 (*this)(MatrixIndexBase+2,MatrixIndexBase+1) = 8*sigma3*sigma2 - 4*sigma1*Sigma;
00489
00490
00491 (*this)(MatrixIndexBase+0,MatrixIndexBase+2) = 8*sigma1*sigma3 - 4*sigma2 * Sigma;
00492 (*this)(MatrixIndexBase+1,MatrixIndexBase+2) = 8*sigma2*sigma3 + 4*sigma1*Sigma;
00493 (*this)(MatrixIndexBase+2,MatrixIndexBase+2) = 4*(-sigma1*sigma1 - sigma2*sigma2 + sigma3*sigma3) + Sigma*Sigma;
00494
00495
00496 (*this) /= pow(1 + tempMatrix(MatrixIndexBase,MatrixIndexBase), 2);
00497 Normalize();
00498 return;
00499 }
00500
00515 void DirectionCosineMatrix::Set(const Quaternion& _qIn)
00516 {
00517
00518 double q1 = _qIn(VectorIndexBase+0);
00519 double q2 = _qIn(VectorIndexBase+1);
00520 double q3 = _qIn(VectorIndexBase+2);
00521 double q4 = _qIn(VectorIndexBase+3);
00522
00523
00524 (*this)(MatrixIndexBase+0,MatrixIndexBase+0) = q4*q4 + q1*q1 - q2*q2 - q3*q3;
00525
00526 (*this)(MatrixIndexBase+1,MatrixIndexBase+0) = 2 * (q1*q2 - q4*q3);
00527 (*this)(MatrixIndexBase+2,MatrixIndexBase+0) = 2 * (q1*q3 + q4*q2);
00528
00529
00530 (*this)(MatrixIndexBase+0,MatrixIndexBase+1) = 2 * (q1*q2 + q4*q3);
00531 (*this)(MatrixIndexBase+1,MatrixIndexBase+1) = q4*q4 - q1*q1 + q2*q2 -q3*q3;
00532
00533 (*this)(MatrixIndexBase+2,MatrixIndexBase+1) = 2 * (q2*q3 - q4*q1);
00534
00535
00536 (*this)(MatrixIndexBase+0,MatrixIndexBase+2) = 2 * (q1*q3 - q4*q2);
00537 (*this)(MatrixIndexBase+1,MatrixIndexBase+2) = 2 * (q2*q3 + q4*q1);
00538
00539 (*this)(MatrixIndexBase+2,MatrixIndexBase+2) = q4*q4 - q1*q1 - q2*q2 + q3*q3;
00540
00541 Normalize();
00542 return;
00543 }
00544
00550 Vector DirectionCosineMatrix::GetEulerAngles(const int& _Sequence) const
00551 {
00553 return Vector(EULERANGLES_SIZE);
00554 }
00555
00569 void DirectionCosineMatrix::GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const
00570 {
00571 _EulerAngle = acos(0.5 * (trace(*this) - 1));
00572 if(sin(_EulerAngle) != 0)
00573 {
00574 _EulerAxis(VectorIndexBase + 0) = ((*this)(MatrixIndexBase+1,MatrixIndexBase+2)
00575 - (*this)(MatrixIndexBase+1,MatrixIndexBase+2))
00576 / (2 * sin(_EulerAngle));
00577 _EulerAxis(VectorIndexBase + 1) = ((*this)(MatrixIndexBase+2,MatrixIndexBase+0)
00578 - (*this)(MatrixIndexBase+0,MatrixIndexBase+2))
00579 / (2 * sin(_EulerAngle));
00580 _EulerAxis(VectorIndexBase + 2) = ((*this)(MatrixIndexBase+0,MatrixIndexBase+1)
00581 - (*this)(MatrixIndexBase+0,MatrixIndexBase+1))
00582 / (2 * sin(_EulerAngle));
00583 }
00584 else
00585 {
00586 _EulerAxis.setToValue(0.0);
00587 _EulerAxis(VectorIndexBase + 0) = 1;
00588 }
00589 return;
00590 }
00591
00597 ModifiedRodriguezParameters DirectionCosineMatrix::GetMRP() const
00598 {
00599 return ModifiedRodriguezParameters(*this);
00600 }
00601
00607 Quaternion DirectionCosineMatrix::GetQuaternion() const
00608 {
00609 return Quaternion(*this);
00610 }
00611
00617 void DirectionCosineMatrix::Normalize()
00618 {
00619 double total = 0;
00620
00621 for (int ii = MatrixIndexBase; ii < MatrixIndexBase + DCM_SIZE; ++ii)
00622 {
00623 total = sqrt(pow((*this)(ii, MatrixIndexBase),2)
00624 + pow((*this)(ii, MatrixIndexBase+1),2)
00625 + pow((*this)(ii, MatrixIndexBase+2),2));
00626 for (int jj = MatrixIndexBase; jj < MatrixIndexBase + DCM_SIZE; ++jj)
00627 {
00628 (*this)(ii, jj) /= total;
00629 }
00630 }
00631 return;
00632 }
00633
00637 DirectionCosineMatrix DirectionCosineMatrix::operator+ (const DirectionCosineMatrix& _DCM2) const
00638 {
00639 return static_cast<DirectionCosineMatrix>(Matrix::operator+(static_cast<Matrix>(_DCM2)));
00640 }
00641
00646 DirectionCosineMatrix DirectionCosineMatrix::operator- (const DirectionCosineMatrix& _DCM2) const
00647 {
00648 return static_cast<DirectionCosineMatrix>(Matrix::operator-(static_cast<Matrix>(_DCM2)));
00649 }
00650
00654 DirectionCosineMatrix DirectionCosineMatrix::operator* (DirectionCosineMatrix _DCM2) const
00655 {
00656 return static_cast<DirectionCosineMatrix>(Matrix::operator*(static_cast<Matrix>(_DCM2)));
00657 }
00658
00662 inline Vector DirectionCosineMatrix::operator* (const Vector& _vec) const
00663 {
00664 return Matrix::operator*(_vec);
00665 }
00666
00670 DirectionCosineMatrix DirectionCosineMatrix::operator~ ()
00671 {
00672 return static_cast<DirectionCosineMatrix>(Matrix::operator~());
00673 }
00674
00689 DirectionCosineMatrix R1(const Angle& _Angle)
00690 {
00691 DirectionCosineMatrix R1_Out;
00692 R1_Out(MatrixIndexBase+1, MatrixIndexBase+1) = cos(_Angle);
00693 R1_Out(MatrixIndexBase+1, MatrixIndexBase+2) = sin(_Angle);
00694 R1_Out(MatrixIndexBase+2, MatrixIndexBase+1) = -sin(_Angle);
00695 R1_Out(MatrixIndexBase+2, MatrixIndexBase+2) = cos(_Angle);
00696 return R1_Out;
00697 }
00698
00713 DirectionCosineMatrix R2(const Angle& _Angle)
00714 {
00715 DirectionCosineMatrix R2_Out;
00716 R2_Out(MatrixIndexBase+0, MatrixIndexBase+0) = cos(_Angle);
00717 R2_Out(MatrixIndexBase+0, MatrixIndexBase+2) = -sin(_Angle);
00718 R2_Out(MatrixIndexBase+2, MatrixIndexBase+0) = sin(_Angle);
00719 R2_Out(MatrixIndexBase+2, MatrixIndexBase+2) = cos(_Angle);
00720 return R2_Out;
00721 }
00722
00737 DirectionCosineMatrix R3(const Angle& _Angle)
00738 {
00739 DirectionCosineMatrix R3_Out;
00740 R3_Out(MatrixIndexBase+0, MatrixIndexBase+0) = cos(_Angle);
00741 R3_Out(MatrixIndexBase+0, MatrixIndexBase+1) = sin(_Angle);
00742 R3_Out(MatrixIndexBase+1, MatrixIndexBase+0) = -sin(_Angle);
00743 R3_Out(MatrixIndexBase+1, MatrixIndexBase+1) = cos(_Angle);
00744 return R3_Out;
00745 }
00746
00748
00752 ModifiedRodriguezParameters::ModifiedRodriguezParameters():Vector(MRP_SIZE)
00753 {
00754 AutoSwitch();
00755 }
00756
00760 ModifiedRodriguezParameters::ModifiedRodriguezParameters(const ModifiedRodriguezParameters& _MRP):Vector(MRP_SIZE)
00761 {
00762 Set(_MRP);
00763 AutoSwitch();
00764 }
00765
00771 ModifiedRodriguezParameters::ModifiedRodriguezParameters(const double& _s1, const double& _s2, const double& _s3):Vector(MRP_SIZE)
00772 {
00773 Set(_s1,_s2,_s3);
00774 AutoSwitch();
00775 }
00776
00780 ModifiedRodriguezParameters::ModifiedRodriguezParameters(const Vector& _sVector):Vector(MRP_SIZE)
00781 {
00782 Set(_sVector);
00783 AutoSwitch();
00784 }
00785
00789 ModifiedRodriguezParameters::ModifiedRodriguezParameters(const DirectionCosineMatrix& _DCM):Vector(MRP_SIZE)
00790 {
00791 Set(_DCM);
00792 AutoSwitch();
00793 }
00794
00799 ModifiedRodriguezParameters::ModifiedRodriguezParameters(const Vector& _Angles, const int& _Sequence):Vector(MRP_SIZE)
00800 {
00801 Set(_Angles, _Sequence);
00802 AutoSwitch();
00803 }
00804
00810 ModifiedRodriguezParameters::ModifiedRodriguezParameters(const Vector& _EulerAxis, const Angle& _EulerAngle):Vector(MRP_SIZE)
00811 {
00812 Set(_EulerAxis, _EulerAngle);
00813 AutoSwitch();
00814 }
00815
00819 ModifiedRodriguezParameters::ModifiedRodriguezParameters(const Quaternion& _qIn):Vector(MRP_SIZE)
00820 {
00821 Set(_qIn);
00822 AutoSwitch();
00823 }
00824
00828 void ModifiedRodriguezParameters::Set(const ModifiedRodriguezParameters& _MRP)
00829 {
00830 for(int ii = VectorIndexBase;ii < VectorIndexBase + MRP_SIZE; ++ii)
00831 (*this)(ii) = _MRP(ii);
00832 return;
00833 }
00834
00840 void ModifiedRodriguezParameters::Set(const double& _s1, const double& _s2, const double& _s3)
00841 {
00842 (*this)(VectorIndexBase+0) = _s1;
00843 (*this)(VectorIndexBase+1) = _s2;
00844 (*this)(VectorIndexBase+2) = _s3;
00845 return;
00846 }
00847
00851 void ModifiedRodriguezParameters::Set(const Vector& _sVector)
00852 {
00853 for(int ii = VectorIndexBase;ii < VectorIndexBase + MRP_SIZE; ++ii)
00854 (*this)(ii) = _sVector(ii);
00855 return;
00856 }
00857
00861 void ModifiedRodriguezParameters::Set(const DirectionCosineMatrix& _DCM)
00862 {
00863 Set(_DCM.GetQuaternion());
00864 return;
00865 }
00866
00871 void ModifiedRodriguezParameters::Set(const Vector& _EulerAngles, const int& _Sequence)
00872 {
00874 Set(DirectionCosineMatrix(_EulerAngles, _Sequence));
00875 return;
00876 }
00877
00884 void ModifiedRodriguezParameters::Set(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence)
00885 {
00887 Set(DirectionCosineMatrix(_Angle1, _Angle2, _Angle3, _Sequence));
00888 return;
00889 }
00890
00891
00899 void ModifiedRodriguezParameters::Set(const Vector& _EulerAxis, const Angle& _EulerAngle)
00900 {
00901 (*this) = (ModifiedRodriguezParameters) (tan(0.25 * _EulerAngle) * _EulerAxis);
00902 return;
00903 }
00904
00905
00912 void ModifiedRodriguezParameters::Set(const Quaternion& _qIN)
00913 {
00914 double denom = (1+_qIN(VectorIndexBase+3));
00915 if(denom == 0)
00916 {
00917 denom = 2;
00918 (*this)(1) = (-_qIN(1) / denom);
00919 (*this)(2) = (-_qIN(2) / denom);
00920 (*this)(3) = (-_qIN(3) / denom);
00921 }
00922 else
00923 {
00924 (*this)(1) = (_qIN(1) / denom);
00925 (*this)(2) = (_qIN(2) / denom);
00926 (*this)(3) = (_qIN(3) / denom);
00927 }
00928 return;
00929 }
00930
00934 DirectionCosineMatrix ModifiedRodriguezParameters::GetDCM() const
00935 {
00936 return DirectionCosineMatrix(*this);
00937 }
00938
00943 Vector ModifiedRodriguezParameters::GetEulerAngles(int _Sequence) const
00944 {
00946 return Vector(MRP_SIZE);
00947 }
00948
00953 void ModifiedRodriguezParameters::GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const
00954 {
00956 Quaternion qTemp(*this);
00957 qTemp.GetEulerAxisAngle(_EulerAxis, _EulerAngle);
00958 return;
00959 }
00960
00964 Quaternion ModifiedRodriguezParameters::GetQuaternion() const
00965 {
00966 return Quaternion(*this);
00967 }
00968
00973 void ModifiedRodriguezParameters::Switch(int _SwitchThreshold)
00974 {
00975 if (norm2((Vector)*this) > _SwitchThreshold)
00976 (*this) = ShadowSet();
00977 return;
00978 }
00979
00984 void ModifiedRodriguezParameters::AutoSwitch(bool _SwitchBoolean)
00985 {
00986 m_AutoSwitch = _SwitchBoolean;
00987 return;
00988 }
00989
00990
00998 ModifiedRodriguezParameters ModifiedRodriguezParameters::ShadowSet() const
00999 {
01000 return (ModifiedRodriguezParameters)(-(*this)(_) / pow(norm2(*this),2));
01001 }
01002
01003
01012 ModifiedRodriguezParameters ModifiedRodriguezParameters::operator+ (const ModifiedRodriguezParameters& _MRP2) const
01013 {
01014 ModifiedRodriguezParameters MRPsum;
01015 MRPsum(_) = (1-pow(norm2(*this),2)) * _MRP2
01016 + (1-pow(norm2(_MRP2),2)) * (*this)
01017 - 2*crossP(_MRP2,(*this));
01018 MRPsum(_) = MRPsum / (1 + pow(norm2(*this),2) * pow(norm2(_MRP2),2)
01019 - 2 * (*this).dot( _MRP2));
01020 return MRPsum;
01021 }
01022
01023
01032 ModifiedRodriguezParameters ModifiedRodriguezParameters::operator- (const ModifiedRodriguezParameters& _MRP2) const
01033 {
01034 ModifiedRodriguezParameters MRPsum;
01035 MRPsum(_) = (1-pow(norm2(_MRP2),2)) * (*this)
01036 + (1-pow(norm2(*this),2)) * _MRP2
01037 - 2*crossP((*this), _MRP2);
01038 MRPsum(_) = MRPsum / ((1 + pow(norm2(_MRP2),2)) * pow(norm2(*this),2)
01039 - 2 * _MRP2.dot(*this));
01040 return MRPsum;
01041 }
01042
01044
01048 Quaternion::Quaternion():Vector(QUATERNION_SIZE)
01049 {
01050
01051 (*this)(VectorIndexBase+3) = 1.0;
01052 }
01053
01061 Quaternion::Quaternion(double _q1, double _q2, double _q3, double _q4):Vector(QUATERNION_SIZE)
01062 {
01063 Set(_q1, _q2, _q3, _q4);
01064 }
01065
01070
01071
01072
01073
01074
01075
01076
01082 Quaternion::Quaternion(const Vector& _qVector):Vector(QUATERNION_SIZE)
01083 {
01084 Set(_qVector);
01085 }
01086
01092 Quaternion::Quaternion(const DirectionCosineMatrix& _DCM):Vector(QUATERNION_SIZE)
01093 {
01094 Set(_DCM);
01095 }
01096
01101 Quaternion::Quaternion(const Vector& _EulerAngles, const int& _Sequence):Vector(QUATERNION_SIZE)
01102 {
01103 Set(_EulerAngles, _Sequence);
01104 Normalize();
01105 }
01106
01111 Quaternion::Quaternion(const Vector& _EulerAxis, const Angle& _EulerAngle):Vector(QUATERNION_SIZE)
01112 {
01113 Set(_EulerAxis, _EulerAngle);
01114 }
01115
01119 Quaternion::Quaternion(const ModifiedRodriguezParameters& _MRP):Vector(QUATERNION_SIZE)
01120 {
01121 Set(static_cast<ModifiedRodriguezParameters>(_MRP));
01122 }
01123
01127 void Quaternion::Set(const Quaternion& _qIn)
01128 {
01129 (*this)(VectorIndexBase+0) = _qIn(MatrixIndexBase+0);
01130 (*this)(VectorIndexBase+1) = _qIn(MatrixIndexBase+1);
01131 (*this)(VectorIndexBase+2) = _qIn(MatrixIndexBase+2);
01132 (*this)(VectorIndexBase+3) = _qIn(MatrixIndexBase+3);
01133 Normalize();
01134 return;
01135 }
01136
01143 void Quaternion::Set(double _q1, double _q2, double _q3, double _q4)
01144 {
01145 (*this)(VectorIndexBase+0) = _q1;
01146 (*this)(VectorIndexBase+1) = _q2;
01147 (*this)(VectorIndexBase+2) = _q3;
01148 (*this)(VectorIndexBase+3) = _q4;
01149 Normalize();
01150 return;
01151 }
01152
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01176 void Quaternion::Set(const Vector& _qVector)
01177 {
01178 (*this)(VectorIndexBase+0) = _qVector(MatrixIndexBase+0);
01179 (*this)(VectorIndexBase+1) = _qVector(MatrixIndexBase+1);
01180 (*this)(VectorIndexBase+2) = _qVector(MatrixIndexBase+2);
01181 (*this)(VectorIndexBase+3) = _qVector(MatrixIndexBase+3);
01182 Normalize();
01183 return;
01184 }
01185
01186
01200 void Quaternion::Set(const DirectionCosineMatrix& _DCM)
01201 {
01202 (*this)(VectorIndexBase+3) = 0.5 * sqrt(1 + trace(_DCM));
01203 (*this)(VectorIndexBase+0) = _DCM(MatrixIndexBase+1,MatrixIndexBase+2)
01204 - _DCM(MatrixIndexBase+2,MatrixIndexBase+1);
01205 (*this)(VectorIndexBase+1) = _DCM(MatrixIndexBase+2,MatrixIndexBase+0)
01206 - _DCM(MatrixIndexBase+0,MatrixIndexBase+2);
01207 (*this)(VectorIndexBase+2) = _DCM(MatrixIndexBase+0,MatrixIndexBase+1)
01208 - _DCM(MatrixIndexBase+1,MatrixIndexBase+0);
01209 (*this)(_(VectorIndexBase,VectorIndexBase+2)) /= (4 * (*this)(VectorIndexBase+3));
01210 Normalize();
01211 return;
01212 }
01213
01218 void Quaternion::Set(const Vector& _EulerAngles, const int& _Sequence)
01219 {
01221 Set(DirectionCosineMatrix(_EulerAngles, _Sequence));
01222 Normalize();
01223 return;
01224 }
01225
01226
01234 void Quaternion::Set(const Vector& _EulerAxis, const Angle& _EulerAngle)
01235 {
01236 (*this)(_(VectorIndexBase+0,VectorIndexBase+2)) = _EulerAxis * sin(0.5 * _EulerAngle);
01237 (*this)(VectorIndexBase+3) = cos(0.5 * _EulerAngle);
01238 Normalize();
01239 return;
01240 }
01241
01242
01249 void Quaternion::Set(const ModifiedRodriguezParameters& _MRP)
01250 {
01251 Matrix tempMatrix = (~_MRP) * (_MRP);
01252 double sigmaSq = tempMatrix(MatrixIndexBase,MatrixIndexBase);
01253 double denom = 1 + sigmaSq;
01254 (*this)(1) = 2 * _MRP(1) / denom;
01255 (*this)(2) = 2 * _MRP(2) / denom;
01256 (*this)(3) = 2 * _MRP(3) / denom;
01257 (*this)(VectorIndexBase+3) = (1 - sigmaSq) /denom;
01258 Normalize();
01259 return;
01260 }
01261
01266 DirectionCosineMatrix Quaternion::GetDCM() const
01267 {
01268 return DirectionCosineMatrix(*this);
01269 }
01270
01275 Vector Quaternion::GetEulerAngles(const int& _Sequence) const
01276 {
01278 return Vector(EULERANGLES_SIZE);
01279 }
01280
01281
01290 Vector Quaternion::GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const
01291 {
01292 Vector returnVector(EULERAXIS_SIZE + 1);
01293 _EulerAngle = 2.0 * acos((*this)(VectorIndexBase+3));
01294 _EulerAxis = (*this)(_(VectorIndexBase+0,VectorIndexBase+2)) * sin(0.5 * _EulerAngle);
01295 returnVector(_(VectorIndexBase,VectorIndexBase+EULERAXIS_SIZE-1)) = _EulerAxis;
01296 returnVector(VectorIndexBase + EULERAXIS_SIZE) = _EulerAngle;
01297 return returnVector;
01298 }
01299
01300
01304 Vector Quaternion::GetEulerAxisAngle() const
01305 {
01306 Vector EulerAxis(EULERAXIS_SIZE);
01307 double EulerAngle;
01308 return GetEulerAxisAngle(EulerAxis, EulerAngle);
01309 }
01310
01311
01316 ModifiedRodriguezParameters Quaternion::GetMRP() const
01317 {
01318 return ModifiedRodriguezParameters(*this);
01319 }
01320
01321
01324 void Quaternion::Normalize()
01325 {
01327 normalize(*this);
01328 return;
01329 }
01330
01352 Quaternion Quaternion::operator+ (const Quaternion& _quat2) const
01353 {
01354 Matrix qSkewed(4,4);
01355
01356 qSkewed(_,MatrixIndexBase+0) = (*this);
01357
01358 qSkewed(MatrixIndexBase+0,MatrixIndexBase+1) = (*this)(VectorIndexBase+0);
01359 qSkewed(MatrixIndexBase+1,MatrixIndexBase+1) = (*this)(VectorIndexBase+2);
01360 qSkewed(MatrixIndexBase+2,MatrixIndexBase+1) = -(*this)(VectorIndexBase+1);
01361 qSkewed(MatrixIndexBase+3,MatrixIndexBase+1) = -(*this)(VectorIndexBase+3);
01362
01363 qSkewed(MatrixIndexBase+0,MatrixIndexBase+2) = -(*this)(VectorIndexBase+1);
01364 qSkewed(MatrixIndexBase+1,MatrixIndexBase+2) = (*this)(VectorIndexBase+2);
01365 qSkewed(MatrixIndexBase+2,MatrixIndexBase+2) = (*this)(VectorIndexBase+3);
01366 qSkewed(MatrixIndexBase+3,MatrixIndexBase+2) = -(*this)(VectorIndexBase+0);
01367
01368 qSkewed(MatrixIndexBase+0,MatrixIndexBase+3) = (*this)(VectorIndexBase+1);
01369 qSkewed(MatrixIndexBase+1,MatrixIndexBase+3) = -(*this)(VectorIndexBase+0);
01370 qSkewed(MatrixIndexBase+2,MatrixIndexBase+3) = (*this)(VectorIndexBase+3);
01371 qSkewed(MatrixIndexBase+3,MatrixIndexBase+3) = -(*this)(VectorIndexBase+2);
01372
01373 return Quaternion(qSkewed * _quat2);
01374 }
01375
01397 Quaternion Quaternion::operator- (const Quaternion& _quat2) const
01398 {
01399 Matrix qSkewed(4,4);
01400
01401 qSkewed(MatrixIndexBase+0,MatrixIndexBase+0) = -_quat2(VectorIndexBase+0);
01402 qSkewed(MatrixIndexBase+1,MatrixIndexBase+0) = -_quat2(VectorIndexBase+1);
01403 qSkewed(MatrixIndexBase+2,MatrixIndexBase+0) = -_quat2(VectorIndexBase+2);
01404 qSkewed(MatrixIndexBase+3,MatrixIndexBase+0) = _quat2(VectorIndexBase+3);
01405
01406 qSkewed(MatrixIndexBase+0,MatrixIndexBase+1) = _quat2(VectorIndexBase+3);
01407 qSkewed(MatrixIndexBase+1,MatrixIndexBase+1) = -_quat2(VectorIndexBase+2);
01408 qSkewed(MatrixIndexBase+2,MatrixIndexBase+1) = _quat2(VectorIndexBase+1);
01409 qSkewed(MatrixIndexBase+3,MatrixIndexBase+1) = _quat2(VectorIndexBase+0);
01410
01411 qSkewed(MatrixIndexBase+0,MatrixIndexBase+2) = _quat2(VectorIndexBase+2);
01412 qSkewed(MatrixIndexBase+1,MatrixIndexBase+2) = _quat2(VectorIndexBase+3);
01413 qSkewed(MatrixIndexBase+2,MatrixIndexBase+2) = -_quat2(VectorIndexBase+0);
01414 qSkewed(MatrixIndexBase+3,MatrixIndexBase+2) = _quat2(VectorIndexBase+1);
01415
01416 qSkewed(MatrixIndexBase+0,MatrixIndexBase+3) = -_quat2(VectorIndexBase+1);
01417 qSkewed(MatrixIndexBase+1,MatrixIndexBase+3) = _quat2(VectorIndexBase+0);
01418 qSkewed(MatrixIndexBase+2,MatrixIndexBase+3) = _quat2(VectorIndexBase+3);
01419 qSkewed(MatrixIndexBase+3,MatrixIndexBase+3) = _quat2(VectorIndexBase+2);
01420
01421 return Quaternion((qSkewed) * (*this));
01422 }
01423 }
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499