2

我一直在研究方向估计,当我直线行走时,我需要估计正确的航向。在遇到一些障碍后,我又从基础开始。

我已经从这里实现了一个互补滤波器,它使用从 Android(不是原始加速度)、原始陀螺仪数据和原始磁力计数据获得的重力矢量。我还在陀螺仪和磁力计数据上应用低通滤波器并将其用作输入。

互补滤波器的输出是欧拉角,我还记录了 TYPE_ROTATION_VECTOR,它以 4D 四元数形式输出设备方向。

所以我想将四元数转换为欧拉并将它们与从互补滤波器获得的欧拉进行比较。当手机静止在桌子上时,欧拉角的输出如下所示。

在此处输入图像描述

在此处输入图像描述

可以看出,Yaw 的值相差很大。

当手机静止时,我在这个简单的情况下做错了什么

然后我走进客厅,得到以下输出。

在此处输入图像描述

在此处输入图像描述

Complementary filter的造型看起来很不错,和安卓的很接近。但是这些值相差很大。

请告诉我我做错了什么?

4

1 回答 1

2

我认为没有必要对陀螺仪应用低通滤波器。由于您正在集成陀螺仪以进行旋转,因此可能会搞砸一切。

请注意,TYPE_GRAVITY 是由陀螺仪和加速度在 Android 自己的传感器融合算法中合成的复合传感器读数。也就是说,这已经通过了卡尔曼滤波器。如果您无论如何都要使用 Android 的内置传感器融合,为什么不直接使用 TYPE_ROTATION_VECTOR 呢?

从外观上看,您的角度以弧度为单位,并且第一组的误差与 90 度相差不远。也许您在磁力计输入中交换了 X 和 Y?

这是我将采取的方法:首先编写一个测试,该测试采用加速度和陀螺仪并从中合成欧拉角。暂时忽略陀螺仪。在房子周围走来走去,确认它做了正确的事情,但很紧张。

接下来,在您的算法上打一个激进的低通滤波器,例如

yaw0 = yaw;
yaw = computeFromAccelMag();  // yaw in radians
factor = 0.2;                 // between 0 and 1; experiment
yaw = yaw * factor + yaw0 * (1-factor);

确认这仍然有效。它应该不那么紧张,但也很迟钝。

最后,添加陀螺仪并用它制作一个互补滤波器。

dt = time_since_last_gyro_update;
yaw += gyroData[2] * dt;            // test: might need to subtract instead of add
yaw0 = yaw;
yaw = computeFromAccelMag();  // yaw in radians
factor = 0.2;                 // between 0 and 1; experiment
yaw = yaw * factor + yaw0 * (1-factor);

他们的关键是在您开发算法时测试每一步,这样当错误发生时,您就会知道是什么原因造成的。

于 2015-06-03T15:40:09.820 回答