00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "Image/KalmanFilter.H"
00039
00040 #include "Image/IO.H"
00041 #include "Image/MathOps.H"
00042 #include "Image/MatrixOps.H"
00043 #include "Util/Assert.H"
00044 #include "Util/log.H"
00045 #include <cmath>
00046 #include <iostream>
00047
00048
00049 inline float sqr(float x) {
00050 return (x * x);
00051 }
00052
00053
00054 KalmanFilter::KalmanFilter()
00055 : initialized(false)
00056 {}
00057
00058
00059 KalmanFilter::KalmanFilter(float initialM, float pNoise,
00060 float mNoise, float timeStep)
00061 : initialized(true)
00062 {
00063 init(initialM, pNoise, mNoise, timeStep);
00064 }
00065
00066
00067
00068 void KalmanFilter::init(float initialM, float pNoise,
00069 float mNoise, float timeStep)
00070 {
00071
00072 itsPNoise = pNoise;
00073 itsMNoise2 = mNoise * mNoise;
00074
00075
00076 H.resize(3,1,ZEROS);
00077 H.setVal(0,0,1.0F);
00078 H.setVal(1,0,0.0F);
00079 H.setVal(2,0,0.0F);
00080 HT = transpose(H);
00081
00082
00083
00084
00085 x.resize(1,3,ZEROS);
00086 x.setVal(0,0,initialM);
00087 x.setVal(0,1,0.0F);
00088 x.setVal(0,2,0.0F);
00089
00090
00091 I = eye<float>(3);
00092
00093
00094 P = I * 1000.0F;
00095
00096
00097 std::vector<float> ts(6);
00098 ts[0] = 1.0F;
00099 for (uint i = 1; i <= 5; ++i)
00100 ts[i] = ts[i-1] * timeStep;
00101
00102
00103 Phi = I;
00104 Phi.setVal(1,0,ts[1]); Phi.setVal(2,0,ts[2]/2.0F); Phi.setVal(2,1,ts[1]);
00105 PhiT = transpose(Phi);
00106
00107
00108 Q.resize(3,3,NO_INIT);
00109 Q.setVal(0,0,ts[5]/20.0F); Q.setVal(1,0,ts[4]/8.0F); Q.setVal(2,0,ts[3]/6.0F);
00110 Q.setVal(0,1,ts[4]/ 8.0F); Q.setVal(1,1,ts[3]/3.0F); Q.setVal(2,1,ts[2]/2.0F);
00111 Q.setVal(0,2,ts[3]/ 6.0F); Q.setVal(1,2,ts[2]/2.0F); Q.setVal(2,2,ts[1]);
00112 Q *= pNoise;
00113
00114
00115 updateFilter();
00116
00117
00118
00119
00120
00121 initialized = true;
00122 }
00123
00124
00125 void KalmanFilter::updateFilter()
00126 {
00127
00128
00129
00130
00131 M = matrixMult(matrixMult(Phi,P),PhiT) + Q;
00132
00133
00134
00135 Image<float> HMHT = matrixMult(matrixMult(H,M),HT);
00136 ASSERT(HMHT.getSize() == 1);
00137 K = matrixMult(M,HT) / (HMHT.getVal(0,0) + itsMNoise2);
00138
00139
00140
00141 P = matrixMult(I - matrixMult(K,H),M);
00142 }
00143
00144
00145 void KalmanFilter::writeToStream(std::ostream& os) const
00146 {
00147 if (initialized) os << "1\n";
00148 else os << "0\n";
00149
00150 if (initialized)
00151 {
00152 os << itsPNoise << ' ' << itsMNoise2 << '\n';
00153
00154 writeImageToStream(os,x);
00155 writeImageToStream(os,I);
00156 writeImageToStream(os,M);
00157 writeImageToStream(os,K);
00158 writeImageToStream(os,P);
00159 writeImageToStream(os,H);
00160 writeImageToStream(os,HT);
00161 writeImageToStream(os,Phi);
00162 writeImageToStream(os,PhiT);
00163 writeImageToStream(os,Q);
00164 }
00165 }
00166
00167
00168 void KalmanFilter::readFromStream(std::istream& is)
00169 {
00170 int i; is >> i;
00171 initialized = (i == 1);
00172
00173 if (initialized)
00174 {
00175 is >> itsPNoise;
00176 is >> itsMNoise2;
00177
00178 readImageFromStream(is,x);
00179 readImageFromStream(is,I);
00180 readImageFromStream(is,M);
00181 readImageFromStream(is,K);
00182 readImageFromStream(is,P);
00183 readImageFromStream(is,H);
00184 readImageFromStream(is,HT);
00185 readImageFromStream(is,Phi);
00186 readImageFromStream(is,PhiT);
00187 readImageFromStream(is,Q);
00188 }
00189 }
00190
00191
00192 Image<float> KalmanFilter::getXEstimate() const
00193 {
00194 return matrixMult(Phi,x);
00195 }
00196
00197
00198 Image<float> KalmanFilter::getXEstimate(float z) const
00199 {
00200 Image<float> Px = getXEstimate();
00201 return (Px + K * (z - matrixMult(H,Px).getVal(0,0)));
00202 }
00203
00204
00205 float KalmanFilter::getEstimate() const
00206 {
00207 ASSERT(initialized);
00208 float est = getXEstimate().getVal(0,0);
00209
00210 return est;
00211 }
00212
00213
00214 float KalmanFilter::getEstimate(float measurement) const
00215 {
00216 ASSERT(initialized);
00217 float est = getXEstimate(measurement).getVal(0,0);
00218
00219 return est;
00220 }
00221
00222
00223 float KalmanFilter::getSpeed() const
00224 {
00225 ASSERT(initialized);
00226 return x.getVal(0,1);
00227 }
00228
00229
00230 float KalmanFilter::getCost(float measurement) const
00231 {
00232 ASSERT(initialized);
00233
00234 float cost = sqr(getEstimate(measurement) - measurement);
00235
00236 if (!(cost == cost))
00237 {
00238 writeToStream(std::cout);
00239 LFATAL("Kalman Filter error");
00240 }
00241
00242 return cost;
00243 }
00244
00245
00246 float KalmanFilter::update()
00247 {
00248 ASSERT(initialized);
00249 x = getXEstimate();
00250 updateFilter();
00251
00252 if (!(x.getVal(0,0) == x.getVal(0,0)))
00253 {
00254 writeToStream(std::cout);
00255 LFATAL("Kalman Filter error");
00256 }
00257
00258 return x.getVal(0,0);
00259 }
00260
00261
00262 float KalmanFilter::update(float measurement)
00263 {
00264 ASSERT(initialized);
00265 x = getXEstimate(measurement);
00266 updateFilter();
00267
00268 if (!(x.getVal(0,0) == x.getVal(0,0)))
00269 {
00270 writeToStream(std::cout);
00271 LFATAL("Kalman Filter error");
00272 }
00273
00274 return x.getVal(0,0);
00275 }
00276
00277
00278 Image<float> KalmanFilter::getStateVector() const
00279 {
00280 ASSERT(initialized);
00281 return x;
00282 }
00283
00284
00285 Image<float> KalmanFilter::getCovariances() const
00286 {
00287 ASSERT(initialized);
00288 return P;
00289 }
00290
00291
00292 bool KalmanFilter::isInitialized() const
00293 {
00294 return initialized;
00295 }
00296
00297
00298
00299
00300
00301