00001 ////////////////////////////////////////////////////////////////////////////////////////////////// 00002 /*! \file Rotation.h 00003 * \brief Rotation toolkit. 00004 * \brief Provides a set of functions to use Rotation matrices 00005 * and their various representations. 00006 * \author $Author: jayhawk_hokie $ 00007 * \version $Revision: 1.3 $ 00008 * \date $Date: 2007/08/02 21:17:23 $ 00009 *////////////////////////////////////////////////////////////////////////////////////////////////// 00010 /* \todo Implement Gibbs vector representation 00011 */ 00012 ////////////////////////////////////////////////////////////////////////////////////////////////// 00013 00014 #ifndef __OSESSAME_ROTATION_H__ 00015 #define __OSESSAME_ROTATION_H__ 00016 #include <matrix/Matrix.h> 00017 #include <math.h> 00018 #include <utils/MathUtils.h> 00019 using namespace O_SESSAME; 00020 00021 namespace O_SESSAME { 00022 // Prototype definitions of classes in Rotation Toolbox 00023 class Quaternion; 00024 class DirectionCosineMatrix; 00025 class ModifiedRodriguezParameters; 00026 class Rotation; 00027 00028 ////////////////////////////////////////////////////////////////////////////////////////////////// 00029 /*! \defgroup RotationLibrary Rotation Library 00030 * The Rotation Library is a collection of attitude representation class definitions that are meant to 00031 * assist in the implementation of spacecraft analysis and operation code. Each attitude representation 00032 * is implemented as a class with member functions that perform transformations and retrievals of the 00033 * rotation information. 00034 * 00035 * The Rotation class is the most general, and useful, of the Kinematics Toolbox classes. All 00036 * attitudes can be stored as a Rotation, and then retrieved in any of the desired formats 00037 * (MRP, DCM, Quaternion, Euler Axis & Angle, Euler Angle). 00038 * 00039 * Here are some examples of using the kinematics toolbox in general. For more specific examples 00040 * refer to the appropriate classes documentation. 00041 * \par Examples: 00042 * 00043 \code 00044 DirectionCosineMatrix dcm1(deg2rad(30),deg2rad(-10),deg2rad(5), 123); // create a DCM with successive rotations of [30,-10,5] degs in a 123 rotation order 00045 Quaternion q1(dcm1); // create a quaternion that is the same attitude transformation as dcm1 00046 Quaternion q2(~dcm1); // create a second quaternion that is the transpose of dcm1 (~dcm1) 00047 Rotation rot1(q1 * q2); // create a rotation that is the successive rotation of q1 and q2 00048 cout << rot1; // output rot1 to the standard stream (usually the screen) 00049 \endcode 00050 \code 00051 Vector eulerAxis; 00052 double eulerAngle; 00053 rot1.GetEulerAxisAngle(eulerAxis, eulerAngle); 00054 cout << eulerAxis << eulerAngle; 00055 \endcode 00056 * 00057 * \example testRotation.cpp 00058 * Demonstrates the use of the Rotation class and associated kinematic representations. 00059 * @{ 00060 */ 00061 00062 /*! \brief Number of elements in a quaternion vector */ 00063 const int QUATERNION_SIZE = 4; 00064 /*! \brief Number of elements in a MRP vector */ 00065 const int MRP_SIZE = 3; 00066 /*! \brief Number of elements in a DCM row or column */ 00067 const int DCM_SIZE = 3; 00068 /*! \brief Number of elements in an euler axis */ 00069 const int EULERAXIS_SIZE = 3; 00070 /*! \brief Number of elements in an euler angle sequence */ 00071 const int EULERANGLES_SIZE = 3; 00072 00073 /*! \brief Various representations of a rotation */ 00074 enum RotationType{DCM_Type, EulerAngle_Type, EulerAxisAngle_Type, MRP_Type, Quaternion_Type}; 00075 00076 /*! \brief The Sense, or "handedness" of a rotation system */ 00077 enum RotationSense{LEFT_HAND = -1, RIGHT_HAND = 1}; 00078 00079 /** @} */ 00080 00081 ////////////////////////////////////////////////////////////////////////////////////////////////// 00082 /*! \brief 3x3 direction cosine matrix attitude representation. 00083 * \ingroup RotationLibrary 00084 * 00085 * 00086 * A simple way to describe and represent an Euler Angle sequence is by the use of a Direction Cosine Matrix (DCM). A DCM is a 3x3 matrix of values, a rotation matrix, that represent the transformation of a vector from one coordinate frame to another: 00087 \f[ 00088 00089 {\bf v}^{b} = {\bf R}^{ba}{\bf v}^{a} 00090 00091 \f] 00092 where \f${\bf v}^{a}\f$ and \f${\bf v}^{b}\f$ are the \f$\hat{\bf v}\f$ vectors in \f$\mathcal{F}_{a}\f$ (Frame {\it a\/}) and \f$\mathcal{F}_{b}\f$ respectively. \f${\bf R}^{ba}\f$ is the DCM describing the rotation from \f$\mathcal{F}_{a}\f$ to \f$\mathcal{F}_{b}\f$. 00093 00094 The direction cosine matrix is constructed by the components of the angles between the frame axes: 00095 \f[ 00096 {\bf R}^{21} = \begin{bmatrix} 00097 \cos{\theta_{x_{2}x_{1}}} && \cos{\theta_{x_{2}y_{1}}} && \cos{\theta_{x_{2}z_{1}}}\\ 00098 \cos{\theta_{y_{2}x_{1}}} && \cos{\theta_{y_{2}y_{1}}} && \cos{\theta_{y_{2}z_{1}}}\\ 00099 \cos{\theta_{z_{2}x_{1}}} && \cos{\theta_{z_{2}y_{1}}} && \cos{\theta_{z_{2}z_{1}}}\end{bmatrix} 00100 \f] 00101 where \f$\cos{\theta_{x_{2}x_{1}}}\f$ is the cosine of the angle between the \f$x\f$ axis of the first frame and the \f$x\f$ axis of the second frame. 00102 00103 To determine successive rotations (say from \f$\mathcal{F}_{a}\f$ to \f$\mathcal{F}_{b}\f$ to \f$\mathcal{F}_{c}\f$), we can simply combine the rotation matrices by multiplying them together: 00104 \f[ 00105 {\bf R}^{ca} = {\bf R}^{cb}{\bf R}^{ba} 00106 \f] 00107 00108 <hr> 00109 A DCM can be created from any of the other attitude representations 00110 \code 00111 DirectionCosineMatrix myEulerDCM(40*RPD, 20*RPD, -120*RPD, 312); // creates a 312 rotation DCM from 3 euler angles 00112 DirectionCosineMatrix myQuatDCM(myQuaternion); // where myQuaternion is an instance of Quaternion 00113 DirectionCosineMatrix myMRPDCM(myMRP); // where myMRP is an instance of ModifiedRodriguezParameters 00114 \endcode 00115 00116 and can also return the transformation in any of the representations. The successive and relative rotations 00117 * between 2 DCMS can be computed: 00118 \code 00119 dcm3 = dcm1 * dcm2; \\ successive rotation 00120 dcm3 = dcm1 + dcm2; \\ successive rotation 00121 dcm1 = dcm3 - dcm2; \\ relative rotation 00122 \endcode 00123 * If the inverse transformation of a direction cosine matrix is required, the transpose operation 00124 * is used: 00125 \code 00126 dcmOI = ~dcmIO; 00127 \endcode 00128 * 00129 * The DirectionCosineMatrix class is derived from Matrix, so therefore includes all 00130 * of the functionality of the Matrix class. This includes subarray accessing, element 00131 * accessing, multiplication, addition (except where redefined by the subclass). 00132 \code 00133 double element11 = dcm1(MatrixBaseIndex + 0, MatrixBaseIndex + 0); 00134 Vector column2 = dcm1(_,MatrixBaseIndex+1); 00135 \endcode 00136 * 00137 */ 00138 class DirectionCosineMatrix:public Matrix 00139 { 00140 public: 00141 00142 // DCM CONSTROCTURS 00143 DirectionCosineMatrix(); 00144 00145 DirectionCosineMatrix(const DirectionCosineMatrix& _DCM); 00146 00147 DirectionCosineMatrix(const Matrix& _DCM); 00148 00149 DirectionCosineMatrix(const Vector& _EulerAngles, const int& _Sequence); 00150 00151 DirectionCosineMatrix(const Vector& _EulerAxis, const Angle& _EulerAngle); 00152 00153 DirectionCosineMatrix(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence); 00154 00155 DirectionCosineMatrix(const ModifiedRodriguezParameters& _MRP); 00156 00157 DirectionCosineMatrix(const Quaternion& _quat); 00158 00159 virtual ~DirectionCosineMatrix(); 00160 00161 // DCM MUTATORS 00162 void Set(const DirectionCosineMatrix& _DCM); 00163 00164 void Set(const Matrix& _DCM); 00165 00166 void Set(const Vector& _EulerAngles, const int& _Sequence); 00167 00168 void Set(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence); 00169 00170 void Set(const Vector& _EulerAxis, const Angle& _EulerAngle); 00171 00172 void Set(const ModifiedRodriguezParameters& _MRP); 00173 00174 void Set(const Quaternion& _qIn); 00175 00176 // DCM INSPECTORS 00177 Vector GetEulerAngles(const int& _Sequence) const; 00178 00179 void GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const; 00180 00181 ModifiedRodriguezParameters GetMRP() const; 00182 00183 Quaternion GetQuaternion() const; 00184 00185 // DCM OPERATORS 00186 void Normalize(); 00187 00188 DirectionCosineMatrix operator+ (const DirectionCosineMatrix& _DCM2) const; 00189 00190 DirectionCosineMatrix operator- (const DirectionCosineMatrix& _DCM2) const; 00191 00192 inline DirectionCosineMatrix operator* (DirectionCosineMatrix _DCM2) const; 00193 00194 inline Vector operator* (const Vector& _vec) const; 00195 00196 inline DirectionCosineMatrix operator~ (); 00197 00198 }; 00199 00200 00201 DirectionCosineMatrix R1(const Angle& _Angle); 00202 00203 DirectionCosineMatrix R2(const Angle& _Angle); 00204 00205 DirectionCosineMatrix R3(const Angle& _Angle); 00206 // end of DirectionCosineMatrix 00207 00208 ////////////////////////////////////////////////////////////////////////////////////////////////// 00209 /*! \brief 3x1 Modified Rodriguez Parameters attitude representation. 00210 * \ingroup RotationLibrary 00211 * 00212 Another method of specifying a rigid body attitude is through the 00213 use of Modified Rodriguez Parameters (MRP). The 3-element set is 00214 defined as follows: 00215 \f[ 00216 {\bf \sigma} = \hat{\bf e}\tan{\frac{\Phi }{4}}. 00217 \f] 00218 Like the quaternions, the MRP is not a unique solution to the transformation, but also has a shadow set, \f${\bf \sigma}^{S}\f$: 00219 \f[ 00220 {\bf \sigma}^{S} = -\frac{1}{|{\bf \sigma}^{2}}{\bf \sigma} 00221 \f] 00222 This can be evaluated whenever \f$|{\bf \sigma}| > 1\f$ since the shadow set will be a shorter rotational distance back to the original frame. 00223 00224 */ 00225 class ModifiedRodriguezParameters:public Vector 00226 { 00227 public: 00228 // MRP CONSTRUCTORS 00229 ModifiedRodriguezParameters(); 00230 00231 ModifiedRodriguezParameters(const ModifiedRodriguezParameters& _MRP); 00232 00233 ModifiedRodriguezParameters(const double& _s1, const double& _s2, const double& _s3); 00234 00235 ModifiedRodriguezParameters(const Vector& _sVector); 00236 00237 ModifiedRodriguezParameters(const DirectionCosineMatrix& _DCM); 00238 00239 ModifiedRodriguezParameters(const Vector& _Angles, const int& _Sequence); 00240 00241 ModifiedRodriguezParameters(const Vector& _EulerAxis, const Angle& _EulerAngle); 00242 00243 ModifiedRodriguezParameters(const Quaternion& _qIN); 00244 00245 // MRP MUTATORS 00246 void Set(const ModifiedRodriguezParameters& _MRP); 00247 00248 void Set(const double& _s1, const double& _s2, const double& _s3); 00249 00250 void Set(const Vector& _sVector); 00251 00252 void Set(const DirectionCosineMatrix& _DCM); 00253 00254 void Set(const Vector& _EulerAngles, const int& _Sequence); 00255 00256 void Set(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence); 00257 00258 void Set(const Vector& _EulerAxis, const Angle& _EulerAngle); 00259 00260 void Set(const Quaternion& _qIN); 00261 00262 // MRP INSPECTORS 00263 DirectionCosineMatrix GetDCM() const; 00264 00265 Vector GetEulerAngles(int _Sequence) const; 00266 00267 void GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const; 00268 00269 Quaternion GetQuaternion() const; 00270 00271 // MRP OPERATORS 00272 void Switch(int _SwitchThreshold = 1); 00273 00274 void AutoSwitch(bool _SwitchBoolean = false); 00275 00276 ModifiedRodriguezParameters ShadowSet() const; 00277 00278 ModifiedRodriguezParameters operator+ (const ModifiedRodriguezParameters& _MRP2) const; 00279 00280 ModifiedRodriguezParameters operator- (const ModifiedRodriguezParameters& _MRP2) const; 00281 // end of MRPOperators 00282 private: 00283 /*! \brief Configuration for auto-switching to shadow set. */ 00284 bool m_AutoSwitch; 00285 }; 00286 // end of ModifiedRodriguezParameters 00287 00288 ////////////////////////////////////////////////////////////////////////////////////////////////// 00289 /*! \brief The non-singular, redundant Euler parameter (quaternion) vector. 00290 * \ingroup RotationLibrary 00291 * 00292 * 00293 The 4-element quaternion set, \f${\bf{\bar q}}\f$ contains no 00294 singularities similar to those found in an Euler angle set. The 00295 quaternion, \f$\bar{\bf q}=[{\bf q}^{T}, q_{4}]^{T}\f$, can be determined from the Euler-axis parameters set 00296 (\f$\hat{\bf e}\f$, \f$\Phi \f$) as follows: 00297 \f[{\bf{q}} = \hat{\bf e}\sin \frac{\Phi}{2}\f] 00298 \f[q_4 = \cos \frac{\Phi }{2}\f] 00299 The quaternion representation has the useful characteristic that it should have unit length. Therefore, the quaternion can be normalized during computations to help accuracy, \f$\bar{\bf q}_{new}=\frac{\bar{\bf q}}{|\bar{\bf q}|}\f$. Also, the quaternion is not unique, but can also equal its negative \f$\bar{\bf q}=-\bar{\bf q}\f$. 00300 */ 00301 class Quaternion:public Vector 00302 { 00303 public: 00304 // QUATERNION CONSTRUCTORS 00305 Quaternion(); 00306 00307 Quaternion(double _q1, double _q2, double _q3, double _q4); 00308 00309 // Quaternion(const Matrix& _qMatrix); 00310 00311 Quaternion(const Vector& _qVector); 00312 00313 Quaternion(const DirectionCosineMatrix& _DCM); 00314 00315 Quaternion(const Vector& _EulerAngles, const int& _Sequence); 00316 00317 Quaternion(const Vector& _EulerAxis, const Angle& _EulerAngle); 00318 00319 Quaternion(const ModifiedRodriguezParameters& _MRP); 00320 00321 // QUATERNION MUTATORS 00322 void Set(const Quaternion& _qIn); 00323 00324 void Set(double _q1, double _q2, double _q3, double _q4); 00325 00326 // void Set(const Matrix& _qMatrix); 00327 00328 void Set(const Vector& _qVector); 00329 00330 void Set(const DirectionCosineMatrix& _DCM); 00331 00332 void Set(const Vector& _EulerAngles, const int& _Sequence); 00333 00334 void Set(const Vector& _EulerAxis, const Angle& _EulerAngle); 00335 00336 void Set(const ModifiedRodriguezParameters& _MRP); 00337 00338 // QUATERNION INSPECTORS 00339 DirectionCosineMatrix GetDCM() const; 00340 00341 Vector GetEulerAngles(const int& _Sequence) const; 00342 00343 Vector GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const; 00344 00345 Vector GetEulerAxisAngle() const; 00346 00347 ModifiedRodriguezParameters GetMRP() const; 00348 00349 // QUATERNION OPERATORS 00350 void Normalize(); 00351 00352 Quaternion operator+ (const Quaternion& _quat2) const; 00353 00354 Quaternion operator- (const Quaternion& _quat2) const; 00355 00356 private: 00357 00358 }; 00359 // end of Quaternion 00360 00361 ////////////////////////////////////////////////////////////////////////////////////////////////// 00362 /*! \brief A generalized rotation class to represent any attitude coordinate transformation. 00363 * \ingroup RotationLibrary 00364 * \todo Write description of rotation class. 00365 * 00366 * 00367 \par Examples: 00368 It is very easy to setup and output rotations. Note that to output a rotation you must first choose what attitude state to represent it in (you cannot "cout << MyRotation" directly: 00369 00370 \code 00371 Rotation rotOB; 00372 rotOB.Set(deg2rad(40),deg2rad(-10),deg2rad(0), 321); \\ setup a 321 rotation of euler angles with [40, -10, 0] deg 00373 cout << rotOB.GetDCM(); 00374 \endcode 00375 00376 Successive Rotations: 00377 \code 00378 Rotation rotOB(quatOB); // create a rotation given the quaternion from Body to Orbital 00379 Rotation rotIO(quatIO); // create a rotation given the quaternion from Orbital to Inertial 00380 Rotation rotIB; 00381 rotIB = rotIO * rotOB; // the successive rotation can be calculate by 'multiplying' the rotations 00382 rotIB = rotIO + rotOB; // or by 'adding' them 00383 \endcode 00384 * 00385 * Inverse Transformation: 00386 \code 00387 Rotation rotBI; 00388 rotBI = ~rotIB; // determine the transformation from Inertial to Body from the inverse (transpose) of Body to Inertial 00389 \endcode 00390 * 00391 * Relative Rotation: 00392 \code 00393 Rotation rotError; 00394 rotError = rotTrue - rotActual; // determine the error rotation by taking the 'difference' between the two respective rotations 00395 \endcode 00396 * 00397 */ 00398 class Rotation 00399 { 00400 public: 00401 // ROTATION CONSTRUCTORS 00402 Rotation(); 00403 00404 Rotation(const Matrix& _inMatrix); 00405 00406 Rotation(const DirectionCosineMatrix& _DCM); 00407 00408 Rotation(const Vector& _Angles, const int& _Sequence); 00409 00410 Rotation(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence); 00411 00412 Rotation(const Vector& _Axis, const Angle& _Angle); 00413 00414 Rotation(const ModifiedRodriguezParameters& _MRP); 00415 00416 Rotation(const Quaternion& _quat); 00417 00418 virtual ~Rotation(); 00419 00420 // ROTATION MUTATORS 00421 void Set(const Matrix& _inMatrix); 00422 00423 void Set(const DirectionCosineMatrix& _DCM); 00424 00425 void Set(const Vector& _Angles, const int& _Sequence); 00426 00427 void Set(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence); 00428 00429 void Set(const Vector& _Axis, const Angle& _Angle); 00430 00431 void Set(const ModifiedRodriguezParameters& _MRP); 00432 00433 void Set(const Quaternion& _quat); 00434 00435 // end of RotationMutators 00436 00437 // ROTATION INSPECTORS 00438 DirectionCosineMatrix GetDCM() const; 00439 00440 Vector GetEulerAngles(const int& _Sequence) const; 00441 00442 Vector GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const; 00443 00444 Vector GetEulerAxisAngle() const; 00445 00446 ModifiedRodriguezParameters GetMRP() const; 00447 00448 Quaternion GetQuaternion() const; 00449 00450 Vector GetRotation(const RotationType& _type, const int& _Sequence = 123) const; 00451 00452 // ROTATION OPERATORS 00453 Rotation operator* (const Rotation& _rot2) const; 00454 00455 Vector operator* (const Vector& _vec) const; 00456 00457 Rotation operator~ () const; 00458 00459 Rotation operator+ (const Rotation& _rot2) const; 00460 00461 Rotation operator- (const Rotation& _rot2) const; 00462 /* 00463 Rotation Rotation::operator* (const Rotation& _rot2) const; 00464 00465 Vector Rotation::operator* (const Vector& _vec) const; 00466 00467 Rotation Rotation::operator~ () const; 00468 00469 Rotation Rotation::operator+ (const Rotation& _rot2) const; 00470 00471 Rotation Rotation::operator- (const Rotation& _rot2) const; 00472 */ 00473 // end of RotationOperators 00474 00475 private: 00476 /*! \brief internal representation of the attitude transformation.*/ 00477 Quaternion m_quaternion; 00478 00479 /*! \brief Handed-ness of the rotation, either LEFT_HANDED or RIGHT_HANDED */ 00480 RotationSense m_RotationSense; 00481 00482 }; 00483 } 00484 00485 #endif 00486 /*!*************************************************************************** 00487 * $Log: Rotation.h,v $ 00488 * Revision 1.3 2007/08/02 21:17:23 jayhawk_hokie 00489 * Fixed Warning. 00490 * 00491 * Revision 1.2 2005/06/10 12:53:28 jayhawk_hokie 00492 * Changed header file format to make it easier to link to the spacecraft code by only having to specify dsacss/dep/spacecraft/src (ex. "file.h" changed to <dir/file.h> where dir is a folder in src). 00493 * 00494 * Revision 1.1.1.1 2005/04/26 17:41:00 cakinli 00495 * Adding OpenSESSAME to DSACSS distrib to capture fixed version. 00496 * 00497 * Revision 1.19 2003/10/18 21:37:28 rsharo 00498 * Removed "../utils" from all qmake project paths. Prepended "utils 00499 * /" to all #include directives for utils. Removed ".h" extensions from STL header 00500 * s and referenced STL components from "std::" namespace. Overall, changed to be 00501 * more portable. 00502 * 00503 * Revision 1.18 2003/08/24 20:59:13 nilspace 00504 * Updated. 00505 * 00506 * Revision 1.17 2003/05/22 03:03:38 nilspace 00507 * Update documentation, and changed all angles to use Angle type. 00508 * 00509 * Revision 1.16 2003/05/21 22:18:05 nilspace 00510 * Moved the documentation to the implementation file. 00511 * 00512 * Revision 1.15 2003/05/20 17:53:51 nilspace 00513 * Updated comments. 00514 * 00515 * Revision 1.14 2003/05/13 19:45:10 nilspace 00516 * Updated comments. 00517 * 00518 * Revision 1.13 2003/04/28 14:16:26 nilspace 00519 * Moved all function definitions out of header file into implementation file. 00520 * 00521 * Revision 1.12 2003/04/27 20:41:10 nilspace 00522 * Encapsulated the rotation library into the namespace O_SESSAME. 00523 * 00524 * Revision 1.11 2003/04/23 14:56:18 simpliciter 00525 * Clarified comments on quaternions (automatic normalization) and 00526 * outputting rotations (can't do it). 00527 * 00528 * Revision 1.10 2003/04/22 21:59:58 nilspace 00529 * Fixed Quaternion::Set(DCM) so it evaluates correctly. 00530 * Implemented Rotation::operator-() 00531 * 00532 * Revision 1.9 2003/04/22 19:36:03 nilspace 00533 * Various bug fixes to DCM & quaternion conversions. Added DirectionCosineMatrix Normalize(). 00534 * 00535 * Revision 1.8 2003/04/22 16:03:11 nilspace 00536 * Updated MRP::Set(Quaternion) to correctly set. 00537 * 00538 * Revision 1.7 2003/04/10 17:25:52 nilspace 00539 * changelog 00540 * 00541 * Revision 1.6 2003/04/08 23:02:27 nilspace 00542 * Added Rotation Sense, or "Handedness". Defaults to RIGHT_HAND 00543 * 00544 * Revision 1.5 2003/03/27 20:22:27 nilspace 00545 * Added GetRotation() function. 00546 * Fixed Quaternion.Set(Quaternion) function. 00547 * Added RotationType enum. 00548 * Made sure to normalize the Quaternions for all the Set() functions. 00549 * 00550 * Revision 1.4 2003/03/25 02:37:36 nilspace 00551 * Added quaternion matrix set and constructor. 00552 * Added Rotation generalized matrix set to check for quaternion. 00553 * 00554 * Revision 1.3 2003/03/04 17:36:20 nilspace 00555 * Added CVS tags for documenting uploads. Also chmod'd to not be executable. 00556 * 00557 * Revision 1.1 2003/02/27 18:37:26 nilspace 00558 * Initial submission of Attitude class implementation. 00559 * 00560 * 00561 ******************************************************************************/