3. S形曲线数学建模:加加速度Jerk的定义、四阶积分关系与边界条件约束
各位同学,欢迎来到第三章。前两章我们聊了为什么启停会抖,以及T形曲线为什么不够用。这一章,我们正式进入S形曲线的数学核心——加加速度Jerk。
说实话,我刚入行那会儿,看到“加加速度”这个词,第一反应是:这玩意儿是来搞笑的吧?加速度还不够,还要加加速度?后来在调试一台高速贴片机时,被那个启停瞬间的振动折磨得够呛,才真正明白——Jerk才是平滑的灵魂。
3.1 加加速度Jerk的定义
先给个严谨定义。Jerk,符号 j 或 J,是加速度对时间的变化率。数学表达式很简单:
j(t) = da(t) / dt
单位是 m/s³。嗯,你没看错,是米每三次方秒。
物理意义呢?说白了,就是加速度变化的快慢。你想想看:
- Jerk = 0:加速度不变,那就是T形曲线,加/减速段是恒定的。
- Jerk > 0:加速度在增大,运动正在“更猛烈”地加速。
- Jerk < 0:加速度在减小,运动正在“收敛”。
核心认知:启停抖动的根源,不是加速度太大,而是加速度的突变——也就是Jerk无穷大。S形曲线做的,就是把Jerk从无穷大拉回到一个有限值。
我在项目中遇到过一位同事,他坚持用T形曲线跑一台龙门架,结果每次启停,整个机架都在晃。我让他把Jerk曲线画出来一看——加速度跳变处,Jerk直接是脉冲。后来换成S形,Jerk限制在500 mm/s³,世界安静了。
3.2 位移/速度/加速度/加加速度的四阶积分关系
这是S形曲线的数学骨架。四个物理量,从Jerk到位移,是三次积分的关系。反过来,从位移到Jerk,是三次微分。
我习惯用一张图来理解这个关系:
这张图我建议你存下来。每次写S形曲线代码时,对着它捋一遍,不容易乱。
具体公式如下:
// 从Jerk到位移的积分链
a(t) = a₀ + ∫₀ᵗ j(τ) dτ
v(t) = v₀ + ∫₀ᵗ a(τ) dτ
s(t) = s₀ + ∫₀ᵗ v(τ) dτ
其中 a₀、v₀、s₀ 是初始条件。在大多数启停场景中,起始和结束时的速度、加速度都是0。
我的习惯:在代码里,我不会直接套用连续积分公式。而是把时间离散化,用梯形法或龙格-库塔法做数值积分。尤其是当Jerk分段变化时,解析解反而容易出错。
3.3 边界条件约束
光有积分关系还不够。你得告诉系统:从哪开始,到哪结束,中间不能超限。这就是边界条件约束。
S形曲线常见的边界条件有7个:
| 序号 | 边界条件 | 数学表达 | 物理含义 |
|---|---|---|---|
| 1 | 起始位置 | s(0) = s_start | 起点已知 |
| 2 | 结束位置 | s(T) = s_end | 终点已知 |
| 3 | 起始速度 | v(0) = v_start | 通常为0 |
| 4 | 结束速度 | v(T) = v_end | 通常为0 |
| 5 | 起始加速度 | a(0) = 0 | 无初始冲击 |
| 6 | 结束加速度 | a(T) = 0 | 无结束冲击 |
| 7 | 最大速度约束 | v(t) ≤ v_max | 电机限速 |
除此之外,还有两个不等式约束:
- 最大加速度约束:|a(t)| ≤ a_max,防止电机过载或机构冲击。
- 最大Jerk约束:|j(t)| ≤ j_max,这是S形曲线的灵魂参数。
我曾经踩过的坑:在早期一个项目中,我只约束了速度和加速度,没约束Jerk。结果生成的曲线虽然加速度没超限,但Jerk在切换点处高达 20000 m/s³,电机直接啸叫。后来加了Jerk约束,啸叫声消失了,运动也更平顺。
3.4 典型S形曲线的分段结构
一个完整的S形曲线,通常分为7段:
- 加加速度段:Jerk = +j_max,加速度从0线性增加到a_max。
- 匀加速度段:Jerk = 0,加速度保持a_max。
- 减加速度段:Jerk = -j_max,加速度从a_max线性减小到0。
- 匀速段:Jerk = 0,加速度 = 0,速度保持v_max。
- 加减速度段:Jerk = -j_max,加速度从0线性减小到-a_max。
- 匀减速度段:Jerk = 0,加速度保持-a_max。
- 减减速度段:Jerk = +j_max,加速度从-a_max线性增加到0。
你想想看,这7段是不是刚好对称?嗯,对于对称S形曲线,确实如此。但实际应用中,如果起始/结束速度不为0,或者位移太短,某些段会被压缩甚至消失。
关键判断:当位移足够长时,7段全在;当位移中等时,匀加速段或匀减速段消失;当位移很短时,可能只剩下加加速、减加速、加减速、减减速4段,甚至更少。
3.5 代码实现:S形曲线参数计算
下面我给出一段Python代码,用于计算S形曲线的关键参数。这段代码我用了很多年,基本逻辑没变过。
def s_curve_params(s_total, v_max, a_max, j_max):
"""
计算S形曲线的关键参数
:param s_total: 总位移 (m)
:param v_max: 最大速度 (m/s)
:param a_max: 最大加速度 (m/s²)
:param j_max: 最大加加速度 (m/s³)
:return: 各段时间 (t1~t7)
"""
# 1. 计算理论最短加/减速时间
t_acc = a_max / j_max # 加加速段时间
# 2. 计算匀加速段能达到的速度增量
v_ramp = a_max * t_acc # 加/减速段速度变化量
# 3. 判断是否能达到最大速度
if v_max <= v_ramp:
# 达不到最大速度,三角形速度曲线
# 实际能达到的最大速度
v_actual = (a_max**2) / j_max
# 加/减速段时间
t1 = t3 = t5 = t7 = (a_max / j_max)
t2 = t4 = t6 = 0
# 总时间
t_total = 4 * t1 + 2 * t2 + t4
return t1, t2, t3, t4, t5, t6, t7, v_actual
else:
# 能达到最大速度
t1 = t3 = t5 = t7 = a_max / j_max
# 匀加速段时间
t2 = (v_max - v_ramp) / a_max
# 匀速段时间
t4 = (s_total - 2 * (0.5 * (v_max + v_ramp) * (2*t1 + t2))) / v_max
t6 = t2
return t1, t2, t3, t4, t5, t6, t7, v_max
使用建议:这段代码只处理了对称情况。实际项目中,我通常会加一个判断:如果t4 < 0,说明位移不够,需要重新计算,退化为三角形或更短曲线。这个逻辑在后续章节会详细展开。
3.6 本章小结
这一章我们干了三件事:
- 定义了Jerk,明白了它是加速度的变化率,是平滑启停的关键。
- 建立了Jerk→加速度→速度→位移的四阶积分关系,这是S形曲线的数学骨架。
- 梳理了7个边界条件和2个不等式约束,这是曲线生成的“游戏规则”。