ジャイロ、加速度計、磁力計でコンパスを作ろうとしています。
acc値と磁力計の値を融合して(回転行列を使用して)方向を取得していますが、かなりうまく機能しています。
しかし今、私は磁気センサーが正確でないときに補償するのを助けるためにジャイロスコープを追加したいと思います。したがって、カルマンフィルターを使用して、2つの結果を融合し、適切にフィルター処理された結果を取得したいと思います(accとmagはすでにlpfを使用してフィルター処理されています)。
私の行列は次のとおりです。
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)}
そして、これは私のカルマンフィルターの実装です:
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;
}
}
最初に、この開始値が与えられます:
Xk => {0,0}
Pk => {1000,0},{0,1000}
次に、2つの結果(カルマン1つとコンパス1つ)を監視します。カルマンのものは0から始まり、測定されたもの(コンパス)に関係なく一定の割合で増加し、増加し続けるだけで止まりません...
何が間違っているのか理解できませんか?