Хобрук: Ваш путь к мастерству в программировании

Реализация JKalman на Android

Есть много вопросов об удалении шума из данных акселерометра, данных других датчиков, расчете пространственно-временного состояния и использовании фильтра Калмана в Android и других устройствах.

Судя по всему, самый простой способ сделать это — реализовать фильтр JKalman на Android для стабильно движущихся устройств, например для автомобилей.

Но глядя на пример реализации в пакете кода JKalman, он мало что говорит и на самом деле сильно отличается от других реализаций Kalman.

Они создают экземпляр класса Калмана следующим образом:

JKalman kalman = new JKalman(4, 2);

Где по определению

public JKalman(int dynam_params, int measure_params) throws Exception {
    this(dynam_params, measure_params, 0);
}

dynam_params – это "количество измерений вектора измерения", а measure_params – это "количество измерений вектора состояния".

Как данные датчика, считанные в Android, должны быть сопоставлены с ними?

Ниже приведены данные с акселерометра, которые отбираются каждые 500 мс. В других слушателях есть данные с гироскопа и компаса. Как мне преобразовать эти данные для ввода в Калман?

    @Override
    public void onSensorChanged(SensorEvent event) {
        actualTime = System.currentTimeMillis();
        if(actualTime - lastUpdateAcc < 500)
            return;
        else{
            lastUpdateAcc = actualTime;
            //update myPosition
            TextView tv = (TextView)findViewById(R.id.textView3);
            tv.setText(String.format("X: %8.4f -- Y: %8.4f -- Z: %8.4f",
                    event.values[0], event.values[1], event.values[2]));
            //draw on the screen

            //draw new path, if one exists
        }
    }

  • Фильтр Калмана и качество внутренних переменных состояния говорят, что они реализовал JKalman, что делает их умнее меня. 06.08.2012
  • И у Ali есть ответ или комментарий под каждым датчиком или вопросом, связанным с Калманом. Поэтому я использую его профиль в качестве ссылки на тему. 06.08.2012
  • Я польщен :) Чего бы вы хотели добиться? Вы хотите отслеживать ориентацию или положение? Насколько я знаю, в Android уже есть что-то вроде фильтра Калмана, почему вы пытаетесь реализовать свой собственный? 06.08.2012
  • Привет, Али :) Я хочу отслеживать позицию. Вы имеете в виду слитые датчики, как в здесь? Они не делаются сами по себе, потому что вам все равно нужно кумулятивное приближение следующего шага. 06.08.2012
  • Другое дело, что эти ребята сделали это с помощью педофильтра (насколько их опрос предполагает) и с постоянной длиной шага. Так что это каким-то образом возможно, и просмотр этого видео придает мне смелости. 06.08.2012
  • ты реализовал калман для андроида? Я сделал это ... но я не могу правильно настроить дисперсию шума процесса для акселерометра и гироскопа ... не могли бы вы мне помочь? 17.02.2015
  • к сожалению, я забросил этот проект. если вы можете решить это, пожалуйста, внесите свой вклад в ответ. удачи. 18.02.2015

Ответы:


1

Кажется, вам нужен 3D фильтр JKalman. Вы можете попробовать это:

JKalman kalman = new JKalman(6, 3);

Matrix s = new Matrix(6, 1); // state [x, y, z, dx, dy, dz]        
Matrix c = new Matrix(6, 1); // corrected state
Matrix m = new Matrix(3, 1); // measurement [x, y, z]

// the initial values follow (sorry for programming in stackoverflow):
m.set(0, 0, x);
m.set(1, 0, y);
m.set(2, 0, z);

// transitions for x, y, z, dx, dy, dz (velocity transitions)
double[][] tr = { {1, 0, 0, 1, 0, 0}, 
                  {0, 1, 0, 0, 1, 0}, 
                  {0, 0, 1, 0, 0, 1}, 
                  {0, 0, 0, 1, 0, 0}, 
                  {0, 0, 0, 0, 1, 0}, 
                  {0, 0, 0, 0, 0, 1} };
kalman.setTransition_matrix(new Matrix(tr));

Затем следуйте примеру в KalmanTest.java и проверьте его на наличие ошибок, пожалуйста.

