4、时间参数计算:已知最大速度、最大加速度、最大加加速度,计算各段时间

好,咱们接着聊。前面几章我们把S曲线的“骨架”——加加速度、加速度、速度、位移——都讲清楚了。现在到了真正动手算的时候了。

这一章的核心问题很简单:已知最大速度 Vmax、最大加速度 Amax、最大加加速度 Jmax,怎么把每一段的时间算出来?

我个人习惯把这个问题拆成两步走:
第一步,判断这个S曲线是“完整”的还是“被截断”的。
第二步,根据判断结果,套用不同的公式。

为什么要先判断?你想想看,如果距离太短,速度还没冲到Vmax就得开始减速了,那加速段和减速段的时间就不是完整的。我在项目中遇到过好几次,新手上来就按完整S曲线算,结果电机还没跑到一半就开始抖,就是因为时间算错了。

核心结论:时间参数计算的关键在于判断“能否达到最大速度”。能,就用完整7段;不能,就用5段甚至3段。

4.1 先判断:能不能跑到Vmax?

判断条件其实就一个:加速到Vmax需要的位移,是否小于总位移的一半?

加速段从0加速到Vmax,需要经过:
加加速段(T1)、匀加速段(T2)、减加速段(T3)。

这三段的总位移,我习惯叫它 S_acc。如果 2 * S_acc <= 总位移 S_total,那就能跑到Vmax。否则,就只能在半路开始减速。

嗯,这里要注意:减速段和加速段是对称的,所以减速段需要的位移也是 S_acc。总位移减去两头的加速和减速,剩下的就是匀速段。

4.2 能跑到Vmax:完整7段时间计算

如果能跑到Vmax,那时间参数就很好算了。我直接给公式,你拿去用就行。

段名 时间公式 说明
T1(加加速) T1 = Amax / Jmax 加速度从0线性增加到Amax
T2(匀加速) T2 = (Vmax / Amax) - (Amax / Jmax) 如果Vmax不够大,T2可能为0
T3(减加速) T3 = T1 对称段,时间相等
T4(匀速) T4 = (S_total - 2 * S_acc) / Vmax S_acc是加速段总位移
T5(加减速) T5 = T1 对称
T6(匀减速) T6 = T2 对称
T7(减减速) T7 = T1 对称

这里有个细节:T2 可能为0。什么意思?就是Vmax不够大,加速度还没到Amax就开始减速了。这种情况其实很常见,比如短距离点动。我曾经调试一个贴片机,发现T2算出来是负数,当时还以为是代码写错了,后来才意识到是Vmax设得太低。

我的经验:如果T2算出来小于0,直接把它置为0。然后重新计算实际能达到的最大速度,那个速度肯定小于你设定的Vmax。

4.3 跑不到Vmax:5段时间计算

如果跑不到Vmax,那匀加速段(T2)和匀减速段(T6)就消失了。整个曲线变成5段:T1、T3、T4、T5、T7。注意,这里的T4不再是匀速,而是“最高速度保持段”,但这个最高速度 V_peak 小于Vmax。

计算步骤稍微绕一点:

  1. 先假设没有匀速段,即T4=0。整个运动只有加速和减速。
  2. 加速段和减速段各占一半位移:S_acc = S_total / 2
  3. 根据S_acc反推实际能达到的峰值速度 V_peak

公式推导我就不展开了,直接给结果:

// 已知 S_total, Amax, Jmax
// 计算峰值速度 V_peak

// 先算一个中间量
double temp = Amax * Amax / Jmax;

if (S_total <= temp) {
    // 三角形速度曲线(连Amax都达不到)
    V_peak = pow(S_total * Jmax * Jmax / 2.0, 1.0/3.0);
    T1 = sqrt(2 * S_total / Jmax);
    T3 = T1;
    T4 = 0;
} else {
    // 梯形加速度曲线(能达到Amax,但达不到Vmax)
    V_peak = sqrt(Amax * S_total - Amax * Amax * Amax / (3 * Jmax));
    T1 = Amax / Jmax;
    T3 = T1;
    T4 = (S_total - 2 * (Amax * T1 * T1 + 0.5 * Amax * T1 * T1)) / V_peak;
}

注意:上面代码里的 pow(..., 1.0/3.0) 是开立方。有些嵌入式平台不支持浮点开立方,可以用牛顿迭代法近似。我之前在STM32上就踩过这个坑,后来自己写了个快速开立方函数。

4.4 特殊情况:连Amax都达不到

这种情况更极端。距离太短,加速度还没升到Amax就得开始减速了。整个曲线只有3段:加加速、减加速、加减速、减减速——实际上就是两个三角形拼在一起。

判断条件:S_total <= Amax^2 / Jmax

这时候的计算最简单:

T1 = cbrt(S_total / (2 * Jmax));  // 开立方
T3 = T1;
T5 = T1;
T7 = T1;
T2 = T4 = T6 = 0;

峰值加速度 A_peak = Jmax * T1,肯定小于Amax。

4.5 一张图看懂所有情况

下面这张SVG图,把三种情况的关系画清楚了。我建议你把它打印出来贴在工位上。

S曲线时间参数计算决策树 已知: Vmax, Amax, Jmax 2 * S_acc <= S_total ? 情况1: 完整7段 情况2: 5段 (无T2/T6) T2 = Vmax/Amax - Amax/Jmax S_total <= Amax²/Jmax ? T1=T3=T5=T7=Amax/Jmax 情况2a: 3段 (三角形) 情况2b: 5段 (有Amax)

4.6 实际项目中的避坑指南

好了,公式和代码都给你了。但光有这些还不够,我在实际项目中踩过的坑,今天一并告诉你:

  • 浮点精度问题:嵌入式MCU的float精度有限,尤其是开立方运算。我建议所有中间变量用double,最后输出时再截断。
  • 边界条件检查:如果S_total刚好等于某个临界值,比如刚好等于 Amax^2 / Jmax,这时候T2=0,但T1、T3正常。代码里要处理这种“等于”的情况。
  • 时间参数不能为负:任何一段算出来是负数,直接置0。然后重新计算实际能达到的V_peak或A_peak。
  • 单位统一:这个不用我多说了吧?Vmax用mm/s,Amax用mm/s²,Jmax用mm/s³。我曾经见过有人把Vmax写成m/s,Amax用mm/s²,结果差了1000倍。

一个小技巧:写完时间参数计算后,用这些时间反算一遍位移,看是否等于S_total。误差在1e-6以内就算通过。这是我最常用的自检方法。

好了,这一章的内容就到这里。时间参数计算是S曲线规划里最“数学”的部分,但只要你把决策树理清楚,剩下的就是套公式。下一章我们会讲怎么把这些时间参数转换成实际的位置指令,也就是“插补”环节。


公众号:蓝海资料掘金营,微信deep3321