我怎样才能find陀螺仪和加速度传感器的距离?

我想build立一个应用程序,使用陀螺仪+加速度计,计算iPhone(不是长途)的精确距离。 这里不需要GPS。

我应该如何解决这个问题?

这个问题背后的基本微积分就是expression式

在这里输入图像描述

(以及类似的y和z位移expression式)和基本几何是毕达哥拉斯定理

在这里输入图像描述

所以,一旦你的加速度计信号通过一个低通滤波器并按照采样间隔dt进行分箱,你可以在x中find位移( 原谅我的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加速度值。

要find总的位移,你只是这样做

 dl=sqrt(dx*dx + dy*dy + dz*dz); 

陀螺仪不是必需的,但是如果您正在测量直线距离,则可以使用陀螺仪读数来控制设备的旋转不是太大。 如果旋转太强,请让用户重新进行测量。

你通过两次整合线性加速度得到位置,但是错误是可怕的。 在实践中是无用的。

这是为什么(Google技术讲座)在23点20分解释。 我强烈推荐这个video。

类似的问题:

  • 跟踪iphone的小动作,没有GPS

  • 手机加速度计用于定位时的真实世界精度是多less?

  • 如何计算手机在静止的垂直方向上的移动?

  • iOS:3D空间中的运动精度

  • 如何使用加速度计为Android应用程序开发测量距离

  • 距离由加速度计移动


更新 (2013年2月24日):@Simon是的,如果你对运动有更多的了解,例如一个人走路,传感器在他的脚下,那么你可以做更多的事情。 这些被称为

领域特定的假设

如果这些假设不成立,它们就会惨败,而且执行起来可能相当麻烦。 不过,如果他们工作,你可以做有趣的事情。 请参阅我的回答中的链接Android加速计精度(惯性导航)在室内定位。

您应该使用简单的iPhone运动检测中所述的Core Motion界面。 尤其是所有的旋转都可以非常精确地跟踪。 如果你打算做一些有关线性运动的东西,这是非常困难的事情。 查看使用Core Motion获取加速度计数据的位移 。

我对此采取了一些措施,并放弃了(深夜,似乎没有任何地方)。 这是一个Unity3d项目。

如果有人想要拿起我离开的地方,我会很乐意详细说明这些东西是干什么的。

基本上,在一些事实certificate是误报后,我想我会尝试使用低通滤波器进行过滤,然后尝试通过发现趋势消除反弹,然后(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); } } 

这是答案 。 有人问过。

有一个名为RangeFinder的应用程序正在做同样的事情(在App Store中可用)。

(acc_x [i-1] + acc_x [i])/ 2是低通滤波器,它是两个时间量之间的平均值

也看看这里: http: //www.freescale.com/files/sensors/doc/app_note/AN3397.pdf pag:3