Rotation.cpp

Go to the documentation of this file.
00001 
00002 
00010 /*  \warning Testing not complete
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 //        m_quaternion.Set(_inMatrix(_,MatrixIndexBase));
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 // Inspectors
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         // convert the 3x3 matrix into a 9x1 vector, by rows.
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     // When in doubt, return the quaternion.
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 // DirectionCosineMatrix Class
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     // Calculations done for each element to increase speed
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     // Column 1
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     // Column 2
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     // Column 3
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     // Calculations done for each element to increase speed
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     // Column 1
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     // Column 2
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     // Column 3
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     // Multiplying factor
00496     (*this) /= pow(1 + tempMatrix(MatrixIndexBase,MatrixIndexBase), 2);
00497     Normalize();
00498     return;
00499 }
00500 
00515 void DirectionCosineMatrix::Set(const Quaternion& _qIn)
00516 {
00517     // Calculations done for each element to increase speed
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     // Column 1
00524     (*this)(MatrixIndexBase+0,MatrixIndexBase+0) = q4*q4 + q1*q1 - q2*q2 - q3*q3;
00525 //    (*this)(MatrixIndexBase+0,MatrixIndexBase+0) = 1 - 2 * (q2*q2 + q3*q3);
00526     (*this)(MatrixIndexBase+1,MatrixIndexBase+0) = 2 * (q1*q2 - q4*q3);
00527     (*this)(MatrixIndexBase+2,MatrixIndexBase+0) = 2 * (q1*q3 + q4*q2);
00528     
00529     // Column 2
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 //    (*this)(MatrixIndexBase+0,MatrixIndexBase+0) = 1 - 2 * (q1*q1 + q3*q3);
00533     (*this)(MatrixIndexBase+2,MatrixIndexBase+1) = 2 * (q2*q3 - q4*q1);
00534     
00535     // Column 3
00536     (*this)(MatrixIndexBase+0,MatrixIndexBase+2) = 2 * (q1*q3 - q4*q2);
00537     (*this)(MatrixIndexBase+1,MatrixIndexBase+2) = 2 * (q2*q3 + q4*q1);
00538 //    (*this)(MatrixIndexBase+0,MatrixIndexBase+0) = 1 - 2 * (q1*q1 + q2*q2);
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     { // no rotation, or rotation of 180 degs, therefore arbitrary axis.
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 // ModifiedRodriguezParameters Class
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 // Quaternion Class
01048 Quaternion::Quaternion():Vector(QUATERNION_SIZE)
01049 {
01050 //    (*this).setToValue(0.0);
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 Quaternion::Quaternion(const Matrix& _qMatrix):Vector(QUATERNION_SIZE)
01072 {
01073     Set(_qMatrix);
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 void Quaternion::Set(const Matrix& _qMatrix)
01158 {
01159     if((_qMatrix[MatrixRowsIndex].getIndexBound() == QUATERNION_SIZE) && (_qMatrix[MatrixColsIndex].getIndexBound() == 1)) 
01160     {
01161         (*this)(VectorIndexBase+0) = _qMatrix(MatrixIndexBase+0,MatrixIndexBase);       
01162         (*this)(VectorIndexBase+1) = _qMatrix(MatrixIndexBase+1,MatrixIndexBase);       
01163         (*this)(VectorIndexBase+2) = _qMatrix(MatrixIndexBase+2,MatrixIndexBase);       
01164         (*this)(VectorIndexBase+3) = _qMatrix(MatrixIndexBase+3,MatrixIndexBase);
01165     }
01166     else
01167     {
01168         (*this) = Quaternion();
01169     }
01170     return;
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     // Column 1
01356     qSkewed(_,MatrixIndexBase+0) = (*this);
01357     // Column 2
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     // Column 3
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     // Column 4
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     // Column 1
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     // Column 2
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     // Column 3
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     // Column 4
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 } // end of namespace O_SESSAME
01424 /*!***************************************************************************
01425 *       $Log: Rotation.cpp,v $
01426 *       Revision 1.23  2003/06/10 14:23:42  nilspace
01427 *       Changed MRP::Set(Quaternion) to not overwrite the const.
01428 *       
01429 *       Revision 1.22  2003/06/10 02:25:32  nilspace
01430 *       Fixed MRP::Set(Quaternion) since there apparently is no Vector::operator-() that returns the negative of a Vector.
01431 *       
01432 *       Revision 1.21  2003/05/27 20:01:38  nilspace
01433 *       Fixed numerous bugs with MRP conversion functions.
01434 *       
01435 *       Revision 1.20  2003/05/27 14:39:12  nilspace
01436 *       Fixed the MRP->Quaternion conversion.
01437 *       
01438 *       Revision 1.19  2003/05/22 03:03:38  nilspace
01439 *       Update documentation, and changed all angles to use Angle type.
01440 *       
01441 *       Revision 1.18  2003/05/21 22:18:05  nilspace
01442 *       Moved the documentation to the implementation file.
01443 *       
01444 *       Revision 1.17  2003/05/20 17:53:51  nilspace
01445 *       Updated comments.
01446 *       
01447 *       Revision 1.16  2003/05/13 19:45:10  nilspace
01448 *       Updated comments.
01449 *       
01450 *       Revision 1.15  2003/05/02 19:44:24  nilspace
01451 *       Modified the DCM::Set(Quaternion) function for a more efficient calculation on the diagonals.
01452 *       
01453 *       Revision 1.14  2003/04/28 14:16:26  nilspace
01454 *       Moved all function definitions out of header file into implementation file.
01455 *       
01456 *       Revision 1.13  2003/04/27 20:41:09  nilspace
01457 *       Encapsulated the rotation library into the namespace O_SESSAME.
01458 *       
01459 *       Revision 1.12  2003/04/22 21:59:58  nilspace
01460 *       Fixed Quaternion::Set(DCM) so it evaluates correctly.
01461 *       Implemented Rotation::operator-()
01462 *       
01463 *       Revision 1.11  2003/04/22 20:52:39  nilspace
01464 *       Added Normalize() call to all of the DCM::Set functions.
01465 *       
01466 *       Revision 1.10  2003/04/22 19:45:16  nilspace
01467 *       Fixed DCM::Set to correctly calculate the MRP tempMatrix (sigma^2)
01468 *       
01469 *       Revision 1.9  2003/04/22 19:36:02  nilspace
01470 *       Various bug fixes to DCM & quaternion conversions. Added DirectionCosineMatrix Normalize().
01471 *       
01472 *       Revision 1.8  2003/04/22 16:03:11  nilspace
01473 *       Updated MRP::Set(Quaternion) to correctly set.
01474 *       
01475 *       Revision 1.7  2003/04/10 17:25:51  nilspace
01476 *       changelog
01477 *       
01478 *       Revision 1.6  2003/04/08 23:02:27  nilspace
01479 *       Added Rotation Sense, or "Handedness". Defaults to RIGHT_HAND
01480 *       
01481 *       Revision 1.5  2003/03/27 20:22:26  nilspace
01482 *       Added GetRotation() function.
01483 *       Fixed Quaternion.Set(Quaternion) function.
01484 *       Added RotationType enum.
01485 *       Made sure to normalize the Quaternions for all the Set() functions.
01486 *       
01487 *       Revision 1.4  2003/03/25 02:37:36  nilspace
01488 *       Added quaternion matrix set and constructor.
01489 *       Added Rotation generalized matrix set to check for quaternion.
01490 *       
01491 *       Revision 1.3  2003/03/04 17:36:19  nilspace
01492 *       Added CVS tags for documenting uploads. Also chmod'd to not be executable.
01493 *       
01494 *       Revision 1.1  2003/02/27 18:37:26  nilspace
01495 *       Initial submission of Rotation class implementation.
01496 *       
01497 *
01498 ******************************************************************************/
01499 

Generated on Wed Aug 6 12:58:51 2003 for Open-Sessame Framework by doxygen1.3