第一章 速度控制基础:从原理到实战

大家好,我是老张。在电机控制这行摸爬滚打了十几年,今天咱们聊聊速度控制。

速度控制,说白了就是让电机按照你想要的转速转起来。你给个目标速度,比如每分钟1500转,系统就得想办法让电机稳定在这个值上。听起来简单,但实际做起来,坑可不少。

1.1 什么是速度控制?

速度控制是一个闭环系统。我习惯把它比作开车:

  • 目标速度:你想开多快(比如80km/h)
  • 实际速度:仪表盘显示的速度
  • 控制器:你的大脑和右脚
  • 执行器:油门踏板和发动机

系统不断比较目标速度和实际速度,算出误差,然后调整输出。这就是闭环控制的核心。

核心公式:

误差 = 目标速度 - 实际速度

输出 = f(误差) —— 这个f就是PID控制器

我在项目中遇到过不少新手,上来就调参数,连速度反馈都没搞清楚。嗯,这里要注意:没有准确的反馈,再好的算法也是白搭

1.2 速度环的PID调节原理

PID是比例、积分、微分的缩写。这三个家伙各有分工,配合好了,系统就稳如老狗。

先看一张图,这是我画的速度控制系统的结构:

目标速度 + - PID控制器 比例(P) + 积分(I) + 微分(D) 输出 = Kp·e + Ki·∫e dt + Kd·de/dt 电机+驱动器 执行控制指令 速度反馈 图1:速度控制闭环系统结构图

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参数,说白了就是找到三个合适的数字。我常用的方法有两种:

方法一:试凑法(经验法)

  1. 先调P:把I和D设为0,慢慢增大Kp,直到系统开始震荡。然后取震荡值的60%-70%。
  2. 再加I:保持P不变,慢慢减小积分时间Ti(积分作用增强),直到稳态误差消失。
  3. 最后加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