Как найти скорость, используя только акселерометры?
Используя только телефон (Android), встроенный в акселерометр, как бы я мог найти его скорость?
Я занимался математикой этого, но любая функция, которую я придумываю, ведет к экспоненциальному росту скорости. Я исхожу из предположения, что при запуске приложения телефон находится в состоянии покоя. Это должно обязательно сделать поиск скорости (по крайней мере грубо) возможным.
У меня есть приличный фон в физике и в математике, поэтому у меня не должно быть никаких проблем с концепциями.
Как мне это сделать?
Ответы
Ответ 1
Во-первых, вы должны удалить ускорение из-за силы тяжести из данных акселерометра. Тогда это просто вопрос интеграции ускорения для получения скорости. Не забывайте, что ускорение и скорость являются соответственно векторами, а не скалярами, и вам также придется отслеживать поворот телефона в пространстве, чтобы правильно определить ориентацию вектора ускорения относительно вычисленного вектора скорости.
Ответ 2
Это будет зависеть от того, что такое ускорение и как долго. Легкое, длительное ускорение может быть измеримым, но любое внезапное увеличение ускорения, за которым следует постоянная скорость, сделает ваши измерения довольно сложными и подвержен ошибкам.
Предполагая постоянное ускорение, формула чрезвычайно проста: a = (V1-V0)/t. Итак, зная время и ускорение и полагая V0 = 0, тогда V1 = a * t
В более реальном мире у вас, вероятно, не будет постоянного ускорения, поэтому вы должны рассчитать Delta V для каждого измерения и добавить все эти изменения скорости, чтобы получить конечную скорость. Всегда считайте, что у вас не будет данных непрерывного ускорения, так что это наиболее осуществимый способ (т.е. Реальные данные и интегральная математическая теория).
В любом случае, даже в наилучшем сценарии, вы получите очень высокий запас ошибки, поэтому я не рекомендую этот подход для любого приложения, которое действительно зависит от реальных скоростей.
Ответ 3
Нет ничего другого, кроме как согласиться с разумными аргументами, изложенными во всех замечательных ответах выше, однако, если вы такой прагматичный тип, как я, мне нужно придумать решение, которое работает как-то.
У меня была схожая проблема с твоей, и я решил сделать свое решение после того, как не нашел его в режиме онлайн. Мне нужен был простой "наклон" вход для управления игрой, чтобы это решение, вероятно, НЕ работало для более сложных задач, однако я решил поделиться им в случае, если другие ищут что-то подобное.
ПРИМЕЧАНИЕ: Здесь я вставлял весь свой код, и он может использоваться для любых целей.
В основном, что я делаю в своем коде, нужно искать датчик акселерометра. Если не найдено, отклон. Наклон будет отключен. Если присутствует датчик акселерометра, я ищу датчик магнитного поля, и если он присутствует, я получаю свой угол наклона рекомендуемым путем, комбинируя данные акселерометра и магнитного поля.
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!
Ответ 4
Интеграция ускорения для получения скорости - это неустойчивая проблема, и ваша ошибка будет расходиться через пару секунд или около того. Телефонные акселерометры также не очень точны, что не помогает, и некоторые из них не позволяют легко различать наклон и перевод, и в этом случае у вас действительно проблемы.
Ответ 5
Акселерометры в телефоне практически бесполезны для такой задачи. Вам нужны высокоточные акселерометры с очень низким дрейфом - что-то, что выходит за рамки того, что вы найдете в телефоне. В лучшем случае вы можете получить полезные результаты в течение нескольких секунд или, если повезет, в течение минуты или двух, после чего результаты становятся бессмысленными.
Кроме того, вам необходимо иметь трехосный гироскоп, который вы бы использовали для интеграции скорости в правильном направлении. В некоторых телефонах есть гироскопы, но они даже хуже, чем акселерометры, что касается дрейфа и точности.
Одним из полезных приложений может быть использование акселерометров в сочетании с гироскопами или магнитным компасом для заполнения отсутствующих данных из GPS. Каждый раз, когда GPS дает хорошее исправление, reset начальные условия положения, скорости и ориентации и акселерометры будут предоставлять данные до следующего действительного GPS-исправления.
Ответ 6
Гравитация уничтожит все ваши измерения. Телефон в состоянии покоя испытывает высокое постоянное ускорение (да, UP). Акселерометр не может различать ускорение и гравитацию (технически, они одинаковые), поэтому через несколько секунд он достигнет чрезвычайно высоких скоростей.
Если вы никогда не слегка наклоняете акселерометр, вы можете просто вычесть постоянное гравитационное притяжение с оси z (или какая бы ни была ось направлена вверх/вниз), но это маловероятно.
В принципе, вам нужно использовать сложную систему гироскопа/магнитометра и акселерометра для вычисления точного направления силы тяжести, а затем вычесть ускорение.
Ответ 7
v = Интеграл (a)?
В общем, хотя, я думаю, неточности в акселерометрах сделают это довольно жестким.
Ответ 8
Если телефон находится в режиме ожидания, у вас есть ускорение ZERO, поэтому ваша скорость равна 0. Вероятно, вы должны найти данные о местоположении из GPS и получить соответствующие отсчеты времени и вычислить скорость с течением времени.