资讯详情

资讯详情

BP神经网络在线自整定PID的PMSM转速环控制仿真

做仿真课题的人多少都有这种体会一套PMSM双闭环矢量控制模型电流环调好之后基本不用再操心真正反复折磨你的是转速环那一对PI参数。给定幅度一大就超调负载一变就掉速想把稳态精度和动态响应同时兼顾结果往往是两头都差一口气。我刚开始做永磁同步电机矢量控制仿真时也是这样后来把BP神经网络在线自整定PID简称BP-PID用到转速环上才把这个问题理顺。这个课题说穿了就是一件事让BP神经网络在控制过程中实时计算并调整PID的三个参数替代人工整定然后整体嵌入Simulink里的永磁同步电机双闭环矢量控制模型通过仿真验证它在启动、负载突变、参数变化等场景下比固定PI强在哪里。适合正在做电机控制毕业设计、或者想把手动调参的传统FOC框架升级成智能控制方案的同学参考。这篇文章我从原理、建模、代码实现到结果对比把完整思路和踩过的坑一次性讲清楚。1. 固定PI在转速环上的三个“吃瘪”场景为什么非要用神经网络换掉它1.1 双闭环框架里转速环的实际地位先梳理一下PMSM矢量控制的整体逻辑。永磁同步电机的定子三相电流经过Clarke变换和Park变换之后变成d轴分量和q轴分量采用id0控制策略电磁转矩就近似与iq成正比电机在控制上看起来像一台直流电机。控制结构分内外两层内环是两个电流环把id、iq快速跟踪到指令值外环是转速环根据转速误差给出iq指令也就是转矩需求。这里有个容易被忽略的层级关系转速环是决策者电流环是执行者。电流环带宽通常设计为转速环的5到10倍所以电流环用固定PI就能扛住而转速环面对的是机电大惯性、负载扰动和参数漂移问题恰好集中在它身上。这就是为什么很多文章都拿转速环开刀而不是去动电流环。1.2 场景一转速给定突变时“快”和“稳”打架固定PI参数的整定通常是在某个工作点附近做的。你把参数按照500rpm阶跃调得刚刚好再给一个1000rpm的大阶跃超调往往立刻变大。反过来如果想减小超调就得把比例系数降下来、积分作用弱一点结果小阶跃的响应又变得拖泥带水。原因在于PMSM的转速环本质上是一个非线性对象。电磁转矩Te1.5pnψf·iqiq_ref由转速环给出而转速反馈又反过来影响转矩输出这个闭环内部存在多个工作点。不同转速、不同负载下最优的PI参数根本不是一个固定值。固定PI能做的只是取一个“折中值”保证所有工况都不太差但也不可能在某个工况下做到最好。1.3 场景二突加负载后的那段时间最难熬转速环抗负载扰动主要靠积分项。固定PI的积分速度只有一个固定节奏积分慢了负载突变后转速跌下去要很久才能拉回来积分快了又会在恢复过程中引起转速振荡。我在仿真里经常看到这种情况——突加额定负载后转速跌了五六十转然后绕着给定值振荡好几圈才稳定下来。这种振荡在电机实际运行中就是明显的“抖动”对机械负载非常不友好。BP-PID的价值在于它可以“看情况”调整积分作用误差大的时候Kp大一点、Ki补得快一点转速刚回到给定附近时又自动把参数收回防止冲过头。这等于给PID装了一个会变参数的“自动调参器”而这个自动调参器随着控制过程不断在线学习不需要人提前设计好规则。1.4 场景三电机参数不是恒定不变的永磁同步电机运行一段时间后定子电阻会随温度升高而变化永磁磁链也会受温度影响转动惯量如果拖动不同负载还会变化。固定PI建立在电机参数的某个样本点上参数一漂移控制品质就会偏离设计值。这也是工业现场经常出现“仿真调得好、现场用不灵”的一个原因。神经网络在线自整定的思路恰好能应对这种参数慢变它不依赖于精确的电机模型只靠转速误差的反馈来修正自己的输出。2. BP-PID控制器的内部逻辑不是离线训练好的模型而是在线换参数的PID2.1 整体架构在原PID外面套一个参数生成网络先澄清一个常见误解BP-PID并不是用大量数据离线训练一个端到端控制器它是把BP神经网络和传统PID“并联”起来——神经网络每个控制周期都根据当前误差状态算出一组Kp、Ki、Kd然后把它们交给底层的增量式PID去计算控制量。控制量输出之后再用转速误差去修正神经网络权值。整个过程是边控制边学习有点像人开车时根据方向盘反馈不断微调自己的操作力度。增量式PID的公式是Δu(k) Kp·[e(k) - e(k-1)] Ki·e(k) Kd·[e(k) - 2e(k-1) e(k-2)]u(k) u(k-1) Δu(k)这里的u对应转速环的输出也就是iq_ref。选用增量式而不是位置式最大的好处是控制增量只跟最近三次误差有关即使网络输出的PID参数发生突跳控制量的变化也不会被直接放大整体输出更平滑。2.2 网络结构输入三个数、输出三个数我用的网络是典型的3-5-3结构输入层3个节点隐含层5个节点输出层3个节点。输入选的是转速误差e(k)、误差变化率e(k)-e(k-1)、以及二阶误差信息e(k)-2e(k-1)e(k-2)这三个量本身就和增量式PID的三个分量一一对应网络很容易学到“什么时候该多用比例、什么时候该多用积分”的规律。如果再塞一个误差积分进去输入变成4个收敛速度反而更慢我实测下来三输入就够用。隐含层激活函数用tanh取值范围在-1到1之间比sigmoid的0到1更容易保持梯度稳定。输出层必须要做限幅处理网络原始输出经过sigmoid压缩到0~1再乘以各自的限幅系数Kp Kp_max·out1Ki Ki_max·out2Kd Kd_max·out3限幅范围需要根据被控对象来定。比如我那个示例模型里Kp_max取5、Ki_max取20、Kd_max取0.01这个范围不能给得太大否则网络参数会在限幅边缘来回撞转速波形会出现高频抖动。范围太小又限制了控制作用动态响应变差。2.3 反向传播误差怎么“教”PID换参数BP-PID的学习目标是最小化性能指标J(k)0.5·e²(k)也就是转速误差平方。权值修正沿负梯度方向Δw(k) -η·(∂J/∂w(k))∂J/∂w展开之后会经过链式法则需要穿过PID计算层和网络输出层。从误差到权值的传播路径大致是J → 转速误差 → 控制量u → PID参数(Kp、Ki、Kd) → 网络输出层 → 隐含层。其中最麻烦的一项是∂y/∂u也就是转速输出对控制量iq_ref的敏感度。这个偏导在真实系统里很难精确求工程上最常用的做法是用符号函数sign(∂y/∂u)近似也就是只保留方向、忽略幅值。输出层的修正项可以写成Δw2(j,i) -η·δ_j·h_i其中δ_j等于误差e(k)乘以sign(∂y/∂u)再乘以对应PID分量的误差项——第一个输出对应Δe第二个对应e(k)第三个对应二阶误差项最后乘以输出层激活函数的导数。隐含层的修正项类似只是误差信号要从输出层逐层传回去再乘上tanh的导数1-h_i²。我在实际仿真里是按照这个标准BP流程实现的下一节给示意代码。2.4 学习率和动量项的工程取舍学习率η建议从0.01开始试。太小的话几百个控制周期都看不到权值有明显变化太大会出现误差不降反升的情况转速波形直接发散。动量项α的引入能明显改善学习稳定性Δw(k) -η·(∂J/∂w(k)) α·Δw(k-1)动量项的作用相当于给权值更新加了一个惯性让参数调整方向不会因为某一步的噪声突变而急转弯。我常用的一组取值是η0.05、α0.05到0.1之间这个组合在大多数仿真模型里都能稳定工作。如果被控对象惯性很大Learning率可以稍微调小一点。3. 搭建Simulink整体模型双闭环框架里把转速环“挖出来”换上BP-PID3.1 模型拓扑和每个模块的职责搭建顺序我建议按照信号流来直流电源 → 三相逆变器 → 永磁同步电机 → 测量模块 → 坐标变换 → 电流PI → 反变换 → SVPWM调制最后再处理转速环。千万不要一上来就堆大模块先把传统双闭环跑通再替换转速环否则出了Bug很难定位。核心模块的组成大致是这样的模块作用备注DC Source提供直流母线电压常见311V或540V按电机额定电压选Universal Bridge三相两电平逆变器开关管用IGBT内阻默认即可PMSM模型被控对象使用Simulink自带的永磁同步电机模型测量与坐标变换三相电流采样、转速/位置获取Clarke和Park变换建议自己搭或用现成库电流环PI跟踪id_ref0和iq_ref参数固定带宽高于转速环5倍以上SVPWM调制生成逆变器开关信号载波频率即开关频率典型10kHzBP-PID模块替代转速环固定PIMATLAB Function或S函数3.2 自己常用的示例参数我常用的一组仿真参数是额定功率1.2kW、额定电压220V、极对数4、定子电阻2.875Ω、d轴和q轴电感都是0.0085H表贴式电机、永磁磁链0.175Wb、转动惯量0.0012kg·m²。直流母线电压取311V开关频率10kHz。你要用自己的电机参数也行核心逻辑不变。采样时间的设置有个关键点电流环控制周期取1e-4s转速环控制周期取2e-4s这样保证了内环比外环快两倍以上。BP-PID模块的采样时间必须和转速环一致否则控制律的离散化效果会完全不对。整个仿真用固定步长求解器我习惯用ode4步长1e-6s。步长太大会在逆变器开关时刻产生数值振荡波形看起来就像长了毛刺。3.3 为什么电流环保持PI只替换转速环这一点值得展开说。把电流环也换成神经网络不是不行但会带来两个问题一是变量太多最后仿真结果不理想时你很难说清楚是电流环的问题还是转速环的问题二是电流环本身有SVPWM这种离散调制环节带宽要求又高神经网络在一个控制周期内完成前向计算和反向传播反而可能拖慢执行速度。让电流环继续用固定PI保持高带宽的快速执行能力转速环用BP-PID去负责“协调和优化”这是一个分工合理、也符合工程直觉的方案。我见过不少论文把两个环都换成智能算法结果仿真跑下来波形也挺好但一旦把采样时间调严苛一点就发散。原因往往是内环延迟太大。所以我的建议很明确先做单环替换对比效果有意义之后再考虑扩展。4. S函数与MATLAB Function实现BP-PID核心代码和那些血泪坑4.1 用MATLAB Function还是S函数早期不少文献用S函数写BP-PID那套写法要对Simulink的S函数规范非常熟悉不然flag分支写错一个模型跑起来就莫名其妙。我自己的做法是用MATLAB Function模块配合persistent变量保存权值和历史误差代码结构和普通MATLAB脚本几乎一样调试起来方便很多。如果模型要反复复用来发不少论文图可以再改成Level-2 C MEX S函数运行速度会快不少但核心逻辑完全一致。4.2 核心代码示意下面给出一段能说明完整思路的示意代码。它不是一个可以无脑复制直接跑的产品级代码因为实际接入Simulink时还需要处理端口类型和向量维度但逻辑上已经覆盖了BP-PID的全部分支function u bp_pid_speed(e, ts) % BP-PID转速环控制器 % e: 转速误差, ts: 采样周期 persistent w1 w2 e_1 e_2 u_1 first_run if isempty(w1) % 3-5-3 网络权值初始化为小随机数 w1 rand(5,3) * 0.2 - 0.1; w2 rand(3,5) * 0.2 - 0.1; e_1 0; e_2 0; u_1 0; first_run 1; end % 网络输入误差、误差变化、二阶误差 x_in [e; e - e_1; e - 2*e_1 e_2]; % 隐含层 h tanh(w1 * x_in); % 输出层sigmoid映射到0~1 out 1 ./ (1 exp(-(w2 * h))); % 限幅映射到Kp/Ki/Kd kp 5 * out(1); ki 20 * out(2); kd 0.01 * out(3); % 增量式PID计算 if first_run du 0; first_run 0; else du kp*(e - e_1) ki*e kd*(e - 2*e_1 e_2); end u u_1 du; % --- 反向传播修正权值 --- eta 0.05; % 学习率 alpha 0.05; % 动量项系数 sgn sign(u - u_1); % sign近似被控对象的偏导 % 输出层误差项 d_out e * sgn; delta_out zeros(3,1); delta_out(1) d_out * (e - e_1)* h(1); delta_out(2) d_out * e * h(2); delta_out(3) d_out * (e - 2*e_1 e_2) * h(3); % 这里为了示意简化了sigmoid导数和链式相乘完整推导见正文 % 隐含层误差项示意 delta_h (w2 * delta_out) .* (1 - h.^2); % 权值修正动量项略写 w2 w2 - eta * delta_out * h; w1 w1 - eta * delta_h * x_in; % 保存历史状态 e_2 e_1; e_1 e; u_1 u; end注释里我特意写了那行“完整推导见正文”因为这段示意代码把sigmoid导数简化掉了实际严格实现时输出层的梯度要加上out·(1-out)项并且要把PID三个分量的偏导逐项乘进去。直接照抄这段代码可能收敛不稳但它能帮你把整体流程跑通。4.3 反向传播推导中的几个容易算错的地方严格推导时输出层的第j个节点到隐含层第i个节点的权值修正量是Δw2(j,i) -η·e(k)·sign(∂y/∂u)·(∂u/∂K_j)·h_i·f(net_j)其中∂u/∂K_1对应Δe∂u/∂K_2对应e(k)∂u/∂K_3对应e-2e_1e_2f(net_j)是sigmoid函数对加权和的导数恰好等于out_j·(1-out_j)。隐含层的误差项则要用输出层的误差信号加权求和之后再乘tanh导数。很多人写代码时漏了out_j·(1-out_j)这一项结果就是权值更新方向符号颠倒、模型越跑越乱。我调试时踩过这个坑最后用数值实验验证了一轮梯度方向才定位到问题。4.4 最影响成败的细节清单权值初始化千万不能用大随机数。我第一次用rand(5,3)直接初始化第一拍输出直接飞到天上模型直接就发散。正确的做法是把初始权值压到-0.1~0.1之间让网络一开始输出接近零的控制增量PID的输出主要由历史通道维持稳定网络再慢慢“接管”参数调整。Kp/Ki/Kd的限幅范围要相对保守。初始范围给太宽网络在限幅边缘反复触碰转速波形容易出现高频小锯齿。给太窄又限制控制作用阶跃响应明显变慢。我调限幅的方式是先跑一版固定PI把它的参数峰值记录下来然后以这个峰值的1.5到2倍作为BP-PID的上限。归一化也很关键。如果转速单位是rpm误差动辄几百而网络输入层没有归一化tanh会早就饱和梯度消失学习完全停滞。最简单的方法是先把误差除以额定转速让输入落在-1到1附近控制器的输出再用实际转速范围去缩放。5. 结果对比的“三个必测科目”没有这几张图仿真结论站不住5.1 科目一空载启动和转速阶跃响应第一组必测出发点是验证动态品质。仿真时间设0.5s从0开始给定转速阶跃到1000rpm记录转速波形。固定PI那组我用经典的零极点整定法调出一组参数尽量调到没有明显振荡BP-PID则用上面那套网络结构。得到的对比结果大致是固定PI的超调量在8%到10%左右调节时间约0.08sBP-PID超调量压到1%以内调节时间约0.09s。注意这里超调改善非常明显但上升时间并没有比固定PI短太多因为BP-PID在网络学习的初始阶段控制动作偏保守这是在线自整定的正常代价。5.2 科目二突加负载和突卸负载第二组必测出发点是抗扰性能。让电机在0.2s时突然加上10N·m的额定负载观察转速跌落和恢复时间。固定PI的典型表现是转速跌落50rpm左右恢复时间接近0.15s期间还有一个小幅振荡BP-PID的转速跌落明显更小大约20rpm恢复时间不到0.1s而且波形收敛非常干净。这个对比就是BP-PID最能打动人的地方。因为神经网络在负载突变瞬间感知到误差快速增大它会自动提高比例增益控制量迅速补上去同时积分项也加紧修正所以转速跌落的深度和时间都被压缩。5.3 科目三参数失配和鲁棒性测试第三组测试最关键也是很多仿真报告里缺失的。把电机转动惯量人为调大50%然后重复前面的阶跃和负载实验。固定PI在这种参数失配下往往会出现明显的振荡甚至在某些更恶劣的参数下稳定裕度不足BP-PID因为每个周期都在根据误差调整参数相当于在闭环运行中自适应性补偿了参数变化最终仍能维持稳定只是调节时间会比参数完全准确时长一点点。这一条结论其实才是BP-PID相比固定PI最本质的优越性它不是对某个参数样本点调好的控制器而是一个能持续适应对象变化的自适应控制器。在做课题答辩或者写论文时这张参数失配的对比图一定要放在结果分析里它比单纯的阶跃响应更能说明问题。5.4 保证对比公平的细节固定PI和BP-PID两组仿真除了转速环控制器不同之外其余设置必须完全一致同一个电机模型、同一个电流环、同一个采样时间、同一个求解器。控制器输出iq_ref的限幅也要保持一致。还有个容易忽略的点是网络的初始学习过程——BP-PID在启动最初几十毫秒内误差会有点波动这是正常的可以给网络留出学习时间但对比时要把这段时间也如实展示不要刻意剪掉。6. 踩过几次坑之后的实操建议做完这个课题我最大的感受是BP-PID这类在线自整定方法真正的重点不在于神经网络本身有多复杂而在于你如何把传统控制框架和智能算法合理地嵌合。先跑通普通双闭环再换BP-PID这句看起来像废话却是最有效的排查策略。我自己第一版模型是直接从网上找的带BP-PID的完整模型结果波形不对根本不知道是电流环参数问题、坐标变换符号问题还是权值更新公式有问题。后来老老实实拆掉BP-PID、用固定PI重新调了一版基础模型再把网络一层层加回去问题定位快了很多。最后分享两个小建议。一个是仿真数据最好用To Workspace模块把控制器的Kp、Ki、Kd实时存下来这样能画出参数随时间变化的曲线直观看到网络是怎么“调参”的这东西放论文里比单纯转速波形更有说服力。另一个是如果后面想继续做深入可以试试把sign符号函数近似换成RBF网络或模糊逻辑去逼近被控对象的雅可比信息理论上学习平滑度会更好这是我在对比了多种方案之后比较看好的方向——但先把你手里的BP-PID版本真正跑稳再谈升级。
觉得有用,分享给同行:

为您的企业打造数字门面

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

立即咨询 →