Merge lp:~oontvoo/kalmanfilterimpl/runnable_class into lp:kalmanfilterimpl

Proposed by Vy Nguyen
Status: Needs review
Proposed branch: lp:~oontvoo/kalmanfilterimpl/runnable_class
Merge into: lp:kalmanfilterimpl
Diff against target: 723 lines (+588/-86)
6 files modified
.bzrignore (+2/-0)
src/kalmanfilter/RunFilter.java (+13/-1)
src/kalmanfilter/RunFilter2.java (+355/-0)
src/kalmanfilter/impl/KalmanFilter.java (+33/-85)
src/kalmanfilter/impl/KalmanFilter1.java (+84/-0)
src/kalmanfilter/impl/KalmanFilter2.java (+101/-0)
To merge this branch: bzr merge lp:~oontvoo/kalmanfilterimpl/runnable_class
Reviewer Review Type Date Requested Status
Vy Thuy Nguyen Pending
Review via email: mp+113821@code.launchpad.net

Description of the change

- Refactor KalmanFilter into an interface.
- Add a runnable class that could generate/read data from text file which can then be used (by Excel) to graph the data

Probably needs A LOT of fixings. The graph doesn't look that good.

To post a comment you must log in.

Unmerged revisions

2. By vnguyen (<email address hidden>)

create a runnable class

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file '.bzrignore'
--- .bzrignore 1970-01-01 00:00:00 +0000
+++ .bzrignore 2012-07-07 07:30:27 +0000
@@ -0,0 +1,2 @@
1nbproject/**
2build/**
03
=== modified file 'src/kalmanfilter/RunFilter.java'
--- src/kalmanfilter/RunFilter.java 2012-07-03 18:46:12 +0000
+++ src/kalmanfilter/RunFilter.java 2012-07-07 07:30:27 +0000
@@ -26,6 +26,8 @@
26import java.util.Arrays;26import java.util.Arrays;
27import java.util.Collections;27import java.util.Collections;
28import java.util.List;28import java.util.List;
29import kalmanfilter.impl.KalmanFilter1;
30import kalmanfilter.impl.KalmanFilter2;
2931
30/**32/**
31 *33 *
@@ -67,6 +69,16 @@
67 this.ay = ay;69 this.ay = ay;
68 }70 }
69 71
72 public String toString()
73 {
74 return "(" + x + ", "
75 + y + ", "
76 + vx + ", "
77 + vy + ", "
78 + ax + ", "
79 + ay + ", "
80 + t + ")";
81 }
70 @Override82 @Override
71 public int compareTo(Point o)83 public int compareTo(Point o)
72 {84 {
@@ -88,7 +100,7 @@
88 List<Point> output = new ArrayList<Point>(inputs.size());100 List<Point> output = new ArrayList<Point>(inputs.size());
89 101
90 //(Matrix X, Matrix P, Matrix Q, Matrix H, Matrix A, Matrix R)102 //(Matrix X, Matrix P, Matrix Q, Matrix H, Matrix A, Matrix R)
91 KalmanFilter filter = new KalmanFilter(createX(inputs, 0),103 KalmanFilter2 filter = new KalmanFilter2(createX(inputs, 0),
92 getP0(),104 getP0(),
93 getQ(),105 getQ(),
94 getH(),106 getH(),
95107
=== added file 'src/kalmanfilter/RunFilter2.java'
--- src/kalmanfilter/RunFilter2.java 1970-01-01 00:00:00 +0000
+++ src/kalmanfilter/RunFilter2.java 2012-07-07 07:30:27 +0000
@@ -0,0 +1,355 @@
1/**
2 * Implementation of the Kalman Filter
3 * Copyright (C) 2012 Vy Nguyen
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21package kalmanfilter;
22
23import Jama.Matrix;
24import java.io.*;
25import java.util.*;
26import kalmanfilter.RunFilter.Point;
27import kalmanfilter.impl.KalmanFilter;
28import kalmanfilter.impl.KalmanFilter1;
29
30/**
31 *
32 * @author Vy Thao Nguyen
33 */
34public class RunFilter2
35{
36 private static List<Point> createIdealValues(int count, double dt,
37 double ax0, double ay0,
38 double vx0, double vy0,
39 double x0, double y0)
40 {
41 // x = x0 + v * dt
42 // v = v0 + a * dt
43
44 List<Point> ret = new ArrayList<Point>();
45 ret.add(new Point(x0, y0, 0, vx0, vy0, ax0, ay0)); // first point
46 --count;
47
48 double t = dt;
49 for (int n = 0; n < count; ++n)
50 {
51 double vx = vx0 + ax0 * t;
52 double x = x0 + vx0 * t + 0.5 * ay0 * t * t;
53
54 double vy = vy0 + ay0 * t;
55 double y = y0 + vy0 * t + 0.5 * ay0 * t * t;
56
57 ret.add(new Point(x, y, t, vx, vy, ax0, ay0));
58 t += dt;
59 }
60 return ret;
61 }
62
63 private static void writeToFile(String fileName, List<Point> toWrite) throws IOException
64 {
65 StringBuilder bd = new StringBuilder();
66
67 for (Point p : toWrite)
68 bd.append(p.x).append(" ").append(p.y).append(System.getProperty("line.separator"));
69
70 FileWriter fstream = new FileWriter(fileName);
71 BufferedWriter out = new BufferedWriter(fstream);
72 out.write(bd.toString());
73 out.close();
74 }
75
76 private static double parseArg(String args[])
77 {
78 if (args.length != 1)
79 {
80 System.out.println("default noise: " + DEFAULT_NOISE);
81 return DEFAULT_NOISE;
82 }
83 return Double.parseDouble(args[0]);
84 }
85
86 private static List<Point> readSensorData(double dt, double ax)
87 {
88 try
89 {
90 Scanner input = new Scanner(new File(SENSOR));
91 double t = 0;
92 List<Point> ret = new ArrayList<Point>();
93
94 while(input.hasNext())
95 {
96 double x = Double.parseDouble(input.next());
97 double y = Double.parseDouble(input.next());
98 ret.add(new Point(x, y, t, 0, 0, ax, ax));
99 t += dt;
100 }
101 return ret;
102 }
103 catch (FileNotFoundException ex)
104 {
105 System.out.println("File not found: " + SENSOR);
106 System.exit(2);
107 }
108 return null;
109 }
110
111 public static void main (String args[]) throws IOException
112 {
113 double ax = 2.5;
114 double ay = 1.256;
115 double dt = 0.8;
116
117 System.out.println("computing the ideal values");
118 List<Point> idealData = createIdealValues(9, dt,
119 ax, ay ,
120 0, 0,
121 0, 0);
122 writeToFile(IDEAL, idealData);
123
124 System.out.println("reading sensor data");
125 List<Point> sensor = readSensorData(dt, ax);
126 double noise = parseArg(args);
127
128 System.out.println("filtering sensor data");
129 writeToFile(CORRECTED, filter(sensor, noise));
130 }
131 /**
132 *
133 * @param inputs
134 * @param sensorNoise
135 * @return
136 */
137 public static List<Point> filter(List<Point> inputs,
138 double sensorNoise)
139 {
140 // sort the points in time order
141 Collections.sort(inputs);
142
143 // compute the velocity
144 List<Point> updated = computeVAndA(inputs);
145
146 // get the standard deviation of acceleration
147 double sd = getSd(updated);
148
149 List<Point> output = new ArrayList<Point>(inputs.size());
150 output.add(inputs.get(0)); // first point is the same
151
152 Matrix P0 = getP0();
153 Matrix H = getH();
154 Matrix R = createR(sensorNoise);
155
156 KalmanFilter filterX = new KalmanFilter1(createXx(updated.get(0)),
157 P0,
158 H,
159 R
160 );
161
162 KalmanFilter filterY = new KalmanFilter1(createXy(updated.get(0)),
163 P0,
164 H,
165 R
166 );
167 for (int n = 1; n < updated.size(); ++n)
168 {
169 Point cur = updated.get(n);
170 Matrix A = createA(cur);
171 Matrix G = createG(cur);
172 Matrix Gx = G.times(cur.ax);
173 Matrix Gy = G.times(cur.ay);
174 Matrix Q = getQ(G, sd);
175
176 Matrix correctedX = filterX.timeUpdate(A, Q, Gx).messurementUpdate(createXx(cur));
177 Matrix correctedY = filterY.timeUpdate(A, Q, Gy).messurementUpdate(createXy(cur));
178
179 output.add(decodeXY(correctedX, correctedY, inputs.get(n)));
180 }
181
182 return output;
183 }
184 private static double getSd(List<Point> p)
185 {
186 // for now, the accelerations are const
187 return 0;
188 }
189
190 /**
191 * TODO: correctly decode the state matrix into a point.
192 * (that is, retrieve a and v)
193 *
194 * @param X the corrected state matrix
195 * @return the corrected value of (x,y,t)
196 */
197 private static Point decodeXY(Matrix X, Matrix Y, Point input)
198 {
199 return new Point(X.get(0, 0) / 10, // x
200 Y.get(0, 0) / 10, // y
201 X.get(1, 0) / 10, // vx
202 Y.get(1, 0) / 10, // vy
203 input.ax, // unchanged
204 input.ay, // unchanged
205 input.t // unchanged
206 );
207 }
208
209 /**
210 * TODO: correctly encode the point (velocity, acceleration, etc.) into a matrix.
211 *
212 * Vector x = {x, vx , ax, ay}
213 *
214 * @param points
215 * @param currentIndex index of the point the filter is currently looking at
216 * @return the input vector X
217 */
218 private static Matrix createXx(Point current)
219 {
220 Matrix x = new Matrix(2, 1);
221
222 x.set(0, 0, current.x);
223 x.set(1, 0, current.vx);
224
225 return x;
226 }
227
228 private static Matrix createXy(Point cur)
229 {
230 Matrix y = new Matrix(2, 1);
231
232 y.set(0, 0, cur.y);
233 y.set(1, 0, cur.vy);
234
235 return y;
236 }
237 /**
238 * Compute the instant velocity and acceleration of each point
239 * <b>This method makes the following assumptions:</b>
240 * 1. Acceleration of a Point object is constant and was properly set in the constructor.
241 * 2. The velocity of the first point is either 0 or has already been correctly calculated.
242 *
243 * TODO: take variable acceleration into account.
244 *
245 * @param points
246 * @return list of point with correct v and a
247 */
248 private static List<Point> computeVAndA(List<Point> points)
249 {
250 int size = points.size();
251 double vx_0 = points.get(0).vx;
252 double vy_0 = points.get(0).vy;
253 double ax_0 = points.get(0).ax;
254 double ay_0 = points.get(0).ay;
255
256 List<Point> result = new ArrayList<Point> (size);
257 result.add(points.get(0));
258
259 for (int i = 1; i < size; ++i)
260 {
261 double dt = points.get(i).t - points.get(0).t;
262 double vx = vx_0 + ax_0 * dt;
263 double vy = vy_0 + ay_0 * dt;
264
265 result.add(new Point(points.get(i).x,
266 points.get(i).y,
267 dt,
268 vx,
269 vy,
270 points.get(i).ax,
271 points.get(i).ay
272 ));
273 }
274
275 return result;
276 }
277
278 /**
279 * TODO:
280 * Same as createX(...)'s
281 *
282 * @param inputs
283 * @param currentIndex
284 * @return the state matrix A based on the the current and past position
285 */
286 private static Matrix createA(Point current)
287 {
288 Matrix A = Matrix.identity(2, 2);
289 A.set(0, 1, current.t);
290 return A;
291 }
292
293 /**
294 *
295 * @param error the sensor's error
296 * @return the measurement noise covariance matrix
297 */
298 private static Matrix createR (double error)
299 {
300 Matrix R = new Matrix(1,1);
301 R.set(0, 0, error);
302 return R;
303 }
304 /**
305 *
306 * @return the initial P matrix, which contains all zeroes
307 */
308 private static Matrix getP0()
309 {
310 double m2x2[][] = new double[VARS_COUNT][VARS_COUNT];
311
312 for (int n = 0; n < VARS_COUNT; ++n)
313 Arrays.fill(m2x2[n], 0);
314
315 return Matrix.constructWithCopy(m2x2);
316 }
317
318 /**
319 * TODO:
320 * correctly determine this
321 *
322 * @return the process noise covariance matrix
323 */
324 private static Matrix getQ(Matrix G, double sd)
325 {
326 return G.times(G.transpose()).times(sd * sd);
327 }
328
329 /**
330 *
331 * @return the [1 by n] observation matrix: [1 0 0 0 .... 0 ]
332 */
333 private static Matrix getH()
334 {
335 Matrix H = new Matrix(1,2);
336 H.set(0, 0, 1);
337 return H;
338 }
339
340 private static Matrix createG(Point p)
341 {
342 Matrix ret = new Matrix(2, 1);
343 ret.set(0, 0, p.t * p.t / 2);
344 ret.set(1, 0, p.t);
345
346 return ret;
347 }
348
349 private static final String IDEAL = "C:\\Users\\NhatPhan\\Desktop\\Choe\\Sensor Research\\data\\ideal.txt";
350 private static final String SENSOR = "C:\\Users\\NhatPhan\\Desktop\\Choe\\Sensor Research\\data\\sensor.txt";
351 private static final String CORRECTED = "C:\\Users\\NhatPhan\\Desktop\\Choe\\Sensor Research\\data\\corrected.txt";
352
353 private static final double DEFAULT_NOISE = 0.5;
354 private static final int VARS_COUNT = 2;
355}
0356
=== modified file 'src/kalmanfilter/impl/KalmanFilter.java'
--- src/kalmanfilter/impl/KalmanFilter.java 2012-07-03 18:46:12 +0000
+++ src/kalmanfilter/impl/KalmanFilter.java 2012-07-07 07:30:27 +0000
@@ -1,85 +1,33 @@
1/**1/**
2 * Implementation of the Kalman Filter2 * Implementation of the Kalman Filter
3 * Copyright (C) 2012 Vy Nguyen3 * Copyright (C) 2012 Vy Nguyen
4 *4 *
5 * This library is free software; you can redistribute it and/or5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful,10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.13 * Library General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU Library General Public15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.18 * Boston, MA 02110-1301, USA.
19 */19 */
20package kalmanfilter.impl;20
21 21package kalmanfilter.impl;
22import Jama.Matrix;22
2323import Jama.Matrix;
24/**24
25 * Implements the Kalman Filter using Jama's Matrix API25/**
26 * 26 *
27 * @author Vy Thao Nguyen27 * @author Vy Thao Nguyen
28 */28 */
29public class KalmanFilter 29public interface KalmanFilter
30{30{
31 // variable states31 public KalmanFilter timeUpdate(Matrix A, Matrix Q, Matrix Ga);
32 private Matrix X; // input vector32 public Matrix messurementUpdate(Matrix Xk);
33 private Matrix P; // state covariance matrix33}
34 private Matrix Q; // process noise covariance matrix
35
36 // const states
37 private final Matrix H; // observation matrix
38 private final Matrix I; // the identity matrix
39 private final Matrix A; // state matrix
40 private final Matrix R; // measurement noise covariance matrix
41 private final Matrix B; // control input matrix
42 private final Matrix u;
43
44 public KalmanFilter(Matrix X, Matrix P, Matrix Q, Matrix H, Matrix A, Matrix R, Matrix B, Matrix u)
45 {
46 this.X = X;
47 this.P = P;
48 this.Q = Q;
49 this.H = H;
50 this.A = A;
51 this.R = R;
52 this.B = B;
53 this.u = u;
54
55 I = Matrix.identity(P.getRowDimension(), P.getColumnDimension());
56 }
57
58 public KalmanFilter timeUpdate()
59 {
60 X = A.times(X).plus(B.times(u));
61 P = A.times(P).times(A.transpose()).plus(Q);
62 return this; // for easy chaining
63 }
64
65 /**
66 *
67 * @param Xk: the new measurement (sensor reading)
68 * @return
69 */
70 public Matrix messurementUpdate(Matrix Xk)
71 {
72 // compute kalman gain
73 //Kk+1 = PkHT(H PkHT + R)-1
74 Matrix K = P.times(H.transpose()).times((H.times(P).times(H.trace()).plus(R)).inverse());
75
76 // update x
77 // xk+1 = xk + K(zk+1 − Hxk )
78 X = X.plus(K.times((Xk.times(H)).minus(H.times(X))));
79
80 // update P
81 P = (I.minus(K.times(H))).times(P);
82
83 return X;
84 }
85}
8634
=== added file 'src/kalmanfilter/impl/KalmanFilter1.java'
--- src/kalmanfilter/impl/KalmanFilter1.java 1970-01-01 00:00:00 +0000
+++ src/kalmanfilter/impl/KalmanFilter1.java 2012-07-07 07:30:27 +0000
@@ -0,0 +1,84 @@
1/**
2 * Implementation of the Kalman Filter
3 * Copyright (C) 2012 Vy Nguyen
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20package kalmanfilter.impl;
21
22import Jama.Matrix;
23
24/**
25 * Implements the original Kalman Filter using Jama's Matrix API
26 *
27 * *original* being all states are encoded into one state matrix.
28 * If you have difficulty encoding all states into one, you might want to consider
29 * using KalmanFilter2.java
30 *
31 * @author Vy Thao Nguyen
32 */
33public class KalmanFilter1 implements KalmanFilter
34{
35 // variable states
36 private Matrix X; // input vector
37 private Matrix P; // state covariance matrix
38
39 // const states
40 private final Matrix H; // observation matrix
41 private final Matrix I; // the identity matrix
42 private final Matrix R; // measurement noise covariance matrix
43
44 public KalmanFilter1(Matrix X, Matrix P, Matrix H, Matrix R)
45 {
46 this.X = X;
47 this.P = P;
48 this.H = H;
49 this.R = R;
50
51 I = Matrix.identity(P.getRowDimension(), P.getColumnDimension());
52 }
53
54 @Override
55 public KalmanFilter1 timeUpdate(Matrix A, Matrix Q, Matrix Ga)
56 {
57 // Matrix Ax = A.times(X);
58 X = (A.times(X)).plus(Ga);
59 P = A.times(P).times(A.transpose()).plus(Q);
60 return this; // for easy chaining
61 }
62
63 /**
64 *
65 * @param Xk: the new measurement (sensor reading)
66 * @return
67 */
68 @Override
69 public Matrix messurementUpdate(Matrix Xk)
70 {
71 // compute kalman gain
72 //Kk+1 = PkHT(H PkHT + R)-1
73 Matrix K = (P.times(H.transpose())).times((H.times(P).times(H.transpose()).plus(R)).inverse());
74
75 // update x
76 // xk+1 = xk + K(zk+1 − Hxk )
77 X = X.plus(K.times((H.times(Xk)).minus(H.times(X))));
78
79 // update P
80 P = (I.minus(K.times(H))).times(P);
81
82 return X;
83 }
84}
085
=== added file 'src/kalmanfilter/impl/KalmanFilter2.java'
--- src/kalmanfilter/impl/KalmanFilter2.java 1970-01-01 00:00:00 +0000
+++ src/kalmanfilter/impl/KalmanFilter2.java 2012-07-07 07:30:27 +0000
@@ -0,0 +1,101 @@
1/**
2 * Implementation of the Kalman Filter
3 * Copyright (C) 2012 Vy Nguyen
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21package kalmanfilter.impl;
22
23import Jama.Matrix;
24
25/**
26 * Implements the filter with different 'groups' of states encoded in different
27 * matrices.
28 *
29 * For eg.,
30 * For a system with the following states:
31 * x: horizontal position
32 * y: vertical position
33 * u: horizontal velocity
34 * v: vertical velocity
35 *
36 * divided into two groups: X1 = {x, u}, X2 = {y, v}
37 *
38 * TODO: make the number of 'groups' variable. Currently, this is only
39 * capable of handling a fixed 2 groups
40 *
41 * @author Vy Thao Nguyen
42 */
43public class KalmanFilter2 //implements KalmanFilter
44{
45 // variable states
46 private Matrix X; // input vector
47 private Matrix P; // state covariance matrix
48 private Matrix Q; // process noise covariance matrix
49
50 // const states
51 private final Matrix H; // observation matrix
52 private final Matrix I; // the identity matrix
53 private final Matrix A; // state matrix
54 private final Matrix R; // measurement noise covariance matrix
55 private final Matrix B; // control input matrix
56 private final Matrix u;
57
58 public KalmanFilter2(Matrix X, Matrix P, Matrix Q, Matrix H, Matrix A, Matrix R, Matrix B, Matrix u)
59 {
60 this.X = X;
61 this.P = P;
62 this.Q = Q;
63 this.H = H;
64 this.A = A;
65 this.R = R;
66 this.B = B;
67 this.u = u;
68
69 I = Matrix.identity(P.getRowDimension(), P.getColumnDimension());
70 }
71
72 // @Override
73 public KalmanFilter2 timeUpdate()
74 {
75 X = A.times(X).plus(B.times(u));
76 P = A.times(P).times(A.transpose()).plus(Q);
77 return this; // for easy chaining
78 }
79
80 /**
81 *
82 * @param Xk: the new measurement (sensor reading)
83 * @return
84 */
85 // @Override
86 public Matrix messurementUpdate(Matrix Xk)
87 {
88 // compute kalman gain
89 //Kk+1 = PkHT(H PkHT + R)-1
90 Matrix K = P.times(H.transpose()).times((H.times(P).times(H.trace()).plus(R)).inverse());
91
92 // update x
93 // xk+1 = xk + K(zk+1 − Hxk )
94 X = X.plus(K.times((Xk.times(H)).minus(H.times(X))));
95
96 // update P
97 P = (I.minus(K.times(H))).times(P);
98
99 return X;
100 }
101}

Subscribers

People subscribed via source and target branches

to all changes: