简体   繁体   English

从rotationMatrix中提取偏航,俯仰和滚动

[英]extract yaw, pitch, and roll from a rotationMatrix

I have a sensor manager that returns a rotationMatrix based on the devices Magnetometer and Accelerometer. 我有一个传感器管理器,它根据设备Magnetometer和Accelerometer返回一个rotationMatrix I have been trying to also calculate the yaw pitch and roll of the user's device but am finding that pitch and roll interfere with each other and give inaccurate results. 我一直试图计算用户设备的偏航俯仰和滚动,但我发现俯仰和滚动相互干扰并给出不准确的结果。 Is there a way to extract YAW PITCH and ROLL of a device from the rotationMatrix ? 有没有办法从rotationMatrix提取设备的YAW PITCH和ROLL?

EDIT Trying to interpret blender's answer below, which i am thankful for but not quite there yet, i am trying to get the angle from a rotaion matrix like this: 编辑试着解释下面的blender的答案,我感谢但还没到那里,我试图从这样的旋转矩阵中获得角度:

       float R[] = phoneOri.getMatrix();
       double rmYaw = Math.atan2(R[4], R[0]);
       double rmPitch = Math.acos(-R[8]);
       double rmRoll = Math.atan2(R[9], R[10]);

i don't know if i am referencing the wrong parts of the matrix or not but i am not getting the results i would think. 我不知道我是否引用矩阵的错误部分,但我没有得到我想的结果。

i was hoping to get values in degrees, but am getting weird integers. 我希望得到度数的价值,但我得到奇怪的整数。

my matrix is coming from my sensorManager which looks like this: 我的矩阵来自我的sensorManager ,如下所示:

public void onSensorChanged(SensorEvent evt) {
            int type=evt.sensor.getType();
            if(type == Sensor.TYPE_ORIENTATION){
                yaw = evt.values[0];
                pitch = evt.values[1];
                roll = evt.values[2];
            }
            if (type == Sensor.TYPE_MAGNETIC_FIELD) {
                orientation[0]=(orientation[0]*1+evt.values[0])*0.5f;
                orientation[1]=(orientation[1]*1+evt.values[1])*0.5f;
                orientation[2]=(orientation[2]*1+evt.values[2])*0.5f;
            } else if (type == Sensor.TYPE_ACCELEROMETER) {
                acceleration[0]=(acceleration[0]*2+evt.values[0])*0.33334f;
                acceleration[1]=(acceleration[1]*2+evt.values[1])*0.33334f;
                acceleration[2]=(acceleration[2]*2+evt.values[2])*0.33334f;
            }
            if ((type==Sensor.TYPE_MAGNETIC_FIELD) || (type==Sensor.TYPE_ACCELEROMETER)) {
                float newMat[]=new float[16];

                SensorManager.getRotationMatrix(newMat, null, acceleration, orientation);
                if(displayOri==0||displayOri==2){
                    SensorManager.remapCoordinateSystem(newMat,SensorManager.AXIS_X*-1, SensorManager.AXIS_MINUS_Y*-1,newMat);
                }else{
                    SensorManager.remapCoordinateSystem(newMat,SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X,newMat);
                }

                matrix=newMat;

sample matrix when device is laying face up on table 当设备面朝上放在桌子上时的样本矩阵

0.9916188,  -0.12448014, -0.03459576,  0.0
0.12525482,  0.9918981,   0.021199778, 0.0
0.031676512,-0.025355382, 0.9991765,   0.0
0.0,         0.0,         0.0,         1

ANSWER 回答

double rmPitch = Math.toDegrees( Math.acos(R[10]));

I believe Blender's answer is not correct, since he gave a transformation from Rotation matrix to Euler angles (zxz extrinsic), and Roll Pitch Yaw are a different kind of Euler angles (zyx extrinsic). 我相信Blender的答案是不正确的,因为他给出了从旋转矩阵到欧拉角(zxz extrinsic)的转换,而Roll Pitch Yaw是一种不同的欧拉角(zyx extrinsic)。

The actual transformation formula would rather be: 实际的转换公式宁愿是:

yaw=atan2(R(2,1),R(1,1));
pitch=atan2(-R(3,1),sqrt(R(3,2)^2+R(3,3)^2)));
roll=atan2(R(3,2),R(3,3));

Source 资源

Feedback : this implementation revealed to lack numerical stability near the singularity of the representation (gimbal lock). 反馈:这种实现显示在表示的单一性(万向节锁定)附近缺乏数值稳定性。 Therefore on C++ I recommend using Eigen library with the following line of code: 因此,在C ++上,我建议使用具有以下代码行的Eigen库:

R.eulerAngles(2,1,0).reverse();

(More details here ) (更多细节在这里

Yaw, pitch and roll correspond to Euler angles. 偏航,俯仰和滚动对应于欧拉角。 You can convert a transformation matrix to Euler angles pretty easily: 您可以非常轻松地将变换矩阵转换为欧拉角

在此输入图像描述

传感器管理器提供SensorManager.getOrientation以获取所有三个角度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM