第一章 速度控制基础:从原理到实战
大家好,我是老张。在电机控制这行摸爬滚打了十几年,今天咱们聊聊速度控制。
速度控制,说白了就是让电机按照你想要的转速转起来。你给个目标速度,比如每分钟1500转,系统就得想办法让电机稳定在这个值上。听起来简单,但实际做起来,坑可不少。
1.1 什么是速度控制?
速度控制是一个闭环系统。我习惯把它比作开车:
- 目标速度:你想开多快(比如80km/h)
- 实际速度:仪表盘显示的速度
- 控制器:你的大脑和右脚
- 执行器:油门踏板和发动机
系统不断比较目标速度和实际速度,算出误差,然后调整输出。这就是闭环控制的核心。
核心公式:
误差 = 目标速度 - 实际速度
输出 = f(误差) —— 这个f就是PID控制器
我在项目中遇到过不少新手,上来就调参数,连速度反馈都没搞清楚。嗯,这里要注意:没有准确的反馈,再好的算法也是白搭。
1.2 速度环的PID调节原理
PID是比例、积分、微分的缩写。这三个家伙各有分工,配合好了,系统就稳如老狗。
先看一张图,这是我画的速度控制系统的结构:
1.3 比例、积分、微分的作用
比例(P)—— 当前误差的放大器
比例项就是看当前误差有多大,然后乘以一个系数输出。误差大,输出就大;误差小,输出就小。
你想想看,如果只有比例控制,会有什么问题?
我举个例子:电机带负载时,比例控制会产生一个稳态误差。比如目标1500转,实际只能到1480转,差了20转。为什么?因为要维持负载,必须有一定的输出,而这个输出需要误差来支撑。
我的经验:
比例系数Kp可以先从0.5开始试。太小了响应慢,太大了会震荡。我曾经调一个印刷机,Kp设到3.0,电机直接啸叫起来,吓得我赶紧断电。
积分(I)—— 消除稳态误差的利器
积分项看的是误差的累积。只要有误差,积分项就会一直增长,直到误差消失。
说白了,积分就是用来消除那20转的差距的。它慢慢累积,慢慢增加输出,直到实际速度追上目标速度。
但积分也有副作用——积分饱和。我记得有一次调试,积分时间设得太短,电机启动时积分项疯狂累积,结果超调了30%,来回震荡了好几次才稳定下来。
避坑指南:
我曾经吃过亏:积分时间Ti设成0.01秒,结果系统直接发散。后来我养成了习惯,积分时间至少从0.1秒起步,慢慢往下调。
微分(D)—— 预测未来的先知
微分项看的是误差的变化率。误差在快速增大,它就输出一个反向力来抑制;误差在快速减小,它也提前收力,防止超调。
微分的作用有点像阻尼器。它让系统更稳定,响应更平滑。
但微分对噪声特别敏感。我遇到过编码器信号有毛刺,微分项一算,输出全是高频抖动。后来加了低通滤波才解决。
1.4 PID参数的整定方法
整定PID参数,说白了就是找到三个合适的数字。我常用的方法有两种:
方法一:试凑法(经验法)
- 先调P:把I和D设为0,慢慢增大Kp,直到系统开始震荡。然后取震荡值的60%-70%。
- 再加I:保持P不变,慢慢减小积分时间Ti(积分作用增强),直到稳态误差消失。
- 最后加D:如果系统有超调或震荡,适当增加微分时间Td。
我习惯用这个顺序。但要注意,每次调整后都要观察系统的响应曲线。
方法二:Ziegler-Nichols法
这个方法更系统一些:
| 参数 | 比例系数Kp | 积分时间Ti | 微分时间Td |
|---|---|---|---|
| P控制器 | 0.5·Ku | ∞ | 0 |
| PI控制器 | 0.45·Ku | 0.85·Tu | 0 |
| PID控制器 | 0.6·Ku | 0.5·Tu | 0.125·Tu |
其中Ku是临界增益(系统开始持续震荡时的Kp值),Tu是震荡周期。
实战建议:
我个人习惯先用试凑法快速得到一个可用的参数,再用Z-N法微调。两种方法结合,效率最高。
1.5 代码示例:速度环PID实现
下面是一个简单的速度环PID代码,我用C语言写的,实际项目中改改就能用:
// 速度环PID结构体
typedef struct {
float Kp; // 比例系数
float Ki; // 积分系数
float Kd; // 微分系数
float integral; // 积分累积值
float prev_err; // 上一次误差
float limit; // 输出限幅
} SpeedPID;
// 速度环PID计算函数
float SpeedPID_Calc(SpeedPID *pid, float target, float actual) {
float err = target - actual; // 计算误差
float output;
// 比例项
float p_out = pid->Kp * err;
// 积分项(带限幅防饱和)
pid->integral += pid->Ki * err;
if (pid->integral > pid->limit) pid->integral = pid->limit;
if (pid->integral < -pid->limit) pid->integral = -pid->limit;
// 微分项
float d_out = pid->Kd * (err - pid->prev_err);
// 总输出
output = p_out + pid->integral + d_out;
// 输出限幅
if (output > pid->limit) output = pid->limit;
if (output < -pid->limit) output = -pid->limit;
// 保存误差
pid->prev_err = err;
return output;
}
这段代码里,我特别加了积分限幅。为什么?因为积分饱和是新手最容易踩的坑。你不限幅,积分项能累积到天上去,系统恢复响应要半天。
1.6 常见问题与避坑
- 电机震荡:Kp太大或者Kd太小。先减小Kp试试。
- 响应太慢:Kp太小或者Ki太小。适当增大Kp。
- 稳态误差消不掉:Ki太小或者积分限幅太紧。检查积分项是否被限幅了。
- 启动超调大:积分累积太快。可以加积分分离或者变积分系数。
一个小技巧:
调试时先用示波器看速度波形。我习惯把目标速度和实际速度同时显示出来,一眼就能看出问题在哪。
好了,速度控制的基础就聊到这儿。记住一句话:PID没有万能参数,只有适合你系统的参数。多试、多看波形、多总结,你也能成为调参高手。
公众号:蓝海资料掘金营,微信deep3321