Visual Servoing Platform
version 3.7.0
Toggle main menu visibility
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
44
BEGIN_VISP_NAMESPACE
56
void
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;
61
F
.resize(
size_state
*
nsignal
,
size_state
*
nsignal
);
62
H
.resize(
size_measure
*
nsignal
,
size_state
*
nsignal
);
63
64
R
.resize(
size_measure
*
nsignal
,
size_measure
*
nsignal
);
65
Q
.resize(
size_state
*
nsignal
,
size_state
*
nsignal
);
66
67
Xest
.resize(
size_state
*
nsignal
);
68
Xest
= 0;
69
Xpre
.resize(
size_state
*
nsignal
);
70
Xpre
= 0;
71
72
Pest
.resize(
size_state
*
nsignal
,
size_state
*
nsignal
);
73
Pest
= 0;
74
75
I
.resize(
size_state
*
nsignal
,
size_state
*
nsignal
);
76
// init_done = false ;
77
iter
= 0;
78
dt
= -1;
79
}
80
87
vpKalmanFilter::vpKalmanFilter
()
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
99
vpKalmanFilter::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
117
vpKalmanFilter::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
140
void
vpKalmanFilter::prediction
()
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
197
void
vpKalmanFilter::filtering
(
const
vpColVector
&z)
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
277
void
278
vpKalmanFilter::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
360
void
361
vpKalmanFilter::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
443
END_VISP_NAMESPACE
vpColVector
Implementation of column vector and the associated operations.
Definition
vpColVector.h:191
vpException
error that can be emitted by ViSP classes.
Definition
vpException.h:60
vpException::fatalError
@ fatalError
Fatal error.
Definition
vpException.h:72
vpKalmanFilter::prediction
void prediction()
Definition
vpKalmanFilter.cpp:140
vpKalmanFilter::size_state
unsigned int size_state
Size of the state vector .
Definition
vpKalmanFilter.h:114
vpKalmanFilter::vpKalmanFilter
vpKalmanFilter()
Definition
vpKalmanFilter.cpp:87
vpKalmanFilter::Xpre
vpColVector Xpre
Definition
vpKalmanFilter.h:182
vpKalmanFilter::Ppre
vpMatrix Ppre
Definition
vpKalmanFilter.h:204
vpKalmanFilter::iter
long iter
Filter step or iteration. When set to zero, initialize the filter.
Definition
vpKalmanFilter.h:111
vpKalmanFilter::R
vpMatrix R
Measurement noise covariance matrix .
Definition
vpKalmanFilter.h:191
vpKalmanFilter::init
void init(unsigned int size_state, unsigned int size_measure, unsigned int n_signal)
Definition
vpKalmanFilter.cpp:56
vpKalmanFilter::nsignal
unsigned int nsignal
Number of signal to filter.
Definition
vpKalmanFilter.h:118
vpKalmanFilter::Q
vpMatrix Q
Process noise covariance matrix .
Definition
vpKalmanFilter.h:193
vpKalmanFilter::W
vpMatrix W
Definition
vpKalmanFilter.h:219
vpKalmanFilter::filtering
void filtering(const vpColVector &z)
Definition
vpKalmanFilter.cpp:197
vpKalmanFilter::Xest
vpColVector Xest
Definition
vpKalmanFilter.h:177
vpKalmanFilter::size_measure
unsigned int size_measure
Size of the measure vector .
Definition
vpKalmanFilter.h:116
vpKalmanFilter::I
vpMatrix I
Identity matrix .
Definition
vpKalmanFilter.h:222
vpKalmanFilter::Pest
vpMatrix Pest
Definition
vpKalmanFilter.h:211
vpKalmanFilter::H
vpMatrix H
Matrix that describes the evolution of the measurements.
Definition
vpKalmanFilter.h:188
vpKalmanFilter::verbose_mode
bool verbose_mode
Definition
vpKalmanFilter.h:122
vpKalmanFilter::F
vpMatrix F
Definition
vpKalmanFilter.h:185
vpKalmanFilter::dt
double dt
Definition
vpKalmanFilter.h:197
vpMatrix
Implementation of a matrix and operations on matrices.
Definition
vpMatrix.h:175
BEGIN_VISP_NAMESPACE
Definition
vpMbtDistanceCircle.cpp:55
yolo-centering-task-afma6.i
i
Definition
yolo-centering-task-afma6.py:329
modules
core
src
math
kalman
vpKalmanFilter.cpp
Generated by
1.17.0