3. S形速度曲线(7段式):加加速度(Jerk)的概念。7段式S曲线的数学推导与分段解析。
好,我们直接进入正题。上一章聊了T形曲线,说白了就是加速-匀速-减速三段。但实际用起来,你会发现一个问题——启动和停止那一下,冲击感太强了。为什么?因为加速度在瞬间跳变,从0直接跳到最大值,或者从最大值直接跌回0。这在物理上意味着什么?意味着力在瞬间变化,机械结构会抖,甚至会震。
所以,我们引入了加加速度(Jerk)。
3.1 加加速度(Jerk)到底是什么?
加加速度,英文叫Jerk,是加速度的变化率。数学定义很简单:
Jerk = da/dt
其中a是加速度,t是时间。说白了,Jerk就是加速度的变化快慢。
我刚开始做机器人控制时,觉得这东西是理论派搞出来的花架子。直到有一次,我调一个六轴机械臂的轨迹,T形曲线跑起来,末端执行器在启停时抖得跟筛糠似的。后来一查,加速度跳变太大,Jerk无穷大。嗯,从那以后,我再也不敢忽视Jerk了。
为什么要引入Jerk?因为真实物理世界,力不能突变。电机有响应时间,机械结构有弹性形变。你让加速度瞬间跳变,相当于给系统一个阶跃输入,那必然激起高频振动。
核心观点: S形曲线的本质,就是让加速度连续变化,从而限制Jerk的大小。这样运动更平滑,机械寿命更长。
3.2 7段式S曲线的分段结构
7段式S曲线,顾名思义,由7个阶段组成。我习惯把它分成三大部分:
- 加加速阶段(第1段): 加速度从0开始,以恒定Jerk增加,直到达到最大加速度。
- 匀加速阶段(第2段): 加速度保持最大值不变,速度线性增加。
- 减加速阶段(第3段): 加速度从最大值开始,以恒定Jerk减小,直到降为0。
- 匀速阶段(第4段): 速度保持最大值不变,加速度为0。
- 加减速阶段(第5段): 加速度从0开始,以恒定Jerk反向增加(即减速),直到达到最大减速度。
- 匀减速阶段(第6段): 减速度保持最大值不变,速度线性减小。
- 减减速阶段(第7段): 减速度从最大值开始,以恒定Jerk减小,直到降为0。
你想想看,这7段其实是对称的。前3段是加速过程,中间1段是匀速,后3段是减速过程。如果位移不够大,匀加速段或匀速段可能被省略,变成5段式甚至4段式。但7段式是最完整的形态。
我的经验: 在实际项目中,如果位移足够长,我建议尽量保留7段。因为匀加速段的存在,可以让平均加速度更高,从而缩短运动时间。但如果你对平滑度要求极高,可以去掉匀加速段,变成纯Jerk受限的5段式。
3.3 数学推导:从Jerk到位置
好,我们来推导一下。假设Jerk为常数J,那么加速度、速度、位置都可以通过积分得到。
先看第1段(加加速段):
设时间区间为 [0, t1]
Jerk: j(t) = J_max (常数)
加速度: a(t) = ∫ j(t) dt = J_max * t
速度: v(t) = ∫ a(t) dt = 0.5 * J_max * t² + v0
位置: s(t) = ∫ v(t) dt = (1/6) * J_max * t³ + v0 * t + s0
其中v0是初始速度,s0是初始位置。通常我们假设v0=0,s0=0。
第2段(匀加速段):
设时间区间为 [t1, t2]
Jerk: j(t) = 0
加速度: a(t) = a_max (常数)
速度: v(t) = a_max * t + v1
位置: s(t) = 0.5 * a_max * t² + v1 * t + s1
这里v1和s1是第1段结束时的速度和位置。
第3段(减加速段):
设时间区间为 [t2, t3]
Jerk: j(t) = -J_max
加速度: a(t) = -J_max * t + a_max
速度: v(t) = -0.5 * J_max * t² + a_max * t + v2
位置: s(t) = -(1/6) * J_max * t³ + 0.5 * a_max * t² + v2 * t + s2
你看,其实每一段都是多项式。第1段是3次多项式,第2段是2次多项式,第3段又是3次多项式。整个S形曲线,位置是分段3次多项式,速度是分段2次多项式,加速度是分段线性函数。
重要结论: 7段式S曲线的位置是C²连续的(即位置、速度、加速度都连续),但Jerk是分段常数,存在跳变。不过这个跳变是可控的,我们通过限制J_max来保证平滑度。
3.4 分段解析:各阶段的边界条件
实际编程时,我们需要知道每个阶段的结束时刻。假设总位移为S,最大速度为V_max,最大加速度为A_max,最大Jerk为J_max。
我习惯先计算理论上的最短时间。如果位移足够大,所有阶段都会出现。各阶段的时间分配如下:
| 阶段 | 时间长度 | 结束时刻 |
|---|---|---|
| 加加速段 | T1 = A_max / J_max | t1 = T1 |
| 匀加速段 | T2 = (V_max / A_max) - T1 | t2 = t1 + T2 |
| 减加速段 | T3 = T1 | t3 = t2 + T3 |
| 匀速段 | T4 = (S - S_acc - S_dec) / V_max | t4 = t3 + T4 |
| 加减速段 | T5 = T1 | t5 = t4 + T5 |
| 匀减速段 | T6 = T2 | t6 = t5 + T6 |
| 减减速段 | T7 = T1 | t7 = t6 + T7 |
其中S_acc是加速阶段的总位移,S_dec是减速阶段的总位移。这两个值可以通过积分算出来。
注意: 如果位移S不够大,匀加速段或匀速段可能不存在。这时候需要重新计算时间分配。我曾经踩过这个坑——直接套用公式,结果算出来的T2是负数。后来我加了一个判断:如果T2 < 0,说明位移不够,需要降低最大速度或最大加速度。
3.5 核心逻辑图
下面我用一张SVG图来展示7段式S曲线的核心逻辑。这张图展示了Jerk、加速度、速度、位置四者的关系。
3.6 实际编程中的注意事项
最后,我分享几个实际编程中的坑:
- 时间同步问题: 每个阶段的时间必须是离散化后的整数倍(比如1ms一个插补周期)。我习惯先算理论时间,然后向上取整到插补周期的整数倍。
- 边界条件检查: 如果位移S太小,可能连加加速段都走不完。这时候需要降低J_max或A_max。我曾经遇到过位移只有1mm,结果算出来的加加速段时间比总时间还长,直接报错。
- 数值稳定性: 多项式计算时,注意浮点数精度。特别是当t很小时,t³可能非常小,容易产生截断误差。我建议用double类型,并且尽量用递推公式而不是直接代入多项式。
- 对称性利用: 前3段和后3段是对称的,只是符号相反。编程时可以用同一个函数,传入不同的参数(正负Jerk、正负加速度)来复用代码。
一个小技巧: 如果你不想手动推导所有公式,可以用符号计算工具(比如SymPy)先推导一遍,然后直接把结果抄到代码里。我当年就是这么干的,省了不少时间。
好了,关于7段式S曲线的数学推导和分段解析,就讲到这里。下一节我们会聊如何根据实际约束(最大速度、最大加速度、最大Jerk)来规划完整的S形轨迹。