旋转的表示转换与实现

旋转的表示

  • 轴角 Angle/Axis
  • 四元数 Quaternion
  • 旋转矩阵
  • 欧拉角

轴角 Angle/Axis

θ单位是rad

Axis=(x,y,z),Angle=θ

四元数 Quaternion

q=(qw,qx,qy,qz)

在实际使用中,不同库有不同的顺序
在Eigen 中

// Eigen::quaternion 有两种初始化方式,
// 方式1
Eigen::Vector4d q_(x,y,z,w);
Eigen::quaterniond q(q_)// 方式2
Eigen::quaterniond q(w,x,y,z);

在Scipy库中 顺序是 (x,y,z,w),以单位四元数为例

r = R.from_quat([[0, 0, 0, 1]])

在isaacsim 中 顺序是 (w,x,y,z)

旋转矩阵

R=[rxxrxyrxzryxryyryzrzxrzyrzz]

欧拉角

欧拉角有12组旋转顺序,内旋 外旋各六组,我们常用外旋的Z-Y-X 顺序
形成的旋转矩阵表示为

R=X(ϕ)Y(θ)Z(ψ)

https://en.wikipedia.org/wiki/Euler_angles

转换与实现

Axis/Angle -> quaternion

对于以下Axis/Angle

Axis=(x,y,z)Angle=θ

到四元数的转换为

q=[cos(θ2)xsin(θ2)ysin(θ2)zsin(θ2)]

rotate_matrix -> quaternion

qw=rxx+ryy+rzz2qx=rzyryz4qwqy=rxzrzx4qwqy=ryxrxy4qw

# 将旋转矩阵转化为四元数

qw = np.sqrt(1.0+R[0, 0]+R[1, 1]+R[2, 2])/2.0

if(return_order == "wxyz"):
	q = np.array([qw,
	(R[2, 1]-R[1, 2])/(4*qw),
	(R[0, 2]-R[2, 0])/(4*qw),
	(R[1, 0]-R[0, 1])/(4*qw)])
else: # xyzw
	q = np.array([(R[2, 1]-R[1, 2])/(4*qw),
	(R[0, 2]-R[2, 0])/(4*qw),
	(R[1, 0]-R[0, 1])/(4*qw),
	qw])

return q

rotate_matrix -> euler

euler -> rotate_matrix

对于欧拉角(顺序 rpy/xyz)

(roll,pitch,yaw)

其旋转矩阵为

Rx=[1000cos(roll)sin(roll)0sin(roll)cos(roll)]Rx=[cos(pitch)0sin(pitch)010sin(pitch)0cos(pitch)]Rx=[cos(yaw)sin(yaw)0sin(yaw)cos(yaw)0001]R=RxRyRz

R_x = lambda roll : np.array([ [1 ,0 , 0 ],
[0 ,np.cos(roll) ,-np.sin(roll)],
[0 ,np.sin(roll) , np.cos(roll)]])

R_y = lambda pitch : np.array([[np.cos(pitch) , 0, np.sin(pitch)],
[0,1,0],
[-np.sin(pitch),0,np.cos(pitch)]])

R_z = lambda yaw : np.array([[np.cos(yaw) ,-np.sin(yaw), 0],
[np.sin(yaw),np.cos(yaw),0],
[0,0,1]])
if(order == "xyz" or order == "rpy"):
	R = np.dot(np.dot(R_x,R_y),R_z)

R = np.dot(np.dot(R_x,R_y),R_z) 表明了顺序

euler -> rotate_matrix

quaternion -> rotation_matrix

对于 四元数

q=(w,x,y,z)

旋转矩阵为

R=[12(yy+zz)2(xyzw)2(xz+yw)2(xy+zw)12(xx+zz)2(yzxw)2(xzyw)2(yz+xw)12(xx+yy)]

r00 = 1 - 2 * (y * y + z * z)
r01 = 2 * (x * y - z * w)
r02 = 2 * (x * z + y * w)
  
r10 = 2 * (x * y + z * w)
r11 = 1 - 2 * (x * x + z * z)
r12 = 2 * (y * z - x * w)

r20 = 2 * (x * z - y * w)
r21 = 2 * (y * z + x * w)
r22 = 1 - 2 * (x * x + y * y)

# 3x3 rotation matrix
rot_matrix = np.array([[r00, r01, r02],
[r10, r11, r12],
[r20, r21, r22]])

quaternion -> euler

对于 四元数

q0=qw,q1=qx,q2=qy,q3=qz

欧拉角为

 roll =tan1(2(q0q1+q2q3)q02q12q22+q32)=atan2[2(q0q1+q2q3),q02q12q22+q32] pitch =sin1(2(q0q2q1q3))=asin[2(q0q2q1q3)] yaw =tan1(2(q0q3+q1q2)q02+q12q22q32)=atan2[2(q0q3+q1q2),q02+q12q22q32]

运算

四元数乘法

先执行 q0 ,在执行 q1 ,可用乘法表示,实现如下

def quaternion_multiply(quaternion0, quaternion1,quat_order="xyzw"):
	if(quat_order == "wxyz"):
		w0, x0, y0, z0 = quaternion0
		w1, x1, y1, z1 = quaternion1
	else: # xyzw
		x0, y0, z0,w0 = quaternion0
		x1, y1, z1,w1 = quaternion1
	return np.array([-x1 * x0 - y1 * y0 - z1 * z0 + w1 * w0,
	x1 * w0 + y1 * z0 - z1 * y0 + w1 * x0,
	-x1 * z0 + y1 * w0 + z1 * x0 + w1 * y0,
	x1 * y0 - y1 * x0 + z1 * w0 + w1 * z0], dtype=np.float64)# wxyz

四元数等价与旋转矩阵,像矩阵乘法一样,四元数乘法满足结合律((ab)c=a(bc)) 但是不满足交换律 ab!=ba

四元数求逆

q1=q=(q0,q1,q2,q3)

旋转矩阵求逆

旋转矩阵是一个 正交矩阵(orthogonal matrix),因此

RT=R1

参考

posted @   Hyaline-w  阅读(103)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示