I want to improve the accuracy of my internal positioning structure and therefore apply kalmanfilter. I found that the apache commons math library supports Kalmanfilter, so I tried to use it and followed the tutorials: https://commons.apache.org/proper/commons-math/userguide/filter.html
I think I configured the matrix correctly for 2D positioning, while the state consists of position and speed. My task is to evaluate the Position () method. How to get the correct pNoise and mNoise variable? And why should I point them out. I thought it was something for Q and R-matrices ... I help in every way!
public class Kalman {
private RealMatrix A;
private RealMatrix B;
private RealMatrix H;
private RealMatrix Q;
private RealMatrix R;
private RealMatrix PO;
private RealVector x;
private final double dt = 0.1d;
private final double measurementNoise = 10d;
private final double accelNoise = 0.2d;
private RealVector u = new ArrayRealVector(new double[] { 0.1d, 0.1d });
private RealVector tmpPNoise = new ArrayRealVector(new double[] { Math.pow(dt, 2d) / 2d, dt });
private RealVector mNoise = new ArrayRealVector(1);
private KalmanFilter filter;
public Kalman(){
A = new Array2DRowRealMatrix(new double[][] {
{ 1d, 0d, dt, 0d },
{ 0d, 1d, 0d, dt },
{ 0d, 0d, 1d, 0d },
{ 0d, 0d, 0d, 1d }
});
B = new Array2DRowRealMatrix(new double[][] {
{ Math.pow(dt, 2d) / 2d },
{ Math.pow(dt, 2d) / 2d },
{ dt},
{ dt }
});
H = new Array2DRowRealMatrix(new double[][] {
{ 1d, 0d, 0d, 0d },
{ 0d, 1d, 0d, 0d },
});
Q = new Array2DRowRealMatrix(new double[][] {
{ Math.pow(dt, 4d)/4d, 0d, Math.pow(dt, 3d)/2d, 0d },
{ 0d, Math.pow(dt, 4d)/4d, 0d, Math.pow(dt, 3d)/2d },
{ Math.pow(dt, 3d)/2d, 0d, Math.pow(dt, 2d), 0d },
{ 0d, Math.pow(dt, 3d)/2d, 0d, Math.pow(dt, 2d) }
});
R = new Array2DRowRealMatrix(new double[][] {
{ Math.pow(measurementNoise, 2d), 0d },
{ 0d, Math.pow(measurementNoise, 2d) }
});
x = new ArrayRealVector(new double[] { 0, 0, 0, 0 });
ProcessModel pm = new DefaultProcessModel(A, B, Q, x, PO);
MeasurementModel mm = new DefaultMeasurementModel(H, R);
filter = new KalmanFilter(pm, mm);
}
public Position<Euclidean2D> esimatePosition(Position<Euclidean2D> position){
RandomGenerator rand = new JDKRandomGenerator();
double[] pos = position.toArray();
filter.predict(u);
RealVector pNoise = tmpPNoise.mapMultiply(accelNoise * pos[0]);
x = A.operate(x).add(B.operate(u)).add(pNoise);
mNoise.setEntry(0, measurementNoise * rand.nextGaussian());
RealVector z = H.operate(x).add(mNoise);
filter.correct(z);
double pX = filter.getStateEstimation()[0];
double pY = filter.getStateEstimation()[1];
return new Position2D(pX, pY);
}
}