我有一个传感器管理器,它根据设备Magnetometer和Accelerometer返回rotationMatrix
。我一直试图计算用户设备的偏航俯仰和滚动,但我发现俯仰和滚动相互干扰并给出不准确的结果。有没有办法从rotationMatrix
?
修改 试着解释下面的搅拌机的答案,我感谢但还没到那里,我试图从这样的旋转矩阵中获得角度:
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]));
答案 0 :(得分:19)
偏航,俯仰和滚动对应于欧拉角。您可以非常轻松地convert a transformation matrix to Euler angles:
答案 1 :(得分:19)
我认为Blender的答案是不正确的,因为他给出了从旋转矩阵到欧拉角(z-x-z extrinsic)的变换,而Roll Pitch Yaw是一种不同的欧拉角(z-y-x 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();
(更多细节here)
答案 2 :(得分:2)
传感器管理器提供SensorManager.getOrientation以获得所有三个角度。