速度规划配置与轨迹规划联动 - 第2节
梯形速度规划:原理与数学公式
梯形速度规划,说白了就是让电机先匀加速、再匀速、最后匀减速。你想想看,这就像开车——红灯变绿时一脚油门踩到限速,然后匀速巡航,快到路口了再踩刹车。简单、直观、好算,工业现场用得最多的就是它。
我个人习惯把梯形规划叫做“三段式”,因为它的速度曲线就三段:加速段、匀速段、减速段。加速度在每一段里都是常数,所以速度变化是线性的。嗯,这里要注意:加速度突变的地方,就是加加速度(Jerk)无穷大的位置——后面我们会聊怎么处理这个冲击。
数学公式推导
假设我们要从起点 P₀ 运动到终点 P₁,总位移为 S,最大速度为 Vmax,加速度为 A(加速和减速的绝对值相等)。那么三段的时间分别是:
- 加速时间:
t₁ = Vmax / A - 减速时间:
t₃ = Vmax / A(对称情况) - 匀速时间:
t₂ = (S - A·t₁²) / Vmax
总时间就是 T = t₁ + t₂ + t₃。我在项目中遇到过一种情况:位移太短,还没加速到 Vmax 就得开始减速了。这时候就没有匀速段,我们叫它“三角形速度规划”。
关键判断条件:如果 S < Vmax² / A,说明位移不够,跑不到最大速度。此时实际最大速度 Vpeak = √(A·S),加速和减速时间各为 t = Vpeak / A。
位置与速度的实时计算
在每一时刻 t,我们可以分段计算速度和位置:
| 时间段 | 速度 v(t) | 位置 p(t) |
|---|---|---|
| 0 ≤ t < t₁ | A·t | ½·A·t² |
| t₁ ≤ t < t₁+t₂ | Vmax | ½·A·t₁² + Vmax·(t - t₁) |
| t₁+t₂ ≤ t ≤ T | Vmax - A·(t - t₁ - t₂) | ½·A·t₁² + Vmax·t₂ + Vmax·(t - t₁ - t₂) - ½·A·(t - t₁ - t₂)² |
这些公式看着有点多,但写代码时就是几个 if-else 的事。我建议你把它们封装成一个函数,输入时间 t,输出速度和位置——后面做轨迹插补时直接调用就行。
加加速度与冲击限制
梯形规划有个硬伤:加速度在切换点瞬间跳变。你想想看,加速度从 0 直接跳到 A,又从 A 直接跳回 0——这意味着加加速度(Jerk)是无穷大。机械上会怎样?冲击、振动、甚至损坏丝杠或导轨。
我曾经调试一台高速贴片机,梯形规划跑出来的加速度曲线像锯齿一样。机器一启动就“哐”一声,导轨上的工件都跟着抖。后来加了 Jerk 限制,改成 S 形速度规划,问题才解决。
加加速度的定义
加加速度就是加速度的变化率:
Jerk = dA / dt
单位是 m/s³ 或 mm/s³。梯形规划的 Jerk 在切换点理论上无穷大,实际中受限于控制周期和机械响应,会表现为一个很陡的斜坡——但依然会造成冲击。
注意:如果你在梯形规划里直接限制 Jerk,那就变成了 S 形规划。梯形规划本身不处理 Jerk,所以如果你的设备对冲击敏感(比如精密加工、晶圆搬运),建议直接上 S 形或更高阶规划。
什么时候可以忽略 Jerk?
也不是所有场合都需要限制 Jerk。我列几个典型场景:
- 可以忽略:传送带启停、低速搬运、大惯量负载(冲击被惯性吸收)
- 必须考虑:高速高精度定位、轻载易振动结构、末端有易碎物品
- 折中方案:在梯形规划的切换点插入一小段圆弧过渡,近似限制 Jerk
代码实现与参数配置
下面给出一段 C 风格的梯形规划实现。我习惯把参数放在结构体里,方便配置和调试。
typedef struct {
float pos_start; // 起始位置
float pos_end; // 终点位置
float vel_max; // 最大速度
float acc; // 加速度(绝对值)
float dec; // 减速度(绝对值,可与加速度不同)
float t_acc; // 加速时间(计算输出)
float t_dec; // 减速时间(计算输出)
float t_const; // 匀速时间(计算输出)
float t_total; // 总时间(计算输出)
float vel_peak; // 实际达到的最大速度(计算输出)
} TrapezoidProfile;
void TrapezoidProfile_Calc(TrapezoidProfile *p) {
float S = p->pos_end - p->pos_start;
float v_max_allowed = p->vel_max;
float a = p->acc;
float d = p->dec;
// 计算理论加速和减速距离
float dist_acc = 0.5f * v_max_allowed * v_max_allowed / a;
float dist_dec = 0.5f * v_max_allowed * v_max_allowed / d;
if (dist_acc + dist_dec <= S) {
// 有匀速段
p->vel_peak = v_max_allowed;
p->t_acc = v_max_allowed / a;
p->t_dec = v_max_allowed / d;
p->t_const = (S - dist_acc - dist_dec) / v_max_allowed;
} else {
// 无匀速段,三角形规划
// 解方程求实际峰值速度
float v_peak = sqrtf(2.0f * a * d * S / (a + d));
p->vel_peak = v_peak;
p->t_acc = v_peak / a;
p->t_dec = v_peak / d;
p->t_const = 0.0f;
}
p->t_total = p->t_acc + p->t_const + p->t_dec;
}
我的经验:加减速度可以设成不同值。比如上升时用大加速度快速启动,下降时用小减速度防止过冲。我在做龙门架时就这么配的——效果比对称加减速好不少。
参数配置建议
配置梯形规划时,我一般按这个顺序来:
- 先定最大速度:看电机额定转速和机械限速,取较小值
- 再定加速度:根据负载惯量和电机扭矩算,留 20% 余量
- 最后调减速度:如果定位有超调,就减小减速度
- 检查位移是否足够:不够就自动降速(代码里已经处理了)
我曾经遇到一个坑:加速度设得太大,电机扭矩够,但联轴器打滑了。嗯,从那以后我每次都会校核机械部件的承受能力,不只是算电机参数。
梯形规划知识体系
这张图把梯形规划的核心脉络理清了。你从根节点往下看:原理、公式、冲击分析,最后汇聚到代码实现。我个人建议初学者先吃透三段式结构和三角形规划的判断条件——这两个搞懂了,梯形规划就算拿下了八成。