我一直在研究方向估计,我需要在直线行走时估算正确的航向。面对一些障碍后,我再次从基础开始。
我已经实现了here的互补滤波器,它使用从Android(非原始加速度),原始陀螺仪数据和原始磁力计数据获得的重力矢量。我还对陀螺仪和磁强计数据应用低通滤波器并将其用作输入。
互补滤波器的输出是欧拉角,我也记录了TYPE_ROTATION_VECTOR,它以4D四元数输出设备方向。
所以我想把Quaternions转换成Euler并将它们与从Complementary过滤器获得的Euler进行比较。当手机在桌子上静止时,欧拉角的输出如下所示。
可以看出,Yaw的价值大幅下降。
手机静止时这个简单的情况我做错了什么
然后我走进客厅,得到以下输出。
补充滤镜的形状看起来非常好,非常接近Android的形状。但价值观大幅下降。
请告诉我,我做错了什么?
答案 0 :(得分:2)
我认为没有必要对陀螺仪应用低通滤波器。因为你正在整合陀螺仪以获得旋转,所以它可能会弄乱一切。
请注意,TYPE_GRAVITY是一个复合传感器读数,由陀螺和accel在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);
关键是在开发算法时测试每一步,这样当错误发生时,你就会知道是什么导致了它。