夜雨聆风学习资料网

ARTICLE · 1017897

离散系统的数字校正:PID 下载进单片机中就震荡?问题可能出在一个约等号上

离散系统的数字校正:PID 下载进单片机中就震荡?问题可能出在一个约等号上

上一期我们把离散系统的"稳、准、快"全挂到了一个圆上——会看了。但看懂不等于会修。

这一期是第三部分,也是整个数字控制最实用的一段:怎么把控制器真正写进代码,怎么把一个不听话的系统调到又快又稳,以及——那个听起来像吹牛的"几拍到位",到底靠不靠谱。

1. PID 写成代码,难的不是公式,是三个「约等号」

连续 PID 谁都会背:

最麻烦的是中间那个积分号。单片机里没有"积分"这回事,只有"把过去的误差加起来"

积分就是攒面积。那问题就只剩一个:这一格的面积,按哪个高度算?

  • 上一拍的误差当高度 —— 前向欧拉
  • 这一拍的误差当高度 —— 后向欧拉
  • 两拍取平均(梯形)—— 双线性变换,也叫 Tustin

就这么朴素。所谓"离散化方法",一句话就是你打算怎么数格子

对应到公式上,无非是把 (s) 换成三个不同的东西:

这一节记住:离散化不是什么高深操作,就是选一种数格子的方式

2. 换个约等号,稳定的系统真会算成不稳定

数格子的方式听起来无伤大雅,但它决定了一件大事:连续世界里的"稳定区",被搬到 z 平面之后落在哪儿。

  • 前向欧拉 
    整个左半平面被摊成半个 z 平面,一大片落在单位圆外。也就是说,连续算着好好的系统,离散完可能直接发散。
  • 后向欧拉
    左半平面被挤进一个半径为 0.5 的小圆,怎么都在圆内?听起来很安全?其实是它把本该发散的东西也算成了稳定——等于骗自己。
  • 双线性
    左半平面 ↔ 单位圆内,边界对边界,不多不少。

真的会炸吗?会

拿个具体例子跑一遍。对象

PID 取

微分项带一个时间常数

的低通。三种写法,只改采样周期:

采样周期 (T)
前向欧拉
后向欧拉
双线性
0.04 s
0.911
0.888
0.895
0.08 s
0.849
0.811
0.787
0.10 s
1.023 发散
0.778
0.732
0.12 s
1.518 发散
0.748
0.676
0.15 s
2.301 发散
0.761
0.591

(表里是闭环极点的最大模长,超过 1 就发散)

看那个临界点:0.10 秒,正好是(2Tf)。

这不是巧合。前向欧拉把连续极点

搬到了

只要 (T>2Tf),这个点就跑到 (-1) 的左边去了——滤波器自己先不稳定了,跟你的 PID 参数一点关系都没有。

所以记住一个数:用前向欧拉采样时,采样周期必须小于微分滤波时间常数的两倍。

顺带补一刀:微分项一定要带低通

如果你用的是"教科书版"的理想微分项(Kd s),双线性变换会在 (z=-1) 给你留一个极点。上一期说过,负实轴上的极点意味着一拍高一拍低的振铃。

这不是精细调优的问题,是能不能用的问题。工程上微分项永远写成 

3. 位置式还是增量式?真正要防的是「积分冲过头」

把三个约等号代进去,就得到两种写法。

位置式——直接算出这一拍该输出多少:

增量式——只算这一拍比上一拍多给多少:

增量式的好处很实在:不用存那个越滚越大的累加和;手动/自动切换的时候不会跳;执行器本身就是积分型的(步进电机、阀门开度)时,直接送增量最自然。

写成代码也就几行:

/* 增量式 PID,每个采样周期调用一次 */floatpid_step(floatreffloat meas){    static float e1 = 0.0f, e2 = 0.0f, u = 0.0f;    float e  = ref - meas;    float du = Kp * (e - e1)             + Ki * T * e             + Kd / T * (e - 2.0f * e1 + e2);    u += du;    if (u > U_MAX) u = U_MAX;     /* 先限幅 */    if (u < U_MIN) u = U_MIN;     /* 再输出,积分就飞不起来 */    e2 = e1;  e1 = e;    return u;}

