【发布时间】:2011-10-02 14:28:29
【问题描述】:
我想构建一个应用程序,使用 Gyro+Accelerometer 计算 iPhone 行进的准确距离(不是长距离)。这里不需要 GPS。
我应该如何解决这个问题?
【问题讨论】:
标签: iphone accelerometer distance gyroscope
我想构建一个应用程序,使用 Gyro+Accelerometer 计算 iPhone 行进的准确距离(不是长距离)。这里不需要 GPS。
我应该如何解决这个问题?
【问题讨论】:
标签: iphone accelerometer distance gyroscope
这个问题背后的基本微积分在表达式中
(以及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];
包含从测量开始到结束时间 0、dt、2*dt、3*dt、... (n-1)*dt 的 x 加速度值。
要找到总位移,您只需这样做
dl=sqrt(dx*dx + dy*dy + dz*dz);
陀螺仪不是必需的,但如果您正在测量线性距离,您可以使用陀螺仪读数来控制设备的旋转不会太大。如果旋转太强,让用户重新测量。
【讨论】:
您可以通过两次积分线性加速度来获得位置,但 错误非常可怕。在实践中是没有用的。
这里是 an explanation why (Google Tech Talk) 23:20。我强烈推荐这个视频。
类似问题:
What is the real world accuracy of phone accelerometers when used for positioning?
how to calculate phone's movement in the vertical direction from rest?
How to use Accelerometer to measure distance for Android Application Development
更新(2013 年 2 月 24 日):@Simon 是的,如果您对运动有更多了解,例如一个人走路并且传感器在他的脚上,那么您可以做更多的事情。这些被称为
特定领域的假设。
如果假设不成立并且实施起来可能非常麻烦,它们就会惨遭破坏。不过,如果它们有效,您可以做一些有趣的事情。室内定位见我的回答Android accelerometer accuracy (Inertial navigation)中的链接。
【讨论】:
您应该使用 Simple iPhone motion detect 中描述的 Core Motion 接口。特别是所有旋转都可以非常准确地跟踪。如果你打算做一些与线性运动相关的事情,这是非常困难的事情。看看Getting displacement from accelerometer data with 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);
}
}
【讨论】:
(acc_x[i-1]+acc_x[i])/2 是一个低通滤波器,它是两个时间度量之间的平均值
也看这里:http://www.freescale.com/files/sensors/doc/app_note/AN3397.pdf 第 3 页
【讨论】:
Navisens。
https://navisens.com/#how-work
声明如下 - Navisens 正在申请专利的技术以独特的方式处理加速度计和陀螺仪数据来定位您的手机。
试用了演示应用程序,该应用程序主要用于在设置初始位置和方向后在不使用定位服务或 WiFi 的情况下绘制运动地图。
iOS SDK - https://github.com/navisens/iOS-SDK
Android SDK - https://github.com/navisens/Android-SDK
注意:这不是开源的
【讨论】:
这里是answer。之前有人问过。
有一个名为 RangeFinder 的应用在做同样的事情(在 App Store 中可用)。
【讨论】: