4、PID控制基础:比例、积分、微分的作用,数字PID的实现方式,采样周期的选择。
各位同学,欢迎来到第四讲。前面我们聊了怠速控制的基本框架,知道了要控制什么、用什么执行器。但真正让这些执行器听话的,是背后的控制算法。今天我们就来啃这块硬骨头——PID控制。
说实话,PID在发动机控制里太常见了。怠速控制、空燃比闭环、扭矩控制,到处都有它的影子。我刚开始做标定时,总觉得PID就是调三个参数,没什么技术含量。后来被现实狠狠教育了一顿——调不好,发动机抖得像拖拉机;调好了,稳如老狗。这里面的门道,咱们今天好好捋一捋。
4.1 比例、积分、微分,到底在干啥?
先问个问题:你开车时想保持100km/h,但脚踩油门不可能一直不动吧?风大了、坡来了,速度就会掉。这时候你会怎么做?
对,看速度表,发现慢了就多踩点油门,快了就松一点。这就是最朴素的反馈控制。PID就是把这个过程数学化了。
4.1.1 比例控制(P)—— 看现在
比例控制最简单:偏差越大,输出越大。
公式:u(t) = Kp * e(t)
其中 e(t) 是目标转速减去实际转速。比如目标800rpm,实际750rpm,偏差50rpm。Kp=10,那输出就是500。偏差越大,修正越猛。
但比例控制有个毛病——稳态误差。什么意思?你想想看,如果只靠比例,要维持输出就必须有偏差。偏差为零,输出也为零,那执行器就回位了。所以实际转速永远到不了目标值,总会差那么一点。
我踩过的坑: 有一次调怠速,Kp给得太大,结果转速来回震荡,像坐过山车。后来把Kp降下来,虽然响应慢了,但至少稳住了。比例不是越大越好,过犹不及。
4.1.2 积分控制(I)—— 看过去
积分就是用来干掉稳态误差的。它把过去所有的偏差累加起来,只要偏差一直存在,积分项就会一直增长,直到把执行器推到正确位置。
公式:u(t) = Ki * ∫e(t)dt
说白了,积分就是「记仇」。你偏差存在多久,它就记多久,然后慢慢还回去。
但积分也有副作用——积分饱和。比如启动时转速很低,偏差很大,积分项疯狂累积。等转速上来了,积分项还很大,导致超调严重。我见过一个案例,积分饱和让怠速从800rpm冲到1200rpm,然后才慢慢回落。
我的习惯: 做积分限幅,限制积分项的最大值。另外,启动时先清空积分项,等转速接近目标再启用积分。这些小技巧能避免很多麻烦。
4.1.3 微分控制(D)—— 看未来
微分看的是偏差的变化趋势。偏差在变大,说明情况在恶化,需要提前干预。偏差在变小,说明控制有效,可以收一收。
公式:u(t) = Kd * de(t)/dt
微分相当于「预测」。它能抑制超调,让系统更稳定。但微分对噪声特别敏感。转速信号稍微抖一下,微分项就会剧烈波动。
注意: 发动机转速信号本身就有波动,直接微分会放大噪声。我建议先做滤波,或者干脆不用微分。很多怠速控制器只用PI,效果已经很好。微分用不好,反而添乱。
4.2 数字PID的实现方式
模拟PID是连续的,但ECU是数字的,只能离散化处理。常见的实现方式有三种。
4.2.1 位置式PID
直接模拟连续PID的公式,用累加代替积分,用差分代替微分。
// 位置式PID
float PID_Position(float setpoint, float feedback) {
float error = setpoint - feedback;
integral += error * dt;
float derivative = (error - last_error) / dt;
float output = Kp * error + Ki * integral + Kd * derivative;
last_error = error;
return output;
}
位置式输出的是执行器的绝对位置。比如节气门开度30%。优点是直观,缺点是积分项容易饱和。
4.2.2 增量式PID
增量式只计算输出的变化量,不关心绝对值。
// 增量式PID
float PID_Incremental(float setpoint, float feedback) {
float error = setpoint - feedback;
float delta = Kp * (error - last_error)
+ Ki * error
+ Kd * (error - 2*last_error + last_last_error);
last_last_error = last_error;
last_error = error;
return delta;
}
增量式输出的是变化量,比如节气门再开2%。它的好处是积分饱和风险小,而且切换手动/自动控制时冲击小。我个人更偏爱增量式,尤其在怠速控制中。
4.2.3 积分分离PID
这个是我在实际项目中常用的变种。当偏差很大时,先关掉积分,只用比例和微分快速逼近。等偏差小了,再启用积分消除稳态误差。
// 积分分离PID
float PID_IntegralSeparation(float setpoint, float feedback) {
float error = setpoint - feedback;
if (fabs(error) < threshold) {
integral += error * dt; // 偏差小,启用积分
} else {
integral = 0; // 偏差大,清空积分
}
float derivative = (error - last_error) / dt;
float output = Kp * error + Ki * integral + Kd * derivative;
last_error = error;
return output;
}
经验之谈: 阈值我一般设为目标转速的5%。比如目标800rpm,偏差小于40rpm时才启用积分。这样启动和负载突变时,积分不会捣乱。
4.3 采样周期的选择
采样周期是数字PID的关键参数。选大了,控制滞后;选小了,计算负担重,还可能引入噪声。
发动机怠速控制,采样周期一般怎么选?我给大家一个参考范围。
| 控制对象 | 推荐采样周期 | 说明 |
|---|---|---|
| 怠速转速控制 | 10ms - 50ms | 发动机响应较慢,10ms足够 |
| 空燃比闭环 | 10ms - 100ms | 氧传感器响应慢,周期可放宽 |
| 节气门位置控制 | 5ms - 20ms | 执行器响应快,周期要短 |
我个人习惯怠速控制用20ms。为什么?因为发动机转速的波动频率一般在几赫兹到十几赫兹,20ms对应50Hz采样率,足够捕捉动态变化。再短的话,比如5ms,计算量翻倍,但控制效果提升不明显。
一个小技巧: 采样周期要和执行器的响应时间匹配。节气门电机响应快,周期可以短一点。但如果是进气旁通阀,响应慢,周期太长反而浪费算力。
另外,采样周期不是越短越好。我记得有一次,为了追求「快速响应」,把采样周期设成了2ms。结果转速信号的高频噪声全被微分项放大了,节气门来回抖动,发动机也跟着喘。后来把周期改回20ms,再配合一阶低通滤波,问题就解决了。
4.4 总结一下
PID控制,说白了就是三个字:P看现在,I看过去,D看未来。数字实现上,增量式比位置式更实用,积分分离能解决启动超调问题。采样周期选10-50ms,具体看执行器响应。
下一讲我们会把这些知识用到怠速控制中,看看PID参数怎么标定、怎么调优。到时候我会分享一些实际标定数据,你们会看到参数变化对转速的影响。嗯,那才是真正有意思的部分。
今天就到这里。有问题随时问我,咱们下节课见。