Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
vpLinearKalmanFilterInstantiation.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See https://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Kalman filtering.
33  *
34 *****************************************************************************/
35 
41 #include <visp3/core/vpDebug.h>
42 #include <visp3/core/vpException.h>
43 #include <visp3/core/vpLinearKalmanFilterInstantiation.h>
44 
45 #include <math.h>
46 #include <stdlib.h>
47 
179  void vpLinearKalmanFilterInstantiation::initFilter(unsigned int n_signal, vpColVector &sigma_state,
180  vpColVector &sigma_measure, double rho, double delta_t)
181 {
182  switch (model) {
184  initStateConstVelWithColoredNoise_MeasureVel(n_signal, sigma_state, sigma_measure, rho);
185  break;
187  initStateConstVel_MeasurePos(n_signal, sigma_state, sigma_measure, delta_t);
188  break;
190  initStateConstAccWithColoredNoise_MeasureVel(n_signal, sigma_state, sigma_measure, rho, delta_t);
191  break;
192  case unknown:
193  vpERROR_TRACE("Kalman state model is not set");
194  throw(vpException(vpException::notInitialized, "Kalman state model is not set"));
195  }
196 }
197 
294  vpColVector &sigma_measure, double delta_t)
295 {
296  // init_done = true ;
298 
299  init(size_state, size_measure, n_signal);
300 
301  iter = 0;
302  Pest = 0;
303  Xest = 0;
304  F = 0;
305  H = 0;
306  R = 0;
307  Q = 0;
308  this->dt = delta_t;
309 
310  double dt2 = dt * dt;
311  double dt3 = dt2 * dt;
312 
313  for (unsigned int i = 0; i < size_measure * n_signal; i++) {
314  // State model
315  // | 1 dt |
316  // F = | |
317  // | 0 1 |
318 
319  F[2 * i][2 * i] = 1;
320  F[2 * i][2 * i + 1] = dt;
321  F[2 * i + 1][2 * i + 1] = 1;
322 
323  // Measure model
324  H[i][2 * i] = 1;
325  H[i][2 * i + 1] = 0;
326 
327  double sR = sigma_measure[i];
328  double sQ = sigma_state[2 * i]; // sigma_state[2*i+1] is not used
329 
330  // Measure noise
331  R[i][i] = sR;
332 
333  // State covariance matrix 6.2.2.12
334  Q[2 * i][2 * i] = sQ * dt3 / 3;
335  Q[2 * i][2 * i + 1] = sQ * dt2 / 2;
336  Q[2 * i + 1][2 * i] = sQ * dt2 / 2;
337  Q[2 * i + 1][2 * i + 1] = sQ * dt;
338 
339  Pest[2 * i][2 * i] = sR;
340  Pest[2 * i][2 * i + 1] = sR / (2 * dt);
341  Pest[2 * i + 1][2 * i] = sR / (2 * dt);
342  Pest[2 * i + 1][2 * i + 1] = sQ * 2 * dt / 3.0 + sR / (2 * dt2);
343  }
344 }
345 
504  vpColVector &sigma_state,
505  vpColVector &sigma_measure,
506  double rho)
507 {
508  if ((rho < 0) || (rho >= 1)) {
509  vpERROR_TRACE("Bad rho value %g; should be in [0:1[", rho);
510  throw(vpException(vpException::badValue, "Bad rho value"));
511  }
512 
514 
515  init(size_state, size_measure, n_signal);
516 
517  iter = 0;
518  Pest = 0;
519  Xest = 0;
520  F = 0;
521  H = 0;
522  R = 0;
523  Q = 0;
524 
525  for (unsigned int i = 0; i < size_measure * n_signal; i++) {
526  // State model
527  // | 1 1 |
528  // F = | |
529  // | 0 rho |
530 
531  F[2 * i][2 * i] = 1;
532  F[2 * i][2 * i + 1] = 1;
533  F[2 * i + 1][2 * i + 1] = rho;
534 
535  // Measure model
536  H[i][2 * i] = 1;
537  H[i][2 * i + 1] = 0;
538 
539  double sR = sigma_measure[i];
540  double sQ = sigma_state[2 * i + 1]; // sigma_state[2*i] is not used
541 
542  // Measure noise
543  R[i][i] = sR;
544 
545  // State covariance matrix
546  Q[2 * i][2 * i] = 0;
547  Q[2 * i][2 * i + 1] = 0;
548  Q[2 * i + 1][2 * i] = 0;
549  Q[2 * i + 1][2 * i + 1] = sQ;
550 
551  Pest[2 * i][2 * i] = sR;
552  Pest[2 * i][2 * i + 1] = 0.;
553  Pest[2 * i + 1][2 * i] = 0;
554  Pest[2 * i + 1][2 * i + 1] = sQ / (1 - rho * rho);
555  }
556 }
557 
728  vpColVector &sigma_state,
729  vpColVector &sigma_measure,
730  double rho, double delta_t)
731 {
732  if ((rho < 0) || (rho >= 1)) {
733  vpERROR_TRACE("Bad rho value %g; should be in [0:1[", rho);
734  throw(vpException(vpException::badValue, "Bad rho value"));
735  }
737 
738  init(size_state, size_measure, n_signal);
739 
740  iter = 0;
741  Pest = 0;
742  Xest = 0;
743  F = 0;
744  H = 0;
745  R = 0;
746  Q = 0;
747  this->dt = delta_t;
748  // initialise les matrices decrivant les modeles
749  for (unsigned int i = 0; i < size_measure * nsignal; i++) {
750  // State model
751  // | 1 1 dt |
752  // F = | o rho 0 |
753  // | 0 0 1 |
754 
755  F[3 * i][3 * i] = 1;
756  F[3 * i][3 * i + 1] = 1;
757  F[3 * i][3 * i + 2] = dt;
758  F[3 * i + 1][3 * i + 1] = rho;
759  F[3 * i + 2][3 * i + 2] = 1;
760 
761  // Measure model
762  H[i][3 * i] = 1;
763  H[i][3 * i + 1] = 0;
764  H[i][3 * i + 2] = 0;
765 
766  double sR = sigma_measure[i];
767  double sQ1 = sigma_state[3 * i + 1];
768  double sQ2 = sigma_state[3 * i + 2];
769 
770  // Measure noise
771  R[i][i] = sR;
772 
773  // State covariance matrix
774  Q[3 * i + 1][3 * i + 1] = sQ1;
775  Q[3 * i + 2][3 * i + 2] = sQ2;
776 
777  Pest[3 * i][3 * i] = sR;
778  Pest[3 * i][3 * i + 1] = 0.;
779  Pest[3 * i][3 * i + 2] = sR / dt;
780  Pest[3 * i + 1][3 * i + 1] = sQ1 / (1 - rho * rho);
781  Pest[3 * i + 1][3 * i + 2] = -rho * sQ1 / ((1 - rho * rho) * dt);
782  Pest[3 * i + 2][3 * i + 2] = (2 * sR + sQ1 / (1 - rho * rho)) / (dt * dt);
783  // complete the lower triangle
784  Pest[3 * i + 1][3 * i] = Pest[3 * i][3 * i + 1];
785  Pest[3 * i + 2][3 * i] = Pest[3 * i][3 * i + 2];
786  Pest[3 * i + 2][3 * i + 1] = Pest[3 * i + 1][3 * i + 2];
787  }
788 }
789 
804 {
805  if (nsignal < 1) {
806  vpERROR_TRACE("Bad signal number. You need to initialize the Kalman filter");
807  throw(vpException(vpException::notInitialized, "Bad signal number"));
808  }
809 
810  // Specific initialization of the filter that depends on the state model
811  if (iter == 0) {
812  Xest = 0;
813  switch (model) {
817  for (unsigned int i = 0; i < size_measure * nsignal; i++) {
818  Xest[size_state * i] = z[i];
819  }
820  prediction();
821  // init_done = true;
822  break;
823  case unknown:
824  vpERROR_TRACE("Kalman state model is not set");
825  throw(vpException(vpException::notInitialized, "Kalman state model is not set"));
826  }
827  iter++;
828 
829  return;
830  }
831  else if (iter == 1) {
833  for (unsigned int i = 0; i < size_measure * nsignal; i++) {
834  double z_prev = Xest[size_state * i]; // Previous measured position
835  Xest[size_state * i] = z[i];
836  Xest[size_state * i + 1] = (z[i] - z_prev) / dt;
837  }
838  prediction();
839  iter++;
840 
841  return;
842  }
843  }
844 
845  filtering(z);
846  prediction();
847 }
848 END_VISP_NAMESPACE
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
error that can be emitted by ViSP classes.
Definition: vpException.h:60
@ badValue
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:73
@ notInitialized
Used to indicate that a parameter is not initialized.
Definition: vpException.h:74
unsigned int size_state
Size of the state vector .
long iter
Filter step or iteration. When set to zero, initialize the filter.
vpMatrix R
Measurement noise covariance matrix .
void init(unsigned int size_state, unsigned int size_measure, unsigned int n_signal)
unsigned int nsignal
Number of signal to filter.
vpMatrix Q
Process noise covariance matrix .
void filtering(const vpColVector &z)
vpColVector Xest
unsigned int size_measure
Size of the measure vector .
vpMatrix H
Matrix that describes the evolution of the measurements.
void initStateConstVel_MeasurePos(unsigned int nsignal, vpColVector &sigma_state, vpColVector &sigma_measure, double dt)
void initStateConstAccWithColoredNoise_MeasureVel(unsigned int nsignal, vpColVector &sigma_state, vpColVector &sigma_measure, double rho, double dt)
void initFilter(unsigned int nsignal, vpColVector &sigma_state, vpColVector &sigma_measure, double rho, double dt)
void initStateConstVelWithColoredNoise_MeasureVel(unsigned int nsignal, vpColVector &sigma_state, vpColVector &sigma_measure, double rho)
#define vpERROR_TRACE
Definition: vpDebug.h:409