簡體   English   中英

從rotationMatrix中提取偏航,俯仰和滾動

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

我有一個傳感器管理器,它根據設備Magnetometer和Accelerometer返回一個rotationMatrix 我一直試圖計算用戶設備的偏航俯仰和滾動,但我發現俯仰和滾動相互干擾並給出不准確的結果。 有沒有辦法從rotationMatrix提取設備的YAW PITCH和ROLL?

編輯試着解釋下面的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]);

我不知道我是否引用矩陣的錯誤部分,但我沒有得到我想的結果。

我希望得到度數的價值,但我得到奇怪的整數。

我的矩陣來自我的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;

當設備面朝上放在桌子上時的樣本矩陣

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

回答

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

我相信Blender的答案是不正確的,因為他給出了從旋轉矩陣到歐拉角(zxz extrinsic)的轉換,而Roll Pitch Yaw是一種不同的歐拉角(zyx extrinsic)。

實際的轉換公式寧願是:

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

資源

反饋:這種實現顯示在表示的單一性(萬向節鎖定)附近缺乏數值穩定性。 因此,在C ++上,我建議使用具有以下代碼行的Eigen庫:

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

(更多細節在這里

偏航,俯仰和滾動對應於歐拉角。 您可以非常輕松地將變換矩陣轉換為歐拉角

在此輸入圖像描述

傳感器管理器提供SensorManager.getOrientation以獲取所有三個角度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM