Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

EKFomegaEKFparam.cpp

Go to the documentation of this file.
00001 /************************************************************************************************/
00002 /*! \file EKFomegaEKFparam.cpp
00003 *  \brief A dual EKF to estimate the angular velocities and moment of inertia in the simple form of Euler's Eqns.
00004 *  \author $Author: rsharo $
00005 *  \version $Revision: 1.3 $
00006 *  \date    $Date: 2003/11/01 21:00:17 $
00007 ************************************************************************************************/
00008 /*! 
00009 *
00010 ************************************************************************************************/
00011 
00012 #include "ExtendedKalmanFilter.h"
00013 #include "KalmanFilterHistory.h"
00014 #include "utils/Time.h"
00015 #include <iostream>
00016 #include <fstream>
00017 #include <float.h>
00018 using namespace std;
00019 using namespace O_SESSAME;
00020 
00021 Matrix state_Euler_Fmatrix(KalmanFilter*);
00022 Matrix state_Euler_Hmatrix(KalmanFilter*);
00023 Matrix state_Euler_Qmatrix(KalmanFilter*);
00024 Matrix state_Euler_Rmatrix(KalmanFilter*);
00025 
00026 Vector state_Euler_stateRHSFunc(double t, Vector initialState, Vector controls, Vector params);
00027 Vector state_Euler_measurementRHSFunc(ExtendedKalmanFilter* ekf);
00028 
00029 Matrix param_Euler_Ematrix(ExtendedKalmanFilter* stateEKF);  // analogous to state H matrix
00030 
00031 
00032 int main() {
00033         
00034         tick();         // start the timer.
00035                 
00036         /*! Declare and initialize intermediate variables */
00037         Vector states(3);
00038         Vector parameters(6);
00039         Vector measurements(3);
00040         Vector controls(3);                     // uninitialized:  remains a zero Vector for the open-loop case.
00041         double t = 0.0;
00042         
00043         /*! Set intial conditions */
00044         states(1) = 0.2;
00045         states(2) = 0.2;
00046         states(3) = 0.2;
00047         
00048         parameters(1) = 5.7;
00049         parameters(2) = 0.4;
00050         parameters(3) = 0.3;
00051         parameters(4) = 5.3;
00052         parameters(5) = 0.45;
00053         parameters(6) = 9.7;
00054                 
00055         
00056         /*! Prepare data files */
00057         ifstream iFile;
00058         ofstream oFile;
00059         
00060         /*! Open input and output files */
00061         iFile.open("DataFiles/eulermeasurements.txt");
00062         oFile.open("DataFiles/EKFomegaEKFparam.txt");
00063         
00064         
00065         /*! Read in initial measurements */
00066         iFile >> t >> measurements(1) >> measurements(2) >> measurements(3);
00067 
00068 
00069 
00070         /*! Set up intial kalman filter data */
00071         Matrix covariance = eye(3);
00072         covariance *= 0.5;
00073         
00074         Matrix kalmanGain(3,3); // does not need to be initialized.
00075         
00076         
00077         /*! Declare and initalize state filter and history */
00078         ExtendedKalmanFilter state_ekf;
00079         KalmanFilterHistory state_ekfhist(&state_ekf);
00080         
00081         state_ekf.SetCovarianceMatrix(covariance);
00082         state_ekf.SetKalmanGainMatrix(kalmanGain);
00083         
00084         state_ekf.SetTimeOfEstimate(t);
00085         state_ekf.SetTimeOfMeasurements(t);
00086         state_ekf.SetStateVector(states);
00087         state_ekf.SetControlVector(controls);
00088         state_ekf.SetMeasurementVector(measurements);
00089         state_ekf.SetParameterVector(parameters);
00090 
00091         state_ekf.SetSystemProcessNoiseMatrix(&state_Euler_Qmatrix);
00092         state_ekf.SetMeasurementCovarianceMatrix(&state_Euler_Rmatrix);
00093         state_ekf.SetStateJacobianMatrix(&state_Euler_Fmatrix);
00094         state_ekf.SetMeasurementJacobianMatrix(&state_Euler_Hmatrix);
00095         
00096         state_ekf.SetStateRHS(&state_Euler_stateRHSFunc);
00097         state_ekf.SetMeasurementRHS(&state_Euler_measurementRHSFunc);
00098         
00099         state_ekfhist.AppendHistory(t);
00100         
00101         
00102         
00103         /*! Declare and initalize parameter filter and its history */
00104         double forgettingFactor = 0.999;        // controls, um, everything?
00105         Matrix param_covariance = eye(6);
00106         param_covariance *= 0.5;        // controls initial behavior
00107                 
00108         Matrix param_kalmanGain(6,3);
00109         Matrix param_Rmatrix(3,3);
00110         
00111         Matrix Ek;
00112         Vector errorVector;
00113         Vector previousStates;
00114         Vector newParameters;
00115         
00116         
00117         
00118         
00119         /* Run the loop! */
00120                 
00121         while (iFile) {
00122                 
00123                 /*! Get next measurement */
00124                 iFile >> t >> measurements(1) >> measurements(2) >> measurements(3);
00125 
00126                 /*! Set new SF data including new measurements */
00127                 state_ekf.SetTimeOfMeasurements(t);
00128                 state_ekf.SetMeasurementVector(measurements);
00129                 
00130                 /*! Estimate state using measurements */
00131                 state_ekf.EstimateState();
00132                 previousStates = states;
00133                 states = state_ekf.GetStateVector();
00134                 
00135                 
00136                 /*! Perform param_ekf update */
00137                 param_covariance *= 1.0/forgettingFactor;
00138 
00139                 Ek = param_Euler_Ematrix(&state_ekf);
00140                 
00141                 param_Rmatrix = eye(3) * pow( (0.005/pow(2.0,0.5)), 2.0 );      // controls decay rate, fiddle with the first number
00142                 param_kalmanGain = (param_covariance * ~Ek) * (Ek * param_covariance * ~Ek + param_Rmatrix).inverse();
00143 
00144                 
00145                 errorVector = (( states - previousStates ) / state_ekf.GetPropagationStepSize()) 
00146                                                          - state_ekf.GetStateDot(t, states, controls, parameters);
00147                 
00148                 newParameters = parameters + param_kalmanGain*errorVector;                              
00149                 param_covariance = ( eye(6) - param_kalmanGain*Ek )*param_covariance;
00150 
00151 
00152                 /*! Update the state_ekf parameter data. */
00153                 state_ekf.SetParameterVector(newParameters);
00154                 
00155                 
00156                 /*! Update the history */
00157                 state_ekfhist.AppendHistory(t);
00158                 
00159         }
00160         
00161         oFile << state_ekfhist.GetHistory();
00162         
00163         cout << "Run completed @ " << tock() << endl;
00164         
00165         iFile.close();
00166         oFile.close();
00167         
00168         return 1;
00169         
00170 }
00171 
00172 
00173 
00174 
00175 
00176 
00177 Vector state_Euler_stateRHSFunc(double t, Vector initialState, Vector controls, Vector params) {
00178         
00179         // build the moment of inertial matrix from the parameter vector
00180         Matrix MOI(3,3);
00181         MOI(1,1) = params(1);   MOI(1,2) = params(2);   MOI(1,3) = params(3);
00182         MOI(2,1) = params(2);   MOI(2,2) = params(4);   MOI(2,3) = params(5);
00183         MOI(3,1) = params(3);   MOI(3,2) = params(5);   MOI(3,3) = params(6);
00184 
00185         // build angular velocity stuff
00186         Vector omega(3);
00187         omega = initialState;
00188         
00189         // build updated state vector
00190         Vector updatedState(3);
00191         updatedState = MOI/( -skew(omega) * MOI * omega );
00192                 
00193         return (updatedState);
00194         
00195 };
00196 
00197 
00198 /*! Right now, this is providing angular velocity feedback
00199  * For the one-millionth time, is this what we get from the rate gyros? */
00200 Vector state_Euler_measurementRHSFunc(ExtendedKalmanFilter* ekf) { 
00201         
00202         Vector temp(3);
00203         temp = ekf->GetStateVector(); 
00204         
00205         return(temp);
00206         
00207 };
00208 
00209 
00210 
00211 Matrix state_Euler_Fmatrix(KalmanFilter* ekf) {
00212         
00213         Vector state  = ekf->GetStateVector();
00214         Vector params = ekf->GetParameterVector();
00215         
00216         // build the moment of inertial matrix from the parameter vector
00217         Matrix MOI(3,3);
00218         MOI(1,1) = params(1);   MOI(1,2) = params(2);   MOI(1,3) = params(3);
00219         MOI(2,1) = params(2);   MOI(2,2) = params(4);   MOI(2,3) = params(5);
00220         MOI(3,1) = params(3);   MOI(3,2) = params(5);   MOI(3,3) = params(6);
00221         
00222         // build angular velocity stuff
00223         Vector omega(3);
00224         omega = state;
00225         
00226         // build the state Jacobian matrix, df/dx
00227         Matrix temp(3,3);
00228         temp =  MOI/( -skew(omega) * MOI + skew(MOI*omega) );
00229         
00230         return temp;
00231         
00232 };
00233 
00234 Matrix state_Euler_Hmatrix(KalmanFilter* ekf) {
00235         
00236         Matrix temp(3,3);
00237         temp = eye(3);
00238         
00239         return temp;
00240         
00241 };
00242 
00243 Matrix state_Euler_Qmatrix(KalmanFilter* ekf) {
00244         
00245         Matrix temp = eye(3);
00246         temp *= 0.002;
00247 
00248         return temp;
00249 
00250 };
00251 
00252 Matrix state_Euler_Rmatrix(KalmanFilter* ekf) {
00253         
00254         Matrix temp = eye(3);
00255         double gyro_err = 1.0, gyro_std = gyro_err / pow(2.0, 0.5);
00256         
00257         temp *= pow(gyro_std, 2.0);
00258         
00259         return temp;
00260         
00261 };
00262 
00263 
00264 
00265 
00266 
00267 
00268 
00269 Matrix param_Euler_Ematrix(ExtendedKalmanFilter* stateEKF) {
00270         
00271         Matrix  temp(3,6);
00272         double  t = stateEKF->GetTimeOfEstimate();
00273         Vector  state = stateEKF->GetStateVector();
00274         Vector  controls = stateEKF->GetControlVector();
00275         Vector  params = stateEKF->GetParameterVector();
00276         Vector  twiddleParams;
00277         Vector  twiddlef;
00278         
00279         Vector  nominalf;
00280         nominalf = stateEKF->GetStateDot(t, state, controls, params);
00281         
00282         double  delta = sqrt(DBL_EPSILON);
00283         double  perturbation;
00284         
00285                         
00286         for (int jj = 1; jj <= 6; jj++) {
00287                 // temp( _(1,3),jj )
00288                 twiddleParams = params;
00289                 perturbation = twiddleParams(jj)*delta + delta;  // + delta avoids problem of twiddleParams(jj) = 0
00290                 twiddleParams(jj) += perturbation;
00291         
00292                 twiddlef = stateEKF->GetStateDot(t, state, controls, twiddleParams);
00293                 temp( _(1,3),jj ) = (twiddlef - nominalf) / perturbation;
00294         }
00295         
00296         return temp;
00297         
00298 };
00299 
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 // Do not change the comments below - they will be added automatically by CVS
00313 /*****************************************************************************
00314 * $Log: EKFomegaEKFparam.cpp,v $
00315 * Revision 1.3  2003/11/01 21:00:17  rsharo
00316 * changed "Time.h" includes to "utils/Time.h" includes. Also eliminated excess compile warnings.
00317 *
00318 * Revision 1.2  2003/07/11 14:10:07  simpliciter
00319 * Good gains.
00320 *
00321 * Revision 1.1  2003/07/10 20:17:45  simpliciter
00322 * These work.
00323 *
00324 *
00325 ******************************************************************************/

Generated on Wed Sep 5 12:54:20 2007 for DSACSS Operational Code by  doxygen 1.3.9.1