/
kalman.js
103 lines (89 loc) · 2.08 KB
/
kalman.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/**
* KalmanFilter
* @class
* @author Wouter Bulten
* @see {@link http://github.com/wouterbulten/kalmanjs}
* @version Version: 1.0.0-beta
* @copyright Copyright 2015-2018 Wouter Bulten
* @license MIT License
* @preserve
*/
export default class KalmanFilter {
/**
* Create 1-dimensional kalman filter
* @param {Number} options.R Process noise
* @param {Number} options.Q Measurement noise
* @param {Number} options.A State vector
* @param {Number} options.B Control vector
* @param {Number} options.C Measurement vector
* @return {KalmanFilter}
*/
constructor({R = 1, Q = 1, A = 1, B = 0, C = 1} = {}) {
this.R = R; // noise power desirable
this.Q = Q; // noise power estimated
this.A = A;
this.C = C;
this.B = B;
this.cov = NaN;
this.x = NaN; // estimated signal without noise
}
/**
* Filter a new value
* @param {Number} z Measurement
* @param {Number} u Control
* @return {Number}
*/
filter(z, u = 0) {
if (isNaN(this.x)) {
this.x = (1 / this.C) * z;
this.cov = (1 / this.C) * this.Q * (1 / this.C);
}
else {
// Compute prediction
const predX = this.predict(u);
const predCov = this.uncertainty();
// Kalman gain
const K = predCov * this.C * (1 / ((this.C * predCov * this.C) + this.Q));
// Correction
this.x = predX + K * (z - (this.C * predX));
this.cov = predCov - (K * this.C * predCov);
}
return this.x;
}
/**
* Predict next value
* @param {Number} [u] Control
* @return {Number}
*/
predict(u = 0) {
return (this.A * this.x) + (this.B * u);
}
/**
* Return uncertainty of filter
* @return {Number}
*/
uncertainty() {
return ((this.A * this.cov) * this.A) + this.R;
}
/**
* Return the last filtered measurement
* @return {Number}
*/
lastMeasurement() {
return this.x;
}
/**
* Set measurement noise Q
* @param {Number} noise
*/
setMeasurementNoise(noise) {
this.Q = noise;
}
/**
* Set the process noise R
* @param {Number} noise
*/
setProcessNoise(noise) {
this.R = noise;
}
}