Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpKalmanFilter.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description:
31 * Kalman filtering.
32 */
33
38
39#include <visp3/core/vpKalmanFilter.h>
40
41#include <math.h>
42#include <stdlib.h>
43
56void vpKalmanFilter::init(unsigned int size_state_vector, unsigned int size_measure_vector, unsigned int n_signal)
57{
58 this->size_state = size_state_vector;
59 this->size_measure = size_measure_vector;
60 this->nsignal = n_signal;
63
66
67 Xest.resize(size_state * nsignal);
68 Xest = 0;
69 Xpre.resize(size_state * nsignal);
70 Xpre = 0;
71
73 Pest = 0;
74
76 // init_done = false ;
77 iter = 0;
78 dt = -1;
79}
80
88 : iter(0), size_state(0), size_measure(0), nsignal(0), verbose_mode(false), Xest(), Xpre(), F(), H(), R(), Q(),
89 dt(-1), Ppre(), Pest(), W(), I()
90{ }
91
99vpKalmanFilter::vpKalmanFilter(unsigned int n_signal)
100 : iter(0), size_state(0), size_measure(0), nsignal(n_signal), verbose_mode(false), Xest(), Xpre(), F(), H(), R(), Q(),
101 dt(-1), Ppre(), Pest(), W(), I()
102{ }
103
117vpKalmanFilter::vpKalmanFilter(unsigned int size_state_vector, unsigned int size_measure_vector, unsigned int n_signal)
118 : iter(0), size_state(0), size_measure(0), nsignal(0), verbose_mode(false), Xest(), Xpre(), F(), H(), R(), Q(),
119 dt(-1), Ppre(), Pest(), W(), I()
120{
121 init(size_state_vector, size_measure_vector, n_signal);
122}
123
139
141{
142 if (Xest.getRows() != size_state * nsignal) {
143 throw(vpException(vpException::fatalError, "Error in vpKalmanFilter::prediction() %d != %d: Filter not initialized",
144 Xest.getRows(), size_state * nsignal));
145 }
146
147 if (verbose_mode) {
148 std::cout << "F = " << std::endl << F << std::endl;
149 std::cout << "Xest = " << std::endl << Xest << std::endl;
150 }
151 // Prediction
152 // Bar-Shalom 5.2.3.2
153 Xpre = F * Xest;
154 if (verbose_mode) {
155 std::cout << "Xpre = " << std::endl << Xpre << std::endl;
156 std::cout << "Q = " << std::endl << Q << std::endl;
157 std::cout << "Pest " << std::endl << Pest << std::endl;
158 }
159 // Bar-Shalom 5.2.3.5
160 Ppre = F * Pest * F.t() + Q;
161
162 // Matrice de covariance de l'erreur de prediction
163 if (verbose_mode)
164 std::cout << "Ppre " << std::endl << Ppre << std::endl;
165}
166
198{
199 if (verbose_mode) {
200 std::cout << "z " << std::endl << z << std::endl;
201 }
202 // Bar-Shalom 5.2.3.11
203 vpMatrix S = H * Ppre * H.t() + R;
204 if (verbose_mode) {
205 std::cout << "S " << std::endl << S << std::endl;
206 }
207
208 W = (Ppre * H.t()) * (S).inverseByLU();
209 if (verbose_mode) {
210 std::cout << "W " << std::endl << W << std::endl;
211 }
212 // Bar-Shalom 5.2.3.15
213 Pest = Ppre - W * S * W.t();
214 if (verbose_mode) {
215 std::cout << "Pest " << std::endl << Pest << std::endl;
216 }
217
218 // Bar-Shalom 5.2.3.12 5.2.3.13 5.2.3.7
219 Xest = Xpre + (W * (z - (H * Xpre)));
220 if (verbose_mode) {
221 std::cout << "Xest " << std::endl << Xest << std::endl;
222 }
223
224 iter++;
225}
226
227#if 0
228
277void
278vpKalmanFilter::initFilterCteAcceleration(double dt,
279 vpColVector &Z0,
280 vpColVector &Z1,
281 vpColVector &Z2,
282 vpColVector &sigma_noise,
283 vpColVector &sigma_state)
284{
285 this->dt = dt;
286
287 double dt2 = dt*dt;
288 double dt3 = dt2*dt;
289 double dt4 = dt3*dt;
290 double dt5 = dt4*dt;
291
292 //init_done = true ;
293
294 Pest = 0;
295 // initialise les matrices decrivant les modeles
296 for (int i = 0; i < size_measure; i++) {
297 // modele sur l'etat
298
299 // | 1 dt dt2/2 |
300 // F = | 0 1 dt |
301 // | 0 0 1 |
302
303 F[3*i][3*i] = 1;
304 F[3*i][3*i+1] = dt;
305 F[3*i][3*i+2] = dt*dt/2;
306 F[3*i+1][3*i+1] = 1;
307 F[3*i+1][3*i+2] = dt;
308 F[3*i+2][3*i+2] = 1;
309
310
311 // modele sur la mesure
312 H[i][3*i] = 1;
313 H[i][3*i+1] = 0;
314 H[i][3*i+2] = 0;
315
316 double sR = sigma_noise[i];
317 double sQ = sigma_state[i];
318
319 // bruit de mesure
320 R[i][i] = (sR);
321
322 // bruit d'etat 6.2.3.9
323 Q[3*i][3*i] = sQ * dt5/20;
324 Q[3*i][3*i+1] = sQ * dt4/8;
325 Q[3*i][3*i+2] = sQ * dt3/6;
326
327 Q[3*i+1][3*i] = sQ * dt4/8;
328 Q[3*i+1][3*i+1] = sQ * dt3/3;
329 Q[3*i+1][3*i+2] = sQ * dt2/2;
330
331 Q[3*i+2][3*i] = sQ * dt3/6;
332 Q[3*i+2][3*i+1] = sQ * dt2/2.0;
333 Q[3*i+2][3*i+2] = sQ * dt;
334
335
336 // Initialisation pour la matrice de covariance sur l'etat
337
338 Pest[3*i][3*i] = sR;
339 Pest[3*i][3*i+1] = 1.5/dt*sR;
340 Pest[3*i][3*i+2] = sR/(dt2);
341
342 Pest[3*i+1][3*i] = 1.5/dt*sR;
343 Pest[3*i+1][3*i+1] = dt3/3*sQ + 13/(2*dt2)*sR;
344 Pest[3*i+1][3*i+2] = 9*dt2*sQ/40.0 +6/dt3*sR;
345
346 Pest[3*i+2][3*i] = sR/(dt2);
347 Pest[3*i+2][3*i+1] = 9*dt2*sQ/40.0 +6/dt3*sR;
348 Pest[3*i+2][3*i+2] = 23*dt/30.0*sQ+6.0/dt4*sR;
349
350
351 // Initialisation pour l'etat
352
353 Xest[3*i] = Z2[i];
354 Xest[3*i+1] = (1.5 *Z2[i] - Z1[i] -0.5*Z0[i]) /(2*dt);
355 Xest[3*i+2] = (Z2[i] - 2*Z1[i] + Z0[i]) /(dt*dt);
356
357 }
358}
359
360void
361vpKalmanFilter::initFilterSinger(double dt,
362 double a,
363 vpColVector &Z0,
364 vpColVector &Z1,
365 vpColVector &sigma_noise,
366 vpColVector &sigma_state)
367{
368 this->dt = dt;
369
370 double dt2 = dt*dt;
371 double dt3 = dt2*dt;
372
373 double a2 = a*a;
374 double a3 = a2*a;
375 double a4 = a3*a;
376
377 //init_done = true ;
378
379 Pest = 0;
380 // initialise les matrices decrivant les modeles
381 for (int i = 0; i < size_measure; i++) {
382 // modele sur l'etat
383
384 // | 1 dt dt2/2 |
385 // F = | 0 1 dt |
386 // | 0 0 1 |
387
388 F[3*i][3*i] = 1;
389 F[3*i][3*i+1] = dt;
390 F[3*i][3*i+2] = 1/a2*(1+a*dt+exp(-a*dt));
391 F[3*i+1][3*i+1] = 1;
392 F[3*i+1][3*i+2] = 1/a*(1-exp(-a*dt));
393 F[3*i+2][3*i+2] = exp(-a*dt);
394
395
396 // modele sur la mesure
397 H[i][3*i] = 1;
398 H[i][3*i+1] = 0;
399 H[i][3*i+2] = 0;
400
401 double sR = sigma_noise[i];
402 double sQ = sigma_state[i];
403
404 R[i][i] = (sR); // bruit de mesure 1.5mm
405
406 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));
407 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);
408 Q[3*i][3*i+2] = sQ/a2*(1-exp(-2*a*dt)-2*a*dt*exp(-a*dt));
409
410 Q[3*i+1][3*i] = Q[3*i][3*i+1];
411 Q[3*i+1][3*i+1] = sQ/a2*(4*exp(-a*dt)-3-exp(-2*a*dt)+2*a*dt);
412 Q[3*i+1][3*i+2] = sQ/a*(exp(-2*a*dt)+1- 2*exp(-a*dt));
413
414 Q[3*i+2][3*i] = Q[3*i][3*i+2];
415 Q[3*i+2][3*i+1] = Q[3*i+1][3*i+2];
416 Q[3*i+2][3*i+2] = sQ*(1-exp(-2*a*dt));
417
418
419 // Initialisation pour la matrice de covariance sur l'etat
420 Pest[3*i][3*i] = sR;
421 Pest[3*i][3*i+1] = 1/dt*sR;
422 Pest[3*i][3*i+2] = 0;
423
424 Pest[3*i+1][3*i] = 1/dt*sR;
425 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));
426 Pest[3*i+1][3*i+2] = sQ/(a2*dt)*(exp(-a*dt)+a*dt-1);
427
428 Pest[3*i+2][3*i] = 0;
429 Pest[3*i+2][3*i+1] = Pest[3*i+1][3*i+2];
430 Pest[3*i+2][3*i+2] = 0;
431
432
433 // Initialisation pour l'etat
434
435 Xest[3*i] = Z1[i];
436 Xest[3*i+1] = (Z1[i] - Z0[i]) /(dt);
437 Xest[3*i+2] = 0;
438
439 }
440}
441
442#endif
443END_VISP_NAMESPACE
Implementation of column vector and the associated operations.
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ fatalError
Fatal error.
Definition vpException.h:72
unsigned int size_state
Size of the state vector .
vpColVector Xpre
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 I
Identity matrix .
vpMatrix H
Matrix that describes the evolution of the measurements.
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175