从CMRotationMatrix获取俯仰角、偏航角和翻滚角

8
我有一个CMRotationMatrix *rot,想从矩阵中获取俯仰角、偏航角和翻滚角。你有什么好的建议吗?
谢谢。
3个回答

29

使用四元数比欧拉角更好...可以使用以下公式从四元数中推导出翻滚、俯仰和偏航值:

roll  = atan2(2*y*w - 2*x*z, 1 - 2*y*y - 2*z*z)
pitch = atan2(2*x*w - 2*y*z, 1 - 2*x*x - 2*z*z)
yaw   =  asin(2*x*y + 2*z*w)

它可以实现为:

CMQuaternion quat = self.motionManager.deviceMotion.attitude.quaternion;
myRoll = radiansToDegrees(atan2(2*(quat.y*quat.w - quat.x*quat.z), 1 - 2*quat.y*quat.y - 2*quat.z*quat.z)) ;
myPitch = radiansToDegrees(atan2(2*(quat.x*quat.w + quat.y*quat.z), 1 - 2*quat.x*quat.x - 2*quat.z*quat.z));
myYaw = radiansToDegrees(asin(2*quat.x*quat.y + 2*quat.w*quat.z));

其中radianstoDegrees是一个预处理器指令,实现方式如下:

#define radiansToDegrees(x) (180/M_PI)*x

这是为了将公式给出的弧度值转换为角度。

有关转换的更多信息可以在这里找到:tinkerforge和这里:四元数和欧拉角之间的转换


2
我很好奇,“为什么使用四元数比欧拉角更好”? - Jacksonkr
2
谢谢。它运行良好。motionManager.deviceMotion.attitude.pitch/roll/yaw非常不稳定。我想知道为什么苹果不修复它们。 - Vince Yuan
2
这是因为欧拉角可能会陷入万向节锁定状态,你将失去一个自由度,无法成功恢复。虽然有一些解决方法(例如检测接近万向节锁定状态),但更好、更高效的解决方案是使用其他表示方法(如四元数或旋转矩阵)。尽管如此,欧拉角易于使用(和理解),在许多用例中仍然可以使用。 - Palli
1
你如何将这些值转换为0:360度范围内的值? - Ilker Baltaci
3
我同意其他评论的观点;苹果设备提供的滚转/俯仰/偏航值似乎不稳定/容易受到万向节锁定状态的影响。具体来说,当我急剧改变设备的俯仰时,即使我并没有实际上“横滚”设备,滚动值也经常变得不稳定。 - Brian Sachetta

1
从矩阵中获取俯仰、偏航和滚转角。有什么想法吗?
按照什么顺序?俯仰、偏航和滚转通常被称为欧拉角,不能明确地表示旋转。根据您执行的单个子旋转的顺序,您最终会得到完全不同的旋转矩阵。
我的个人建议:根本不要使用欧拉角,它们只会引起(数值)问题。使用矩阵(您已经在使用)或四元数。

-2

我自己找到了答案:

CMAttitude *currentAttitude = motionManager.deviceMotion.attitude;    

        if (currentAttitude == nil)
        {
            NSLog(@"Could not get device orientation.");
            return;
        }
        else {
            float PI = 3.14159265;
            float yaw = currentAttitude.yaw * 180/PI;
            float pitch = currentAttitude.pitch * 180/PI;
            float roll = currentAttitude.roll * 180/PI;

        }

2
M_PI 将是更精确的π表示法,并且可以节省变量 ;) - Peter Kazazes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接