PMSM模型预测控制:单矢量到三矢量的Simulink仿真详解
1. 先把技术版图说清楚单矢量、占空比、双矢量、三矢量各自解决什么问题做永磁同步电机PMSM的模型预测控制MPC仿真很多人第一反应就是搭个单矢量模型跑通再说。单矢量跑通之后你会发现电流纹波大、稳态噪声明显这时候有人开始加占空比有人直接上双矢量、三矢量。我自己的经历也是这样从单矢量一路改到三矢量所以想把这一整套逻辑用一篇Simulink仿真的文章讲清楚让后来的人少走弯路。1.1 模型预测控制为什么在PMSM上这么受宠模型预测控制的核心思路并不复杂你不是要控制电流吗那我先把逆变器所有能输出的开关状态全部列出来然后逐个预测“如果这个周期用这个矢量电流会变成多少”最后选一个让电流误差最小的矢量执行。整个过程听起来像一个暴力枚举但在数字控制器里执行起来非常直接尤其适合带有强耦合、非线性特性的永磁同步电机。和传统PI控制加空间矢量调制SVPWM相比MPC最大的优势是动态响应快。PI需要调两个环多个参数遇到负载突变或转速跳变时电流环可能要几个毫秒才拉回来而MPC在下一个采样周期就能切换出最合适的电压矢量动态过程非常干脆。代价是稳态性能差因为一个控制周期内只作用一个固定的电压矢量电流在平均意义上被迫绕着参考值波动形成明显的纹波。1.2 从开关状态穷举到矢量组合寻优一条清晰的演进路线单矢量MPC是整条路线的基础款。两电平三相逆变器一共8个开关状态对应6个非零电压矢量和2个零矢量单矢量MPC在每个控制周期里从这8个候选中选出最优的那一个然后在整个周期内只输出它。这个方案概念最简单代码也容易写但它有本质缺陷分配粒度太粗导致稳态精度差、开关频率漂移大。占空比MPC是对单矢量的第一层修补。既然“一个矢量顶整个周期”太粗暴那我让选中的非零矢量只作用一部分时间剩下的时间切换到零矢量相当于在“全有”和“全无”之间做一个折中。这个比例就是占空比通常可以通过代价函数的二次关系直接解析算出最优值计算量只比单矢量多一点点但电流纹波能明显降下来。双矢量MPC再往前走一步不再让零矢量来填剩余时间而是在相邻的两个非零矢量之间分配时间。这样等效电压矢量可以在扇区内的连线上滑动比“非零矢量加零矢量”的直线路径更贴近实际需要的电压参考动态和稳态表现都比占空比更好。三矢量MPC则是这条路线的集大成者每个周期内作用两个相邻非零矢量加零矢量等效合成电压矢量的自由度更高已经非常接近传统SVPWM的连续调制效果。它的问题也很明显作用时间的计算复杂了预测和评估的计算量上去了而且候选组合需要重新设计。1.3 四类策略的性能定位表为了直观看出差异我这段时间反复对比过这几种方案把它们放在同一组电机参数和工况下观察大致表现如下方案每周期矢量的作用方式电流THD计算量实现复杂度最典型的使用场景单矢量1个矢量作用整个周期高低低教学演示、原理验证占空比1个非零矢量加零矢量按比例分配中低低工程快速改造现有MPC双矢量2个相邻非零矢量按比例分配中低中中追求动态性能且计算资源有限三矢量2个相邻非零矢量加零矢量按比例分配低高高波形质量敏感、接近SVPWM效果这张表只是相对趋势。实际THD的降幅和电机参数、采样频率都有关系不能指望三矢量在所有工况下都能压掉一半纹波但它确实是在往这个方向走。2. 单矢量MPCSimulink里的基础款是怎么跑起来的我在搭双矢量、三矢量之前花了不少时间把单矢量MPC的每一个环节掰开揉碎因为后面所有改进都建立在同样的预测模型和代价函数上。如果这里符号搞错、离散化搞错后面改再多矢量都是白搭。2.1 逆变器提供的8个候选电压矢量和开关表两电平三相逆变器由三个桥臂组成每个桥臂要么上管导通要么下管导通所以一共有2的3次方等于8种开关组合。定义每一种组合为(Sa, Sb, Sc)取值1表示该相上桥臂导通、下桥臂关断。标准排列如下SaSbSc电压矢量编号矢量性质000V0零矢量100V1非零矢量110V2非零矢量010V3非零矢量011V4非零矢量001V5非零矢量101V6非零矢量111V7零矢量6个非零矢量在α-β平面上相隔60度正好把平面分成6个扇区。如果按等幅值变换的Clarke公式电压矢量的αβ分量为u_alpha Vdc * (2/3) * (Sa - 0.5Sb - 0.5Sc) u_beta Vdc * (sqrt(3)/3) * (Sb - Sc)这个系数特别容易踩坑。Simulink自带PMSM模块内部的坐标变换有些用的是等幅值有些用的是等功率系数差一个sqrt(2/3)的比例。如果你的预测模型和电机模块的变换系数不一致跑出来的电流会整体偏小或偏大PI都不需要预测控制自己就把系统带偏了。2.2 电流预测方程的离散化与代价函数设计PMSM在d-q旋转坐标系下的定子电压方程按电机惯例写法可以整理成ud Rid Ld(did/dt) - weLqiq uq Riq Lq(diq/dt) weLdid we*flux其中we是电角速度flux是永磁体磁链。用一阶前向欧拉离散化采样周期为Ts可以得到下一拍电流的预测值id_pred id Ts * (ud - Rid weLqiq) / Ld iq_pred iq Ts * (uq - Riq - weLdid - we*flux) / Lq这里注意每个开关状态都会算出不同的ud和uq所以id_pred和iq_pred也会不同。代价函数最常用的是电流误差平方和也就是g (id_ref - id_pred)^2 (iq_ref - iq_pred)^2选择让g最小的那个开关状态作为当前周期的输出。电机控制最终目标是电磁转矩而转矩和iq强相关所以iq的权重实际上隐含在里面如果后续要加入转矩控制或者磁链控制就需要改成带权重系数的多目标代价函数。2.3 MATLAB Function函数实现骨架在Simulink里我习惯把整个MPC控制算法写进一个MATLAB Function模块输入是id_ref、iq_ref、id、iq、theta和we输出是三相开关信号。核心代码如下function [Sa,Sb,Sc] mpc_single(id_ref, iq_ref, id, iq, theta, we, Vdc) R 0.958; Ld 5.25e-3; Lq 12.0e-3; flux 0.1827; Ts 1e-5; table [0 0 0; 1 0 0; 1 1 0; 0 1 0; 0 1 1; 0 0 1; 1 0 1; 1 1 1]; g_best inf; Sa 0; Sb 0; Sc 0; for i 1:8 Sa_t table(i,1); Sb_t table(i,2); Sc_t table(i,3); u_alpha Vdc * (2/3) * (Sa_t - 0.5*Sb_t - 0.5*Sc_t); u_beta Vdc * (sqrt(3)/3) * (Sb_t - Sc_t); ud u_alpha*cos(theta) u_beta*sin(theta); uq -u_alpha*sin(theta) u_beta*cos(theta); id_pred id Ts * (ud - R*id we*Lq*iq) / Ld; iq_pred iq Ts * (uq - R*iq - we*Ld*id - we*flux) / Lq; g (id_ref - id_pred)^2 (iq_ref - iq_pred)^2; if g g_best g_best g; Sa Sa_t; Sb Sb_t; Sc Sc_t; end end end这段代码执行完后输出Sa、Sb、Sc直接送到逆变器门极驱动。如果模型报代数环可以在MATLAB Function后面加一个Memory模块让输出延迟一拍通常就能解决。MS注意好的这部分先跑通再把后面的占空比、双矢量、三矢量逐级替换控制模块。3. 占空比MPC不换矢量只换“停留时间”的巧妙改进很多人跑完单矢量MPC看到电流波形第一反应是“这也太糙了”。我当时也一样然后很自然地想到能不能在一个控制周期里让非零矢量只作用一部分时间剩下时间用零矢量这就是占空比MPC的出发点。它在不改变“选矢量”逻辑的前提下给每个周期增加了一个时间分配的维度效果立竿见影。3.1 单矢量“要么全有要么全无”的本质缺陷单矢量MPC的问题在于量化粒度太粗。想想看你本来需要的是一杯温水但系统只给你“热水”“冰水”两个按钮不管怎么选最后温度都有偏差。控制周期越短这种偏差越小但受限于开关频率和硬件能力Ts不可能无限小所以只能靠算法层面的优化。占空比方案相当于给每个周期增加了一个混合比例旋钮这个周期先让优选出来的非零矢量作用d*T时间再让零矢量作用(1-d)*T时间。等效出来的电压矢量在这两个矢量之间的连线上滑动很大程度上弥补了“离散电压矢量和实际需求电压”之间的落差。3.2 最优占空比推导从代价函数二次函数求导说起既然占空比是一个连续变量那就可以用解析方法找最优值。先定义两种情况下的预测电流x1最优非零矢量作用整个周期时的预测电流x0零矢量作用整个周期时的预测电流如果占空比为d则等效预测电流可以近似为x_pred x0 d * (x1 - x0)这里的x可以理解成(id, iq)组成的二维状态向量。代价函数J(d) (id_ref - id_pred)^2 (iq_ref - iq_pred)^2把x_pred代入并展开J(d)是d的二次函数对d求导并令导数为0就能得到最优占空比d* ((x_ref - x0)^T * (x1 - x0)) / ((x1 - x0)^T * (x1 - x0))最后把d*夹在0到1之间。这个推导在Simulink里实现起来很简单多写几行向量运算就行。提示如果想让公式更贴近工程习惯可以把x换成电流误差向量e也就是e0 x_ref - x0e1 x_ref - x1然后用误差投影的几何意义理解同样成立。3.3 改成占空比后仿真模型里要改哪里在Simulink模型里占空比MPC的输出不再是简单三路开关信号而是“三相占空比信号”。实现方法是先把选中的非零矢量和零矢量按d*的时间拼成一个完整周期然后生成PWM脉冲送给逆变器。这里要注意PWM载波频率和MPC采样频率的关系载波频率通常等于Ts的倒数扇区内每个载波周期内对齐一个开关动作点否则占空比信号和实际逆变器输出之间会有相位误差。还有一个容易忽略的地方占空比MPC计算最优d*时默认电流变化轨迹在“非零矢量预测点”和“零矢量预测点”之间近似线性。实际电流轨迹是带反电动势和电阻项的指数曲线但在Ts足够小的情况下线性近似误差很小。如果你把Ts拉到50微秒以上这个近似就开始明显失真所以这类方案对采样周期比较敏感。4. 双矢量MPC为什么选相邻非零矢量以及作用时间怎么算占空比MPC虽然比单矢量好但它的剩余时间都用零矢量填充等效电压矢量的轨迹只能在“非零矢量到零矢量”这条直线上走。双矢量MPC换了一种思路不找零矢量而是让两个非零矢量在一个周期里按比例分配时间。这样等效电压矢量的可到达区域变大动态响应也更好。4.1 双矢量候选集6个相邻非零矢量对的组合逻辑两电平逆变器有6个非零电压矢量按扇区顺序编号V1到V6。为什么要选相邻矢量组合而不是任意两个组合因为任意两个不相邻的矢量之间等效电压矢量需要穿越很大区域合成出来的电压矢量指向可能偏差很大而且会带来不必要的高频开关动作。相邻矢量的组合只在60度扇区内变化每次切换最多让一个桥臂翻转开关损耗和电流谐波都能接受。所以候选集就是6个相邻矢量对(V1,V2)、(V2,V3)、(V3,V4)、(V4,V5)、(V5,V6)、(V6,V1)。每一对矢量对应一个扇区。控制器的任务变成两件事先确定当前时刻使用哪个矢量对再确定这对矢量之间的时间比例。4.2 伏秒平衡与等效电压矢量下的作用时间求解双矢量MPC的作用时间计算和占空比MPC非常像区别只是把“零矢量”换成了第二个非零矢量。假设一对候选矢量为v1和v2v1的作用比例为dv2的作用比例为1-d那么等效电压矢量为u_eq d * v1 (1-d) * v2把这等效电压矢量代入离散预测方程得到预测电流x_pred(d)再构造代价函数并求导得到的d*公式和占空比那一节几乎一样d* ((x_ref - x2_pred)^T * (x1_pred - x2_pred)) / ((x1_pred - x2_pred)^T * (x1_pred - x2_pred))其中x1_pred是v1作用整个周期时的预测电流x2_pred是v2作用整个周期时的预测电流。最后把d*限制在0到1之间。这样每个候选矢量对都能算出一组最优时间和对应的最小代价最后在所有矢量对里选代价最小的那组作为输出。代码结构上双矢量MPC只需要把单矢量的8次枚举改成6次“矢量对评估”每次评估内部还要算一次d*。计算量比单矢量翻了约一倍但远没到三矢量那种程度。如果在单片机上实现这个计算量完全可控。4.3 时间分配和扇区判断在模型中的联动在Simulink里双矢量方案建议不要用“纯开关信号输出”的方式而是输出三相占空比信号给PWM发生器。这样最方便先根据选中的矢量对和作用时间生成一个周期内的开关动作序列再转换成三相占空比。比如选中V1和V2V1作用0.3T、V2作用0.7T那么在这一个周期内三相的开关状态会先保持一段100再切换到110最后视情况回到零矢量。扇区判断在这类算法里通常不难。你只需要看当前合成电压矢量落在哪个60度区间。但要注意这里说的合成电压矢量不是实际测量出来的而是根据预测方程反推的参考电压矢量。在双矢量方案里我一般会先用单矢量MPC的思路确定一个目标方向再判断它落在哪个扇区然后把该扇区对应的两个边界矢量作为候选。这样比直接枚举6个矢量对更能减少无效计算。5. 三矢量MPC从穷举矢量退化成选扇区的质变三矢量MPC是目前这几个方案里控制精度最高的一档也是我在Simulink里调得最久的一版。它的核心变化不是“三个矢量比两个矢量多一点”而是算法结构彻底变了不再是逐个枚举开关组合而是先算出参考电压矢量然后按SVPWM的思路在固定扇区里做时间分配。5.1 三矢量的候选组合生成两个相邻非零矢量加零矢量三矢量的候选不是任意三个开关状态的组合而是每个60度扇区内的两个边界非零矢量再加上零矢量。比如扇区1候选组合就是V1、V2、V0扇区2就是V2、V3、V0以此类推。所以整个三矢量算法的候选集合是6个扇区组合每个组合内包含3个电压矢量。为什么还要加零矢量因为两个非零矢量的时间比例虽然能合成出扇区内任意方向的电压矢量但合成矢量的长度被限定在由两个非零矢量端点连成的线段上不能太短。加入零矢量之后可以额外调整等效矢量的“平均长度”让合成范围变成整个扇区内部。直观来说就像先把两个方向向量混合成向量a再加一个可以任意拉低平均幅值的零向量这样就能覆盖扇区里的几乎所有目标点。5.2 无差拍参考电压与SVPWM式时间分配三矢量MPC的第一步是先根据电流预测方程反解出一个“无差拍”参考电压。这个参考电压的含义是如果这个周期能完美输出这么一组ud、uq那么下一拍电流就能精确等于参考电流。反解公式来源就是把离散化方程中的id_pred替换成id_refud_ref Ld * (id_ref - id) / Ts Rid - weLqiq uq_ref Lq * (iq_ref - iq) / Ts Riq weLdid we*flux然后反Park变换得到αβ轴分量判断参考电压所在扇区。比如它落在扇区1那么本周期就用V1、V2、V0三个矢量。作用时间按下式分配t1 K * sin(π/3 - theta_sector) * T t2 K * sin(theta_sector) * T t0 T - t1 - t2其中K等于sqrt(3)*|u_ref|/Vdc再乘一个系数系数取决于你的Clark变换方式。theta_sector是参考电压矢量在当前扇区内相对起始边的角度范围0到60度。这个公式其实就是SVPWM的经典时间计算公式很多人没意识到它可以直接移植到MPC里用因为它本质是伏秒平衡。5.3 三矢量相对双矢量在谐波、开关频率、计算量上的实际权衡三矢量方案的电流THD通常是最低的这点在很多仿真对比里都能看到。因为等效电压矢量的合成自由度更高电流轨迹更贴近理想正弦包络谐波自然被压下去。代价是计算量明显上升每个控制周期要做扇区判断、三角函数求解、时间分配和预测评估MATLAB Function里的代码量也会大不少。另一个实际问题是开关频率漂移。三矢量方案虽然在一个周期内使用了三个矢量但开关动作点仍然取决于参考电压矢量的变化不是严格的固定频率PWM。如果你后续想做硬件实验这个特征要注意。很多半实物平台会对MPC输出再做一层周期化处理否则逆变器发热和谐波都会超出预期。我用三矢量方案跑下来最大的感受是它和传统SVPWM的效果越来越接近但保留了MPC快速响应和直接处理约束的优势。如果你是在做课题研究三矢量方案提供的对比数据会非常扎实如果只是工程应用且计算资源有限双矢量加合理占空比其实性价比更高。6. 这套仿真模型里最容易翻车的几个细节最后这部分是纯粹的踩坑记录。我调这套Simulink模型时遇到的很多问题不是算法本身而是工程实现层面的细节。有时候波形乱七八糟不是算法错了是Simulink模型里某个环节没对齐。6.1 坐标变换的角基准不统一电流预测全乱最坑的是坐标变换的角基准。Simulink自带PMSM模块输出电角度theta你用它做Park变换时必须和你自己的电机方程、反电动势方向统一。如果电机模块用的是某个参考方向你的控制代码里却用了相反的Park矩阵结果是id和iq整反预测控制会一直往错的方向推电流直接发散。我的排查经验是先断开MPC用一个简单的开环电压给定跑一下看电机的dq电流方向是否和自己方程一致确认无误再接入预测算法。6.2 采样周期和预测周期不一致控制效果失真这是比坐标变换更隐蔽的问题。Simulink模型里的求解器步长、控制器模块的采样步长、预测方程中的Ts这三个时间参数如果没设成一致仿真结果会非常具有迷惑性。比如预测方程里写的Ts是1e-5但MATLAB Function模块的采样周期设成了1e-4那控制器实际每10个仿真步才更新一次但预测公式假设每个步长都在预测电流预测值和实际自然就对不上。建议把Ts定义成一个工作区变量Simulink的固定步长和预测方程的Ts都引用同一个变量这样改参数时不会漏改。6.3 权重系数设置的由果推因法如果你用纯电流MPC代价函数里两项误差的权重天然是1不需要调。但很多人把目标改成转矩和磁链误差时就必须面对权重系数lambda。这个系数没有解析公式常规做法是看仿真波形倒推如果转矩响应太慢说明转矩项的权重偏低如果磁链波形过冲说明磁链项权重太高。我习惯先让lambda取一个中间值然后只调一两个数量级观察稳态和动态的取舍。6.4 代数环处理MATLAB Function要不要加单位延迟MPC模块的输出直接送逆变器逆变器电流又作为模块输入Simulink经常会报代数环错误。最简单的解决办法是在MATLAB Function的输出端加一个零阶保持器或者Memory模块。但要注意加延迟会让当前周期的控制动作晚一个周期生效这在预测控制里其实可以接受因为预测模型本身就是基于当前周期状态外推下一拍。不要试图用Transport Delay去解决代数环那样只会引入额外相位滞后。6.5 死区与开关频率漂移的观察仿真模型里如果不加死区单矢量MPC和三矢量MPC的对比会很干净但实际硬件会多出死区时间、管压降等非理想因素。在Simulink里模拟死区可以在门极信号和桥臂之间串联一个Dead Time模块。加了死区之后三矢量方案的低THD优势更明显因为它的开关动作次数相对均匀死区造成的畸变更容易被平均掉。最后再分享一个小技巧不管你要做单矢量、占空比、还是双矢量、三矢量我建议先把单矢量的模型完整保存一份后续所有版本都复制改不要在一个文件里反复覆盖。多矢量方案的对比结果需要统一工况、统一参数如果每个方案的文件里电机参数或采样时间悄悄变了出来的对比图说服力就大打折扣。我自己保留了一套“基础电机模型”和一套“控制算法库”换方案只换库里的控制模块这样整个调试周期会短很多。