3、S型速度曲线:七段式结构详解、加加速度约束、时间最优求解思路
S型速度曲线,说白了就是让速度变化本身也变得平滑。T型曲线那种“急加速-匀速-急减速”的玩法,在高速高精设备上很容易把机械结构震散架。我最早做半导体固晶机的时候,用T型曲线跑300mm/s,结果焊头末端抖动直接超了规格书三倍……后来换成S型,问题一下就解决了。
这一节我们重点拆解S型曲线的七段结构,聊聊加加速度(Jerk)这个关键约束,再给出时间最优的求解思路。嗯,内容有点干,但都是实战里必须啃下来的硬骨头。
3.1 七段式结构详解
标准的S型速度曲线,由七个阶段组成。为什么是七段?因为要让速度从零开始,平滑加速到目标值,再平滑减速到零,中间还要有一段匀速。每一段的加速度变化率(也就是Jerk)都是常数。
这七段分别是:
- 加加速段(T1):加速度从零开始线性增加,Jerk为正常数。
- 匀加速段(T2):加速度保持最大值,Jerk为零。
- 减加速段(T3):加速度线性减小到零,Jerk为负常数。
- 匀速段(T4):速度保持最大值,加速度和Jerk都为零。
- 加减速段(T5):加速度从零开始反向线性增加(即减速),Jerk为负常数。
- 匀减速段(T6):加速度保持反向最大值,Jerk为零。
- 减减速段(T7):加速度线性减小到零,Jerk为正常数。
你看,T1到T3是对称的加速过程,T5到T7是对称的减速过程。T4是中间的匀速巡航。如果位移不够大,T4可能会消失,甚至T2和T6也可能消失——这就是所谓的“非完整七段式”。
核心要点:七段式S型曲线的本质,是用三段线性变化的加速度来拼出一个平滑的速度轮廓。每一段的Jerk符号决定了加速度是“变快”还是“变慢”。
我个人习惯把七段的时间分配记成:加速三兄弟 + 匀速老四 + 减速三兄弟。这样好记,写代码时也容易对应数组索引。
3.2 加加速度(Jerk)约束
Jerk,也就是加加速度,单位是 m/s³。它描述的是加速度的变化率。为什么要有Jerk约束?
你想想看,如果加速度从0瞬间跳到最大值(T型曲线),那相当于给电机一个阶跃的力矩指令。电机响应再快,机械结构也会因为惯性产生冲击。Jerk约束就是限制这个冲击的剧烈程度。
在实际项目中,Jerk的取值通常受两个因素限制:
- 机械结构刚度:刚性越差,Jerk上限越低。我做过一个龙门架项目,Jerk设到5000 mm/s³,结果横梁末端抖得像面条……后来降到800才稳定。
- 电机力矩响应带宽:伺服驱动器的电流环带宽决定了它能多快跟踪力矩变化。Jerk太大,力矩指令变化太快,电流环跟不上,实际加速度就会失真。
| 应用场景 | 典型Jerk范围 (mm/s³) | 说明 |
|---|---|---|
| 高精度点胶机 | 200 - 800 | 对末端抖动极其敏感 |
| 通用工业机器人 | 1000 - 3000 | 兼顾效率与平稳性 |
| 高速拾放设备 | 3000 - 8000 | 追求节拍,牺牲部分平滑 |
| 重型机床 | 100 - 500 | 大惯量,Jerk必须保守 |
避坑指南:我曾经在一个项目中,把Jerk设得和加速度一样大,以为这样能跑得更快。结果电机在换向时剧烈震动,编码器读数直接跳变。后来才明白,Jerk和加速度是不同量纲的物理量,不能简单类比。Jerk的物理意义是“加速度的变化速度”,不是“加速度的倍数”。
3.3 时间最优求解思路
给定起点速度、终点速度、最大速度、最大加速度、最大Jerk,以及总位移,我们要找到一组七段时间(T1~T7),使得总时间最短,同时所有约束都满足。
这个问题本质上是一个带约束的非线性优化问题。但在工程实践中,我们通常用解析法来求解,而不是跑迭代优化——因为实时性要求摆在那里。
我的求解思路分三步走:
- 先假设七段完整:按最大Jerk加速到最大加速度,再按最大加速度加速到最大速度,然后匀速,最后对称减速。算出理论最短时间。
- 检查位移是否足够:如果理论位移大于实际位移,说明匀速段(T4)需要缩短甚至消失。如果位移还不够,匀加速段(T2、T6)也要缩短。
- 逐级降阶处理:当位移不足以支持完整七段时,依次退化为“六段式(无匀速)”、“四段式(无匀速且无匀加速)”,甚至退化为“三角型S曲线”。
下面是一个简化的求解流程伪代码:
// 输入:s(位移), v0(初速), v1(终速), vmax(最大速度), amax(最大加速度), jmax(最大Jerk)
// 输出:T1~T7
// 第一步:计算理论加速到vmax所需时间
T_acc = vmax / amax; // 如果只用匀加速
// 但S型需要先加Jerk,所以实际加速时间更长
// 第二步:按最大Jerk计算加速段参数
T1 = amax / jmax;
T2 = (vmax - v0) / amax - T1;
// 如果T2 < 0,说明无法达到amax,需要降阶
// 第三步:计算加速段位移
s_acc = 0.5 * jmax * T1^3 + 0.5 * amax * T2^2 + ... // 完整公式略
// 第四步:判断是否需要匀速段
if (s > 2 * s_acc) {
// 有匀速段
T4 = (s - 2 * s_acc) / vmax;
} else {
// 无匀速段,重新计算
// 进入降阶处理
}
实战技巧:我在写S型曲线规划器时,会把七段时间存成一个数组 double T[7],然后写一个 int calcProfileType() 函数,返回当前是“完整七段”、“六段”、“四段”还是“三角型”。这样主逻辑清晰,调试时也容易定位问题。
时间最优求解的难点在于:约束之间会互相打架。比如你为了缩短时间想提高Jerk,但机械结构受不了;你想提高加速度,但电机力矩不够。所以实际工程中,时间最优往往是在“硬件极限”和“工艺要求”之间取一个折中。
下面这张图展示了七段式S型曲线的完整结构,以及各段之间的衔接关系:
从图上可以清楚看到,T1和T3对称,T5和T7对称。这种对称性不是巧合——它保证了加速过程和减速过程的平滑度一致。如果不对称,速度曲线在峰值处会出现拐点,反而引入新的抖动。
最后说一句,时间最优求解在实际代码里,边界条件判断是最容易出bug的地方。我建议你写单元测试时,专门构造“位移极小”、“速度差极大”、“Jerk极低”这些极端case,把降阶逻辑的每一条分支都覆盖到。嗯,这个坑我踩过不止一次。