ViSP  2.10.0
vpKalmanFilter.cpp
1 /****************************************************************************
2  *
3  * $Id: vpKalmanFilter.cpp 5060 2014-12-12 18:31:03Z 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 
299 void
300 vpKalmanFilter::initFilterCteAcceleration(double dt,
301  vpColVector &Z0,
302  vpColVector &Z1,
303  vpColVector &Z2,
304  vpColVector &sigma_noise,
305  vpColVector &sigma_state )
306 {
307  this->dt = dt ;
308 
309  double dt2 = dt*dt ;
310  double dt3 = dt2*dt ;
311  double dt4 = dt3*dt ;
312  double dt5 = dt4*dt ;
313 
314  //init_done = true ;
315 
316  Pest =0 ;
317  // initialise les matrices decrivant les modeles
318  for (int i=0; i < size_measure ; i++ )
319  {
320  // modele sur l'etat
321 
322  // | 1 dt dt2/2 |
323  // F = | 0 1 dt |
324  // | 0 0 1 |
325 
326  F[3*i][3*i] = 1 ;
327  F[3*i][3*i+1] = dt ;
328  F[3*i][3*i+2] = dt*dt/2 ;
329  F[3*i+1][3*i+1] = 1 ;
330  F[3*i+1][3*i+2] = dt ;
331  F[3*i+2][3*i+2] = 1 ;
332 
333 
334  // modele sur la mesure
335  H[i][3*i] = 1 ;
336  H[i][3*i+1] = 0 ;
337  H[i][3*i+2] = 0 ;
338 
339  double sR = sigma_noise[i] ;
340  double sQ = sigma_state[i] ;
341 
342  // bruit de mesure
343  R[i][i] = (sR) ;
344 
345  // bruit d'etat 6.2.3.9
346  Q[3*i ][3*i ] = sQ * dt5/20;
347  Q[3*i ][3*i+1] = sQ * dt4/8;
348  Q[3*i ][3*i+2] = sQ * dt3/6 ;
349 
350  Q[3*i+1][3*i ] = sQ * dt4/8 ;
351  Q[3*i+1][3*i+1] = sQ * dt3/3 ;
352  Q[3*i+1][3*i+2] = sQ * dt2/2 ;
353 
354  Q[3*i+2][3*i ] = sQ * dt3/6 ;
355  Q[3*i+2][3*i+1] = sQ * dt2/2.0 ;
356  Q[3*i+2][3*i+2] = sQ * dt ;
357 
358 
359  // Initialisation pour la matrice de covariance sur l'etat
360 
361  Pest[3*i ][3*i ] = sR ;
362  Pest[3*i ][3*i+1] = 1.5/dt*sR ;
363  Pest[3*i ][3*i+2] = sR/(dt2) ;
364 
365  Pest[3*i+1][3*i ] = 1.5/dt*sR ;
366  Pest[3*i+1][3*i+1] = dt3/3*sQ + 13/(2*dt2)*sR ;
367  Pest[3*i+1][3*i+2] = 9*dt2*sQ/40.0 +6/dt3*sR ;
368 
369  Pest[3*i+2][3*i ] = sR/(dt2) ;
370  Pest[3*i+2][3*i+1] = 9*dt2*sQ/40.0 +6/dt3*sR ;
371  Pest[3*i+2][3*i+2] = 23*dt/30.0*sQ+6.0/dt4*sR ;
372 
373 
374  // Initialisation pour l'etat
375 
376  Xest[3*i] = Z2[i] ;
377  Xest[3*i+1] = ( 1.5 *Z2[i] - Z1[i] -0.5*Z0[i] ) /( 2*dt ) ;
378  Xest[3*i+2] = ( Z2[i] - 2*Z1[i] + Z0[i] ) /( dt*dt ) ;
379 
380  }
381 }
382 
383 void
384 vpKalmanFilter::initFilterSinger(double dt,
385  double a,
386  vpColVector &Z0,
387  vpColVector &Z1,
388  vpColVector &sigma_noise,
389  vpColVector &sigma_state )
390 {
391  this->dt = dt ;
392 
393  double dt2 = dt*dt ;
394  double dt3 = dt2*dt ;
395 
396  double a2 = a*a ;
397  double a3 = a2*a ;
398  double a4 = a3*a ;
399 
400  //init_done = true ;
401 
402  Pest =0 ;
403  // initialise les matrices decrivant les modeles
404  for (int i=0; i < size_measure ; i++ )
405  {
406  // modele sur l'etat
407 
408  // | 1 dt dt2/2 |
409  // F = | 0 1 dt |
410  // | 0 0 1 |
411 
412  F[3*i][3*i] = 1 ;
413  F[3*i][3*i+1] = dt ;
414  F[3*i][3*i+2] = 1/a2*(1+a*dt+exp(-a*dt)) ;
415  F[3*i+1][3*i+1] = 1 ;
416  F[3*i+1][3*i+2] = 1/a*(1-exp(-a*dt)) ;
417  F[3*i+2][3*i+2] = exp(-a*dt) ;
418 
419 
420  // modele sur la mesure
421  H[i][3*i] = 1 ;
422  H[i][3*i+1] = 0 ;
423  H[i][3*i+2] = 0 ;
424 
425  double sR = sigma_noise[i] ;
426  double sQ = sigma_state[i] ;
427 
428  R[i][i] = (sR) ; // bruit de mesure 1.5mm
429 
430  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) ) ;
431  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 ) ;
432  Q[3*i ][3*i+2] = sQ/a2*(1-exp(-2*a*dt)-2*a*dt*exp(-a*dt) ) ;
433 
434  Q[3*i+1][3*i ] = Q[3*i ][3*i+1] ;
435  Q[3*i+1][3*i+1] = sQ/a2*(4*exp(-a*dt)-3-exp(-2*a*dt)+2*a*dt ) ;
436  Q[3*i+1][3*i+2] = sQ/a*(exp(-2*a*dt)+1- 2*exp(-a*dt)) ;
437 
438  Q[3*i+2][3*i ] = Q[3*i ][3*i+2] ;
439  Q[3*i+2][3*i+1] = Q[3*i+1][3*i+2] ;
440  Q[3*i+2][3*i+2] = sQ*(1-exp(-2*a*dt) ) ;
441 
442 
443  // Initialisation pour la matrice de covariance sur l'etat
444  Pest[3*i ][3*i ] = sR ;
445  Pest[3*i ][3*i+1] = 1/dt*sR ;
446  Pest[3*i ][3*i+2] = 0 ;
447 
448  Pest[3*i+1][3*i ] = 1/dt*sR ;
449  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));
450  Pest[3*i+1][3*i+2] = sQ/(a2*dt)*(exp(-a*dt)+a*dt-1) ;
451 
452  Pest[3*i+2][3*i ] = 0 ;
453  Pest[3*i+2][3*i+1] = Pest[3*i+1][3*i+2] ;
454  Pest[3*i+2][3*i+2] = 0 ;
455 
456 
457  // Initialisation pour l'etat
458 
459  Xest[3*i] = Z1[i] ;
460  Xest[3*i+1] = ( Z1[i] - Z0[i] ) /(dt ) ;
461  Xest[3*i+2] = 0 ;
462 
463  }
464 }
465 
466 #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:199
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:1296
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:98