4、S型速度规划(S-Curve):7段式S曲线原理,加加速度约束下的时间计算,对称与非对称S曲线

各位做运动控制的同行,今天我们来聊聊S型速度规划。说实话,梯形速度规划虽然简单,但在实际设备上跑起来,那个加速度突变带来的冲击感,真的让人头疼。我最早做数控系统时,就吃过这个亏——电机一启动,整个机架都在抖。

S型曲线,说白了就是给加速度也加了个“软启动”。它把梯形曲线的加速度突变,变成了连续变化的加加速度(Jerk)。这样一来,运动就丝滑多了。

4.1 7段式S曲线的基本原理

标准的S型速度规划,由7个阶段组成。我习惯叫它“7段式”。你想想看,一个完整的运动过程,就像开车一样:

  • 加加速段(T1):加速度从0开始线性增加,速度曲线呈抛物线上升。
  • 匀加速段(T2):加速度达到最大值并保持,速度线性上升。
  • 减加速段(T3):加速度线性减小到0,速度曲线再次呈抛物线,但曲率相反。
  • 匀速段(T4):加速度为0,速度保持最大值。
  • 加减速段(T5):加速度反向线性增加(负方向),速度开始下降。
  • 匀减速段(T6):负加速度保持最大值,速度线性下降。
  • 减减速段(T7):负加速度线性减小到0,速度平滑归零。

嗯,这里要注意:T1、T3、T5、T7这四个阶段,本质上都是加加速度在起作用。它们决定了运动的“柔顺度”。

核心公式:

加加速度 J = dA/dt (加速度的变化率)

在T1段:A(t) = J·t,V(t) = V₀ + ½·J·t²

在T2段:A(t) = A_max,V(t) = V₁ + A_max·t

7段式S曲线速度规划示意图 T1 T2 T3 T4 T5 T6 T7 加速度 加加速度 速度/加速度 时间 T1加加速 → T2匀加速 → T3减加速 → T4匀速 → T5加减速 → T6匀减速 → T7减减速

4.2 加加速度约束下的时间计算

做S曲线规划,最核心的问题就是:给定最大速度V_max、最大加速度A_max、最大加加速度J_max,怎么算出每个阶段的时间?

我在项目中遇到过好几次,有人直接把梯形规划的时间套到S曲线上,结果加速度还没达到最大值就开始减速了,整个曲线变形严重。说白了,S曲线的时间计算,必须考虑加加速度的约束。

4.2.1 对称S曲线的时间计算

对称S曲线,就是加速段和减速段完全镜像。这种情况下,T1=T3=T5=T7,T2=T6。计算步骤如下:

  1. 先算加加速段时间:T1 = A_max / J_max
  2. 再算匀加速段时间:T2 = (V_max - A_max·T1) / A_max
  3. 判断是否达到最大速度:如果T2 < 0,说明速度还没达到V_max就要开始减速了。

我的经验:实际调试时,我一般先设J_max为A_max的5~10倍。这样既能保证平滑,又不会让加加速段太长导致总时间增加太多。如果设备刚性好,可以适当提高J_max。

4.2.2 非对称S曲线的时间计算

非对称S曲线,说白了就是加速和减速的参数不一样。比如,空载加速时可以快一点,重载减速时要慢一点。这种情况在实际产线上非常常见。

我记得有一次调试一个龙门架,负载变化很大。如果强制用对称S曲线,要么加速太慢影响效率,要么减速太快导致过冲。后来改成非对称,问题就解决了。

非对称S曲线的计算,需要分别处理加速段和减速段:

参数 加速段 减速段
最大加速度 A_max_acc A_max_dec
最大加加速度 J_max_acc J_max_dec
加加速段时间 T1 = A_max_acc / J_max_acc T5 = A_max_dec / J_max_dec
匀加速段时间 T2 = (V_max - A_max_acc·T1) / A_max_acc T6 = (V_max - A_max_dec·T5) / A_max_dec

注意:非对称S曲线中,加速段和减速段的总位移可能不相等。规划时必须根据实际位移重新调整匀速段时间T4,否则终点位置会偏。

4.3 代码实现:7段式S曲线时间计算

下面是我常用的一个C++实现片段。嗯,这里只展示核心逻辑,实际工程中还要加边界检查和异常处理。

// 对称S曲线时间计算
struct SCurveTime {
    double T1, T2, T3, T4, T5, T6, T7;
};

SCurveTime CalcSymmetricSCurve(double Vmax, double Amax, double Jmax, double S) {
    SCurveTime t = {0};
    
    // 1. 计算加加速段时间
    t.T1 = Amax / Jmax;
    t.T3 = t.T1;
    t.T5 = t.T1;
    t.T7 = t.T1;
    
    // 2. 计算加加速段和减加速段的速度增量
    double Vj = Amax * t.T1;  // 加加速段结束时的速度增量
    
    // 3. 计算匀加速段时间
    if (Vmax > 2 * Vj) {
        t.T2 = (Vmax - 2 * Vj) / Amax;
        t.T6 = t.T2;
    } else {
        // 速度不够,没有匀加速段
        t.T2 = 0;
        t.T6 = 0;
        // 重新计算实际能达到的最大速度
        Vmax = 2 * Vj;
    }
    
    // 4. 计算加速段总位移
    double S_acc = Vj * (t.T1 + t.T2 + t.T3);
    
    // 5. 计算匀速段时间
    if (S > 2 * S_acc) {
        t.T4 = (S - 2 * S_acc) / Vmax;
    } else {
        // 位移不够,没有匀速段
        t.T4 = 0;
        // 需要重新规划,这里省略
    }
    
    return t;
}

4.4 对称与非对称S曲线的选择策略

你可能会问:什么时候用对称,什么时候用非对称?我个人的经验是这样的:

  • 对称S曲线:适用于负载恒定、正反向特性一致的场合。比如小型桌面机器人、3D打印机。优点是计算简单,调试方便。
  • 非对称S曲线:适用于负载变化大、正反向特性不同的场合。比如大型机床、起重设备。优点是能充分利用电机能力,提高效率。

避坑指南:我曾经在一个项目中,为了省事直接用了对称S曲线。结果设备在重载减速时,电机电流过大,触发了过流保护。后来改成非对称,把减速段的加速度和加加速度都调低了一半,问题就解决了。所以,千万别小看非对称的作用。

4.5 实际调试中的注意事项

最后,分享几个我在现场调试中总结的经验:

  1. 加加速度不是越大越好:J_max太大,S曲线就退化成梯形曲线,失去了平滑的意义。J_max太小,运动时间会显著增加。
  2. 注意整数倍关系:有些控制器的插补周期是固定的。如果计算出的T1不是插补周期的整数倍,实际效果会打折扣。我一般会做一次取整处理。
  3. 预留安全余量:理论计算的最大加速度和加加速度,实际使用时建议打8折。电机和机械系统的响应总有延迟。