姿态插补算法

前言

姿态空间插值的一个主要问题是姿态空间的三个自由度是相互耦合的,而不像位置空间一样三个自由度完全解耦正交。所以,直接对欧拉角三个角度分别插值,可能会出现错误的结果。

姿态空间是一个 SO(3)群。当确定姿态空间的空间属性,我们就可以通过数学方法来定义它的空间插值。

Serp 插值可以认为是最短路径插值,类似于位置空间的直线插值。但直线(Slerp)插值只能保证一阶连续,过渡点处的角速度方向会发生突变。

Lerp插值

线性插值(Lerp/Linear Interpolation),即沿着一条直线(也就是圆上的一个弦)进行插值,此种插值方式所得结果并非单位四元数(只有单位四元数才能表示旋转)。
q t   = L e r p ( q 0 , q 1 , t ) = ( 1 − t ) q 0   + t q 1 \mathrm{q_t~=Lerp(q_0,q_1,t)=(1-t)q_0~+tq_1} qt =Lerp(q0,q1,t)=(1t)q0 +tq1
在这里插入图片描述
在这里插入图片描述

Slerp插值

球面线性插值(SphericalLinearInterpolation)对每一对四元数使用Slerp插值,虽然能够保证每两个四元数之间的角速度是固定的,但是角速度会在切换插值的四元数时出现断点,或者说在切换点不可导.
Slerp球面线性插值是对角度本身进行线性插值,适用于插补角度不接近0度的情况。

在这里插入图片描述

Slerp插值公式:
S l e r p ( t ; q 0 , q 1 ) = q 0 sin ⁡ [ ( 1 − t ) θ ] + q 1 sin ⁡ ( t θ ) sin ⁡ θ ( t ∈ [ 0 , 1 ] ) \mathrm{Slerp(t;q_0,q_1)=\frac{q_0\sin\left[(1-t)\theta\right]+q_1\sin(t\theta)}{\sin\theta}\quad(t\in[0,1])} Slerp(t;q0,q1)=sinθq0sin[(1t)θ]+q1sin(tθ)(t[0,1])

对于单位四元数:
q = cos ⁡ ( θ ) + u ^ sin ⁡ ( θ ) \mathrm{q}=\cos(\theta)+\hat{\mathrm{u}}\sin(\theta) q=cos(θ)+u^sin(θ)
其中 u ^ \hat{\mathrm{u}} u^为单位三维矢量, u ^ u ^ = − 1 \hat{\mathrm{u}}\hat{\mathrm{u}}=-1 u^u^=1

对于单位四元数,该公式可写为:
S l e r p ( t ; q 0 , q 1 ) = q 0 ( q 0 − 1 q 1 ) t \mathrm{Slerp(t;q_0,q_1)=q_0(q_0^{-1}q_1)^t} Slerp(t;q0,q1)=q0(q01q1)t

四元数有定理:
e x p ( u ^ θ ) = cos ⁡ ( θ ) + u ^ sin ⁡ ( θ ) q t = ( cos ⁡ ( θ ) + u ^ sin ⁡ ( θ ) ) t = exp ⁡ ( u ^ θ t ) l o g ( q ) = l o g ( cos ⁡ ( θ ) + u ^ sin ⁡ ( θ ) ) = l o g ( exp ⁡ ( u ^ θ ) ) = u ^ θ \begin{array}{c}\mathrm{exp(\hat{u}\theta)=\cos(\theta)+\hat{u}\sin(\theta)}\\\mathrm{q^t=(\cos(\theta)+\hat{u}\sin(\theta))^t=\exp(\hat{u}\theta t)}\\\mathrm{log(q)=log(\cos(\theta)+\hat{u}\sin(\theta))=log(\exp(\hat{u}\theta))=\hat{u}\theta}\end{array} exp(u^θ)=cos(θ)+u^sin(θ)qt=(cos(θ)+u^sin(θ))t=exp(u^θt)log(q)=log(cos(θ)+u^sin(θ))=log(exp(u^θ))=u^θ

