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