it-swarm-ru.tech

Как обнаружить ходьбу с помощью Android акселерометра

Я пишу приложение, и моя цель - определить, когда пользователь гуляет. Я использую фильтр Калмана, как это:

float kFilteringFactor=0.6f;

        gravity[0] = (accelerometer_values[0] * kFilteringFactor) + (gravity[0] * (1.0f - kFilteringFactor));
        gravity[1] = (accelerometer_values[1] * kFilteringFactor) + (gravity[1] * (1.0f - kFilteringFactor));
        gravity[2] = (accelerometer_values[2] * kFilteringFactor) + (gravity[2] * (1.0f - kFilteringFactor));

        linear_acceleration[0] = (accelerometer_values[0] - gravity[0]);
        linear_acceleration[1] = (accelerometer_values[1] - gravity[1]);
        linear_acceleration[2] = (accelerometer_values[2] - gravity[2]);

        float magnitude = 0.0f;
        magnitude = (float)Math.sqrt(linear_acceleration[0]*linear_acceleration[0]+linear_acceleration[1]*linear_acceleration[1]+linear_acceleration[2]*linear_acceleration[2]);
        magnitude = Math.abs(magnitude);
if(magnitude>0.2)
  //walking

Гравитация массива [] инициализируется 0.

Я могу определить, когда пользователь ходит или нет (смотря на величину величины вектора ускорения), но моя проблема в том, что когда пользователь не ходит и перемещает телефоны, кажется, что он ходит.

Я использую правильный фильтр?

Правильно ли наблюдать только величину вектора или я должен смотреть на отдельные значения ??

17
havanakoda

Google предоставляет API для этого, называемого DetectedActivity, который можно получить с помощью ActivityRecognitionApi. Эти документы могут быть доступны здесь и здесь .

DetectedActivity имеет метод public int getType() для получения текущей активности пользователя, а также public int getConfidence(), которая возвращает значение от 0 до 100. Чем выше значение, возвращаемое getConfidence(), тем более уверенным является то, что API выполняет возвращаемое действие.

Вот постоянное резюме того, что возвращает getType():

  • int IN_VEHICLE Устройство находится в транспортном средстве, например в автомобиле.
  • int ON_BICYCLE Устройство на велосипеде.
  • int ON_FOOT Устройство находится на пользователе, который ходит или работает.
  • int RUNNING Устройство работает от пользователя, который работает.
  • int STILL Устройство все еще (не движется).
  • int TILTING Угол устройства относительно силы тяжести существенно изменился.
  • int UNKNOWN Невозможно определить текущую активность.
  • int WALKING Устройство находится на пользователе, который ходит.
19
Dick Lucas

Моей первой интуицией было бы провести FFT-анализ истории сенсоров и посмотреть, какие частоты имеют высокие значения при ходьбе.

По сути, он видит, как "звучит" ходьба, рассматривает входы датчика акселерометра как микрофон и видит громкие частоты при ходьбе (другими словами, на какой частоте происходит наибольшее ускорение).

Я предполагаю, что вы будете искать большую величину на некоторой низкой частоте (например, скорость шага) или что-то еще. Было бы интересно увидеть данные.

Я предполагаю, что вы запускаете БПФ и смотрите, чтобы величина на некоторой частоте была больше некоторого порога, или разница между величинами двух частот больше некоторой величины. Опять же, фактические данные будут определять, как вы пытаетесь их обнаружить.

5
doug65536

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

В этом приложении использовался следующий код https://play.google.com/store/apps/details?id=com.tartakynov.robotnoise

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER){
            return;
        }
        final float z = smooth(event.values[2]); // scalar kalman filter                               
        if (Math.abs(z - mLastZ) > LEG_THRSHOLD_AMPLITUDE)
        {
            mInactivityCount = 0;
            int currentActivity = (z > mLastZ) ? LEG_MOVEMENT_FORWARD : LEG_MOVEMENT_BACKWARD;                  
            if (currentActivity != mLastActivity){
                mLastActivity = currentActivity;
                notifyListeners(currentActivity);
            }                   
        } else {
            if (mInactivityCount > LEG_THRSHOLD_INACTIVITY) {
                if (mLastActivity != LEG_MOVEMENT_NONE){
                    mLastActivity = LEG_MOVEMENT_NONE;
                    notifyListeners(LEG_MOVEMENT_NONE);                                 
                }
            } else {
                mInactivityCount++;
            }
        }
        mLastZ = z;
    }
4
tartakynov

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

Вы измеряете горизонтальное ускорение и обновляете значение скорости с его помощью. Скорость будет дрейфовать со временем, но вам нужно сохранять сглаженную скользящую среднюю скорость за время шага, и пока она не дрейфует больше, чем, скажем, половина скорости ходьбы за 3 колебания, тогда она идет, но только если она первоначально за короткое время поднялся до скорости ходьбы, то есть, возможно, за полсекунды или 2 колебаний.
Все это должно почти покрыть это. Конечно, немного ai поможет сделать вещи проще или сложнее, но удивительно точными, если вы рассмотрите все это как входные данные для NN. Т.е. предварительная обработка.

0
Jim Cook

Правка: Я не думаю, что это достаточно точно, так как при обычной ходьбе среднее ускорение было бы около 0. Максимум, что вы могли бы сделать, измеряя ускорение, это обнаружить, когда кто-то начинает идти или останавливается (Но, как вы сказали, его трудно отфильтровать устройство сдвинуто кем-то стоящим на одном месте)

Итак ... то, что я написал ранее, вероятно, не сработает

Вы можете "предсказать", движется ли пользователь, отбрасывая, когда пользователь не движется (очевидно), и первые два варианта, которые приходят мне в голову:
Проверьте, не скрыт ли телефон, используя датчик приближения и освещенности (опция). Этот метод менее точен, но проще.
Контроль непрерывности движения, если телефон движется дольше, чем ... 10 секунд, и движение не является презренным, тогда вы считаете, что он ходит. Я знаю, что это тоже не perfet, но это трудно без использования какого-либо позиционирования, кстати ... почему бы вам просто не использовать LocationManager?

0
mdelolmo