Android 的互补滤波器(陀螺仪 + 加速度)

Posted

技术标签:

【中文标题】Android 的互补滤波器(陀螺仪 + 加速度)【英文标题】:Complementary filter (Gyro + accel) with Android 【发布时间】:2011-11-25 02:07:15 【问题描述】:

最近我做了一些研究,使用加速度计和陀螺仪来使用这些传感器在没有 GPS 帮助的情况下跟踪智能手机(见这篇文章) Indoor Positioning System based on Gyroscope and Accelerometer

为此,我将需要我的方向(角度(俯仰、滚动等)),所以到目前为止我所做的:

public void onSensorChanged(SensorEvent arg0) 
    if (arg0.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
    
        accel[0] = arg0.values[0];
         accel[1] = arg0.values[1];
   accel[2] = arg0.values[2];
   pitch = Math.toDegrees(Math.atan2(accel[1], Math.sqrt(Math.pow(accel[2], 2) + Math.pow(accel[0], 2))));

  tv2.setText("Pitch: " + pitch + "\n" + "Roll: " + roll);

    else if (arg0.sensor.getType() == Sensor.TYPE_GYROSCOPE )

  if (timestamp != 0) 
  final float dT = (arg0.timestamp - timestamp) * NS2S;         
  angle[0] += arg0.values[0] * dT;
  filtered_angle[0] = (0.98f) * (filtered_angle[0] + arg0.values[0] * dT) + (0.02f)* (pitch);
           
   timestamp = arg0.timestamp;
 

在这里,我试图从我的加速度计(俯仰)角度(仅用于测试),从集成 gyroscope_X 低谷时间用互补滤波器过滤它

filtered_angle[0] = (0.98f) * (filtered_angle[0] + gyro_x * dT) + (0.02f)* (pitch)

dT 开始或多或少 0.009 秒

但我不知道为什么,但我的角度并不准确......当设备平放在桌子上时(屏幕朝上)

Pitch (angle fromm accel) = 1.5 (average) 
Integrate gyro = 0 to growing (normal it's drifting) 
filtered gyro angle = 1.2

当我将手机抬起90°时(看到屏幕正对着我面前的墙壁)

Pitch (angle fromm accel) = 86 (MAXIMUM) 
Integrate gyro = he is out ok its normal 
filtered gyro angle = 83 (MAXIMUM)

所以角度永远不会达到 90 ???即使我试着再举起手机…… 为什么直到 90° 才开始?我的计算错了吗?还是传感器质量差?

我想知道的另一件事是:在 android 中,我不会“读出”传感器的值,但当它们发生变化时我会收到通知。问题是,正如您在代码中看到的,Accel 和 Gyro 共享相同的方法....所以当我计算过滤角度时,我将在 0.009 秒前采用加速度测量的俯仰,不是吗?这可能是我问题的根源吗?

谢谢!

【问题讨论】:

Indoor Positioning System based on Gyroscope and Accelerometer的可能重复 【参考方案1】:

我只能repeat myself.

您可以通过两次积分线性加速度来获得位置,但 错误非常可怕。它在实践中是没有用的。 换句话说,你正在尝试解决不可能的问题。

您实际上可以做的只是跟踪方向。

滚动、俯仰和偏航是邪恶的,不要使用它们。 38:25 签到the video I already recommended。

这是一个excellent tutorial,关于如何使用陀螺仪和加速度计跟踪方向。

可能对您有帮助的类似问题:

track small movements of iphone with no GPSWhat is the real world accuracy of phone accelerometers when used for positioning?how to calculate phone's movement in the vertical direction from rest?ios: Movement Precision in 3D SpaceHow to use Accelerometer to measure distance for Android Application DevelopmentDistance moved by AccelerometerHow can I find distance traveled with a gyroscope and accelerometer?

【讨论】:

感谢您的帮助,很抱歉让您重复了一些东西。确实,gentlnav 教程非常好!我刚刚快速阅读了它,它很好地解释了 DCM 我会更仔细地阅读它 我在 *** 上发现了一个类似的问题,您在其中谈论相同的教程,并且您说您将它用于人体运动感应。所以这意味着您成功地设法使用 DCM 获得良好的方向? ***.com/questions/5314217/…谢谢 @Alexis 没问题,祝你好运!是的,我有一个 C++ 实现,但用 Java for Android 编写自己的实现并不难。不幸的是,也许有现有的应用程序我不知道。对于您的应用程序而言,仅定向就足够了吗? 因为这只是我学校的一个项目,我只是想知道它是否可能......经过大量阅读后我发现它不是:) 或者它是否领先于我的数学理解......所以我只是要改变一点,并尝试使用陀螺仪+加速器来获得方向:) 我刚刚发现:diydrones.com/profiles/blogs/a-simple-deadreckoning 它使用 DCM + 航位推算来跟踪飞机(他进行了两次积分以获得位置,但我不明白他是如何纠正结果的)跨度> @Alexis 我没有查看详细信息,但在我看来,他的算法是基于 GPS 的,而 IMU 用于“填补空白”。是的,您可以使用卡尔曼滤波器做到这一点,但在您的问题中您说您没有/使用 GPS。【参考方案2】:

我写了一篇关于使用互补滤波器通过陀螺仪和加速度计进行方向跟踪的教程:http://www.pieter-jan.com/node/11 也许它可以帮助你。

【讨论】:

【参考方案3】:

我测试了您的代码,发现比例因子可能不一致。 将音高转换为 0-pi 可获得更好的结果。 在我的测试中,过滤后的结果约为 90 度。

pitch = (float) Math.toDegrees(Math.atan2(accel[1], Math.sqrt(Math.pow(accel[2], 2) + Math.pow(accel[0],   2))));
pitch = pitch*PI/180.f;

filtered_angle = weight * (filtered_angle + event.values[0] * dT) + (1.0f-weight)* (pitch);

【讨论】:

【参考方案4】:

我试过了,这会给你 90 角...

filtered_angle = (filtered_angle / 83) * 90;

【讨论】:

以上是关于Android 的互补滤波器(陀螺仪 + 加速度)的主要内容,如果未能解决你的问题,请参考以下文章

互补滤波原理

四轴飞行器无线的充电usb怎么充电

读书笔记iOS-加速计与陀螺仪

Human Motion Analysis with Wearable Inertial Sensors——阅读3

卡尔曼(Kalman)滤波--卡尔曼滤波的应用: 四元数卡尔曼滤波(QKF)的C代码实现姿态解算

GPS +加速度计的C语言中的任何卡尔曼滤波器实现?