07.01.2014
  • Большое Вам спасибо. Не нашел возможности реализовать код. Как только я попробую, я вернусь к вам. 12.10.2014
  • Хахахах. Нет. :( 22.05.2020

  • 2

    вот как я это делаю с двумя переменными (GPS: LAT, LON):

    import jkalman.JKalman;
    import jama.Matrix;
    
    public class KalmanFilter {
        private int variables;
        private JKalman kalman;
        private Matrix s; // state [x, y, dx, dy, dxy]
        private Matrix c; // corrected state [x, y, dx, dy, dxy]
        private Matrix m; // measurement [x]
    
        /*
         * Inicializa el filtro kalman con 2 variables
         */
        public void initialize2() throws Exception{
            double dx, dy;
    
            if(variables != 0){
                 throw new RuntimeException();
            }
            variables = 2;
            kalman = new JKalman(4, 2);
    
            // constant velocity
            dx = 0.2;
            dy = 0.2;
    
            s = new Matrix(4, 1); // state [x, y, dx, dy, dxy]        
            c = new Matrix(4, 1); // corrected state [x, y, dx, dy, dxy]                
    
            m = new Matrix(2, 1); // measurement [x]
            m.set(0, 0, 0);
            m.set(1, 0, 0);
    
            // transitions for x, y, dx, dy
            double[][] tr = { {1, 0, dx, 0}, 
                              {0, 1, 0, dy}, 
                              {0, 0, 1, 0}, 
                              {0, 0, 0, 1} };
            kalman.setTransition_matrix(new Matrix(tr));
    
            // 1s somewhere?
            kalman.setError_cov_post(kalman.getError_cov_post().identity());
    
        }
    
        /*
         * Aplica Filtro a variables
         */
        public void push(double x,double y) throws Exception{
             m.set(0, 0, x);
             m.set(1, 0, y);
    
             c = kalman.Correct(m);
             s = kalman.Predict();
        }
    
        /*
         * obtiene arreglo con datos filtrados.
         */
        public double[] getKalmanPoint2() throws Exception{
            double[] point = new double[2];
            point[0] = c.get(0,0);
            point[1] = c.get(1,0);
            return point;
        }
    
        /*
         * obtiene arreglo con prediccion de punto.
         */
        public double[] getPredict2() throws Exception{
            double[] point = new double[2];
            point[0] = s.get(0,0);
            point[1] = s.get(1,0);
            return point;
        }
    
        /*
         * obtiene cantidad de variables del objeto
         */
        public int getNVariables() throws Exception{
            return this.variables;
        }
    
    }
    

    Но я не знаю, как установить первую точку, я всегда начинаю с (0,0) и делаю 50 сэмплов, чтобы добраться до точки, с циклом не очень элегантно.

    25.03.2015

    3

    Вы не можете создать универсальное приложение для отслеживания положения просто потому, что гироскопы слишком шумные. (Да, гироскопы, а не акселерометр.)

    Что касается внутреннего позиционирования, см. также ссылку выше.

    06.08.2012
  • Спасибо, Али :) Я читал этот вопрос, как и другие раньше. Но я не хочу принимать решение до того, как испытаю это. На этом этапе мне нужно реализовать фильтр Калмана. 06.08.2012
  • И про гироскопы. Зачем вам гироскопы, если они такие шумные и у вас есть 3-х осевой акселерометр? Акселерометр дает вам вектор ускорения по трем осям, поэтому вы можете оценить, куда вы направляетесь, и даже рассчитать свое положение. 06.08.2012
  • И вы сказали, что в Android уже есть что-то вроде фильтра Калмана, какие-нибудь подсказки в этом направлении? 06.08.2012
  • Я действительно пытаюсь помочь, но на данный момент я должен попросить вас внимательно посмотреть / прочитать связанные материалы, особенно видео и связанный файл UCAM-CL-TR-696.pdf, подраздел 6.2.3. Если вы это сделаете, то поймете, зачем вам нужны гироскопы. Вы также поймете, почему вы не можете выполнять отслеживание позиций общего назначения. Если вы посмотрите видео, вы будете знать, что искать на платформе Android, которая реализует фильтр Калмана (или что-то в этом роде). 06.08.2012
  • Я вижу, как сильно вы пытаетесь помочь в SO, и я очень ценю это. Еще раз спасибо :) Я смотрел и просматривал документы (хотя на самом деле я этого не делал) несколько раз. Дэвид Сакс предполагает в 27:13, что динамика модели с фильтром Калмана лучше, чем фильтр верхних частот, оба из которых корректируют дрейф по-своему (и тогда есть педофильтр, если вы идете). А в упомянутой вами статье говорится, что источником дрейфа является двойное интегрирование. Поскольку я не смог найти способ реализации JKalman, я пытаюсь рассчитать расстояние через x = 1/2 at^2 (...›) 06.08.2012
  • (...) где a — среднее ускорение 15 выборок, сделанных каждые 300 мс после вычитания стандартного среднего шума, которое происходит, когда устройство стоит на столе. Так что это довольно прямая логика, но только в теории. Но через несколько часов, думаю, закончу. 06.08.2012
  • * То, что я пытался сказать о документах, было то, что я действительно не понимал всех концепций в них. Но у меня есть идея. 06.08.2012
  • Новые материалы

    Решения DBA Metrix
    DBA Metrix Solutions предоставляет удаленного администратора базы данных (DBA), который несет ответственность за внедрение, обслуживание, настройку, восстановление базы данных, а также другие..

    Начало работы с Блум
    Обзор и Codelab для генерации текста с помощью Bloom Оглавление Что такое Блум? Некоторые предостережения Настройка среды Скачивание предварительно обученного токенизатора и модели..

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

    Как свинг-трейдеры могут использовать ИИ для больших выигрышей
    По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

    Как построить любой стол
    Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...