根据上述定理,可以推得:
( q 0 − 1 q 1 ) t = exp ⁡ ( u ^ θ t ) = exp ⁡ ( log ⁡ ( q 0 − 1 q 1 ) ∗ t ) \mathrm{(q_0^{-1}q_1)^t=\exp(\hat{u}\theta t)=\exp(\log(q_0^{-1}q_1)*t)} (q01q1)t=exp(u^θt)=exp(log(q01q1)t)

Slerp插值可写为
S l e r p ( t ; q 0 , q 1 ) = q 0   e x p ( l o g ( q 0 − 1 q 1 ) ∗ t ) \mathrm{Slerp(t;q_0,q_1)=q_0~exp(log(q_0^{-1}q_1)*t)} Slerp(t;q0,q1)=q0 exp(log(q01q1)t)
在这里插入图片描述
以下4个Slerp公式相等:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

如果四元数点积的结果是负值(夹角大于90°),那么后面的插值就会在4D球面上绕远路。为了解决这个问题,先测试点积的结果,当结果是负值时,将2个四元数的其中一个取反(并不会改变它代表的朝向)。而经过这一步操作,可以保证这个旋转走的是最短路径。

q 1 q_1 q1 q 2 q_2 q2的夹角θ差非常小时会导致sinθ→0,这时除法可能会出现问题。为了避免这样的问题,当θ非常小时可以使用简单的线性插值代替(当θ → 0时,sinθ ≈ θ,因此方程退化为线性方程:slerp(p, q, t) = (1−t)p + tq

Nlerp正规化线性插值

正规化线性插值(Normalized LinearInterpolation),是对线性插值的改进,即将线性插值除以其模长,将其转化为一个单位四元数。这种插补算法适用于插补角度接近0度的情况。
q t = L e r p ( q 0 , q 1 , t ) = ( 1 − t ) q 0 + t q 1 ∥ ( 1 − t ) q 0 + t q 1 ∥ \mathrm{q_t=Lerp(q_0,q_1,t)=\frac{(1-t)q_0+tq_1}{\|(1-t)q_0+tq_1\|}} qt=Lerp(q0,q1,t)=(1t

  • 17
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一段基于向量运算的空间圆弧插补算法,可以根据给定的圆心、起始点、法向量和圆心角生成空间圆弧插补路径: 1. 首先,需要根据给定的圆心、起始点和法向量计算出圆弧所在的平面。可以使用向量叉积运算得到该平面的法向量,具体地说,可以将起始点与圆心连线向量和法向量进行叉积运算,得到该平面的法向量。 2. 接下来,需要计算圆弧的起始角和终止角。可以使用余弦定理和向量点积运算计算出起始点与圆心之间的夹角,然后根据给定的圆心角计算出终止角。具体地说,可以使用以下公式计算起始角和终止角: cos(theta) = dot(v1, v2) / (|v1| * |v2|) start_angle = acos(cos(theta)) end_angle = start_angle + circle_angle 其中,v1为起始点与圆心向量,v2为终点与圆心向量,theta为起始角,circle_angle为圆心角。 3. 然后,可以将圆弧分成若干个小段,并在每个小段的中心点处进行插补。可以通过在起始点处计算切向量和法向量,然后在每个小段的中心点处使用旋转矩阵计算出下一个插补点的位置和姿态。具体地说,可以使用以下公式计算下一个插补点的位置和姿态: p = R * (q - c) + c 其中,p为下一个插补点的位置,q为当前插补点的位置,c为圆心位置,R为旋转矩阵,可以通过将切向量、法向量和圆心向量组成的矩阵进行正交化得到。 4. 最后,可以将所有插补点连接起来,生成圆弧插补路径。 需要注意的是,在实际应用中,还需要考虑轨迹平滑、速度规划、加减速等因素,以确保加工效果和机床稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

余加木

想喝蜜雪冰城柠檬水(≧≦)/

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值