资讯详情

资讯详情

增量式PID从公式到Simulink建模:原理、整定与工程落地

简介这是一份面向自动化、电气及控制类专业学生和工程师的Simulink仿真资源帮助理解增量式PID算法相比位置式PID在计算量与响应速度上的优势并掌握仿真建模与参数调试方法。压缩包共2个文件包括1个slx仿真模型和1个m脚本整体仅18KB内容精简可直接在MATLAB/Simulink环境中打开运行。模型围绕比例、积分、微分三部分展开完整实现了误差变化量计算、误差累计、变化率求解及控制增量合成配套脚本则便于批量修改Kp、Ki、Kd参数并观察响应曲线。已有6909人学习下载适合初步接触增量式PID、希望借助仿真直观理解控制器工作机制的读者。通过该资源可以快速搭建自己的仿真环境并进一步体会积分饱和、微分噪声等实际工程问题的处理手法。 做电机控制、温控、推力控制这类项目躲不开PID。很多人入门时看教程学的是位置式PID公式背得滚瓜烂熟但真到了Simulink里搭模型、甚至上电机台架才发现位置式有一堆坑。我第一次把PID搬上Simulink时也是从位置式开始的后来跟一位做运动控制的老师傅聊了一次他一句话点醒我你输出的是绝对控制量执行器一旦饱和积分项就是一笔糊涂账。后来我改用增量式PID很多问题迎刃而解。这篇文章就把增量式PID从差分方程到Simulink模型完整讲一遍包括两种常用的建模范式、完整闭环仿真的搭建步骤、参数整定的实操顺序以及仿真通过之后真正落地时容易踩的坑。适合刚开始接触Simulink的学生、做嵌入式控制和电机驱动的工程师以及所有想快速把PID跑起来而不是被公式劝退的人。1. 增量式PID和位置式PID为什么我总是推荐前者1.1 位置式PID的三个硬伤位置式PID的输出是绝对量。它的离散形式是u(k) Kp·e(k) Ki·Ts·Σe(j) Kd·(e(k)-e(k-1))/Ts里面有一个对历史误差的累加项。换句话说控制器输出是多少直接就等于一个已经攒了很久的值。这个结构在理论仿真里很完美但放到物理系统里有三个问题。第一执行器饱和之后积分项仍然在累计误差。比如电机堵转时你持续给PWM误差一直是正的积分项一路往上冲等堵转解除积分项还处在高位控制量半天降不下来系统会出现明显超调甚至振荡。第二手动/自动切换的瞬间位置式PID的输出是历史积分的值很可能和当前手动给定差了一大截切换瞬间必然产生冲击。第三积分项没有上限如果控制器输出没有被限制数值本身也容易变得不健康。1.2 增量式的本质输出变化量而不是绝对量增量式PID的思路非常直接我不直接算这次要输出多少而是算这次要比上次多输出多少。从位置式PID的相邻两次输出做差u(k) Kp·e(k) Ki·Ts·Σe(j) Kd·(e(k)-e(k-1))/Ts u(k-1) Kp·e(k-1) Ki·Ts·Σe(j-1) Kd·(e(k-1)-e(k-2))/Ts两式相减得到Δu(k) u(k) - u(k-1) Kp·[e(k)-e(k-1)] Ki·Ts·e(k) Kd·[e(k)-2e(k-1)e(k-2)]/Ts注意积分项的累加符号Σ在做差的时候被消掉了剩下的只是当前误差e(k)乘以一个系数。这是增量式最精妙的地方它不需要记住过去所有时间的误差只需要记住最近三次的误差就能算出控制量的增量。增量式的积分作用其实已经融合在增量的计算里——当误差持续为正时Δu保持正值控制量通过累加逐步上升等效地实现了积分功能。1.3 增量式的代价也不能无视增量式不是银弹。它输出的是变化量要得到实际的控制量必须在算法外部加一个累加器u(k) u(k-1) Δu(k)。这多了一个状态变量需要管理。另外微分项对噪声更敏感因为公式里的二阶差分会放大高频噪声。还有一点增量式算法依赖最近几次的误差值如果采样周期或对象延迟很大系统的相位裕度会被吃掉更多。用个生活类比位置式PID像你要在某个时间点说出整个存款余额增量式PID像你只需要说明白这一个月比上个月多花了多少。后者不需要记住几年前的账但你需要一个账户在外部帮你做累加。2. 从公式到SimulinkUnit Delay建模范式与MATLAB Function范式2.1 Unit Delay范式零代码搭建适合讲原理在Simulink里搭增量式PID最直观的方式是用Unit Delay模块保存历史误差。Unit Delay就是离散域的延迟一拍相当于把信号保存一个采样周期。整个模型分三步。第一步生成误差。用Sum模块一个输入是期望值一个输入是反馈值符号配置成 -得到当前误差e(k)。第二步做差分。误差e(k)接一个Unit Delay输出e(k-1)e(k-1)再接一个Unit Delay输出e(k-2)。这里要把Unit Delay的Initial condition设置为0否则仿真一开始差分结果会飘。第三步组合三项。用三个Gain模块分别设置Kp、Ki、Kd把三项加起来比例项 Kp × (e(k) - e(k-1)) 积分项 Ki × e(k) 微分项 Kd × (e(k) - 2e(k-1) e(k-2))然后用Sum模块把三个结果相加得到Δu(k)。这里有个细节值得提醒Simulink里的离散模块需要在Configuration Parameters中设置Sample timeUnit Delay的采样时间要和整个控制回路的采样时间一致通常是0.01s或0.001s。如果配错了仿真结果会非常奇怪最常见的就是输出波形出现莫名其妙的阶梯状跳动。2.2 MATLAB Function范式几行代码搞定适合快速验证如果你更喜欢写代码而不是拖模块可以用MATLAB Function块算法能一行不差地写成代码function dU incrPID(e, Kp, Ki, Kd, Ts) persistent e_1 e_2 if isempty(e_1) e_1 0; e_2 0; end % 增量式PID核心计算 dU Kp*(e - e_1) Ki*e*Ts Kd*(e - 2*e_1 e_2)/Ts; % 更新历史误差 e_2 e_1; e_1 e; end需要注意这个写法里Ki和Kd是传给函数的两个增益但Ki实际和Ts相乘了所以它属于连续域参数折算后的离散增益。如果你看到的增量式公式是Δu Kp·Δe Ki·e Kd·(Δe - Δe_1)那这里的Ki、Kd就已经是离散域增益不应该再乘Ts。两种写法都能用关键是参数含义不能混。我在给代码做注释时一定会标明参数是连续域还是离散域这个习惯救了我很多次。2.3 选择建议Unit Delay范式适合做演示和教学每个模块都能看到信号逻辑清晰MATLAB Function范式适合快速改算法、批量测试。如果是做实际控制器代码生成S-Function或者手写C代码会更贴近嵌入式实现方式。我自己在仿真阶段常用MATLAB Function因为改参数快在给团队做培训时用Unit Delay因为讲得清楚。3. 搭建一个能跑的闭环模型对象、累加器与波形验证3.1 被控对象怎么选增量式PID的闭环模型需要一个被控对象。别找太复杂的对象仿真初期用一个二阶系统就能看出PID各项作用。我常用G(s) 10 / ((s1)(s2))这是一个惯性加惯性的二阶系统响应平滑调节过程能明显看到比例、积分、微分的贡献。对象用Transfer Fcn模块搭分子填[10]分母填[1 3 2]。如果真想体会延迟对控制的影响可以再串一个Transport Delay比如延迟0.1秒观察PID如何应对。延迟是控制工程的常客越早仿真越有感觉。3.2 关键一步增量输出要累加这是增量式PID仿真里最容易遗漏的环节。增量式PID输出的是Δu但被控对象要的是绝对控制量u所以必须有一个累加器。在Simulink里最可靠的做法是用Discrete-Time Integrator模块设置成求和模式采样时间和PID保持一致。也可以用手动的Unit DelayAdd做递归累加。累加之后建议接一个Saturation限幅模块。比如控制量范围是[-10, 10]就填上下限。限幅不是可选项后面第5节会解释为什么它如此关键。3.3 闭环连接与波形观察完整信号流动画一遍Step → Sum(误差) → 增量式PID → Δu → Sum(累加) → Saturation → 被控对象 → 输出反馈回Sum。再分一路把误差、控制量u、增量Δu送到Scope去观察。第一次跑仿真先给定一个阶跃目标比如从0到10。观察三条曲线输出响应曲线是否跟踪目标超调多大调节时间多长控制量u是否被限幅是的话持续了多久增量Δu是否有高频毛刺毛刺来源是微分项还是噪声如果输出曲线收敛不了先别急着调参数检查模型本身。最常见的错误是Unit Delay的采样时间没有设置或者累加器没有采样保持导致整个回路变成连续系统仿真增量式算法的离散特性完全丢失。3.4 代数环问题搭这个模型时还有一个Simulink特有坑——代数环。如果被控对象是纯增益或者信号路径上没有离散状态Simulink可能报告代数环冲突。增量式PID里的Unit Delay天然带一个离散状态通常能打破代数环但如果你的累加器用的是连续积分器Integrator而不是Discrete-Time Integrator问题就来了。所以累加器务必用离散版本不要图省事拖一个连续Integrator进去。这是我在仿真中最常遇到的一类低级错误排查起来还特别费时间因为Simulink只报warning不报error。4. 参数整定实操顺序先Kp、再Ki、最后Kd4.1 一上来就三个参数一起调基本调不出来很多新手拿到模型第一件事是给Kp、Ki、Kd随便填三个数结果波形一团糟然后开始质疑算法有问题。实际参数整定是有顺序的我的习惯是第一步把Ki和Kd全部置0只保留Kp。从小到大慢慢增加Kp观察系统响应。当Kp比较小时稳态误差肯定存在这是正常的因为比例控制本身没法消除稳态误差。继续加大Kp响应会更快超调也会变大。当系统开始出现持续等幅振荡时记录此时的Kp为临界增益Ku振荡周期为Tu。第二步用经验公式给初值。比如Ziegler-Nichols整定表里在只有比例控制下找到Ku和Tu可以算出PID的建议值Kp 0.6×KuTi 0.5×TuTd 0.125×Tu。这个值不一定完美但至少是个靠谱的起点。第三步从起点慢慢微调Kp、Ki、Kd。每一次只动一个参数观察波形变化再动下一个。4.2 增量式里Ki的观察技巧增量式PID判定积分作用是否过头有个很好用的观察技巧看Δu曲线。当系统稳定在目标值附近但存在稳态误差时误差e保持恒定值即使是小值此时如果Ki太大Δu曲线上会看到明显的持续偏移控制量不断爬升系统会出现爬行甚至低频振荡。如果Ki太小稳态误差消除得很慢输出曲线贴近目标值很久误差还是差那么一点点。我不建议直接看u的绝对值判断Ki大小因为绝对控制量受Kp影响更大Δu才是增量式积分作用的直接体现。把Scope切到只看Δu再看系统收敛过程你会很直观地理解什么是积分项在推动控制量爬升。4.3 一组起始参数以G(s)10/((s1)(s2))采样周期Ts0.01s为例一组能稳定工作的起始参数是参数数值说明Kp5比例增益Ki3离散域增益注意这里不是连续域KiKd0.5微分增益Ts0.01s控制器采样周期这组参数跑出来的效果是输出大概在1秒内跟上目标有一点小超调稳态误差基本为0。如果你的波形差异很大先检查采样时间再检查模型结构最后再怀疑参数。4.4 微分项的坑Kd加多了比例和积分好不容易压下来的超调又会反弹而且高频小幅度振荡反而增强。微分项会放大测量噪声真要加Kd时建议在误差信号后端加一个低通滤波Simulink里用Transfer Fcn搭一个一阶低通最方便比如 1/(0.01s 1)。滤波拐点选在控制带宽的5到10倍以上别把有用的响应也滤掉了。5. 仿真没告诉你的工程细节限幅、采样周期与抗积分饱和陷阱5.1 输出限幅为什么是刚需模型仿真里被控对象是数学表达式你给它多大的控制量它都能接受。但真实执行器有物理极限PWM占空比不可能超过100%电压也不可能没上限。如果不加限幅增量式PID的累加器会把u推到几百甚至几千控制器设计再漂亮也没有意义。在增量式PID里限幅要分两层考虑。第一层限制Δu防止单步控制量变化过大这能保护实际执行机构避免步进电机或者伺服系统被剧烈冲击。第二层限制累加后的u让它落在执行器的物理范围内。Simulink的Saturation模块可以分别设上下限我把控制量u的饱和限幅看作硬限幅把Δu限幅看作软限幅。5.2 增量式PID真的不会积分饱和吗经常有人宣传增量式PID天生抗积分饱和这话对了一半。增量式确实不容易出现位置式那种积分项疯狂累积、误差反向时它还在还债的现象因为它的输出是增量饱和时Δu直接被限幅u不会继续涨。但它不是完全没有问题。当系统长时间处于饱和状态时Δu虽然被限幅但u仍然停在饱和值。等误差反向之后u要一步一步从饱和值爬回来如果Δu限幅太小回退速度会非常慢系统出现迟滞感。所以工程上还是要做抗积分饱和处理。最简单的做法是条件限幅法当u到达饱和上限且Δu为正时强制把累加结果钳位在饱和值反之亦然。Simulink里可以写个MATLAB Function块来处理或者用多个Saturation Switch组合实现。5.3 采样周期增量式PID的隐形参数很多人在Simulink里只会调Kp、Ki、Kd忽略Ts。Ts不合适参数整定再准也没用。增量式PID的差分结构对采样周期极其敏感微分项里有个除以Ts的因子采样越快这个因子越大噪声放大越严重采样越慢积分项等效增益越小稳态误差消除能力变差。经验法则采样周期取系统最快时间常数的1/10到1/5。比如上面那个例子对象时间常数约0.5秒Ts取0.05秒以下比较稳妥。如果你改了Ts注意Ki和Kd等效值也会跟着变。离散域增益不变的情况下连续域等效Ki 离散Ki/Ts连续域等效Kd 离散Kd×Ts。这个换算是Simulink仿真和实际控制器代码之间最常见的对接错误也是为什么我坚持在代码注释里标明参数域的原因。5.4 手动/自动切换无冲击增量式PID最值得吹的工程优势之一就是无冲击切换。模拟手动控制时把累加器的初始值设定为当前手动给定值切到自动时Δu从0附近开始控制量u不会突变。Simulink里可以用一个Manual Switch在手动给定和PID输出之间切换累加器通过Initial condition端子来装手动值。这个功能在做伺服系统、飞行器控制时非常关键位置式PID做不到这种平滑切换。我在实际项目里做过一个风机转速控制手动给30%开度切到自动PID之后如果用的是普通位置式转速会明显跳动一下换成增量式加上累加初值设定切换时转速曲线几乎察觉不到波动那个测试数据给我留下了很深的印象。其实增量式PID在Simulink里搭一次后面可以复用到很多项目。我自己后来做直流电机速度环、无刷电机电流环、温度控制系统都是把这一份增量式PID外壳拿过来改改被控对象、改改限幅范围、跑一遍参数整定就直接用。最终落地到嵌入式代码的时候也是同一份公式把单位延迟用结构体成员保存就行。如果你还处在刚接触PID的阶段我建议动手把Unit Delay版模型搭一遍然后手动切换成MATLAB Function版对比两者的Δu波形是否一致。跑通这一步你对增量式PID的理解会比看十篇教程都扎实。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →