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;
}
}
嗯,代码很简单,但实际项目中要考虑的细节很多。比如加减速不对称、初速度不为零、中途速度限制变化等等。这些我们后面的章节会逐步展开。
好了,这一章就到这里。下一章我们聊聊插补技术——怎么把规划好的速度曲线,变成电机能执行的脉冲或位置指令。那又是另一个有意思的话题了。