Finding a Quaternion from Gyroscope Data?

£可爱£侵袭症+ 提交于 2019-12-23 17:15:08

问题


I've been trying to build a filter that can successfully combine compass, geomagnetic, and gyroscopic data to produce a smooth augmented reality experience. After reading this post along with lots of discussions, I finally found out a good algorithm to correct my sensor data. Most examples I've read show how to correct accelerometers with gyroscopes, but not correct compass + accelerometer data with gyroscope. This is the algorithm I've settled upon, which works great except that I run into gimbal lock if I try to look at the scene if I'm not facing North. This algorithm is Balance Filter, only instead of only implemented in 3D

Initialization Step:

  • Initialize a world rotation matrix using the (noisy) accelerometer and compass sensor data (this is provided by the Android already)

Update Steps:

  • Integrate the gyroscope reading (time_delta * reading) for each axis (x, y, z)

  • Rotate the world rotation matrix using the Euler angles supplied by the integration

  • Find the Quaternion from the newly rotated matrix

  • Find the rotation matrix from the unfiltered accelerometer + compass data (using the OS provided function, I think it uses angle/axis calculation)

  • Get the quaternion from the matrix generated in the previous step.

  • Slerp between quaternion generated in step 2 (from the gyroscope), and the accelerometer data using a coefficient based on some experimental magic

  • Convert back to a matrix and use that to draw the scene.

My problem is that when I'm facing North and then try to look south, the whole thing blows up and it appears to be gimbal lock. After a few gimbal locks, the whole filter is in an undefined state. Searching around I hear everybody saying "Just use Quaternions" but I'm afraid it's not that simple (at least not to me) and I know there's something I'm just missing. Any help would be greatly appreciated.


回答1:


The biggest reason to use quaternions is to avoid the singularity problem with Euler angles. You can directly rotate a quaternion with gyro data.




回答2:


Many appologies if information is delayed or not useful specifically but may be useful to others as I found it after some research:::

a. Using a kalman (linear or non linear) filter you do following ::

Gyro to integrate the delta angle while accelerometers tell you the outer limit.

b. Euler rates are different from Gyro rate of angle change so you ll need quaternion or Euler representation::

Quaternion is non trivial but two main steps are ----

1. For Roll, pitch,yaw   you get three quaternions as cos(w) +sin(v) where w is scalar part and v is vector part (or when coding just another variable) 
 Then simply multiply all 3 quat. to get a delta quaternion
 i.e   quatDelta[0] =c1c2*c3 - s1s2*s3;
  quatDelta[1] =c1c2*s3 + s1s2*c3;
  quatDelta[2] =s1*c2*c3 + c1*s2*s3;
  quatDelta[3] =c1*s2*c3 - s1*c2*s3;
where c1,c2,c3 are cos of roll,pitch,yaw and s stands for sin of the same actually half of those gyro pre integrated angles.

2. Then just multiply by old quaternion you had

  newQuat[0]=(quaternion[0]*quatDelta[0] - quaternion[1]*quatDelta[1] - quaternion[2]*quatDelta[2] - quaternion[3]*quatDelta[3]);
  newQuat[1]=(quaternion[0]*quatDelta[1] + quaternion[1]*quatDelta[0] + quaternion[2]*quatDelta[3] - quaternion[3]*quatDelta[2]);
  newQuat[2]=(quaternion[0]*quatDelta[2] - quaternion[1]*quatDelta[3] + quaternion[2]*quatDelta[0] + quaternion[3]*quatDelta[1]);
  newQuat[3]=(quaternion[0]*quatDelta[3] + quaternion[1]*quatDelta[2] - quaternion[2]*quatDelta[1] + quaternion[3]*quatDelta[0]);

As you loop through the code it gets updated so only quatenion is a global variables not the rest

3. Lastly if you want Euler angles from them then do the following:


`euler[2]=atan2(2.0*(quaternion[0]*quaternion[1]+quaternion[2]*quaternion[3]), 1-2.0*(quaternion[1]*quaternion[1]+quaternion[2]*quaternion[2]))euler[1]=safe_asin(2.0*(quaternion[0]*quaternion[2] - quaternion[3]*quaternion[1]))euler[0]=atan2(2.0*(quaternion[0]*quaternion[3]+quaternion[1]*quaternion[2]), 1-2.0*(quaternion[2] *quaternion[2]+quaternion[3]*quaternion[3]))`

euler[1] is pitch and so on.. 

I just wanted to outline general steps of quaternion implementation. There may be some minor errors but I tried this myself and it works. Please note that when changing to euler angles you will get singularities also called as "Gimbal lock"

An important note here is that this is not my work but I found it over the internet and wanted to thank who ever did this priceless code...Cheers



来源:https://stackoverflow.com/questions/7779236/finding-a-quaternion-from-gyroscope-data

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