4、速度环优化:加减速曲线设计、梯形与S形曲线对比、速度平滑处理
速度环优化,说白了就是让电机该快的时候快,该慢的时候慢,而且不能抖。我刚开始做步进电机驱动那会儿,总觉得只要给足脉冲,电机就能乖乖听话。结果呢?丢步、过冲、共振,各种问题轮着来。后来才明白,加减速曲线才是速度环的灵魂。
4.1 为什么需要加减速曲线?
你想想看,步进电机的转子有惯性。如果一上来就给满速指令,转子根本来不及跟上。这就好比让一辆车瞬间从静止加速到100公里——轮胎肯定打滑。电机也一样,会丢步。
反过来,高速运行时突然急停,转子会因为惯性继续往前冲,造成过冲。嗯,这就是位置超调。
所以,加减速曲线的核心目的就两个:
- 避免丢步:让电机平稳地从低速过渡到高速
- 避免过冲:让电机平滑地从高速减速到停止
我在项目中遇到过一台贴片机,每次启动时都会发出刺耳的尖叫声。后来一查,就是加减速太陡,电机直接进入了共振区。改了曲线之后,世界安静了。
4.2 梯形加减速曲线
梯形曲线是最基础、最常用的加减速方式。它的速度变化分三个阶段:匀加速、匀速、匀减速。画出来像个梯形,所以叫这个名字。
代码实现起来也很直接:
// 梯形加减速示例(伪代码)
void trapezoidal_move(float target_speed, float accel, float decel) {
// 加速阶段
while (current_speed < target_speed) {
current_speed += accel * dt;
set_speed(current_speed);
}
// 匀速阶段
while (distance_remaining > decel_distance) {
set_speed(target_speed);
}
// 减速阶段
while (current_speed > 0) {
current_speed -= decel * dt;
set_speed(current_speed);
}
}
梯形曲线的优点很明显:实现简单,计算量小,适合资源受限的MCU。我早期用STM32F103做项目时,梯形曲线几乎是唯一选择。
但缺点也很突出——加速度突变。在加速开始和结束的瞬间,加速度从0跳变到某个值,或者从某个值跳变到0。这种突变会产生冲击力,引起机械振动。说白了,就是电机在「抖」。
4.3 S形加减速曲线
S形曲线,也叫S-Curve,是对梯形曲线的改良。它把加速度的变化也做了平滑处理——加速度本身是逐渐增加和逐渐减小的。这样,速度的变化就不再是直线,而是S形。
为什么会这样?因为S形曲线引入了「加加速度」(Jerk)的概念。加加速度就是加速度的变化率。梯形曲线的加加速度是无穷大(瞬间变化),而S形曲线把加加速度控制在一个有限值。
实现起来稍微复杂一点:
// S形加减速示例(伪代码)
void s_curve_move(float target_speed, float jerk, float accel_max) {
// 加加速阶段(加速度从0增加到accel_max)
while (accel < accel_max) {
accel += jerk * dt;
current_speed += accel * dt;
set_speed(current_speed);
}
// 匀加速阶段
while (accel == accel_max) {
current_speed += accel * dt;
set_speed(current_speed);
}
// 减加速阶段(加速度从accel_max减小到0)
while (accel > 0) {
accel -= jerk * dt;
current_speed += accel * dt;
set_speed(current_speed);
}
// ... 匀速、减速阶段类似
}
S形曲线的优势很明显:
- 启动和停止极其平滑,几乎没有冲击
- 有效抑制机械共振
- 定位精度更高,过冲更小
代价呢?计算量大,占用更多CPU时间。而且,如果参数设置不当(比如加加速度太小),整个运动过程会变得很「肉」,响应慢。
4.4 梯形 vs S形:怎么选?
我整理了一个对比表,方便你快速决策:
| 对比项 | 梯形曲线 | S形曲线 |
|---|---|---|
| 实现难度 | 简单 | 中等 |
| 计算开销 | 低 | 高 |
| 启动冲击 | 大 | 小 |
| 振动抑制 | 差 | 好 |
| 定位精度 | 一般 | 高 |
| 适用场景 | 通用、低成本 | 高精度、低振动 |
我个人习惯是:能用梯形就用梯形。只有在梯形曲线导致明显振动或丢步时,才考虑S形。你想想看,多一个S形曲线,代码量翻倍,调试时间翻倍,值不值得?
4.5 速度平滑处理的实战技巧
除了选对曲线类型,还有一些细节能让速度更平滑:
4.5.1 速度前馈
在速度环中引入前馈项,可以提前补偿系统的惯性。说白了,就是「预判」电机的需求,而不是等误差出现了再纠正。我在做3D打印机固件时,加了速度前馈之后,打印拐角时的振纹明显减少了。
4.5.2 低通滤波
对速度指令做低通滤波,可以滤掉高频噪声。但要注意,滤波会引入延迟。滤波系数调太大,响应变慢;调太小,滤波效果不明显。嗯,这里要找到一个平衡点。
// 一阶低通滤波示例
float smooth_speed = 0;
float alpha = 0.3; // 滤波系数,0~1之间
void update_speed(float target_speed) {
smooth_speed = alpha * target_speed + (1 - alpha) * smooth_speed;
set_speed(smooth_speed);
}
4.5.3 微步细分
微步细分本身就是一种速度平滑手段。把一步分成256个微步,电机的运动就变得非常细腻。但要注意,微步细分并不能消除加减速带来的冲击——它只是让每一步更小而已。加减速曲线和微步细分是两回事,别搞混了。
4.6 避坑指南
最后,分享几个我踩过的坑:
- 我曾经把S形曲线的加加速度设得太小,结果电机启动慢得像蜗牛,客户投诉说「这机器是不是坏了」。后来把加加速度调大了3倍,才恢复正常。
- 我曾经在梯形曲线中忘了计算减速距离,结果电机高速运行时突然急停,直接把联轴器扭断了。嗯,从那以后我每次都会预留减速距离。
- 我曾经在速度环中同时用了低通滤波和S形曲线,结果两个平滑叠加,导致响应延迟过大,位置跟踪误差超标。后来只保留了S形曲线,去掉了滤波。
说白了,速度环优化没有银弹。每个系统都有自己的脾气,你得慢慢摸透它。多试、多调、多记录,慢慢就有感觉了。
下一章,我们会聊位置环的优化——那又是另一片天地了。