android从加速度计读数中删除重力

Posted

技术标签:

【中文标题】android从加速度计读数中删除重力【英文标题】:android remove gravity from accelerometer readings 【发布时间】:2011-10-18 05:18:18 【问题描述】:

我正在开发一个 android 应用程序,我需要从加速度计读数中消除重力。关于这个问题我看了很多讨论,我也找到了一个算法here,但是我不是很明白。

我想过滤每个轴的重力,而不是总加速度。

你能帮帮我吗?我的代码应该是这样的:

public void onSensorChanged(SensorEvent sensorEvent) 
    float vals[] = sensorEvent.values;
    float accelerationX = filterGravity(vals[0]);
    float accelerationY = filterGravity(vals[1]);
    float accelerationZ = filterGravity(vals[2]);

我应该在 filterGravity() 方法中放置什么代码?

【问题讨论】:

【参考方案1】:

对于基本解决方案,您需要low pass filter 其他方法(例如卡尔曼滤波器)对于背后的数学运算非常困难。 Android 的一个简单示例是单击您的链接 http://developer.android.com/reference/android/hardware/SensorEvent.html#values。

简单地说,低通滤波器会根据您的所有历史值构建加权平均值。例如,如果您的过滤因子为 0.1,则意味着将当前值的 10% 添加到先前的平均值:newMeanValue = currentValue 的 10% + oldMeanValue 的 90%。这意味着即使有一个突然的峰值,也只会因为 10% 而缓慢地推动您的平均值。

【讨论】:

@Kay 对不起,我想为你的答案投票。请在您的最后一句话中添加一个点(或进行一些编辑),这样我的反对票就会变成赞成票。对不起... @Ali: 加点,没问题 :-) @Kay 该站点应该支持这样的撤消功能。也许我会在 meta*** 上提出来。 @Ali meta.stackexchange.com/questions/19940/… 它的状态已被拒绝,但我只是赞成它。也许有一天会实现。【参考方案2】:

线性加速是你所需要的。检查 Sensor.TYPE_LINEAR_ACCELERATION here。

【讨论】:

非常感谢。这将解决我的问题。但是,这仅从 API 级别 9 开始支持。有没有办法在早期的 API 版本中实现这一点? @Gabriel 恐怕不会。这背后有一些繁重的数学运算,融合了加速度计、陀螺仪和指南针数据。这是一个关于传感器融合的有趣视频:youtube.com/watch?v=C7JQ7Rpwn2k【参考方案3】:

不太确定您要完成什么,但如果您正在寻找 幅度(这将给出 0 到 1 之间的结果),那么您所做的就是将结果除以 10

public void onSensorChanged(SensorEvent sensorEvent) 
float vals[] = sensorEvent.values;
float accelerationX = (vals[0]/10);
float accelerationY = (vals[1]/10);
float accelerationZ = (vals[2]/10);

在游戏环境中,当传感器完全倾斜时,您的对象将处于最大速度

【讨论】:

【参考方案4】:

如果您没有带有 TYPE_LINEAR_ACCELERATION 的手机,您会被 TYPE_ACCELERATION 卡住,它无法将重力(倾斜)与线性加速度分开。

一种选择是应用低通滤波器。如果陀螺仪可用,另一种方法是使用传感器融合。这两种方法各有优缺点。

我在开源项目Acceleration Explorer 中有很多工作示例。

【讨论】:

嗨 Kaleb,我目前正在开发类似于您的 FusedLinearAcceleration android 应用程序的 java 应用程序,但我无法使用 android 虚拟传感器来计算重力。我从 sensorManager 移植了一些方法,但我找不到获取重力矢量的算法。我发现这可以使用四元数来实现,并更改/写了如下内容:gist.github.com/Bresiu/c0a69552881b8df34a2e。但它给出了不好的结果 - 重力仅从 z 轴补偿(其余代码基于您的应用程序)。你有什么提示,有什么问题吗?我的代码:goo.gl/5jmlvY @Bresiu:FusedLinearAcceleration 使用的唯一虚拟传感器是 Sensor.TYPE_GRAVITY,您可以将其更改为 Sensor.TYPE_ACCELERATION。但是,如果您的设备带有陀螺仪,则应实现 Sensor.TYPE_GRAVITY。您可以查看这篇博客文章 (kircherelectronics.com/blog/index.php/11-android/sensors/…),其中详细说明了您发布的代码(以及我的代码)。它可能会有所帮助,因为它涵盖了重力矢量。请记住,如果您要在动态加速期间测量任何东西(例如汽车),则需要对其进行修改。 我有一个带有陀螺仪、加速度计和磁力计的设备,所以我正在寻找一些传感器融合以获得最佳效果。我看到了你的其他应用程序,FusedLinear 似乎最准确。我会继续寻找... FusedLinearAcceleration 几乎是最好的。很难将倾斜/静态加速度与动态/线性加速度区分开来。由于加速度计通过某种融合(通常是互补滤波器)来补偿陀螺仪漂移,因此动态/线性加速度会导致陀螺仪中的错误漂移补偿。反馈回路是所有传感器融合的问题。 Sensor.TYPE_LINEAR_ACCELERATION 也有这个问题。它对于测量动态/线性加速度是无用的。

以上是关于android从加速度计读数中删除重力的主要内容,如果未能解决你的问题,请参考以下文章

来自智能手机的后处理传感器读数 - 从磁力计计算的重力

Android 加速度计精度(惯性导航)

Android 加速度计精度(惯性导航)

加速度计到相对位置

陀螺仪和加速度计的读数和四元数怎么建立关系

Android 加速度计在 z 轴上读数为 0 而没有变化