contrib/oul/ouel/kalman_filter.h
Go to the documentation of this file.
00001 // This is oul/ouel/kalman_filter.h
00002 // Copyright (c) 1999 Brendan McCane
00003 // University of Otago, Dunedin, New Zealand
00004 // Reproduction rights limited as described in the COPYRIGHT file.
00005 //----------------------------------------------------------------------
00006 #ifndef OTAGO_kalman_filter__h_INCLUDED
00007 #define OTAGO_kalman_filter__h_INCLUDED
00008 //:
00009 // \file
00010 // \brief A linear Kalman filter class
00011 //
00012 // Implementation of a linear Kalman filter. We want to estimate the
00013 // value of a time-varying signal from a measurement and predict the
00014 // next value of the signal.
00015 //
00016 // The relationship between signal and measurement is:
00017 // \verbatim
00018 // z(k)        =  H(k)    *    x(k)     +    v(k)
00019 // measurement    relation     signal        noise
00020 //                matrix
00021 // \endverbatim
00022 //
00023 // The relationship between signals at different times is:
00024 // \verbatim
00025 // x(k+1)      =  A(k)    *    x(k)   +   B(k)   *   u(k)   +   w(k)
00026 // signal         relation     signal     control    control    noise
00027 //                matrix                  matrix     signal
00028 // \endverbatim
00029 //
00030 // Status: Completed
00031 // \author Brendan McCane
00032 //----------------------------------------------------------------------
00033 
00034 #include <vnl/vnl_matrix.h>
00035 #include <vcl_iosfwd.h>
00036 
00037 class KalmanFilter
00038 {
00039   // The number of dimensions in signal (ns)
00040   unsigned int num_signal_dimensions;
00041 
00042   // The number of dimensions in measurement (nm)
00043   unsigned int num_measurement_dimensions;
00044 
00045   // The number of dimensions in control input (nc)
00046   unsigned int num_control_dimensions;
00047 
00048   // The relation between one signal and the next (ns*ns)
00049   vnl_matrix<double> A;
00050 
00051   // The relation between measurement and signal (nm*ns)
00052   vnl_matrix<double> H;
00053 
00054   // The control input relation  (nc*ns)
00055   vnl_matrix<double> B;
00056 
00057   // The signal vector estimate - actually a column matrix (ns*1)
00058   vnl_matrix<double> x;
00059 
00060   // The signal vector prediction - actually a column matrix (ns*1)
00061   vnl_matrix<double> x_pred;
00062 
00063   // The measurement vector - again a column matrix (nm*1)
00064   vnl_matrix<double> z;
00065 
00066   // The error covariance matrix  (ns*ns)
00067   vnl_matrix<double> P;
00068 
00069   // The Kalman gain matrix (ns*nm)
00070   vnl_matrix<double> K;
00071 
00072  public:
00073   KalmanFilter(unsigned int ns, unsigned int nm, unsigned int nc,
00074                const vnl_matrix<double> &Ai,
00075                const vnl_matrix<double> &Hi,
00076                const vnl_matrix<double> &Bi,
00077                const vnl_matrix<double> &z_initial,
00078                const vnl_matrix<double> &x_initial,
00079                const vnl_matrix<double> &Pi);
00080 
00081   // this version does not have a control input
00082   KalmanFilter(unsigned int ns, unsigned int nm,
00083                const vnl_matrix<double> &Ai,
00084                const vnl_matrix<double> &Hi,
00085                const vnl_matrix<double> &z_initial,
00086                const vnl_matrix<double> &x_initial,
00087                const vnl_matrix<double> &Pi);
00088 
00089   // some utility functions
00090   void set_initial_input(const vnl_matrix<double> &x_initial)
00091     {x_pred = x_initial;}
00092 
00093   // zk is the next input measurement
00094   // Rk is the measurement  error covariance matrix
00095   //    which is calculated from the noise distribution
00096   void measurement_update(const vnl_matrix<double> &zk,
00097                           const vnl_matrix<double> &Rk);
00098 
00099   // Qk is the process error covariance matrix
00100   //    which is calculated from the noise distribution
00101   // The predicted value of x(k+1) is returned
00102   vnl_matrix<double> predict(const vnl_matrix<double> &Qk);
00103 
00104   // Qk is the process error covariance matrix
00105   //    which is calculated from the noise distribution
00106   // uk is the control input
00107   // The predicted value of x(k+1) is returned
00108   vnl_matrix<double> predict(const vnl_matrix<double> &Qk,
00109                              const vnl_matrix<double> &uk);
00110 
00111   // Do both measurement update and predict
00112   vnl_matrix<double> update_predict(const vnl_matrix<double> &zk,
00113                                     const vnl_matrix<double> &Rk,
00114                                     const vnl_matrix<double> &Qk);
00115 
00116   // accessor functions
00117   // return the current signal estimate
00118   inline vnl_matrix<double> estimate() const {return x;}
00119   // return the current signal prediction
00120   inline vnl_matrix<double> prediction() const {return x_pred;}
00121 
00122   friend vcl_ostream &operator<<(vcl_ostream &os, const KalmanFilter &kf);
00123 };
00124 
00125 #endif // OTAGO_kalman_filter__h_INCLUDED