我想构建一个应用程序,使用陀螺+加速度计计算iPhone(非长距离)行进的精确距离。这里不需要GPS。
我该如何解决这个问题?
答案 0 :(得分:78)
此问题背后的基本演算在表达式
中
(以及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);
此时不需要陀螺仪,但如果您正在测量线性距离,则可以使用陀螺仪读数来控制设备的旋转不会太大。如果旋转太强,请让用户重新进行测量。
答案 1 :(得分:43)
通过将线性加速度积分两次得到位置,但错误很可怕。它在实践中毫无用处。
这是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日):@西蒙是的,如果您对运动有更多了解,例如行走的人和传感器在他的脚上,那么您可以做更多事情。这些被称为
域特定假设。
如果假设不成立并且实施起来非常麻烦,那么它们会惨遭打破。然而,如果他们工作,你可以做有趣的事情。在室内定位中查看我的回答Android accelerometer accuracy (Inertial navigation)中的链接。答案 2 :(得分:5)
您应该使用Simple iPhone motion detect中描述的Core Motion界面。特别是可以非常精确地跟踪所有旋转。如果你计划做一些与线性运动有关的事情,这是非常困难的事情。看看Getting displacement from accelerometer data with Core Motion。
答案 3 :(得分:1)
我对此采取了一个裂缝并且放弃了(深夜,似乎没有到达任何地方)。这是针对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);
}
}
答案 4 :(得分:0)
这是answer。有人问过。
有一个名为RangeFinder的应用程序做同样的事情(在App Store中可用)。
答案 5 :(得分:0)
(acc_x [i-1] + acc_x [i])/ 2是低通滤波器,它是两个时间测量值之间的平均值
另见:http://www.freescale.com/files/sensors/doc/app_note/AN3397.pdf pag:3
答案 6 :(得分:0)
Navisens 。
https://navisens.com/#how-work
在此提出索赔-Navisens正在申请专利的技术以独特的方式处理加速度计和陀螺仪数据,从而找到您的手机。
试用了该演示应用程序,该应用程序主要用于在设置了初始位置和方向后使用定位服务或WiFi映射移动情况。
iOS SDK-https://github.com/navisens/iOS-SDK
Android SDK-https://github.com/navisens/Android-SDK
注意:这不是开源的