I am trying to build a compass with a gyroscope, accelerometer and magnetometer.
I am fusing acc values with magnon values to get the orientation (using the rotation matrix), and it works very well.
But now I want to add a gyroscope to help compensate when the magnetic sensor is not accurate. So I want to use the kalman filter to fuse the two results and get a good filtered one (acc and mag are already filtered with lpf).
My matrices:
state(Xk) => {Compass Heading, Rate from the gyro in that axis}. transition(Fk) => {{1,dt},{0,1}} measurement(Zk) => {Compass Heading, Rate from the gyro in that axis} Hk => {{1,0},{0,1}} Qk = > {0,0},{0,0} Rk => {e^2(compass),0},{0,e^2(gyro)}
And this is my implementation of the Kalman filter:
public class KalmanFilter { private Matrix x,F,Q,P,H,K,R; private Matrix y,s; public KalmanFilter(){ } public void setInitialState(Matrix _x, Matrix _p){ this.x = _x; this.P = _p; } public void update(Matrix z){ try { y = MatrixMath.subtract(z, MatrixMath.multiply(H, x)); s = MatrixMath.add(MatrixMath.multiply(MatrixMath.multiply(H, P), MatrixMath.transpose(H)), R); K = MatrixMath.multiply(MatrixMath.multiply(P, H), MatrixMath.inverse(s)); x = MatrixMath.add(x, MatrixMath.multiply(K, y)); P = MatrixMath.subtract(P, MatrixMath.multiply(MatrixMath.multiply(K, H), P)); } catch (IllegalDimensionException e) { e.printStackTrace(); } catch (NoSquareException e) { e.printStackTrace(); } predict(); } private void predict(){ try { x = MatrixMath.multiply(F, x); P = MatrixMath.add(Q, MatrixMath.multiply(MatrixMath.multiply(F, P), MatrixMath.transpose(F))); } catch (IllegalDimensionException e) { e.printStackTrace(); } } public Matrix getStateMatirx(){ return x; } public Matrix getCovarianceMatrix(){ return P; } public void setMeasurementMatrix(Matrix h){ this.H = h; } public void setProcessNoiseMatrix(Matrix q){ this.Q = q; } public void setMeasurementNoiseMatrix(Matrix r){ this.R = r; } public void setTransformationMatrix(Matrix f){ this.F = f; } }
First, the initial values begin:
Xk => {0,0} Pk => {1000,0},{0,1000}
Then I look at two results (one Kalman and one compass). Kalman alone starts at 0 and grows at a certain speed regardless of the measured (compass), and it does not stop, it just keeps increasing ...
I don’t understand what am I doing wrong?