Get Euler Yaw angle of an Android Device

僤鯓⒐⒋嵵緔 提交于 2019-12-04 18:35:23
Hoan Nguyen

If you want to calculate the rotation about the device z-axis independent of the device position (that is flat or not flat) then you have to keep track of a few things. If the app support both Portrait and Landscape then it is more complicated, I am going to give an answer when the activity is restricted to Portrait only.

So flat here means the pitch is less than 25 or more than 155 degrees and not flat otherwise.
When the device is in transition from flat to not flat and vice versa there probably some inconsistent in the UI.

Register for TYPE_GRAVITY and TYPE_MAGNETIC_FIELD (needed for flat) and do the calculation below.

  • getRotationMatrix

    a[0] a[1] a[2]
    a[3] a[4] a[5]
    a[6] a[7] a[8]

  • Calculate pitch = Math.asin(-R[7])

  • Using pitch to determine the flatness of the device (I think you can use less than 45 and more than 135 to determine flatness, you just have to experiment to see if the azymuth value is correct)
  • if the device is not flat the rotation is Math.atan2(a[6], a[7])

  • If the device is flat to start with get the initial azymuth = Math.atan2(R[1], R[4]) and then take the difference with subsequent azymuths to get the rotation.

  • If the device transition from flat to not flat there should be no problem the rotation is just the rotation for not flat above.

  • If the device transition from not flat to flat then you need to get the initial azymuth. This initial azymuth can be set to the back camera direction Math.atan2(-a[2], -a[5]), if the device is upright and there is only rotation about the z-axis then this direction should not change. In reallity it will probably change by a few degrees so you will need to take the average.

All the math except for Math.atan2(a[6], a[7]) is explained at Android: Algorithms for SensorManager.getRotationMatrix and SensorManager.getOrientation()
So let me give the explanation for finding the rotation when the device is not flat.

As explained in the link above you have to specify the fixed vector and the vector that varies that you want to calculate the angle between them. In this case the vector that varies is a vector lying in the device y-axis and the fixed vector is the projection of the gravity vector into the device xy-plane. In the rotation matrix above the last row is the normalize gravity vector in device coordinate, thus the projection to the device xy-plane is (a[6], a[7]). Now it is simple trigonometry to see that Math.atan2(a[6], a[7]) is the angle between the device y-axis and the gravity projection. (Draw picture if you do not see it).

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