Как я могу найти скорость, используя только акселерометры? - PullRequest
10 голосов
/ 22 мая 2011

Используя только встроенный акселерометр телефона (Android), как мне найти его скорость?

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

У меня неплохой опыт работы в физике и математике, поэтому у меня не должно возникнуть никаких проблем с какими-либо понятиями здесь.

Как мне это сделать?

Ответы [ 8 ]

7 голосов
/ 22 мая 2011

Это действительно будет зависеть от того, что такое ускорение и как долго. Мягкое, продолжительное ускорение может быть измеримо, но любое внезапное увеличение ускорения, сопровождаемое постоянной скоростью, сделает ваши измерения довольно трудными и подверженными ошибкам.

При условии постоянного ускорения формула предельно проста: a = (V1-V0) / t. Итак, зная время и ускорение и предполагая V0 = 0, тогда V1 = a * t

В более реальном мире у вас, вероятно, не будет постоянного ускорения, поэтому вы должны рассчитать Delta V для каждого измерения и сложить все эти изменения скорости, чтобы получить окончательную скорость. Всегда учитывайте, что у вас не будет данных непрерывного ускорения, так что это наиболее выполнимый способ (т. Е. Реальные данные против интегральной математической теории).

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

7 голосов
/ 22 мая 2011

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

4 голосов
/ 07 апреля 2013

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

У меня возникла проблема, похожая на вашу, и я решил найти собственное решение, не найдя в сети. Для управления игрой мне понадобился только простой входной сигнал «наклона», поэтому это решение, вероятно, НЕ подойдет для более сложных задач, однако я решил поделиться им в случае, если другие ищут что-то похожее.

ПРИМЕЧАНИЕ: Я вставил сюда весь свой код , и он может свободно использоваться для любых целей.

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

public TiltSensor(Context c) {
    man = (SensorManager) c.getSystemService(Context.SENSOR_SERVICE);
    mag_sensor = man.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    acc_sensor = man.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    has_mag = man.registerListener(this, mag_sensor, delay);
    has_acc = man.registerListener(this, acc_sensor, delay);
    if (has_acc) {
        tiltAvailble = true;
        if (has_mag) {
            Log.d("TiltCalc", "Using accelerometer + compass.");
        }
        else {
            Log.d("TiltCalc", "Using only accelerometer.");
        }
    }
    else {
        tiltAvailble = false;
        Log.d("TiltCalc", "No acceptable hardware found, tilt not available.");
        //No use in having listeners registered
        pause();
    }
}

Если, однако, присутствовал только датчик акселерометра, я возвращаюсь к накоплению ускорения, которое постоянно уменьшается (умножается на 0,99), чтобы устранить любой дрейф. Для моих простых потребностей наклона это прекрасно работает.

@Override
public void onSensorChanged(SensorEvent e) {
    final float[] vals = e.values;
    final int type = e.sensor.getType();
    switch (type) {
        case (Sensor.TYPE_ACCELEROMETER): {
            needsRecalc = true;
            if (!has_mag) {
                System.arraycopy(accelerometer, 0, old_acc, 0, 3);
            }
            System.arraycopy(vals, 0, accelerometer, 0, 3);
            if (!has_mag) {
                for (int i = 0; i < 3; i++) {
                    //Accumulate changes
                    final float sensitivity = 0.08f;
                    dampened_acc[i] += (accelerometer[i] - old_acc[i]) * sensitivity;
                    //Even out drift over time
                    dampened_acc[i] *= 0.99;
                }
            }
        }
            break;
        case (Sensor.TYPE_MAGNETIC_FIELD): {
            needsRecalc = true;
            System.arraycopy(vals, 0, magnetic_field, 0, 3);
        }
            break;
    }
}

В заключение я просто повторю, что это, вероятно, не «правильно», а просто работает как простой вход в игру. Чтобы использовать этот код, я просто делаю что-то вроде следующего (да, магические константы плохие, mkay):

Ship ship = mShipLayer.getShip();
mTiltSensor.getTilt(vals);
float deltaY = -vals[1] * 2;//1 is the index of the axis we are after
float offset = ((deltaY - (deltaY / 1.5f)));
if (null != ship) {
    ship.setOffset(offset);
}

Enjoi!

2 голосов
/ 16 сентября 2015

Гравитация разрушит все ваши измерения.Телефон в состоянии покоя испытывает постоянное ускорение вверх (да, вверх).Акселерометр не может различить ускорение и гравитацию (технически они одинаковы), поэтому он достигнет чрезвычайно высоких скоростей через несколько секунд.Если вы никогда не наклоните свой акселерометр хотя бы немного, то вы можете просто вычесть постоянное гравитационное притяжение от оси z (или от того, какая ось направлена ​​вверх / вниз), но это весьма маловероятно.

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

2 голосов
/ 25 мая 2011

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

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

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

2 голосов
/ 22 мая 2011

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

1 голос
/ 22 мая 2011

v = Integral (a)?

Как правило, я думаю, что неточности в акселерометрах сделали бы это довольно жестким

0 голосов
/ 22 мая 2011

Если телефон находится в состоянии покоя, у вас ускорение ZERO, поэтому ваша скорость равна 0. Вероятно, вы должны найти данные о местоположении от GPS и получить соответствующие выборки времени и вычислить расстояние скорости во времени.

...