Comparison: TYPE_ROTATION_VECTOR with Complemenary Filter

冷暖自知 提交于 2019-12-11 02:48:35

问题


I have been working on Orientation estimation and I need to estimate correct heading when I am walking in straight line. After facing some roadblocks, I started from basics again.

I have implemented a Complementary Filter from here, which uses Gravity vector obtained from Android (not Raw Acceleration), Raw Gyro data and Raw Magnetometer data. I am also applying a low pass filter on Gyro and Magnetometer data and use it as input.

The output of the Complementary filter is Euler angles and I am also recording TYPE_ROTATION_VECTOR which outputs device orientation in terms of 4D Quaternion.

So I thought to convert the Quaternions to Euler and compare them with the Euler obtained from Complementary filter. The output of Euler angles is shown below when the phone is kept stationary on a table.

As it can be seen, the values of Yaw are off by a huge margin.

What am I doing wrong for this simple case when the phone is stationary

Then I walked in my living room and I get the following output.

The shape of Complementary filter looks very good and it is very close to that of Android. But the values are off by huge margin.

Please tell me what am I doing wrong?


回答1:


I don't see any need to apply a low-pass filter to the Gyro. Since you're integrating the gyro to get rotation, it could mess everything up.

Be aware that TYPE_GRAVITY is a composite sensor reading synthesized from gyro and accel inside Android's own sensor fusion algorithm. Which is to say that this has already been passed through a Kalman filter. If you're going to use Android's built-in sensor fusion anyway, why not just use TYPE_ROTATION_VECTOR?

Your angles are in radians by the looks of it, and the error in the first set wasn't too far from 90 degrees. Perhaps you've swapped X and Y in your magnetometer inputs?

Here's the approach I would take: first write a test that takes accel and gyro and synthesizes Euler angles from it. Ignore gyro for now. Walk around the house and confirm that it does the right thing, but is jittery.

Next, slap an aggressive low-pass filter on your algorithm, e.g.

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

Confirm that this still works. It should be much less jittery but also sluggish.

Finally, add gyro and make a complementary filter out of it.

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);

They key thing is to test every step of the way as you develop your algorithm, so that when the mistake happens, you'll know what caused it.



来源:https://stackoverflow.com/questions/30573588/comparison-type-rotation-vector-with-complemenary-filter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!