KalmanFilter
KalmanFilter.h
1 #ifndef KALMANFILTER_H
2 #define KALMANFILTER_H
3 
4 #include "model.h"
5 #include "filterModel.h"
6 #include <iostream>
7 
8 /*
9  * Abstract class KalmanFilter that describes a general Kalman filter
10  * with its properties. Any kalman filter has a filterModel that describes
11  * the model. The protected methods are the interface layer between the
12  * filterModel and KalmanFilter subclasses such as discreteDiscreteKalmanFilter.
13  * The public getter methods are for the subclass users. The pure virtual methods
14  * are the predict and update phase as that depends on the specific filter type.
15  */
16 template<class VECTOR,class MATRIX, class T1>
18 
20 
21  T1 currentTime;
22 
23  VECTOR currentEstimate;
24  MATRIX currentCovariance;
25 
26  protected:
27 
28  int getStateCount(){
29  return model->getStateCount();
30  }
31 
32  int getSensorCount(){
33  return model->getSensorCount();
34  }
35 
36  MATRIX getTransitionJacobian(VECTOR v, T1 t){
37  return model->transitionJacobian(v,t);
38  }
39 
40  MATRIX getMeasurementJacobian(VECTOR v, T1 t){
41  return model->measurementJacobian(v,t);
42  }
43 
44  VECTOR transition(VECTOR t, T1 time){
45  return model->transition(t,time);
46  }
47 
48  VECTOR measure(VECTOR t, T1 time){
49  return model->measurement(t,time);
50  }
51 
52 
53  void setCurrentCovariance(MATRIX t){
54  currentCovariance = t;
55  }
56 
57  void setCurrentTime(T1 t){
58  currentTime=t;
59  }
60 
61  void setCurrentEstimate(VECTOR t){
62  currentEstimate = t;
63  }
64 
65  MATRIX getProcessNoiseCovariance(VECTOR v, T1 t){
66  return model->getProcessNoiseCovariance(v,t);
67  }
68 
69  MATRIX getSensorNoiseCovariance(VECTOR v, T1 t){
70  return model->getSensorNoiseCovariance(v,t);
71  }
72 
73  MATRIX getProcessNoiseCovarianceSqrt(VECTOR v, T1 t){
74  return model->getProcessNoiseCovarianceSqrt(v,t);
75  }
76 
77  MATRIX getSensorNoiseCovarianceSqrt(VECTOR v, T1 t){
78  return model->getSensorNoiseCovarianceSqrt(v,t);
79  }
80 
81  public:
82 
83  MATRIX getCurrentCovariance(){
84  return currentCovariance;
85  }
86 
87  VECTOR getCurrentEstimate(){
88  return currentEstimate;
89  }
90 
91  T1 getCurrentTime(){
92  return currentTime;
93  }
94 
96  T1 initialTime,
97  VECTOR initialEstimate,
98  MATRIX initialCovariance,
100  model(model){
101  currentTime = initialTime;
102  currentEstimate = initialEstimate;
103  currentCovariance = initialCovariance;
104  };
105 
106  virtual void predict(T1 timeUnitsForward) = 0;
107  virtual void update(VECTOR measurement) = 0;
108 };
109 
110 
111 /*
112  *
113  */
114 template<class VECTOR, class MATRIX>
115 class discreteDiscreteKalmanFilter: public KalmanFilter<VECTOR,MATRIX,int>{
117 
118  public:
120  int initialTime,
121  VECTOR initialEstimate,
122  MATRIX initialCovariance,
124  KF::KalmanFilter(initialTime,
125  initialEstimate,initialCovariance,model){}
126 
127  void predict(int timeUnitsForward){//TODO - have to run things time steps forward
128  VECTOR est = KF::getCurrentEstimate();
129  int time = KF::getCurrentTime();
130  MATRIX jacob = KF::getTransitionJacobian(est,KF::getCurrentTime());
131  MATRIX covariance = KF::getCurrentCovariance();
132 
133  KF::setCurrentEstimate(KF::transition(est,time));
134  KF::setCurrentCovariance(jacob*covariance*jacob.transpose() + KF::getProcessNoiseCovariance(est,time));
135  KF::setCurrentTime(time + 1);
136  }
137 
138  void update(VECTOR measurement){
139  VECTOR est = KF::getCurrentEstimate();
140  MATRIX covariance = KF::getCurrentCovariance();
141  int time = KF::getCurrentTime();
142  //TODO: prevent/fix inverse
143  MATRIX measurementJacobian = KF::getMeasurementJacobian(est,time);
144  MATRIX Sk = KF::getSensorNoiseCovariance(est,time) + measurementJacobian*covariance*measurementJacobian.transpose();
145  MATRIX KalmanGain = covariance*measurementJacobian.transpose()*Sk.inverse();
146  KF::setCurrentEstimate(est + KalmanGain*(measurement - KF::measure(est,time)));
147  KF::setCurrentCovariance((MATRIX::Identity(KF::getStateCount(),KF::getStateCount())-KalmanGain*measurementJacobian)*covariance);
148  }
149 };
150 
151 
152 template<class VECTOR, class MATRIX>
153 class discreteDiscreteKalmanFilterSquareRoot: public KalmanFilter<VECTOR,MATRIX,int>{
155 
156 
157  MATRIX getCurrentCovariance(){
158  return currentCovarianceSQRT*currentCovarianceSQRT.transpose();
159  }
160 
161  private:
162  MATRIX currentCovarianceSQRT;
163 
164  MATRIX getCurrentCovarianceSQRT(){
165  return currentCovarianceSQRT;
166  }
167 
168  public:
170  int initialTime,
171  VECTOR initialEstimate,
172  MATRIX initialCovariance,
174  KF::KalmanFilter(initialTime,
175  initialEstimate,initialCovariance,model){
176  currentCovarianceSQRT = initialCovariance;
177  MATRIX::lowerTriangulate(currentCovarianceSQRT);
178  }
179 
180  void predict(int timeUnitsForward){
181  int stateCount = KF::getStateCount();
182  int sensorCount = KF::getSensorCount();
183  VECTOR est = KF::getCurrentEstimate();
184  int time = KF::getCurrentTime();
185  MATRIX jacob = KF::getTransitionJacobian(est,KF::getCurrentTime());
186  MATRIX covarianceSQRT = getCurrentCovarianceSQRT();
187 
188  MATRIX tmp(stateCount,stateCount*2);//TODO: empty constructor
189  tmp.block(0,0,stateCount,stateCount) = jacob*covarianceSQRT;
190  tmp.block(0,stateCount,stateCount,stateCount) = KF::getProcessNoiseCovarianceSqrt(est,time);
191 
192  MATRIX::lowerTriangulate(tmp);
193 
194  KF::setCurrentEstimate(KF::transition(est,time));
195  currentCovarianceSQRT = tmp.block(0,0,stateCount,stateCount);
196  KF::setCurrentTime(time + 1);
197  }
198 
199  void update(VECTOR measurement){
200  int stateCount = KF::getStateCount();
201  int sensorCount = KF::getSensorCount();
202  VECTOR est = KF::getCurrentEstimate();
203  MATRIX covariance = KF::getCurrentCovariance();
204  int time = KF::getCurrentTime();
205  MATRIX measurementJacobian = KF::getMeasurementJacobian(est,time);
206 
207  MATRIX tmp(stateCount + sensorCount, stateCount + sensorCount);
208  tmp.block(0,0,sensorCount,sensorCount) = KF::getSensorNoiseCovarianceSqrt(est,time);
209  tmp.block(0,sensorCount,sensorCount,stateCount) = measurementJacobian*currentCovarianceSQRT;
210  tmp.block(sensorCount,sensorCount,stateCount,stateCount) = currentCovarianceSQRT;
211 
212  MATRIX::lowerTriangulate(tmp);
213  MATRIX tmp2 = tmp.block(0,0,sensorCount,sensorCount);
214  VECTOR ek = VECTOR::solve(tmp2,(measurement - KF::measure(est,time)));//TODO - is this correct?
215  KF::setCurrentEstimate(est+tmp.block(sensorCount,0,stateCount,sensorCount)*ek);
216  currentCovarianceSQRT = tmp.block(sensorCount,sensorCount,stateCount,stateCount);
217  }
218 };
219 #endif
Definition: filterModel.h:7
Definition: KalmanFilter.h:17
Definition: KalmanFilter.h:153
Definition: KalmanFilter.h:115
Definition: model.h:14