ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

PI闭环控制从入门到实战:比例积分如何消除稳态误差?

PI闭环控制从入门到实战:比例积分如何消除稳态误差? 前阵子调试一台直流电机转速闭环我把比例增益从0.1一路加到1.5想着系统总能压到目标转速。结果电机始终比设定值低几十转继续加就开始啸叫、转速来回窜。后来把积分项加上去那几十转的偏差几分钟内就被抹掉了。这个经历我猜很多人都有过——纯比例控制天生消不掉稳态误差工程上绕不过去的解法就是PI闭环控制。PI闭环控制全称比例积分控制器是整个工业自动化里用得最多的控制算法没有之一。它的输入是设定值和反馈量的误差输出是送给执行器的命令比例项负责“当下反应”积分项负责“历史记忆”。直流电机转速、步进电机闭环、开关电源电压环、FOC电流环这些场景看着毫不相干核心逻辑都是同一个PI闭环。这篇文章就围绕“为什么要加I”“怎么离散化落地”“怎么调参”“有什么坑”四个方向展开适合正在做电机驱动、电源、运动控制项目的工程师也适合那些一直调用现成PID库、却不知道内部取舍的人。1. 从开环到闭环为什么非要有反馈不可1.1 开环控制天生看不见结果开环控制说起来很直白你给执行器发一个固定命令然后就完事了完全不关心系统实际变成什么样。比如早期电风扇的档位你拨到3档电机就以某个转速转电网电压波动、负载变大变小它都不管。这个“不管”就是开环的核心特征——输出不反馈回去参与下一步计算。开环的最大问题是它抵抗不了扰动。你按经验算出电机达到1000转需要给它50%的占空比但电池电压从12V掉到11V同样的占空比可能就只有950转负载被机械结构多带了一点转速还会继续往下掉。系统里的摩擦、老化、温漂、负载变化开环一概不感知、不纠偏。你唯一能做的就是提高控制量把参数往上调但参数一旦超过某个值系统在满载时会过冲、在轻载时甚至会飞车。另一个问题是开环依赖精确的模型。如果你想用开环实现精确控制得把被控对象的特性摸得非常透而且要保证工作过程中模型不变。这在实验室里可能做到一到现场就是灾难——每个电机参数都不一样每台设备装配误差都不一样。于是就有了闭环控制的需求我不管你的模型有多准也不管外面有多少扰动只要我能量到实际输出就能把偏差算出来、再把偏差压回去。1.2 闭环的本质误差驱动一切闭环控制的结构看起来也很简单五个环节串在一起给定值你想要的目标→ 控制器PI→ 执行器电机、加热器、阀门→ 被控对象转速、温度、压力→ 传感器编码器、热电偶、压力变送器。传感器量到的反馈量回到输入端和给定值相减得到误差e(t)然后把误差交给控制器处理。关键就在这个“相减”上。误差既是控制器的输入也是系统存在的全部理由——有误差控制器就动作没误差控制器就维持现状。这样一来扰动也好、模型不准也好都会先表现为误差的变化然后被控制器纠正。这就是闭环能抵抗扰动的原因它不需要知道扰动是什么只需要看到误差不为零就持续纠正。但闭环也不是白拿的代价是会振荡。原因在于控制量到达被控对象有一个过程传感器反馈回来也有延迟如果控制器反应过猛系统就会在设定值附近来回震荡像你开车看到前方面包车减速你猛踩一脚刹车结果停得太急又猛踩油门追上去如此反复。所以控制器的任务不是“用力纠偏”而是“稳稳地把误差收敛到零”。PI闭环就是最简单的、能完成这个任务的结构。2. PI控制器为什么是“PI”而不是只有P2.1 比例项反应快但留下了稳态误差比例项很简单输出u Kp × e误差越大输出越大误差为零输出也为零。你拿纯比例控制一台电机设定1000转编码器实测900转误差100转控制器输出一个正比于100转的占空比当负载导致转速只有990误差变成10转输出下降系统最终会稳定在某个转速那时误差是多少呢是那个刚好能维持当前负载所需控制量的误差值。这句话是理解稳态误差的关键。绝大多数被控对象都有一个特性想要输出不为零控制量就必须不为零。电机要克服摩擦和负载占空比必须有个基础值加热器要保持温度PWM功率必须等于热损失。而纯比例控制下控制量和误差严格成正比你想让它输出这个“基础值”就得保留对应的误差。所以比例控制永远有静差。我还记得第一次做温度控制纯P控制恒温在60℃结果实际温度始终停在58.6℃我以为是Kp不够大把它翻了3倍温度确实拉到了59.4℃但一开房间门热量流失温度又掉到58.2℃。那个“始终差一点”不是参数问题是算法问题比例项注定留下残差。2.2 积分项一个自动记账的补偿器积分项做的事就俩字记账。它把历史误差从头到尾累加起来输出u Ki × ∫e(t)dt只要误差不为零这笔账就越记越大输出就持续增大直到误差被完全消灭。回到电机那个例子。误差是100转P项输出50%占空比I项开始积累先从0慢慢加每一毫秒都往输出上叠一点占空比从50%变成51%、52%……转速开始回升误差变小。误差小了P项输出降了一些但I项不会立刻缩水——它是累积量只会慢慢调整方向。最终误差被压到零I项的累积值正好停留在那个“维持负载所需的基础控制量”上系统就稳定了而且是在误差为零的位置稳定。P项做不到的I项做到了。生活化类比一下比例项像一个反应快但脾气急躁的员工看到月末业绩差立刻加班加点冲积分项像一个记账的小会计把你这个月每一天的欠账都记下来天天提醒你补直到补齐为止。P管当下I管历史二者相辅相成。2.3 PI合体之后的工作逻辑把两者组合起来控制率就是u(t) Kp·e(t) Ki·∫e(t)dt。表面看是相加实际上是分工系统刚出现误差时P项占主导立刻给出一个较大的控制量把系统拉向目标随着时间推移I项把残余的微小误差逐渐抹平最终稳态误差为零。这里有个很重要的细节I项不是越快越好。大Ki能让系统快速消除误差但如果积得太快系统会过冲——还没到1000转误差已经变成负数积分项还在以旧账的方式往上冲等它反应过来往回收转速已经冲到1050转了。所以PI的调参本质上是在“快速归零”和“不要过冲”之间找平衡点。比例项也并非越大越好。Kp太大会导致控制器对微小噪声都做过激反应系统会抖。我调试步进电机时见过很典型的现象Kp从200升到400速度响应确实快了一截但编码器读数的噪声也被放大了电流波形上全是高频毛刺电机运行噪音变大发热还更严重。后来我保留了一个适中的Kp把稳态精度交给了I项问题才解决。3. 算法落地位置式PI与增量式PI的工程取舍3.1 位置式PI的直白逻辑实际代码里积分不是真正的连续积分而是离散累加。位置式PI的公式是float PI_Positional(float target, float feedback) { float error target - feedback; integral error; // 历史误差累加 float u Kp * error Ki * integral; return u; }非常直白。每过一个控制周期算一次误差加进积分器再按比例放大输出。这里的u是“绝对控制量”比如占空比50%、电流5A。它最明显的缺点是积分项integral会越来越大一旦执行器饱和误差还在累加退出饱和时输出会拖很久才能收回——这就是积分饱和的雏形。位置式PI还有一个容易被忽略的问题你换了一个工况积分器的初始值要从零开始或者需要手动复位。如果不清零系统会带着上一轮的“旧账”进入新的工作状态启动时可能瞬间满功率输出。所以工程上位置式PI通常要和积分限幅、条件积分配合使用。3.2 增量式PI嵌入式项目更偏爱它增量式PI不直接算绝对控制量而是算“这次比上次要多输出多少”。推导过程也不复杂u(k) Kp·e(k) Ki·Σe(i)u(k-1) Kp·e(k-1) Ki·Σe(i-1)两式相减积分项直接消掉大部分得到Δu Kp·(e(k) - e(k-1)) Ki·e(k)float PI_Incremental(float target, float feedback) { float error target - feedback; float du Kp * (error - last_error) Ki * error; last_error error; u du; // 输出 上一次输出 增量 return u; }增量式的优势在工程上非常明显。第一它天然没有积分累积量不会出现旧账清不掉的问题第二当系统出现故障、执行器手动切换时增量式只需要停止增量输出控制量保持在当前值不会跳变。位置式可能因为积分器里的庞大数据瞬间给出一个离谱的输出增量式不会。代价也有它需要保存上一个周期的误差而且它对测量噪声更敏感——计算里有一项是“当前误差减上次误差”噪声会让这个差值乱跳输出也会跟着抖。所以用增量式PI时反馈信号的滤波处理就特别重要编码器速度值我会先做一阶低通滤波不然系统会抖到你怀疑人生。3.3 固定控制周期和输出限幅无论位置式还是增量式都有一个隐秘前提控制周期必须固定。PI公式里的Ki依赖时间单位你算好的Ki是基于10ms周期调的突然改成1ms执行积分速度放大了10倍系统当场就可能震荡。所以控制周期必须用定时器固定住我习惯把周期做成宏定义整个项目里只允许这一个变量控制执行频率。输出限幅也是刚需。电机PWM占空比最大100%电流环最大电压受限你算出来的u理论上可以到几百但执行器不可能输出超过物理极限的量。不做输出限幅不仅执行器可能过流积分器也会因为误差持续累积而陷入深度饱和。我的习惯是在PI结构体里放三个变量输出上限、输出下限、积分上限。每次周期任务里算完u先判断是否越界再决定要不要继续积分。这里其实已经一只脚踩进了抗积分饱和的领域下一节展开说。4. 调参实战先P后I、临界振荡与积分饱和4.1 一条靠谱的调参路径先P后I我见过的调参方式五花八门新手最容易犯的错是一个参数两个旋钮一起拧拧到系统抖了又不知道是谁的责任。我自己的经验是严格分两步走第一步把Ki设为0只调Kp。先把目标转速设到额定值的30%左右从一个很小的Kp开始比如电机系统从0.01起逐步增加观察响应。你会发现一开始系统反应很肉转速缓慢爬升Kp增大到一定程度系统开始出现超调和轻微振荡。记录下这个临界振荡的Kp值然后把它往回退到60%~70%的安全区。这一步的目的就是让P项单独能“稳住”系统不要指望它消静差只要不振荡就行。第二步引入I项。Ki从非常小的值开始比如Kp的1/10每次翻倍观察转速从启动到稳定的过程。理想状态是误差先被P项快速压下去然后I项慢慢地、毫不暴力地把最后一点残差抹平。如果出现明显的过冲或振荡说明Ki偏大先按1/3倍退回来稳定后再缓慢增加。这个流程听起来慢但很稳。工程调试最忌讳的是“眼见系统响应不够快就猛加参数”结果往往是参数失控系统要么长时间振荡要么超调大到不可接受最后还得从头来过。4.2 积分饱和一个几乎绕不过去的坑积分饱和是PI落地时最经典的问题。它发生在执行器已经达到物理极限、误差却还在继续累积的时候。比如堵转的电机你设定1000转电机实际0转误差1000积分器持续累加很快输出就顶到100%占空比。此时执行器已经饱和你无论怎么继续积分物理上都不可能增加输出。等你排除故障、转矩恢复正常问题来了积分器里积累的是一个巨大的值输出被它拖着继续保持100%占空比电机会疯狂加速冲过设定值系统在几秒后才反应过来开始退积分——这期间已经超调了一大截。对于有位置约束的机构这一大截超调可能就是撞机、过流、烧驱动。积分饱和的本质是“控制器记住了它在饱和期间不该记的账”。防止它核心就一句话让积分器只在输出未饱和时工作。4.3 三种抗积分饱和的实现方案第一种是钳位法最直接输出达到上限时限制积分器继续增大输出达到下限时限制积分器继续减小。实现上放一个判断u Kp * error Ki * integral; if (u u_max) u u_max; else if (u u_min) u u_min; else integral error; // 只在没饱和时累加这套逻辑很简单但有个问题如果积分器和输出是同一个结构比如位置式得把积分器的判断放在u超出限幅之前否则正常工作时积分器也会漏掉一些累加。我一般用一个更保险的写法——先算出未限幅的u判断未超界才允许积分累加。第二种是积分分离也叫条件积分。误差绝对值大于某个阈值时关闭积分误差小到阈值以内才打开积分。原理是误差大时系统处在快速动态区靠P项即可积分的意义不大反而容易堆积误差小时系统接近稳态正是积分器发挥作用的区域。阈值一般取设定值的5%~10%。第三种是反算法主流PID库用得比较多。核心思想是输出饱和时把“饱和状态下实际输出和理论输出的差”反馈回去反向抑制积分器的增长。这个是经典的anti-windup回路代码稍复杂但响应品质最好。我在做FOC电流环时用的就是反算法效果明显优于单纯钳位。5. 从PI到PID微分项补了什么位置5.1 微分项的本质是预测但会放大噪声PI已经能消除稳态误差为什么还要D因为你可能会发现用PI调节时系统在动态过程中仍然有明显的超调和振荡。D项的工作是计算误差的变化率u Kp·e Ki·∫e Kd·(de/dt)误差变化越快输出就越早“刹车”。你可以把它理解成驾驶员看到前方红灯P是“看到距离还很远就先匀速开”D是“根据接近速度提前踩刹车”。但微分项有一个非常现实的代价噪声。理想情况下误差是一条平滑曲线但实际反馈信号里总带着测量噪声噪声的导数非常大D项会把噪声放大到比信号本身还猛。我试过在某些编码器分辨率偏低的场合直接加D结果输出的PWM出现了密集毛刺电机噪声立刻变大电流波形也没法看。5.2 哪些场景保留PI就够了以我的经验以下场景D项是可有可无甚至有害的电机速度环、电流环电流环本身是PI就可以做得很快加D反而会引入高频噪声、大惯量对象因为速度本身已经包含了变化率信息再加D意义不大。D项真正不可替代的场景是温度、流量这类大滞后系统或一些位置控制中需要极强的动态响应时。但加D之前必须先保证反馈信号经过了平滑滤波数值上误差不能跳变。否则我建议不加宁愿多花时间调PI也不要去扛噪声的副作用。现在很多新手一看书上有PID就三个参数都往上调实际上大多数工程项目里PI已经够用了。你不用D是给自己省掉一大堆后顾之忧。先想清楚被控对象缺什么再决定要不要加第三个旋钮。6. 工程实例步进电机闭环与FOC电流环里的PI6.1 步进电机速度闭环里的PI配置步进电机的开环控制以丢步闻名加了编码器做闭环之后可以在不失步的前提下把电流用得更足。实际接法是这样电机轴端装一个2000线的编码器STM32的定时器接口直接读脉冲速度计算就是单位时间脉冲增量换算成转速值目标转速由上位机给到误差进PI控制器输出作为步进电机的目标电流或脉冲频率修正量。调参时我发现步进电机有一个特殊性它的转矩与电流关系相对线性但机械系统的共振点会让某些转速段出现抖动。PI参数如果调得过快刚好会激励这个共振。我的做法是速度环Ki取偏小让系统响应略“肉”一点然后靠前馈补偿基础电流PI只负责修正残差这样既稳又准。6.2 FOC电流环的PI周期短、限幅严在FOC磁场定向控制里电流环是内环控制周期极短常常是10kHz~20kHz对应的控制周期是50~100微秒。电流环PI的Kp和Ki要考虑到电流采样延迟、PWM占空比更新延迟参数给得太大电流波形直接发散给太小转矩响应又慢。FOC电流环里还有一个避不开的限制电压限幅。母线电压就那么多电机反电动势在高速时还会抵消一部分可用电压。如果PI输出算出的电压超过限幅值电流环就会饱和表现就是高速时电流跟不上指令、波形削顶。所以在FOC里抗积分饱和不是可选功能是标配。我调FOC电流环的经验是先断开速度环给定一个固定电流指令单独调电流环的Kp和Ki。Kp从电阻压降对应的电压值估算起Ki取Kp的1/10左右然后看阶跃响应。电流环达到“响应快、无超调、稳态稳”的目标后再去调外环速度环。这种分层调试的方法能让你尽早隔离问题——如果电流响应就有问题不用急着去动速度环。最后说一个很实战的小技巧调PI时别只用设定值跟踪看效果一定要做一次负载突变测试比如瞬间加大负载转矩观察系统能否快速恢复。PI参数在稳态看起来差别不大但抗扰动能力一测便知。我自己习惯用“扰动恢复时间”作为最终验收指标这个指标比纯阶跃响应对参数优劣的区分度高得多。
返回列表