Фильтр Калмана — компас и гироскоп

Я пытаюсь построить компас с гироскопом, акселерометром и магнитометром.

Я объединяю значения acc со значениями магнитометра, чтобы получить ориентацию (используя матрицу вращения), и это работает очень хорошо.

Но теперь я хочу добавить гироскоп, чтобы помочь компенсировать, когда магнитный датчик не точен. Итак, я хочу использовать фильтр Калмана, чтобы объединить два результата и получить хороший отфильтрованный результат (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}

Затем я смотрю на два результата (по калману и по компасу). Калман начинается с 0 и увеличивается с некоторой скоростью, независимо от измеренного (компас), и он не остановится, просто продолжит увеличиваться...

Я не могу понять, что я делаю неправильно?


person user1396033    schedule 07.03.2013    source источник
comment
Зачем вы сами совмещаете эти данные? Что не так с тем, что предлагает платформа?   -  person Ali    schedule 07.03.2013
comment
Исправьте меня, если я ошибаюсь, но Android предлагает только соединение acc + mag   -  person user1396033    schedule 07.03.2013
comment
Нет, насколько я знаю, гироскопы тоже учитываются.   -  person Ali    schedule 07.03.2013
comment
Хорошо, я проверю это, но в любом случае для учебных целей кто-нибудь может ответить на мой вопрос?   -  person user1396033    schedule 07.03.2013
comment
Да .. вы правы .. Android изначально предохраняет только магнит и акк .. не говоря уже о том, что не на многих устройствах есть гироскопы. Я нашел ваш пост, в котором исследуется возможность передачи фильтра низких частот или фильтра Калмана непосредственно в компас, прежде чем объединить его с акселерометром. головокружительная проблема.   -  person erik    schedule 23.05.2013


Ответы (1)


Проблема, которую вы видите, заключается в том, что хотя гироскопы имеют очень низкий уровень шума, его среднее значение не равно нулю. Когда вы используете свой термин e^2(gyro), вы реализуете фильтр, в котором вы утверждаете, что z_gyro = true_gyro + v где v ~ N(0, e^2) Истина больше похожа на v ~ N(bias, e^2), где даже смещение имеет несколько членов (в основном статическое смещение при включении плюс сдвиг смещения, вызванный температурным дрейфом). В результате вы интегрируете смещение и постоянно вращаетесь.

Если вы откалибруете это смещение (просто измерьте выход гироскопа в неподвижном состоянии), то вы можете вызвать update(imu - bias) вместо просто update(imu). Возможно, вам придется увеличить e^2(gyro), чтобы учесть смещения смещения, но не так сильно, как если бы вы попытались учесть все это (нескомпенсированное смещение превратится в фиксированное смещение курса пропорционально R условиям магнитометра и гироскопа). ).

Лучший способ — добавить смещение к вектору состояния. Вы получите что-то вроде Hk = {{1,0,0},{0,1,1}}, что означает, что ваше предсказанное измерение гироскопа представляет собой истинную скорость плюс ваш член смещения. Магия фильтра Калмана здесь заключается в том, что, хотя вы сказали, что ваше измерение представляет собой просто сумму двух членов, они различаются по нескольким ключевым параметрам:

  • В F курс связан с фактической скоростью поворота (на dt), и, таким образом, ковариация состояния P развивает недиагональные члены, связывающие курс и скорость поворота каждый раз, когда вы обновляете P.
  • Точно так же в H вы описали взаимосвязь между смещением и скоростью гироскопа, которая выражает идею «либо я вращаюсь быстрее, либо у меня больше смещения», поэтому фильтр обновляет состояние, чтобы сбалансировать эти две возможности на основе ковариаций шума.
  • В Q шум процесса скорости поворота должен быть установлен достаточно высоким, чтобы учесть любое неожиданное движение, которое вы измеряете. Но Q для смещения намного, намного меньше, потому что смещение развивается не очень быстро (на самом деле, лучшая модель, вероятно, — это процесс Гаусса-Маркова первого порядка, который я не буду здесь объяснять, кроме как отбросить еще один полезный термин Google). в «фильтре с ограниченной памятью»). В пределе вы могли бы представить, что член Q для смещения равен 0 (смещение моделирования как случайная константа), но это не работает численно в EKF и не является строго верным из-за смещать дрейф.
  • Точно так же начальное P_0 системы намного меньше для члена смещения (его полный возможный диапазон задокументирован в таблице данных), чем для полностью неизвестного направления/угловой скорости.
  • В многоосевой системе смещение всегда идет с осью (это свойство аппаратного обеспечения, не связанное с тем, как оно ориентировано), но влияние гироскопа на состояние, такое как «курс», вращается из-за ремня. вниз ИДУ.

Наблюдение за тем, как EKF «узнает» такое значение, как смещение гироскопа, для меня еще более волшебно, чем предсказание остального состояния.

person Ben Jackson    schedule 16.11.2014