00001 ////////////////////////////////////////////////////////////////////////////////////////////////// 00002 /*! \file QuaternionEKFObserver.h 00003 * \brief Estimation of the Quaternion and angular rates. Based on the Multiplicatimve Quaternion 00004 * Formulation in "Optimal Estimation of Dynamic Systems" by Crassidis and Junkins. 00005 * \author $Author: jayhawk_hokie $ 00006 * \version $Revision: 1.8 $ 00007 * \date $Date: 2007/07/24 08:42:15 $ 00008 *////////////////////////////////////////////////////////////////////////////////////////////////// 00009 /* 00010 */ 00011 ////////////////////////////////////////////////////////////////////////////////////////////////// 00012 00013 #ifndef __SSSL_QUATERNION_EKF_OBSERVER_H__ 00014 #define __SSSL_QUATERNION_EKF_OBSERVER_H__ 00015 00016 00017 #include <iostream> 00018 #include <cmath> 00019 #include <fstream> 00020 00021 #include "dsacssinterface.h" 00022 00023 #include "Base/Whorl.h" 00024 #include "rotation/Rotation.h" 00025 #include "matrix/Matrix.h" 00026 #include "utils/Time.h" 00027 00028 #include "Utils/matrixFunctionInterface.h" 00029 00030 #include "Sensors/DMUAccelerometer.h" 00031 #include "Sensors/DMURateGyro.h" 00032 #include "Sensors/Magnetometer.h" 00033 00034 #include "Observer.h" 00035 #include "triadObserver.h" 00036 00037 00038 extern "C" 00039 { 00040 #include "Hardware/satctl.h" 00041 #include "Hardware/common.h" 00042 } 00043 00044 00045 using namespace std; 00046 using namespace O_SESSAME; 00047 00048 class QuaternionEKFObserver : public Observer 00049 { 00050 public: 00051 00052 ///////////////////////////////////////////////////// 00053 // Contructors/Deconstructors 00054 //////////////////////////////////////////////////// 00055 00056 /*! \brief Default Constructor */ 00057 QuaternionEKFObserver( ); 00058 00059 /*! \brief Create a Quaternion Extended Kalman Filter Observer from XML handle and whorl object 00060 * @param handle XML handle with current whorl as starting node 00061 * @param ptr_whorl Pointer to a whorl object 00062 */ 00063 QuaternionEKFObserver( TiXmlHandle handle, Whorl *ptr_whorl ); 00064 00065 /*! \brief Default Deconstructor */ 00066 ~QuaternionEKFObserver( ); 00067 00068 ///////////////////////////////////////////////////// 00069 // Facilitators 00070 ///////////////////////////////////////////////////// 00071 00072 /*! \brief Initialize the observer */ 00073 int Initialize( ); 00074 00075 /*! \brief Deinitialize the observer. */ 00076 int Deinitialize( ); 00077 00078 /*! Run is the funtion that implements the estimator in the derived class Filter. */ 00079 int Run( ); 00080 00081 /*! \brief Start the Quaternion Extended Kalman Filter routine in a separate thread. */ 00082 void StartEKF( ); 00083 00084 /*! \brief Friend function split in a new thread that runs the Quaternion Extended Kalman Filter routine. 00085 * @param arg the argument is set to be a "this" pointer cast as a void pointer 00086 */ 00087 friend void* QuaternionEKF( void* arg ); 00088 00089 friend void* QuaternionEKFOriginal( void* arg ); 00090 00091 /*! \brief Stop the Quaternion Extended Kalman Filter routine. 00092 * This function does not need to be called a t the end of the program. 00093 * The thread will be closed automatically when the program ends. 00094 */ 00095 void StopEKF( ); 00096 00097 void InitializeFilter( ); 00098 00099 void MurrellAlgorithm( ); 00100 00101 Vector SingleMeasurement( Vector _inertial, Vector _measurement, Vector _dXhatMinus, Matrix _estimatedAttitude, Matrix _sensorNoise ); 00102 00103 void MeasurementUpdate( ); 00104 00105 void StateCovarianceUpdate( ); 00106 00107 void StateCovarianceUpdate( Vector dXhatPlus ); 00108 00109 void StateTransitionMatrix( ); 00110 00111 void Parse(TiXmlHandle handle); 00112 00113 ///////////////////////////////////////////////// 00114 // Mutators 00115 //////////////////////////////////////////////// 00116 00117 00118 ///////////////////////////////////////////////// 00119 // Inspectors 00120 ///////////////////////////////////////////////// 00121 00122 /*! \brief Get Current Measurements from Accelerometers, Angular Rates Gyros, and Magnetometer. 00123 * The values are stored in member variables. */ 00124 void GetCurrentMeasurements( ); 00125 00126 void GetInitialGuessTriad( ); 00127 00128 void CheckMagnetometerMeasurement( ); 00129 00130 protected: 00131 00132 private: 00133 00134 /*! \brief Member variable of Whorl type */ 00135 Whorl* m_whorl; 00136 00137 // inertial vectors 00138 Vector m_magnetometerInertial; // [magnetometer counts] 00139 Vector m_accelerometerInertial; // [m/s^2] 00140 00141 // Body Vectors 00142 Vector m_measurementsBody; // magnetometer and accelerometer 00143 // Vector *m_magnetometerBody; // [magnetometer counts] 00144 // Vector *m_accelerometerBody; // [m/s^2] 00145 Vector m_angularRates; // [rad/s] 00146 00147 Vector m_rsensor; 00148 00149 ssfTime m_currentMeasurementTime; 00150 ssfTime m_previousMeasurementTime; 00151 00152 /*! \brief Time step inside EKF */ 00153 ssfTime m_stepTime; 00154 /*! \brief Duration Time inside EKF */ 00155 ssfTime m_durationTime; 00156 00157 Vector m_BM; 00158 00159 Matrix m_R; 00160 double m_sigmav; 00161 double m_sigmau; 00162 double m_P0a; 00163 double m_P0b; 00164 00165 /*! \brief state vector comprised of quaternion and angular rates */ 00166 Vector m_outputState; 00167 00168 /*! \brief Kalman Gain */ 00169 Matrix m_K; 00170 00171 /*! \brief */ 00172 Vector m_qminus; 00173 00174 /*! \brief attitude estimate */ 00175 Vector m_qplus; 00176 00177 Matrix m_H; 00178 00179 Vector m_h; 00180 00181 Vector m_angularRatehat; 00182 00183 Vector m_previousMeasurement; 00184 00185 /*! \brief State Estimate Error Covariance Matrix */ 00186 Matrix m_Pminus; 00187 00188 /*! \brief Measurement Update Estimate Covariance Matrix */ 00189 Matrix m_Pplus; 00190 00191 Matrix m_phi; 00192 00193 int m_magnetometerCondition; 00194 00195 int m_initialRange; 00196 int m_finalRange; 00197 00198 ///////////////////////////// 00199 // Threads 00200 //////////////////////////// 00201 00202 /*! \brief Member pthread for splitting off EKF routine */ 00203 pthread_t m_EKFThreadID; 00204 00205 /*! \brief Memeber mutex lock variable*/ 00206 pthread_mutex_t m_Mutex; 00207 00208 int m_exitCondition; 00209 }; 00210 00211 00212 00213 #endif 00214 00215 // Do not change the comments below - they will be added automatically by CVS 00216 /***************************************************************************** 00217 * $Log: QuaternionEKFObserver.h,v $ 00218 * Revision 1.8 2007/07/24 08:42:15 jayhawk_hokie 00219 * Removed matrix pointers. 00220 * 00221 * Revision 1.7 2007/06/19 20:00:07 jayhawk_hokie 00222 * Changed inverse matrix function to basic algebra expression for a 3x3 matrix. Should reduce work load on PC104. 00223 * 00224 * Revision 1.6 2007/06/18 13:31:34 jayhawk_hokie 00225 * Added Murrell's Algorithm to EKF Observer. 00226 * 00227 * Revision 1.5 2007/05/30 23:46:39 jayhawk_hokie 00228 * Modified thread termination. 00229 * 00230 * Revision 1.4 2007/05/29 21:39:00 jayhawk_hokie 00231 * Fixed deconstructor seg fault. 00232 * 00233 * Revision 1.3 2007/05/29 15:30:01 jayhawk_hokie 00234 * Modified Deconstructor 00235 * 00236 * Revision 1.2 2007/05/23 22:07:03 jayhawk_hokie 00237 * Implemented ignoring magnetometer measurement due to magnitude spikes. 00238 * 00239 * Revision 1.1 2007/05/21 17:47:48 jayhawk_hokie 00240 * Initial Submission 00241 * 00242 * 00243 * 00244 * 00245 ******************************************************************************/ 00246