ViSP  2.9.0
vpKalmanFilter.cpp
1 /****************************************************************************
2  *
3  * $Id: vpKalmanFilter.cpp 4649 2014-02-07 14:57:11Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  * Description:
34  * Kalman filtering.
35  *
36  * Authors:
37  * Eric Marchand
38  * Fabien Spindler
39  *
40  *****************************************************************************/
41 
42 
48 #include <visp/vpKalmanFilter.h>
49 
50 #include <math.h>
51 #include <stdlib.h>
52 
63 void
64 vpKalmanFilter::init(unsigned int size_state_vector, unsigned int size_measure_vector,
65  unsigned int n_signal)
66 {
67  this->size_state = size_state_vector;
68  this->size_measure = size_measure_vector ;
69  this->nsignal = n_signal ;
71  H.resize(size_measure*nsignal, size_state*nsignal) ;
72 
73  R.resize(size_measure*nsignal, size_measure*nsignal) ;
74  Q.resize(size_state*nsignal, size_state*nsignal) ;
75 
76  Xest.resize(size_state*nsignal) ; Xest = 0;
77  Xpre.resize(size_state*nsignal) ; Xpre = 0 ;
78 
79  Pest.resize(size_state*nsignal, size_state*nsignal) ; Pest = 0 ;
80 
81  I.resize(size_state*nsignal, size_state*nsignal) ;
82  // init_done = false ;
83  iter = 0 ;
84  dt = -1 ;
85 }
86 
94  : iter(0), size_state(0), size_measure(0), nsignal(0), verbose_mode(false),
95  Xest(), Xpre(), F(), H(), R(), Q(), dt(-1), Ppre(), Pest(), W(), I()
96 {
97 }
98 
106 vpKalmanFilter::vpKalmanFilter(unsigned int n_signal)
107  : iter(0), size_state(0), size_measure(0), nsignal(n_signal), verbose_mode(false),
108  Xest(), Xpre(), F(), H(), R(), Q(), dt(-1), Ppre(), Pest(), W(), I()
109 {
110 }
111 
124 vpKalmanFilter::vpKalmanFilter(unsigned int size_state_vector, unsigned int size_measure_vector, unsigned int n_signal)
125  : iter(0), size_state(0), size_measure(0), nsignal(0), verbose_mode(false),
126  Xest(), Xpre(), F(), H(), R(), Q(), dt(-1), Ppre(), Pest(), W(), I()
127 {
128  init( size_state_vector, size_measure_vector, n_signal) ;
129 }
130 
146 void
148 {
149  if (Xest.getRows() != size_state*nsignal) {
150  std::cout << " in vpKalmanFilter::prediction()" << Xest.getRows()
151  <<" " << size_state*nsignal<< std::endl ;
152  std::cout << " Error : Filter non initialized " << std::endl;
153  exit(1) ;
154  }
155 
156 // if (!init_done) {
157 // std::cout << " in vpKalmanFilter::prediction()" << Xest.getRows()<<" " << size_state<< std::endl ;
158 // std::cout << " Error : Filter non initialized " << std::endl;
159 // exit(1) ;
160 // return;
161 // }
162 
163  if (verbose_mode) {
164  std::cout << "F = " << std::endl << F << std::endl ;
165  std::cout << "Xest = "<< std::endl << Xest << std::endl ;
166  }
167  // Prediction
168  // Bar-Shalom 5.2.3.2
169  Xpre = F*Xest ;
170  if (verbose_mode) {
171  std::cout << "Xpre = "<< std::endl << Xpre << std::endl ;
172  std::cout << "Q = "<< std::endl << Q << std::endl ;
173  std::cout << "Pest " << std::endl << Pest << std::endl ;
174  }
175  // Bar-Shalom 5.2.3.5
176  Ppre = F*Pest*F.t() + Q ;
177 
178  // Matrice de covariance de l'erreur de prediction
179  if (verbose_mode)
180  std::cout << "Ppre " << std::endl << Ppre << std::endl ;
181 }
182 
214 void
216 {
217  if (verbose_mode)
218  std::cout << "z " << std::endl << z << std::endl ;
219  // Bar-Shalom 5.2.3.11
220  vpMatrix S = H*Ppre*H.t() + R ;
221  if (verbose_mode)
222  std::cout << "S " << std::endl << S << std::endl ;
223 
224  W = (Ppre * H.t())* (S).inverseByLU() ;
225  if (verbose_mode)
226  std::cout << "W " << std::endl << W << std::endl ;
227  // Bar-Shalom 5.2.3.15
228  Pest = Ppre - W*S*W.t() ;
229  if (verbose_mode)
230  std::cout << "Pest " << std::endl << Pest << std::endl ;
231 
232  if (0) {
233  // Bar-Shalom 5.2.3.16
234  // numeriquement plus stable que 5.2.3.15
235  vpMatrix Pestinv ;
236  Pestinv = Ppre.inverseByLU() + H.t() * R.inverseByLU()*H ;
237  Pest = Pestinv.inverseByLU() ;
238  }
239  // Bar-Shalom 5.2.3.12 5.2.3.13 5.2.3.7
240  Xest = Xpre + (W*(z - (H*Xpre))) ;
241  if (verbose_mode)
242  std::cout << "Xest " << std::endl << Xest << std::endl ;
243 
244  iter++ ;
245 }
246 
247 
248 #if 0
249 
250 
300 void
301 vpKalmanFilter::initFilterCteAcceleration(double dt,
302  vpColVector &Z0,
303  vpColVector &Z1,
304  vpColVector &Z2,
305  vpColVector &sigma_noise,
306  vpColVector &sigma_state )
307 {
308  this->dt = dt ;
309 
310  double dt2 = dt*dt ;
311  double dt3 = dt2*dt ;
312  double dt4 = dt3*dt ;
313  double dt5 = dt4*dt ;
314 
315  //init_done = true ;
316 
317  Pest =0 ;
318  // initialise les matrices decrivant les modeles
319  for (int i=0; i < size_measure ; i++ )
320  {
321  // modele sur l'etat
322 
323  // | 1 dt dt2/2 |
324  // F = | 0 1 dt |
325  // | 0 0 1 |
326 
327  F[3*i][3*i] = 1 ;
328  F[3*i][3*i+1] = dt ;
329  F[3*i][3*i+2] = dt*dt/2 ;
330  F[3*i+1][3*i+1] = 1 ;
331  F[3*i+1][3*i+2] = dt ;
332  F[3*i+2][3*i+2] = 1 ;
333 
334 
335  // modele sur la mesure
336  H[i][3*i] = 1 ;
337  H[i][3*i+1] = 0 ;
338  H[i][3*i+2] = 0 ;
339 
340  double sR = sigma_noise[i] ;
341  double sQ = sigma_state[i] ;
342 
343  // bruit de mesure
344  R[i][i] = (sR) ;
345 
346  // bruit d'etat 6.2.3.9
347  Q[3*i ][3*i ] = sQ * dt5/20;
348  Q[3*i ][3*i+1] = sQ * dt4/8;
349  Q[3*i ][3*i+2] = sQ * dt3/6 ;
350 
351  Q[3*i+1][3*i ] = sQ * dt4/8 ;
352  Q[3*i+1][3*i+1] = sQ * dt3/3 ;
353  Q[3*i+1][3*i+2] = sQ * dt2/2 ;
354 
355  Q[3*i+2][3*i ] = sQ * dt3/6 ;
356  Q[3*i+2][3*i+1] = sQ * dt2/2.0 ;
357  Q[3*i+2][3*i+2] = sQ * dt ;
358 
359 
360  // Initialisation pour la matrice de covariance sur l'etat
361 
362  Pest[3*i ][3*i ] = sR ;
363  Pest[3*i ][3*i+1] = 1.5/dt*sR ;
364  Pest[3*i ][3*i+2] = sR/(dt2) ;
365 
366  Pest[3*i+1][3*i ] = 1.5/dt*sR ;
367  Pest[3*i+1][3*i+1] = dt3/3*sQ + 13/(2*dt2)*sR ;
368  Pest[3*i+1][3*i+2] = 9*dt2*sQ/40.0 +6/dt3*sR ;
369 
370  Pest[3*i+2][3*i ] = sR/(dt2) ;
371  Pest[3*i+2][3*i+1] = 9*dt2*sQ/40.0 +6/dt3*sR ;
372  Pest[3*i+2][3*i+2] = 23*dt/30.0*sQ+6.0/dt4*sR ;
373 
374 
375  // Initialisation pour l'etat
376 
377  Xest[3*i] = Z2[i] ;
378  Xest[3*i+1] = ( 1.5 *Z2[i] - Z1[i] -0.5*Z0[i] ) /( 2*dt ) ;
379  Xest[3*i+2] = ( Z2[i] - 2*Z1[i] + Z0[i] ) /( dt*dt ) ;
380 
381  }
382 }
383 
384 void
385 vpKalmanFilter::initFilterSinger(double dt,
386  double a,
387  vpColVector &Z0,
388  vpColVector &Z1,
389  vpColVector &sigma_noise,
390  vpColVector &sigma_state )
391 {
392  this->dt = dt ;
393 
394  double dt2 = dt*dt ;
395  double dt3 = dt2*dt ;
396 
397  double a2 = a*a ;
398  double a3 = a2*a ;
399  double a4 = a3*a ;
400 
401  //init_done = true ;
402 
403  Pest =0 ;
404  // initialise les matrices decrivant les modeles
405  for (int i=0; i < size_measure ; i++ )
406  {
407  // modele sur l'etat
408 
409  // | 1 dt dt2/2 |
410  // F = | 0 1 dt |
411  // | 0 0 1 |
412 
413  F[3*i][3*i] = 1 ;
414  F[3*i][3*i+1] = dt ;
415  F[3*i][3*i+2] = 1/a2*(1+a*dt+exp(-a*dt)) ;
416  F[3*i+1][3*i+1] = 1 ;
417  F[3*i+1][3*i+2] = 1/a*(1-exp(-a*dt)) ;
418  F[3*i+2][3*i+2] = exp(-a*dt) ;
419 
420 
421  // modele sur la mesure
422  H[i][3*i] = 1 ;
423  H[i][3*i+1] = 0 ;
424  H[i][3*i+2] = 0 ;
425 
426  double sR = sigma_noise[i] ;
427  double sQ = sigma_state[i] ;
428 
429  R[i][i] = (sR) ; // bruit de mesure 1.5mm
430 
431  Q[3*i ][3*i ] = sQ/a4*(1-exp(-2*a*dt)+2*a*dt+2*a3/3*dt3-2*a2*dt2-4*a*dt*exp(-a*dt) ) ;
432  Q[3*i ][3*i+1] = sQ/a3*(1+exp(-2*a*dt)-2*exp(-a*dt)+2*a*dt*exp(-a*dt)-2*a*dt+a2*dt2 ) ;
433  Q[3*i ][3*i+2] = sQ/a2*(1-exp(-2*a*dt)-2*a*dt*exp(-a*dt) ) ;
434 
435  Q[3*i+1][3*i ] = Q[3*i ][3*i+1] ;
436  Q[3*i+1][3*i+1] = sQ/a2*(4*exp(-a*dt)-3-exp(-2*a*dt)+2*a*dt ) ;
437  Q[3*i+1][3*i+2] = sQ/a*(exp(-2*a*dt)+1- 2*exp(-a*dt)) ;
438 
439  Q[3*i+2][3*i ] = Q[3*i ][3*i+2] ;
440  Q[3*i+2][3*i+1] = Q[3*i+1][3*i+2] ;
441  Q[3*i+2][3*i+2] = sQ*(1-exp(-2*a*dt) ) ;
442 
443 
444  // Initialisation pour la matrice de covariance sur l'etat
445  Pest[3*i ][3*i ] = sR ;
446  Pest[3*i ][3*i+1] = 1/dt*sR ;
447  Pest[3*i ][3*i+2] = 0 ;
448 
449  Pest[3*i+1][3*i ] = 1/dt*sR ;
450  Pest[3*i+1][3*i+1] = 2*sR/dt2 + sQ/(a4*dt2)*(2-a2*dt2+2*a3*dt3/3.0 -2*exp(-a*dt)-2*a*dt*exp(-a*dt));
451  Pest[3*i+1][3*i+2] = sQ/(a2*dt)*(exp(-a*dt)+a*dt-1) ;
452 
453  Pest[3*i+2][3*i ] = 0 ;
454  Pest[3*i+2][3*i+1] = Pest[3*i+1][3*i+2] ;
455  Pest[3*i+2][3*i+2] = 0 ;
456 
457 
458  // Initialisation pour l'etat
459 
460  Xest[3*i] = Z1[i] ;
461  Xest[3*i+1] = ( Z1[i] - Z0[i] ) /(dt ) ;
462  Xest[3*i+2] = 0 ;
463 
464  }
465 }
466 
467 #endif
Definition of the vpMatrix class.
Definition: vpMatrix.h:98
void resize(const unsigned int nrows, const unsigned int ncols, const bool nullify=true)
Definition: vpMatrix.cpp:183
void filtering(vpColVector &z)
long iter
Filter step or iteration. When set to zero, initialize the filter.
unsigned int size_state
Size of the state vector .
vpMatrix R
Measurement noise covariance matrix .
unsigned int size_measure
Size of the measure vector .
vpColVector Xest
vpMatrix I
Identity matrix .
unsigned int nsignal
Number of signal to filter.
void init(unsigned int size_state, unsigned int size_measure, unsigned int n_signal)
vpMatrix t() const
Definition: vpMatrix.cpp:1225
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
vpMatrix inverseByLU() const
vpColVector Xpre
vpMatrix F
Transition matrix that describes the evolution of the state.
unsigned int getRows() const
Return the number of rows of the matrix.
Definition: vpMatrix.h:161
vpMatrix H
Matrix that describes the evolution of the measurements.
bool verbose_mode
When set to true, print the content of internal variables during filtering() and prediction().
vpMatrix Q
Process noise covariance matrix .
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:94