Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ExampleExtendedKalman.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 /** @example ExampleExtendedKalman.cpp
27  @relates ExtendedKalman
28  @ingroup g_examples
29  @ingroup g_stateestimation
30  @brief Example using a very simple filter for estimating a constant value. Therefore the state-
31  transition-function is the identity (nothing happens during timestep) and
32  the measurement-function is a direct observation of the state (identity).
33  @author MIP
34 */
35 
36 #include <Base/Math/Random.hh>
37 #include <StateEstimator/ExtendedKalman.hh>
38 
39 #ifdef WIN32
40  #include <Base/Common/W32Compat.hh>
41 #else //Linux
42  #include <sys/time.h>
43 #endif
44 
45 namespace BIAS {
46  /** \cond HIDDEN_SYMBOLS */
47  class MyKalman : public ExtendedKalman {
48 
49  public:
50  MyKalman(){};
51  virtual ~MyKalman(){};
52 
53  virtual void MeasurementFunction(const Vector<double>& state,
54  Vector<double>& measurePred)
55  {
56  measurePred = state;
57  }
58 
59  virtual void StateTransition(const Vector<double>& oldState,
60  const Vector<double>& control,
61  Vector<double>& newState)
62  {
63  newState = oldState;
64  }
65 
66  };
67  /** \endcond */
68 }
69 
70 using namespace std;
71 using namespace BIAS;
72 
73 int main(int argc, char ** argv )
74 {
75  if (argc < 2) {
76  cout << "Give number of iterations!" << endl;
77  exit(0);
78  }
79 
80  //randomizer for noisy data
81  Random random; random.Reset();
82 
83  //'real' state to estimate
84  double mean1 = 20.0;
85  double mean2 = 30.5;
86 
87  //filter to use
88  MyKalman filter;
89 
90  //read the number for maximum iterations to make
91  int maxIter = atoi(argv[1]);
92 
93  //prepare initial state and cov-matrices
94  Vector<double> state(2);
95  state[0] = random.GetNormalDistributed(mean1, 2);
96  state[1] = random.GetNormalDistributed(mean2, 4);
97  Matrix<double> zero(2,2);
98  zero.SetZero();
99  Matrix<double> cov(2,2);
100  cov.SetZero();
101  cov[0][0] = 4.0; // = 2^2 = sigma1^1
102  cov[1][1] = 16.0;// = 4^2 = simga2^2
103  Matrix<double> id(2,2);
104  id.SetIdentity();
105  //observation and control-params (no ctrlparams needed here -> vec empty)
106  Vector<double> observation(2), ctrlparam(0);
107 
108  //set initial state and cov (high uncertainty at start)
109  filter.SetInitial(state, 100.0*cov);
110  //set derivatives for measurement and state-transition
111  filter.SetMeasureDerive(id, id); //dh/dx and dh/dv
112  filter.SetStateDerive(id, zero); //df/dx and df/dv
113  //set cov-matrix for measurements (diagonal matrix with squared std. deviation)
114  filter.SetMeasureCov(cov);
115  //a constant is estimated so there's no process noise
116  filter.SetProcessCov(zero);
117 
118  double sum1 = 0, sum2 = 0;
119 
120  //do maxIter updates with normal ditributed noise (sigma1 = 2, sigma2 = 4)
121  for (int i=0; i<maxIter; i++) {
122  //get noisy data (constants + little noise with given sigma)
123  observation[0] =
124  random.GetNormalDistributed(mean1, 2);
125  sum1 += observation[0];
126  observation[1] =
127  random.GetNormalDistributed(mean2, 4);
128  sum2 += observation[1];
129  //update prediction with observation
130  filter.Update(observation);
131  //predict state and cov. ahead
132  filter.Predict(ctrlparam);
133  }
134 
135  //get estimated state
136  filter.GetState(state);
137 
138  //output results...
139  //There should be only small diffenrence between the filtered result and the
140  //'simple' average computation. This is because we have a stationary system
141  //(estimating a constant) and use always the same cov. for updates. This way
142  //the Kalman-filter can't take advantage of it's capabilities!
143  cout << "should be 1: " << mean1 << " 2: " << mean2
144  << endl << flush;
145  cout << "kalman state 1: " << state[0] << " 2: " << state[1]
146  << endl << flush;
147  cout << "avarage: 1: " << sum1/double(maxIter) << " 2: "
148  << sum2/double(maxIter) << endl << flush;
149 
150  return 0;
151 }
void Reset()
calls srand() with a seed generated from system call time, also initializes some other variables ...
Definition: Random.cpp:113
Classical ExtendedKalman-filter (EKF).
double GetNormalDistributed(const double mean, const double sigma)
on succesive calls return normal distributed random variable with mean and standard deviation sigma ...
Definition: Random.hh:71
class for producing random numbers from different distributions
Definition: Random.hh:51