我希望获得Android手机的加速度矢量。问题是,加速度计坐标是相对于手机的旋转。我想要的是“绝对”加速度,即它应该以手机面对的方式返回相同的值。 (我想检测滑雪的用户是否在不使用GPS的情况下滑下斜坡。我还需要能够区分滑行和升降机。)
我可以通过将加速度计与陀螺仪相结合来获得这些值,但我不知道如何用陀螺仪来补偿加速度计的值。
这是可能的,如果是的话,怎么样?
答案 0 :(得分:11)
除非您稍微重新定义问题,否则您所描述的内容无法完成。为了帮助您重新定义它,我将概述主要问题:
首先,我猜你的“绝对加速度”是指地理参考的加速度。单独使用加速度计无法做到,因为它不了解地理参考。如果你移动足够的gps,或使用指南针,你可能能够解决这个问题,但每个都有自己的问题(尽管至少问题是可以解决的)。
第二个问题是,仅使用加速度计就完全无法区分重力和加速度(这被称为“等效原理”)。因此,任何测得的加速度总是重力和加速度的矢量和,但这些方程式总是存在多种解,并且在加速度小于重力的通常情况下,你实际上无法确定加速度的任何信息。 。虽然重力在某种程度上是不变的,但也有一些方法可以解决这个问题,例如使用陀螺仪,或者你的用户可能会将手机固定在一个固定的位置(例如,通过观察地平线等外部线索),以及其中任何一种方法可以让你减去重力的影响,但这通常是一个非平凡的问题。
最后一点不是你似乎在想一个固定在地球上的坐标系,手机的加速度计只是手机固定的。那就是加速度计的z轴很多与地球上下都无关 - 这种关系将取决于手机的方向。真的,很多人更喜欢地球固定系统,但手机却不知道。您可以使用外部提示(GPS,磁场,陀螺仪,重力,地平线等)来尝试对齐它们,但只有一个任意读数形成加速度计,信息就不存在。
<强>解释强>
加速度矢量:这是从加速度计读取的x,y,z(每个读数将取决于手机的方向),有时写为A =(a x , a y , z )
加速度:这是a = sqrt(a x 2 + a y 2 + a z 2 ),这不应取决于手机方向(如果不同的轴校准相同)。如果手机是静止的,这基本上只是读取引力。另请注意,使用此度量会丢失加速度矢量中的大量信息
标准化加速:加速方向,有1个,即,A / a
地球坐标的加速度我认为这是你真正想要的,没有简单的方法可以获得它,即使你可以,但我认为它不会像它那样有用一开始似乎。
<强>滑雪强>:
我认为你可以根据加速度计的测量结果确定某人是否正在滑雪。使用加速度计,像颠簸和转弯这样的事情应该是非常独特的。对于这些我会使用完整的加速度矢量。例如,轮流,加速度幅度将保持大致恒定,并且方向将扫过。还要注意自由落体(即,基本上每当滑雪者在地面上没有他们的天空/脚/屁股/等时,他们是否在发射撞击/跳跃时向上移动,或者从滑雪缆车中掉出来) ,自由落体时的加速度幅度为零。对于缆车而言,似乎它可能在一个平面内有一种独特的节奏摇摆。
所有这些事情都可以解决。如果您真的想解决这个问题,我建议您在滑雪时记录加速度计的数据,看看您是否可以根据数据的特征确定何时滑雪。 (我的猜测是,你的主要绊脚石将是数学,因为想出一个可以区分滑雪签名的算法可能有点棘手,所以似乎审查矢量是一个好主意数学,以及像点产品和交叉产品之类的东西,而且,我怀疑有一点关于另一个被称为FFT或傅里叶变换的主题可能有助于整理滑雪时间和频率签名与在升降椅中摆动。)
你也可以折叠GPS测量,这不是那么可靠,或者提供良好的时间分辨率,但至少可以用来仔细检查你的算法。
答案 1 :(得分:3)
您可以使用以下方式计算加速度,而不管手机的方向如何:
a = sqrt(x*x + y*y + z*z)
其中a
是绝对加速度,x
,y
和z
是每个手机3轴的加速度计值。
答案 2 :(得分:1)
有些手机内置了气压计(气压传感器)。应用移动平均线后,我发现它已准备就绪,可以确定用户是上升还是下降 - 对您的问题有用。在星系s4和5上,我得到的分辨率足以确定设备是否刚从桌子移到地板上。
请注意,天气的逐渐变化会影响您的读数,因此您必须在合理的时间间隔内考虑Delta,并忽略某些阈值附近的变化。
答案 3 :(得分:0)
考虑使用GPS。在飞行记录应用程序中,我使用加速度(尽管是绝对值,而不是矢量)来过滤嘈杂的GPS数据(我删除了速度变化所需的加速度不合理的位置):
/**
* Remove noise from the measurement of the location.
* @param loc a location
* @return Answer <code>false</code> iff the location should not be used.
*/
private boolean filterNoise(final Location loc) {
if( ! loc.hasSpeed() )
return true;
if( this.recentSpeeds.isEmpty() ) { // rescentSpeeds is a queue of locations
this.recentSpeeds.add(loc);
return true;
}
final Location lastFix = this.recentSpeeds.getHead();
final long delta_t = (loc.getTime() - lastFix.getTime()) / 1000;
if( delta_t == 0 )
return false;
final float delta_v = loc.getSpeed() - lastFix.getSpeed();
final float a = delta_v / delta_t;
if( Math.abs(a) <= AccelThreshold ) {
this.recentSpeeds.add(loc);
return true;
}
return false;
}
如果使用上次修复和当前修正的坐标计算速度,则将加速度作为向量。