Как найти расстояние, пройденное с помощью гироскопа и акселерометра?
Я хочу создать приложение, которое рассчитывает точное расстояние, пройденное iPhone (не большое расстояние) с помощью гироскопа + акселерометр. Нет необходимости для GPS здесь.
Как мне подойти к этой проблеме?
6 ответов
Основное исчисление этой проблемы заключается в выражении
(и аналогичные выражения для смещений в y и z) и основной геометрии является теорема Пифагора
Итак, как только ваши сигналы акселерометра будут пропущены через фильтр нижних частот и скомпонованы во времени с интервалом выборки dt, вы можете найти смещение в x как (простите мой C...)
float dx=0.0f;
float vx=0.0f;
for (int i=1; i<n; i++)
{
vx+=(acceleration_x[i-1] + acceleration_x[i])/2.0f*dt;
dx+=vx*dt;
}
и аналогично для dy и dz. Вот
float acceleration_x[n];
содержит значения x-ускорения от начала до конца измерения в моменты времени 0, dt, 2*dt, 3*dt, ... (n-1)*dt.
Чтобы найти общее смещение, вы просто делаете
dl=sqrt(dx*dx + dy*dy + dz*dz);
Гироскоп не нужен для этого, но если вы измеряете линейные расстояния, вы можете использовать показания гироскопа, чтобы контролировать, что вращение устройства не было слишком большим. Если вращение было слишком сильным, попросите пользователя повторить измерение.
Вы получаете позицию, интегрируя линейное ускорение дважды, но ошибка ужасна. Это бесполезно на практике.
Вот объяснение, почему (Google Tech Talk) в 23:20. Я очень рекомендую это видео.
Похожие вопросы:
Какова реальная точность телефонных акселерометров при позиционировании?
Как рассчитать движение телефона в вертикальном направлении от отдыха?
Как использовать акселерометр для измерения расстояния для разработки приложений для Android
Обновление (24 февраля 2013 г.): @Simon Да, если вы знаете больше о движении, например, о человеке, идущем и датчик на ноге, то вы можете сделать гораздо больше. Они называются
доменные специфические предположения.
Они терпят неудачу, если предположения не выполняются и могут быть довольно громоздкими для реализации. Тем не менее, если они работают, вы можете делать забавные вещи. Смотрите ссылки в моем ответе Точность акселерометра Android (Инерциальная навигация) при позиционировании в помещении.
Вы должны использовать интерфейс Core Motion, как описано в Простом обнаружении движения iPhone. Особенно все повороты можно отслеживать очень точно. Если вы планируете делать что-то, связанное с линейными движениями, это очень сложная вещь. Взгляните на Получение смещения из данных акселерометра с помощью Core Motion.
Я взял трещину в этом и сдался (поздно ночью, казалось, никуда не денется). Это для проекта Unity3d.
Если кто-то захочет узнать, где я остановился, я был бы рад подробно рассказать о том, что делает весь этот материал.
В основном после того, что оказалось ложным срабатыванием, я решил попробовать отфильтровать это, используя фильтр нижних частот, затем попытался удалить отскоки, найдя тренд, затем (acc_x[i-1]+acc_x[i])/2.
Похоже, что ложный позитив все еще исходит от наклона, который я попытался удалить..
Если этот код полезен или ведет вас куда-то, пожалуйста, дайте мне знать!
using UnityEngine;
using System.Collections.Generic;
/// <summary>
/// rbi.noli@gmail.com
/// </summary>
public class AccelerometerInput : MonoBehaviour
{
Transform myTransform;
Gyroscope gyro;
GyroCam gyroCam;
void Awake()
{
gyroCam= FindObjectOfType<GyroCam> ();
myTransform = transform;
if (SystemInfo.supportsGyroscope) {
gyro = Input.gyro;
gyro.enabled = true;
}
}
bool shouldBeInitialized = false;
void Update ()
{
transform.Translate (GetAccelerometer ());// * Time.deltaTime * speed);
//GetComponent<Rigidbody> ().AddForce (GetAccelerometer ());
}
public float speed = 10.0F;
public Vector3 dir;
public float f;
Vector3 GetAccelerometer()
{
dir = Input.acceleration;
dir.x *= gyro.attitude.x;
dir.z *= gyro.attitude.z;
if (Mathf.Abs (dir.x) < .001f)
dir.x = 0;
dir.y = 0;
if (Mathf.Abs (dir.z) < .001f)
dir.z = 0;
RecordPointsForFilter (dir);
//print ("Direction : " + dir.ToString("F7"));
return TestPointsForVelocity();
}
Vector3[] points = new Vector3[20];
int index;
void RecordPointsForFilter(Vector3 recentPoint)
{
if (index >= 20)
index = 0;
points [index] = EvaluateTrend (recentPoint);;
index++;
}
//try to remove bounces
float xTrend = 0;
float zTrend = 0;
float lastTrendyX = 0;
float lastTrendyZ = 0;
Vector3 EvaluateTrend(Vector3 recentPoint)
{
//if the last few points were positive, and this point is negative, don't pass it along
//accumulate points into a trend
if (recentPoint.x > 0)
xTrend += .01f;
else
xTrend -= .1f;
if (recentPoint.z > 0)
zTrend += .1f;
else
zTrend -= .1f;
//if point matches trend, keep it
if (xTrend > 0) {
if (recentPoint.x > 0)
lastTrendyX = recentPoint.x;
} else // xTrend < 0
if (recentPoint.x < 0)
lastTrendyX = recentPoint.x;
if (zTrend > 0) {
if (recentPoint.z > 0)
lastTrendyZ = recentPoint.z;
} else // xTrend < 0
if (recentPoint.z < 0)
lastTrendyZ = recentPoint.z;
return new Vector3( lastTrendyX, 0, lastTrendyZ);
}
Vector3 TestPointsForVelocity()
{
float x = 0;
float z = 0;
float xAcc = 0;
float zAcc = 0;
int successfulHits = 0;
for(int i = 0; i < points.Length; i++)
{
if(points[i]!=null)
{
successfulHits ++;
xAcc += points[i].x;
zAcc += points[i].z;
}
}
x = xAcc / successfulHits;
z = zAcc / successfulHits;
return new Vector3 (x, 0, z);
}
}
Navisens.
Вот претензия - запатентованная технология Navisens обрабатывает данные акселерометра и гироскопа уникальным способом для определения местоположения вашего телефона.
Опробовал демонстрационное приложение, которое в основном работает с картированием движений без служб геолокации или Wi-Fi после установки исходного местоположения и направления.
SDK для iOS - https://github.com/navisens/iOS-SDK
Android SDK - https://github.com/navisens/Android-SDK
Примечание: это не открытый исходный код
(acc_x[i-1]+acc_x[i])/2 - фильтр нижних частот, это среднее значение между двумя тактами во времени
также посмотрите здесь: http://www.freescale.com/files/sensors/doc/app_note/AN3397.pdf pag: 3
Вот ответ. Кто-то спросил раньше.
Существует приложение под названием RangeFinder, которое делает то же самое (доступно в App Store) .