尧图精选

从PI闭环到抗积分饱和:电机调速系统实战全解析

🕒 发布时间:2026/9/9 9:44:10 📁 来源:尧图网络
做运动控制项目的人多半都经历过这么一幕参数在仿真里跑得漂漂亮亮一上实物就开始抖或者开环状态下给了50%的PWM电机空载转速看起来还行一压上负载转速瞬间掉下去一大截。我这个系列项目推进到P2阶段核心工作就是给执行机构加上PI闭环控制让转速从“大概是多少”变成“说多少就是多少”。这篇记录不打算泛泛讲PI公式推导而是把从反馈采样、离散化、代码实现到参数整定、抗积分饱和的完整链路摊开写一写实测中真正有效的那套做法。适合正在做电机调速、温度控制、电流环或者任何需要把系统“稳住”的工程师和爱好者参考。1. 为什么先上PI而不是直接上PID——控制方案选型的取舍1.1 开环控制的痛点给了电压不等于给了转速最开始的实验台是没有闭环的。上位机给定一个PWM占空比经过驱动板放大后直接加到直流电机两端电机轴上装一个编码器用来测速但测到的速度只是用来显示不参与控制。这就是典型的开环控制输入是占空比输出是转速中间没有任何“看看当前实际转速再修正一下”的环节。问题很快就暴露了。空载时给定50%占空比电机稳稳转在2800 RPM左右用手捏住联轴器模拟一下负载转速不到一秒钟就掉到2200 RPM附近。松开手转速又自己弹回来一点但回不到原先的值。原因是电机的转速近似由电枢平均电压减去电枢内阻压降后决定负载一大电枢电流就大内阻上的压降上升实际作用于反电动势的电压变小转速自然掉下来。开环系统根本不知道转速掉了它只负责把占空比保持不变于是转速误差就被完整地保留在系统输出上。如果项目只是让风扇转起来这点误差可能无所谓但P2阶段的目的是做一套可以复用的伺服式转速控制单元后续还要驱动进给机构负载扰动几乎一定会出现。这个时候第一条设计决策就出来了必须引入闭环加入反馈用误差去驱动控制量。1.2 纯比例控制的硬伤稳态误差无法根治最直觉的闭环控制方案是纯比例控制。把目标转速和实际转速做差误差越大PWM输出越大公式就一行u Kp * ee 是误差Kp 是比例增益。这个方案接入系统后响应速度明显改善用手捏联轴器转速掉的幅度比开环小很多恢复也快了不少。但有一个现象非常讨厌只要负载一直存在转速就永远比目标值低那么一小截。比如目标3000 RPM带负载后稳定在2950 RPM误差50 RPM永远消不掉。这不是Kp不够大的问题而是纯比例控制的数学结构决定的。系统稳定时误差必须保持一个非零值来支撑输出u因为如果把误差减到零输出uKp*00电机就失去了维持转速的驱动力。负载越大维持这个转速需要的PWM越高稳态误差也越大。换句话说纯比例控制是用“永远差一点”换来的“跟得上变化”它本质上是一种有差调节。所以在P2阶段光有比例项是不够的必须把积分项加进来让系统变成一个真正的PI闭环控制用积分去清除那个“永远差一点”的残余误差。1.3 为什么这个阶段不引入微分项既然都聊到PID了可能有人会问为什么不直接上完整版的PID非要停在PI我的回答很简单微分项在这套系统里的副作用远大于收益。微分项的输出正比于误差变化率D参数稍微给大一点它对噪声就是一台放大器。电机上用的编码器测速哪怕做了滤波相邻两个采样周期之间的脉冲计数也会有几一点的跳动温度变送器输出的信号噪声更大。这些噪声经过微分放大之后叠加在PWM输出上系统会表现出高频抖振电机嗡嗡响执行器发热。PI闭环控制已经能解决大多数“快和准”的问题。D项真正有价值的地方是在被控对象有明显超调倾向、需要额外阻尼的场合。这个项目P2阶段的首要目标是先把稳态精度和抗负载扰动做扎实而不是追求极限的动态响应所以我选了PI而不是PID。始终记住一句话控制器的复杂度应该跟着被控对象的实际情况走不是为了把某种算法名气大就硬上。2. 比例项管快、积分项管准PI闭环的数学机理与数字化表达2.1 闭环回路的基本骨架给定、反馈、偏置与执行PI闭环控制系统可以抽象成四个基本环节给定值r、反馈值y、控制误差e、执行量u。一个采样周期里的动作顺序大致是采集反馈y计算误差er-y按PI公式算出一个新的控制量u再把u送给执行器然后等待下一个采样周期。这里面有一个非常容易踩坑的地方反馈量和给定量必须是同一个物理量、同一个量纲。电机控制里编码器测出来的原始数据是脉冲数要换算成RPM再和给定的RPM比较温度控制里如果测温模块输出的是ADC码而给定值是摄氏度就必须先完成标定换算。把原始数据直接拿来做差Kp和Ki的数值会变得非常难理解参数调整也会极其痛苦。2.2 连续域公式与离散化公式教科书上的连续域PI公式长这样u(t) Kp * e(t) Ki * ∫e(t)dt其中Kp是比例增益Ki是积分增益。到了单片机和嵌入式系统里积分没法做连续运算必须离散化。如果采样周期Ts固定用最简单的矩形积分近似位置式PI就可以写成integral[k] integral[k-1] e[k] * Ts u[k] Kp * e[k] Ki * integral[k]这里integral就是误差累积量Ki是积分项的增益。注意Ts在这里的作用很关键它决定了每次累加误差时的“时基”。如果Ts不稳定比如主循环里顺手调一次PI而主循环周期受其他任务影响而波动那么积分强度的实际效果就是时快时慢系统会出现说不清的低频抖动。所以正统做法是用定时器中断固定一个采样周期PI计算在中断里完成主循环只负责收发命令和显示数据。2.3 Kp、Ki、Ti三者关系以及不同控制器的表达差异这里必须单独拿出来强调因为我在实际项目里见过太多人栽在单位上。Kp和Ki是控制代码里直接使用的增益而在很多商用PLC、驱动器、温控器里参数面板上写的不是Ki而是Ti即积分时间常数单位是秒。两者的关系是Ki Kp / Ti由于单位体系和习惯不一样很容易出现把Ti当Ki填进去的情况。不同控制器对积分参数的表达方式大致有这么几种参数形式常见设备数值变大意味着什么Ki积分增益自写嵌入式代码积分作用增强Ti积分时间西门子、倍福等PLC积分作用减弱Res积分速率部分驱动器积分作用增强判断逻辑很简单凡是叫“增益”的通常是Ki数值越大积分越猛凡是叫“时间”的通常是Ti数值越大积分越弱。拿到一台不熟悉的设备第一步先查清楚参数单位再开始调参数。2.4 比例和积分配合的直观感受用开定速巡航的车上坡来类比比例项是“现在速度比目标低就多踩油门”它立刻反应踩多少和速度偏差成正比积分项是“从刚才就一直比目标低我一直欠着动力得持续补上”它记忆过去把之前没有消除的误差积攒起来逐步把油门加到能克服坡度的程度。下坡时速度超过目标比例项先松油门积分项再把之前积攒的“欠账”慢慢还掉直到重新平衡。比例项决定系统对误差有多敏感积分项决定系统能不能把残余误差彻底清零。P让控制及时、跟手I让控制无静差、抗负载扰动。两者配合的目标是在“响应够快”和“不过度超调”之间找到一个可接受的平衡点。3. 以电机转速环为例把PI闭环控制落到一串可运行的代码上3.1 被控对象、执行器与测速反馈的选择P2阶段的实际被控对象是一台带霍尔编码器的直流减速电机额定电压24V额定转速3000 RPM减速比30。执行器是PWM输出经过一个H桥驱动板控制电机两端电压。测速反馈有好几种选择最简单的是在电机轴上装光电或霍尔编码器单位时间内计数得到脉冲频率。测速方法上速度环最常见的是M法和T法。M法是在固定时间窗口内数脉冲个数适合速度较高的场合T法是测量一个或多个脉冲的时间间隔适合低速场合。低速时脉冲计数很少M法分辨率急剧下降所以很多驱动器会把两者综合起来。如果你的电机在多数工况下转速不算太低M法配合几ms到几十ms的测速窗口已经够用。转速换算公式RPM (pulse_count / pulses_per_rev) * (60 / T_measure)比如编码器一圈输出1000个脉冲测速窗口10ms一个窗口内数到50个脉冲那么转速就是(50/1000)*(60/0.01)300 RPM。3.2 采样周期怎么定才靠谱PI闭环控制的采样周期不是一个可以随便拍脑袋定的数。采样太快比例项会把反馈信号里的高频噪声当成真实误差PWM输出跟着高频抖采样太慢反馈滞后严重系统容易变成低频振荡总也稳不下来。工程上有一个常用经验采样周期至少要比系统主要时间常数快5到10倍或者说采样频率取期望闭环带宽的20到50倍。直流电机速度环的主要机电时间常数一般在几十毫秒量级速度环采样周期取1ms左右是比较常见的选择电流环要求更高带宽通常0.1ms到0.25ms温度控制对象时间常数以秒甚至几十秒计采样周期放到0.5秒到2秒没有问题。3.3 位置式与增量式选哪种离散化PI程序有两种常见形态位置式和增量式。位置式PI直接算出当前控制量的绝对值算法结构和连续域公式一一对应直观易懂integral err * Ts; out Kp * err Ki * integral;增量式PI算出的是控制量的变化量du当前输出等于上一次输出加dufloat du Kp * (err - err_prev) Ki * Ts * err; err_prev err; out du;两种方式在数学上是等价的但工程表现有差异。增量式输出的历史累积在out变量里切换手动自动、从零点起步时没有积分项跳变的问题抗饱和处理也相对简单位置式输出绝对量必须额外做积分限幅和抗饱和处理。很多工业运动控制器偏爱增量式就是因为切换无扰动。但位置式更适合讲解原理我在下面的代码里给出一个位置式的实用实现并带好抗饱和逻辑。3.4 可直接使用的C语言PI控制器下面这段代码是我在STM32平台上实际用过的结构移植到任何MCU上只需要改数据类型和输入输出接口。typedef struct { float Kp; float Ki; float Ts; float integral; float out_max; float out_min; } PI_Controller; float PI_Update(PI_Controller *pi, float setpoint, float feedback) { float err setpoint - feedback; float out; // 先按当前积分项算出未限幅输出 out pi-Kp * err pi-Ki * pi-integral; // 抗积分饱和输出已经顶在限幅上且误差方向继续加深饱和时冻结积分 if ((out pi-out_max err 0) || (out pi-out_min err 0)) { // 不更新 integral } else { pi-integral err * pi-Ts; } // 重新计算并做输出限幅 out pi-Kp * err pi-Ki * pi-integral; if (out pi-out_max) out pi-out_max; if (out pi-out_min) out pi-out_min; return out; }使用前把结构体清零设置Kp、Ki、Ts以及输出限幅值然后在定时中断里周期调用PI_Controller speed_pi {0}; speed_pi.Kp 0.15f; speed_pi.Ki 0.8f; speed_pi.Ts 0.001f; speed_pi.out_max 1.0f; // 归一化PWM0~1 speed_pi.out_min -1.0f; // 负值代表反转这个归一化PWM的写法比较省事占空比0到1映射到驱动板的实际输出需要反转时用负值配合H桥使能信号。3.5 参数初值如何快速估算很多人第一次调PI不知道Kp和Ki从多少开始于是随机填结果要么不动要么疯狂振荡。其实可以根据执行器余量做一个粗略估算。如果100%PWM对应3000 RPM也就是说每增加10%PWM大约能提升300 RPM那么要让100 RPM的误差产生10%的PWM修正量Kp大约是0.1。这个值不精确但作为起点比较安全。Ki的初值可以根据Kp和时间常数估算Ki Kp / (3 * T)。假设速度环等效时间常数T约0.05s那么Ki约0.67。你可以取一个更保守的0.1然后按下一节的整定流程逐步加不要一上来就用大Ki。4. 从“能转”到“稳且准”参数整定方法与响应曲线判读4.1 先比例后积分的凑试流程调PI参数绝大多数情况下都应该走“先比例后积分”的路线不要一上来就同时拧两个旋钮。我的操作流程是这样的第一步把Ki设成0只保留比例项。Kp从估算值的0.5倍开始给电机一个小阶跃比如目标从0升到500 RPM观察响应曲线。如果转速上得太慢Kp翻倍如果出现明显的持续振荡Kp减到上一档。第二步找到Kp的一个“可用值”即系统响应速度还行、轻微超调但不持续振荡的状态。这时候记录稳态误差比如目标500 RPM最终稳定在470 RPM偏差30 RPM。第三步从0开始慢慢加大Ki。每加一次观察两个东西一是静差是否在几个周期内逐步消失二是系统是否出现低频长周期振荡。静差消散太慢就继续加Ki出现低频振荡就退回上一档。第四步把Kp和Ki做一次微调。通常规律是超调大时先降一点Ki再考虑降Kp响应慢但静差消得快说明Ki已经够问题在Kp偏小。这个过程看的是阶跃响应曲线而不是靠耳朵听电机响不响、眼睛看转速表准不准。曲线能告诉你的信息量远大于体感。4.2 临界比例度法Ziegler-Nichols的操作要点如果不想完全靠瞎凑可以用经典的Ziegler-Nichols临界比例度法也叫边界振荡法。操作步骤如下把Ki设成0系统只保留比例控制。Kp从小到大逐步增加每加一次给系统一个较小的阶跃扰动观察输出。直到系统输出出现等幅振荡记下当前的Kp为临界增益Ku同时用示波器或上位机记录振荡周期Tu。根据Ku和Tu按Ziegler-Nichols的经验公式设置参数。PI控制器的对应参数是控制器KpTiKiP0.5 * Ku--PI0.45 * Ku0.85 * TuKp / Ti这里Ki是算出来的因为公式里给的是Ti积分时间。注意单位别把Tu当秒数把Ki直接填成0.45*Ku凑数。必须提醒一句临界比例度法会让系统达到等幅振荡边界这对机械系统有一定风险。带皮带、减速箱、丝杠的实验台在振荡测试前先把行程限位和安全停机检查好给一个较小的速度目标做测试别直接在3000 RPM下做临界振荡试验。4.3 常见波形现象与参数调整对照表在实际调试中我习惯把给定值、反馈值、PI输出三个信号用串口或上位机记录到同一个图表里然后对照下面这张表排查现象主要可能原因调整方向响应很慢静差长期不消Kp偏小增大Kp高频小幅振荡电机嗡嗡响Kp偏大减小Kp低频大幅振荡转速来回冲积分过强减小Ki或增大Ti静差始终存在但响应平稳Ki偏小增大Ki带载后掉速恢复得慢Ki偏弱增大Ki超调大且要很久才回到设定值Ki过大或Kp过大先减Ki再观察Kp一个关键原则一次只改一个参数。改成之后至少等系统完成一个完整的调节过程再判断。很多人一看到振荡就同时把Kp和Ki都往小了拧结果系统变成沉闷的“慢郎中”静差也回来了最后只能从头再调。4.4 保存调试日志让参数调整有据可依我做PI闭环控制这几年最大的体会之一就是调试过程必须有日志。没有日志你只会记得“刚才好像振了一下”但忘了振的频率、幅度和你上次改的参数值。有日志每次调整都对应一条曲线哪次改了什么参数一目了然。最简单的做法是在PI控制函数执行后通过串口打印三通道数据printf(%.2f,%.2f,%.2f\n, setpoint, feedback, out);直接输出CSV格式上位机端用串口助手保存成文本拖到Excel或Python里就能画图。调参时给每组参数取个编号比如P2_PI_001日志文件里写上Kp、Ki、Ts这样整个调试过程完全可回溯。5. 数字PI最容易翻车的现场限幅、积分饱和与抗饱和设计5.1 输出限幅第一道安全线PI控制器的输出最终要送到PWM寄存器、DAC或者伺服驱动器的指令端口这些执行器件都有明确的物理上限。PI计算出来的数值如果不做限幅直接下发轻则出现截断和异常行为重则损坏设备。输出限幅的第一件事是确定上下限。对PWM来说上限就是100%占空比下限是0如果需要反转那就是-100%到100%用负占空比配合H桥方向信号。对DAC来说是满量程电压。限幅的代码很简单if (out pi-out_max) out pi-out_max; if (out pi-out_min) out pi-out_min;千万别觉得这是多此一举。PID输出本质上是浮点数而执行器是物理量二者之间的映射边界必须由控制器主动管理不能指望执行器自己把多余的输入“消化”掉。5.2 积分饱和的发生机理与典型故障现象积分饱和是数字PI实现里最阴险的坑它的发生机制是这样的系统刚启动时误差非常大比如目标3000 RPM电机还没转起来误差就是3000。积分项每个采样周期都在累加几个毫秒后积分值就变得很大控制器输出瞬间顶到输出上限这很正常。问题在于电机转速上升是需要时间的。在转速还没跟上来的这段时间里误差持续为正积分项继续累积哪怕输出已经到100%了积分还在往上堆。等到转速终于到达目标值附近误差变成零但积分项里已经积累了远超实际需要的“能量”输出继续维持在很高的水平电机一路冲过目标转速直到误差反转为负数并持续一段时间积分才被慢慢“还回去”。整个过程的典型表现是大超调、长时间振荡极端情况下电机直接冲高速机械机构受到很大的冲击。5.3 抗积分饱和的三种做法冻结法、条件积分与反算法解决积分饱和的思路是想办法让积分项不要超出合理范围或者让多余积分尽快释放。工程上有三种常见做法。冻结法最常用当控制器输出已经顶在限幅值上并且当前误差的方向仍然是继续加深饱和时就不更新积分项。对应到代码就是我前一节给出的那段逻辑先算一次未限幅输出判断是否饱和且误差同向如果是跳过积分累加。这个方法实现简单、可靠性高大多数场合够用。条件积分积分分离误差绝对值大于某个阈值时只用比例项不让积分参与等误差小于阈值后再恢复积分。这个方法适合给定值经常大范围跳变的系统可以避免超大误差把积分项打满代价是多了一个额外阈值参数需要根据实际工况去试。反算/back-calculation在抗积分饱和能力要求高的场合用未限幅输出与限幅后输出之间的差值乘以一个反馈系数反向修正积分项integral err * Ts Kb * (out_sat - out_unsat)这个公式的作用是一旦执行器饱和控制器就“知道”自己给的输出被压住了并把压掉的那部分从积分上退回来。Kb一般取1/Kp或1/Ti具体数值要实测调整。5.4 手动自动切换、启动停机中的积分处理位置式PI还有一个很现实的问题手动自动切换的瞬间积分项可能为零而这时执行器还在某个非零输出位置。如果直接把自动输出切上去控制量会出现一个跳变设备猛冲一下这就是无扰切换没有做好。解决办法是在手动状态下把积分项的值实时刷新为“当前执行器输出除以Ki”pi-integral current_output / pi-Ki;这样切到自动时PI控制器输出接近当前执行器位置不会产生跳变。很多运动控制器在增量式PI里天然规避了这个麻烦因为它输出的是增量切换时自动加上之前的手动位置即可。启动和停机也要考虑积分处理。大惯量系统启动时可以先给一个固定偏置PWM让系统尽快进入PI可控区间停机时把积分清零避免下一次启动带着错误记忆。5.5 我踩过的一次积分饱和故障复盘第一次调这个实验台的时候我在代码里只做了输出限幅没有抗积分饱和。上电瞬间PWM输出直接冲到100%转轴像弹出去一样联轴器都被带得“咔”一声幸亏速度目标给得不大不然传动结构都可能受伤。后来我把串口日志调出来看非常清楚启动后10ms积分项就已经比稳态需要的值大了将近一倍输出一直是100%速度到目标之后输出还维持在100%整整几百毫秒转速冲过去一大截才开始掉头。这就是一个教科书级的积分饱和案例。加了冻结法之后启动冲击明显变小超调从将近30%降到10%以内。那次之后我形成了一个习惯只要是位置式PI第一版代码就把抗积分饱和写进去不给“以后再补”留机会。6. PI闭环的适用边界与延伸场景以及我的一套调试习惯6.1 温度、电流、电压环中的PI差异PI闭环控制绝不只用在电机转速上温度控制、电流环、电压环、充电控制等多个场景都在用但每个场景的参数尺度差异很大。温度控制的对象通常有非常大的热惯性时间常数从几秒到几十分钟不等采样周期必须放到秒级甚至十几秒级。PI里的积分项在这里负责消除稳态误差比如恒温箱设定50°C如果只用比例可能稳定在49.2°C就再也上不去了加上适度的积分经过一段时间的累积温度会慢慢逼近50°C。但积分强度不能给大否则就会出现温度冲到55°C再掉下来的“过冲式恒温”。电流环是高性能场合的典型例子比如伺服驱动器、直流有刷电机的电流内环。电流环采样周期很短通常0.1ms级别控制器输出直接决定PWM占空比。电流过冲可能损坏功率器件所以电流环的PI参数一般偏保守强调阻尼和平稳而不是一味追快。电压环在DC-DC电源、充电板里很常见负责维持输出电压恒定。负载突增时电压会瞬间跌落PI的积分项决定恢复速度。这里要注意的是电压环的反馈信号往往有较大的纹波噪声积分太强会导致输出端出现低频自激振荡。6.2 什么时候才需要考虑PIDPI闭环控制可以解决大量一阶惯性加延迟的系统但有些场景确实需要D项出手。典型表现是系统超调倾向明显单纯调小Kp和Ki能把超调压住但响应时间被拉得太长这种情况下加D可以起到阻尼作用在响应速度和超调之间找平衡。但D项的前提是反馈信号足够干净。如果编码器测速在低速段本来就有脉冲抖动或者温度变送器输出本身波动幅度大加D之前必须先做滤波或者降低采样带宽否则D会把噪声放大成实实在在的输出抖动。一个实用判断先看系统是否能在PI参数下稳定运行。如果PI已经能把系统稳下来只是动态性能不满意再考虑加D如果系统连PI都稳不住先把硬件、采样、执行器层面检查一遍多半问题不在缺少微分项。6.3 PI闭环解决不了的问题控制算法不是万能的PI闭环控制同样有它的能力边界。我遇到过几个场景最后都没有在PI框架内硬扛。第一类是有明显大时间延迟的系统。比如温度传感器离加热器很远热量的传输本身需要较长时间误差反馈回来时已经太晚PI会表现为反复振荡。这种情况需要Smith预估器或者模型预测控制而不是单纯加大阻尼。第二类是强非线性对象。某些执行器在低输出段不动作超过某个阈值才猛地起效这种死区加饱和会让PI参数很难同时兼顾小信号和大信号。简单的办法是加非线性补偿或增益调度把PI参数按工作点分段切换。第三类是执行器余量不足。如果电源电压已经不足以支撑目标转速PI怎么调都不可能把误差清零。控制器能做的只是输出饱和误差只会被积分项记住然后一直维持在一个极限点。这时候要回头检查硬件而不是继续折腾参数。6.4 我现在调试PI的习惯最后聊几个我已经固化的习惯算是给后来的调试者一些参考。第一个习惯是所有参数调整都必须伴随日志记录把给定、反馈、输出三路信号完整保存下来参数改动前后各跑一次同样的阶跃两相对比比自己凭记忆判断靠谱得多。第二个习惯是永远保持“先纯比例后加积分”的调参顺序先让系统稳下来再考虑准确性顺序反了你很难定位问题是出在P还是i。第三个习惯是位置式PI的代码第一版就写好抗积分饱和不要等现场出了问题再补。PI闭环控制这个主题原理讲起来很简单真正玩明白靠的是反复处理那些不起眼的工程细节采样周期固定、反馈单位统一、限幅和抗饱和到位、参数调整有据可依。把这段话消化掉你手上那套系统离“稳且准”就不会太远了。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →