导语:在三维旋转处理中,四元数、万向锁、Lerp和Slerp是四个紧密关联的概念。通过一个具体的机器人关节旋转示例,将这四个概念串联起来,深入浅出地解析其原理。最后以问答形式巩固理解。
一、 场景:机器人肩关节的旋转任务
假设我们有一个网球AI教练系统中的机器人,其肩关节需要从初始姿态AAA旋转到目标姿态BBB,以完成一个发球动作。
- 姿态 A:机器人手臂自然下垂,朝向正前方。
- 姿态 B:手臂抬起,同时向外旋转一定角度。
我们需要解决三个问题:
- 如何用数学描述这两个姿态?(引入欧拉角与四元数)
- 为什么直接对角度进行插值会导致动作突变?(揭示万向锁)
- 如何实现平滑、恒定的旋转动画?(对比Lerp与Slerp)
如图所示的三轴陀螺仪,若旋转红圈过程中,恰巧旋转到了图二所示状态,然后进行步骤3时会发现,旋转蓝圈与绿圈效果一样。也就是这种状态下,旋转Y或Z轴效果一样了,都只能使飞机左右倾斜,而不能再俯视或仰视(它只能头朝天),这下坏了,飞机操作失灵了,只能向上直冲。这就所谓的万向节死锁(gimbal lock)
二、 欧拉角(Euler Angles):直观的旋转表示
1. 什么是欧拉角?
欧拉角是描述三维刚体取向的一种直观方法,它将任意旋转分解为绕三个坐标轴的一系列旋转。通常这三个轴对应:
- 偏航(Yaw):绕垂直轴(通常为Y轴或Z轴)的旋转,如摇头。
- 俯仰(Pitch):绕水平横向轴(通常为X轴)的旋转,如点头。
- 滚转(Roll):绕前后纵深轴(通常为Z轴或X轴)的旋转,如翻滚。
2. 旋转顺序与约定
由于三维旋转不满足交换律(先绕X转再绕Y转 ≠ 先绕Y转再绕X转),必须约定旋转顺序。常见的约定有:
- 航空约定(ZYX):先偏航(Z),再俯仰(Y),最后滚转(X)。
- 机器人学常用(XYZ 或 ZYZ):根据具体关节设计而定。
在示例中,我们假设使用ZYX 顺序(偏航-俯仰-滚转)。姿态 A 对应(0∘,0∘,0∘)(0^\circ, 0^\circ, 0^\circ)(0∘,0∘,0∘),姿态 B 对应(45∘,90∘,45∘)(45^\circ, 90^\circ, 45^\circ)(45∘,90∘,45∘)。
3. 欧拉角的优点与隐患
- 优点:极其直观,人类容易理解和调试(“俯仰角30度”一听就懂)。
- 隐患:当中间轴(如俯仰轴)旋转到特定角度(如±90∘\pm 90^\circ±90∘)时,会触发万向锁(Gimbal Lock),导致自由度丢失。
三、 万向锁(Gimbal Lock):欧拉角的阿喀琉斯之踵
1. 通俗理解:三轴陀螺仪
想象一个机械三轴陀螺仪,有三个嵌套的金属环,分别控制偏航、俯仰、滚转。正常情况下,三个环互不干扰,提供三个自由度。
但是,当中间的俯仰环旋转到90°时,最外层的偏航环和最内层的滚转环会共面,它们的旋转轴完全重合。此时,转动偏航或滚转,手臂只能在同一个平面上画圈,系统丢失了一个自由度——这就是万向锁。
2. 数学本质
万向锁的本质是参数化奇异性。在俯仰角为90∘90^\circ90∘时,旋转矩阵退化为:
R=Rz(α)Ry(90∘)Rx(γ)=Rz(α+γ)Ry(90∘) R = R_z(\alpha) R_y(90^\circ) R_x(\gamma) = R_z(\alpha+\gamma) R_y(90^\circ)R=Rz(α)Ry(90∘)Rx(γ)=Rz(α+γ)Ry(90∘)
此时α\alphaα和γ\gammaγ无法被独立解耦,它们被“捆绑”成一个角度。数学上,雅可比矩阵在该点秩亏,无法求逆。
3. 在示例中的危害
如果我们的目标姿态 B 是(45∘,90∘,45∘)(45^\circ, 90^\circ, 45^\circ)(45∘,90∘,45∘),俯仰角正好90∘90^\circ90∘。若使用欧拉角插值(从0∘0^\circ0∘到90∘90^\circ90∘逐渐增加俯仰),当俯仰接近90∘90^\circ90∘时,偏航和滚转会瞬间耦合,机械臂末端轨迹会出现非预期的剧烈抖动,甚至触发电机保护。
四、 四元数(Quaternion):无奇异的旋转表示
1. 为什么需要四元数?
为了彻底避开万向锁,数学家发明了四元数。它是复数的四维扩展,形式为:
q=w+xi+yj+zk q = w + xi + yj + zkq=w+xi+yj+zk
其中i2=j2=k2=ijk=−1i^2 = j^2 = k^2 = ijk = -1i2=j2=k2=ijk=−1。在机器人学中,我们使用单位四元数(模长为1)来表示旋转。
2. 几何意义:轴角表示
任意一个三维旋转都可以理解为绕某个单位轴(x,y,z)(x, y, z)(x,y,z)旋转θ\thetaθ角度。四元数完美封装了这两者:
- w=cos(θ/2)w = \cos(\theta/2)w=cos(θ/2)
- (x,y,z)=sin(θ/2)⋅旋转轴(x, y, z) = \sin(\theta/2) \cdot \text{旋转轴}(x,y,z)=sin(θ/2)⋅旋转轴
为什么是θ/2\theta/2θ/2?因为四元数旋转通过两次乘法实现:q⋅p⋅q−1q \cdot p \cdot q^{-1}q⋅p⋅q−1,一次乘法贡献一半旋转,两次刚好完成θ\thetaθ旋转。
3. 四元数如何解决万向锁?
四元数直接在一个四维超球面上描述旋转,不存在“依次旋转的三个轴”,因此天然没有奇点。无论旋转路径如何,它都能平滑过渡。在示例中,我们将姿态 A 和 B 转换为四元数qAq_AqA和qBq_BqB,完全避开了欧拉角的陷阱。
五、 Slerp 与 Lerp 插值:平滑旋转的保证
现在我们需要在qAq_AqA和qBq_BqB之间生成中间帧,让机器人手臂平滑运动。
1. Lerp(线性插值)
Lerp 在两点间沿直线插值:v(t)=(1−t)v0+tv1v(t) = (1-t)v_0 + t v_1v(t)=(1−t)v0+tv1。
- 问题1:角速度不均匀。直线切割单位球面,导致在起点和终点附近角速度慢,中间快。手臂动作会“一顿一顿”。
- 问题2:向量缩水。插值结果模长小于1,需要额外归一化(Nlerp),且当qAq_AqA与qBq_BqB夹角接近180∘180^\circ180∘时,中间向量趋近零,数值不稳定。
2. Slerp(球面线性插值)
Slerp 在单位球面上沿**最短圆弧(大圆)**插值:
Slerp(q0,q1,t)=sin((1−t)Ω)sinΩq0+sin(tΩ)sinΩq1 \text{Slerp}(q_0, q_1, t) = \frac{\sin((1-t)\Omega)}{\sin\Omega} q_0 + \frac{\sin(t\Omega)}{\sin\Omega} q_1Slerp(q0,q1,t)=sinΩsin((1−t)Ω)q0+sinΩsin(tΩ)q1
其中Ω=arccos(q0⋅q1)\Omega = \arccos(q_0 \cdot q_1)Ω=arccos(q0⋅q1)是两四元数的夹角。
Slerp 的优势:
- 恒定角速度:参数ttt线性对应旋转角度,运动丝滑。
- 天然单位长度:结果始终在球面上,无需归一化。
- 数值稳定:只要q0q_0q0和q1q_1q1不互为反向,公式始终有效。
在示例中,使用 Slerp 能让机器人手臂以恒定速度从 A 旋转到 B,完美完成发球动作。
importnumpyasnp# 1. 欧拉角转四元数(示例:ZYX顺序)defeuler_to_quat(yaw,pitch,roll):cy=np.cos(yaw*0.5)sy=np.sin(yaw*0.5)cp=np.cos(pitch*0.5)sp=np.sin(pitch*0.5)cr=np.cos(roll*0.5)sr=np.sin(roll*0.5)w=cr*cp*cy+sr*sp*sy x=cr*sp*sy-sr*cp*cy y=cr*sp*cy+sr*cp*sy z=sr*sp*cy-cr*cp*syreturnnp.array([w,x,y,z])# 2. 定义姿态q_A=euler_to_quat(0,0,0)# 初始姿态q_B=euler_to_quat(np.pi/4,np.pi/2,np.pi/4)# 目标姿态(含90°俯仰)# 3. Slerp 插值defslerp(q0,q1,t):dot=np.dot(q0,q1)ifdot<0:# 走最短路径q1=-q1 dot=-dot dot=np.clip(dot,-1,1)Omega=np.arccos(dot)ifOmega<1e-6:return(1-t)*q0+t*q1 sin_Omega=np.sin(Omega)return(np.sin((1-t)*Omega)/sin_Omega)*q0+(np.sin(t*Omega)/sin_Omega)*q1# 4. 生成平滑轨迹trajectory=[]fortinnp.linspace(0,1,30):q_interp=slerp(q_A,q_B,t)trajectory.append(q_interp)七、 原理解析
Q1: 欧拉角为什么需要约定旋转顺序?
A:三维空间中的旋转是不可交换的。先绕X轴转30°再绕Y轴转30°,与先绕Y轴转30°再绕X轴转30°,最终姿态完全不同。因此必须严格约定顺序(如ZYX),否则同一个(α,β,γ)(α, β, γ)(α,β,γ)会对应无数种姿态。
Q2: 万向锁是机械结构的故障吗?
A:不是。它是欧拉角数学表示的固有缺陷。当中间轴旋转到90°时,第一轴和第三轴的旋转轴在数学上重合,导致自由度丢失。即使是最完美的机械陀螺仪,只要使用欧拉角描述,就会遇到这个问题。
Q3: 四元数旋转为什么要用θ/2\theta/2θ/2?
A:四元数旋转操作是q⋅p⋅q−1q \cdot p \cdot q^{-1}q⋅p⋅q−1,这是一个共轭乘法。代数上可以证明,这种双重乘法会将旋转角度加倍。因此,为了最终得到θ\thetaθ的旋转,四元数本身必须存储θ/2\theta/2θ/2。
Q4: 为什么 Slerp 能保证恒定角速度?
A:Slerp 的公式是从球面几何推导出来的。它使得插值参数ttt与球面上的弧长成严格正比,而弧长对应旋转角度。因此,匀速变化的ttt直接对应匀速旋转,角速度自然恒定。
Q5: 在什么情况下可以用 Lerp 代替 Slerp?
A:当两个四元数夹角非常小(如小于 5°)时,直线(弦)和圆弧(大圆)几乎重合,此时 Lerp 归一化(Nlerp)的计算量远小于 Slerp,且视觉上难以区分。但在大角度或高精度机器人控制中,必须使用 Slerp。
八、 总结
通过机器人肩关节旋转的示例,我们串联了四个核心概念:
- 欧拉角:直观但存在万向锁隐患。
- 万向锁:欧拉角在中间轴90°时的自由度丢失,是数学奇异性。
- 四元数:用四维向量无奇点地表示旋转,彻底避开万向锁。
- Slerp/Lerp:Slerp 在单位球面上沿圆弧插值,保证恒定角速度;Lerp 走直线,仅适用于小角度。
理解这些概念及其内在联系,是掌握三维旋转处理、动作捕捉与机器人轨迹规划的关键。