但真正的分水岭不在"位置式还是增量式",而在执行器饱和的那一刻你干了什么。

电机已经满功率了,误差还在,位置式的积分项照样闷头累加。等系统终于追上来,那个攒了一肚子的积分还得慢慢吐出去——于是冲过头。

同一套参数,三种写法:

写法
超调
调节时间
位置式,不做抗饱和
30.7%
9.8 s
位置式 + 抗饱和
7.4%
4.8 s
增量式
8.7%
4.6 s

增量式天生不容易冲过头,但抗饱和才是解药——两者不是二选一。

4. 数字校正:给系统配一副眼镜

PID 只是校正器里最出名的那一个。更一般的说法是:在回路里串一个 D(z),把闭环极点挪到你想要的地方。

常用的就两副"眼镜"。

超前校正:买速度

在对象的慢极点旁边放一个零点把它"按住",再放一个更靠近圆心的极点,根轨迹就被拽进来了

同一个对象

超调
调节时间
控制量峰值
纯比例
20.6%
8.4 s
1.0
加超前校正
1.2%
1.4 s
5.6

调节时间砍到六分之一,超调几乎没了。代价写在最后一列:控制量峰值大了 5.6 倍。你的电机、驱动器扛不扛得住,这才是能不能这么调的真正边界。

滞后校正:买精度

滞后校正不管速度,专治"总差一口气"。做法是在 (z=1) 附近塞一对挨得很近的零极点,把低频增益抬上去。

一个 0 型系统,纯比例控制时稳态误差 0.50,加上

动态几乎没动,误差掉到原来的五分之一。

超前花的是功率,滞后花的是时间。天下没有白调的参数。

5. 无差拍:真能「几拍到位」吗?

前面都是"设计一个 D(z),然后看看效果"。无差拍控制把这个顺序反了过来:

先写下你想要的闭环,再反解控制器。

想要 (N) 拍到位?那就令闭环传递函数直接等于

输入延迟 (N) 拍原样输出,这不就是"(N) 拍精确到位"吗?然后反解:

听起来像作弊,但它真的成立:

两拍,输出精确等于 1,一点误差都没有。

然后看下面那一栏。

控制量第一下冲到 32.6,而这个系统稳定下来只需要 3.0 ——11 倍。而且它一正一负地甩:+32.6、−26.7、+22.9……执行器要是有限幅(哪个没有呢),这套设计当场失效。

还有两个更要命的

第一,采样点之间它在疯狂来回。控制器每隔 (T) 看一眼,每次看到的都是漂亮的 1.000。但被控对象经历的是一条 ±34% 上下翻滚的曲线。控制器很满意,机器很难受。

第二,模型错一点点就崩无差拍是拿 (1/G(z)) 硬凑出来的,等于把控制器和对象完全绑死。对象的增益实际上偏了 30%——这在工程里根本不算大误差——结果就是超调 30%,说好的 2 拍变成了 8 拍。

所以:无差拍是一把尺子,量出"最快能多快";它不是一个可以直接上机器的目标。实际工程里常用的是"阻尼无差拍"——故意把 (\Phi(z)) 设计得没那么激进,用几拍的速度换一大截鲁棒性。

6. 总结?

还是六个词:

数格子、看落点、防饱和、买速度、买精度、留余量。

  • 数格子:三种离散化就是三种数面积的方式;
  • 看落点:前向欧拉会把稳定算成发散,双线性才是一一对应;
  • 防饱和:执行器一顶到头,积分就得停手;
  • 买速度:超前校正把极点拽向圆心,付的是控制量;
  • 买精度:滞后校正抬低频增益,付的是响应时间;
  • 留余量:无差拍的极限性能,是用鲁棒性换来的。

到这里,离散控制的三块拼图——建模、分析、校正——就齐了。你已经能把一个连续系统搬进单片机,判断它稳不稳,再把它调到想要的样子。

相关学习资料

返回首页浏览学习资料