如何在Android 3轴加速度计中去除重力因素

18

有人可以帮忙去除加速度计读数中的重力因素吗?

我正在使用SensorEventListener和onSensorChanged()方法获取Sensor.TYPE_ACCELEROMETER数据。我需要所有方向上的纯加速度值。所以在任何状态下,如果设备保持稳定(或恒定速度),它应该大致为(0.0,0.0,0.0)。

目前,根据其俯仰和滚动,它会根据作用于每个轴上的g力而给出变量输出。

我希望有一些公式可以消除这种影响,因为我还从Sensor.TYPE_ORIENTATION侦听器获取方向值(俯仰和滚动)。我已经尝试了一些方法但并没有奏效。

7个回答

12

使用Sensor.TYPE_LINEAR_ACCELERATION替代Sensor.TYPE_ACCELEROMETER


7
注意,不是所有设备都具有Sensor.TYPE_LINEAR_ACCELERATION。 - Lytic
1
智能手表通常没有TYPE_LINEAR_ACCELERATION。 - Joost Verbraeken

12

您可以使用低通滤波器。

对于您的每个传感器值,请执行以下操作:

g = 0.9 * g + 0.1 * v

其中v是您当前的传感器值,g是一个全局变量,最初设置为零。请注意,您需要与轴数相同数量的g变量。

使用v = v - g,您可以从传感器值中消除重力因素。


2
请注意,这可以重写为g = (1-a)*g + a*v,其中a是一个介于0和1之间的变量,用于控制滤波器的截止。 - Drew Noakes
11
低通滤波器如何“去除”恒定偏差?我不理解。难道不应该使用高通滤波器吗? - matth
6
这个计算方法行不通,因为它假设设备的方向不会随时间改变,而这种情况非常罕见。 - fishinear
它的工作原理类似于电容器(在无线电电子学中的RC滤波器中的一部分)- 主要部分(0.9克)缓慢变化(电容器的电荷),但振荡部分(0.1)的影响仅在相同符号且不为零的情况下才会显著。 - Alex Shutov
请注意,过滤器的响应速度取决于您的采样率(即SENSOR_DELAY_XXX设置),可能会快或慢。 - Sarsaparilla

8

实际上,Android文档中的计算是不正确的,因为它们假设设备的方向不会改变。当然,在实践中这种情况极为罕见。 - fishinear

6

只需从旋转矩阵的z方向中减去g(~9.8m/s^2)即可。更明确地说,让

a = your accelerometer reading,
R = your rotation matrix (as a 9-long vector).

那么您需要的是:
(a[0]-g*R[6], a[1]-g*R[7], a[2]-g*R[8]).

1
这是正确的,但对于新手来说计算旋转矩阵有点困难。如果您想了解更多细节,请搜索方向余弦矩阵。 - xryl669
1
你只从Z中减去它吗?那X和Y呢? - rclai
3
只要设备始终朝向Z方向向下,仅从Z中减去即可。一旦设备倾斜,数据就会偏移,因为重力不仅拉Z轴。 - Mathieu Brouwers
@Theodore Sternberg,您能否提供一下您所提到的旋转矩阵的解释来源?我已经搜索过了,发现这是一个数学概念,但不知道如何在物理方面实现它。 - Ofek Glick

4
不同时间函数的导数可以消除常数。因此,通过对加速度计信号进行导数运算,您将得到"Jerk",然后可以重新积分以获得您要寻找的加速度的非常数部分。通俗易懂地说,每隔1秒从加速度计中取样一次,并从上一个样本中减去它。如果答案(非常接近)为零,则相对于地球不会加速。如果结果不为零,则进行积分(在这种情况下,乘以一秒),您就得到了加速度。不过有两点需要注意:一是要注意信号中的噪声,舍入输入;二是不要期望从芯片上的加速度计获得超精确的结果。您可以使用它们来检测震动、方向变化,但不能真正知道在车辆急转弯时经历了多少G力。

3

一种方法(仅适用于具有加速度计的设备)是通过减去在相同方向下静态情况下出现的值来从加速度计数据中消除重力向量。但由于方向再次是通过采取加速度读数而不是独立计算得出的,因此不太准确。

陀螺仪可能会在这种情况下有所帮助。但是,一些安卓手机仍然没有真正的陀螺仪。而使用其原始读数并不简单。


1
你需要假设两个坐标系: 1- 固定的全局系统。 2- 移动坐标系,其中原点随着传感器的移动和旋转而移动。 在全局系统中,g始终与z轴平行,但在移动系统中不是这样的。 所以你需要做的就是通过方向角或偏航、俯仰和横滚计算出3*3旋转矩阵(你可以在任何地方找到公式)。 然后将此旋转矩阵乘以传感器测量的3*1加速度向量。 这将转换坐标并在固定的全局系统中声明值。 之后唯一要做的就是从z值中简单地减去g。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接