14、速度规划:T型速度规划、S型速度规划、时间最优速度规划

各位做运动控制的同行,今天我们来聊聊速度规划。说实话,这是轨迹规划里最基础也最容易被忽视的一环。我见过不少项目,算法选型没问题,电机选型也没问题,最后就栽在速度规划上——要么冲击太大把机械搞坏了,要么效率太低被客户投诉。

速度规划要解决的核心问题是什么?说白了就是:怎么让电机从A点跑到B点,又快又稳。快,是效率;稳,是寿命。这两者往往要权衡。

14.1 T型速度规划:简单粗暴但有效

T型速度规划,名字很形象——速度曲线像个梯形。先匀加速,再匀速,最后匀减速。这是最基础的速度规划方式,也是我入行时第一个接触的算法。

核心公式:

  • 加速段:v(t) = v₀ + a·t
  • 匀速段:v(t) = v_max
  • 减速段:v(t) = v_max - a·t

它的优点很明显:计算量小,实现简单。我在做早期的点胶机项目时,用的就是T型规划。那时候MCU主频才几十兆赫,算力有限,T型规划刚好够用。

但T型规划的缺点也很致命——加速度突变。在加速开始、加速结束、减速开始、减速结束这四个时刻,加速度从0跳变到a,或者从a跳变到0。这种突变会产生冲击力,也就是我们常说的"急动度"(Jerk)。

我曾经踩过的坑:

有一次做高速贴片机项目,用了T型规划。结果运行一段时间后,发现机械臂的关节处出现了裂纹。排查了很久,最后发现是加速度突变导致的冲击疲劳。从那以后,我对T型规划的使用就谨慎多了——如果负载大或者对机械寿命有要求,慎用T型

14.2 S型速度规划:平滑但计算量大

S型速度规划,说白了就是给T型规划加了个"圆角"。它把加速度的变化也做了平滑处理,让加速度从0逐渐增加到a,再逐渐减小到0。这样急动度就是有限的,不会产生冲击。

S型规划通常分为7段:加加速、匀加速、减加速、匀速、加减速、匀减速、减减速。你想想看,比T型多了整整4段,计算量自然上去了。

关键参数:

  • 最大速度 v_max
  • 最大加速度 a_max
  • 最大急动度 j_max

我个人习惯用急动度j_max作为约束条件。为什么?因为急动度直接决定了机械振动的程度。j_max越小,运动越平滑,但时间也越长。

这里有个经验值:对于一般的工业机器人,j_max取a_max的5~10倍比较合适。比如a_max=2m/s²,那j_max就设10~20m/s³。当然,具体要看机械刚性和负载情况。

我的调试技巧:

在实际项目中,我通常先设一个较大的j_max,让曲线接近T型,然后逐步减小j_max,直到机械振动在可接受范围内。这样既能保证效率,又能保证平滑度。

14.3 时间最优速度规划:极限拉扯的艺术

时间最优速度规划,目标很明确——在满足所有约束的前提下,用最短的时间走完轨迹。这听起来很美好,但实现起来相当复杂。

为什么复杂?因为约束条件太多了:

约束类型 具体内容
运动学约束 速度上限、加速度上限、急动度上限
动力学约束 电机力矩上限、关节力矩上限
几何约束 轨迹曲率、路径连续性

时间最优规划的核心思想是:在约束边界上跑。能加速就加速,能减速就减速,始终贴着约束边界走。这就像赛车手过弯——入弯前全力刹车,弯心处贴着极限,出弯后全力加速。

我记得在做一个六轴机器人项目时,客户要求节拍时间缩短20%。T型规划做不到,S型规划也差一点。最后用了时间最优规划,把每个关节的力矩约束都考虑进去,硬是把时间压下来了。但代价是什么?调试周期长了三倍,而且对电机和减速器的要求更高了。

注意:

时间最优规划不是万能的。它会让电机始终工作在极限状态,发热和磨损都会加剧。我建议只在节拍要求极高、且机械和电气裕量充足的情况下使用。

14.4 三种规划的对比与选型

说了这么多,到底该用哪种?我整理了一个对比表,方便大家选型:

规划类型 平滑度 计算量 时间效率 适用场景
T型 低(有冲击) 低负载、低精度、低成本
S型 高(平滑) 通用工业机器人、数控机床
时间最优 中(取决于约束) 高速高节拍、特殊定制

我个人建议:80%的场景用S型就够了。T型只用在非常简单的场合,比如传送带启停。时间最优嘛,除非你真的很懂动力学,否则别轻易碰——我曾经见过一个团队,时间最优规划没调好,结果电机直接过载烧了。

14.5 代码示例:T型速度规划实现

最后,给一个T型规划的简单实现。虽然简单,但麻雀虽小五脏俱全:

// T型速度规划参数
typedef struct {
    float v0;      // 初速度
    float v_max;   // 最大速度
    float a;       // 加速度
    float total_dist; // 总位移
} TProfileParam;

// 计算T型规划各段时间
void TProfileCalc(TProfileParam *param, float *t_acc, float *t_const, float *t_dec) {
    float v0 = param->v0;
    float v_max = param->v_max;
    float a = param->a;
    float dist = param->total_dist;
    
    // 加速段距离
    float d_acc = (v_max*v_max - v0*v0) / (2*a);
    // 减速段距离(假设减速到0)
    float d_dec = v_max*v_max / (2*a);
    
    if (d_acc + d_dec >= dist) {
        // 没有匀速段,三角形规划
        // 实际处理需要解方程,这里简化
        *t_const = 0;
    } else {
        *t_acc = (v_max - v0) / a;
        *t_const = (dist - d_acc - d_dec) / v_max;
        *t_dec = v_max / a;
    }
}

嗯,代码很简单,但实际项目中要考虑的细节很多。比如加减速不对称、初速度不为零、中途速度限制变化等等。这些我们后面的章节会逐步展开。

好了,这一章就到这里。下一章我们聊聊插补技术——怎么把规划好的速度曲线,变成电机能执行的脉冲或位置指令。那又是另一个有意思的话题了。