资讯详情

资讯详情

MATLAB调用PLECS模型扫频:从扰动注入到环路分析实战

简介面向电力电子与控制系统仿真研究者的MATLABPLECS联合扫频分析资源包主要解决在MATLAB环境中调用PLECS模型、执行频率扫描并绘制响应曲线的工程问题。压缩包共4个文件包含3个MATLAB脚本和1个PLECS模型文件脚本分别承担模型加载、扫频计算和结果绘制等任务模型文件可用来验证整套调用流程资源整体仅7KB结构紧凑适合已有一定MATLAB基础的中高级工程师或研究生直接参考。已有1564人学习/下载。脚本演示了从加载PLECS电路模型、设定扫频范围与步进点数到利用Bode图、Nyquist图等方式观察频率响应的完整思路同时可自定义图例、坐标轴、线型与颜色并支持通过saveas导出图像或csvwrite输出数据模型与脚本配套即可运行读者可在此基础上修改电路参数或扩展其他频域分析既省去从零搭建接口环境的时间也能加深对PLECS-MATLAB协同仿真及频域分析方法的理解。1. 在MATLAB里调用PLECS对模型做扫频环路分析从这一步开始做电源、电机驱动或者并网逆变器的朋友应该都有这种感觉仿真波形看着对但一问到“环路增益余量多少、输出阻抗峰在哪”手上就缺一张能拿得出手的频率响应图。在MATLAB里调用PLECS对其中模型做扫频再把结果画成图正是补上这块短板的常规操作。PLECS负责把功率电路和控制环路的非线性行为跑出来MATLAB负责在指定频率范围内给它加正弦扰动、收集响应、算增益和相位。这套流程在环路稳定性校验、滤波器设计、阻抗测量中几乎每天都要用。适合手里已有PLECS模型、想在MATLAB里统一做频域分析但还没把扫频链路跑通的工程师。2. 先把联调环境搭对PLECS模型怎么被MATLAB“看见”2.1 PLECS Blockset与独立版选哪条路打通PLECS常见有两种形态一种是独立版本自带PLECS Circuit和PLECS Control画图、仿真都在自己的界面里完成另一种是PLECS Blockset作为Simulink库嵌入MATLAB里面是PLECS Circuit和若干个PLECS Control子系统。做联合扫频时我一般用Blockset形态因为Simulink Control Design的线性化工具能直接识别它封装出来的块。独立版也能被MATLAB调用常见做法是通过PLECS的MATLAB Server接口或者把独立版模型导出成C代码再由MATLAB驱动的S-Function包进来。这个链路比Blockset长而且每次模型改动都要重新导出、生成调试时多一层中转。如果你手上的模型本来就搭在独立版里但项目要求最后在MATLAB里出频响图我的建议是先花半天时间把模型迁到Blockset后面省下的时间远不止半天。2.2 把PLECS模型改造成可扫频的输入输出结构不是随便一个PLECS模型丢进Simulink就能扫频。扫频本质上是在输入端口加一组已知频率的正弦扰动再从输出端口读响应所以模型必须满足三个条件有明确的输入输出端口、控制信号能从外部注入、仿真起始时刻是稳态的。常见的改造做法是在PLECS Circuit里把直流源或调制信号源替换成来自外部的Inport把要观测的电压或电流引出成Outport。如果是电压环通常输入选参考电压或占空比输出选输出电压采样如果是阻抗特性输入选注入电流源输出选响应电压。还有一个容易被忽略的动作在Simulink里给PLECS Circuit块套一层子系统子系统里面用GoTo/From或者Signal Conversion把信号类型固定下来。原因是PLECS产生的信号有时是物理单位或仿真单位线性化工具对这些信号做代数运算时会因为维度不一致拒绝执行。我在某次做直流变换器环路时就是因为输出端直接引了电压传感器的物理信号frestimate一直报“Invalid signal dimension”套了单位转换层之后一次通过。3. 扫频的三种实现路径扰动注入、线性化工具与PLECS自带频响3.1 路径一Simulink Control Design的frestimate扫频这条路是最常用的适合对带控制器的完整PLECS模型做实际频率响应估计。frestimate的原理是在输入端口注入一系列单频正弦波等仿真输出达到稳态后再读该频率下的幅值和相位然后扫下一个频点。它不要求模型可解析线性化所以对于PLECS这种含开关器件的模型反而更稳。% 打开模型模型名称为plecs_buck_ac mdl plecs_buck_ac; load_system(mdl); % 定义扫频频点从10Hz到100kHz每十倍频程25个点共101个点 frequencies logspace(1, 5, 101); % 指定注入输入信号所在的Simulink端口路径 io_input [mdl /Plecs_Subsystem/Duty_In]; io_output [mdl /Plecs_Subsystem/Vout_Measure]; % 配置frestimate选项 opts frestimateOptions(... Estimate, accel, ... % 用加速仿真模式扫频更快 UseParallel, true, ... % 多核并行扫频有并行工具箱才生效 SimulationTime, 10); % 每个频点最长仿真10s稳态后自动停 % 执行扫频返回频率响应数据对象 sys_frd frestimate(mdl, io_input, io_output, frequencies, opts);这段代码里frequencies用logspace(1,5,101)生成10Hz到100kHz的对数均匀频点适合看宽频带特性。Estimate选项有两个常用值sim表示普通仿真accel表示把模型编译成加速执行包扫频点较多时速度差距明显一般到50个频点以上我就会切到accel。UseParallel依赖MATLAB Parallel Computing Toolbox没有这个工具箱时该选项会被忽略但不会报错。这里有一个实际工程中很关键的参数SimulationTime。frestimate每个点会先做一段时域仿真等响应稳定后才记录数据。如果这个时间给短了低频段还没有进入稳态扫出来的增益会偏小给长了高频段浪费时间。我一般先给一个较大的值跑5个频点看看单点耗时再缩放。3.2 路径二用linearize对PLECS模型做小信号线性化与frestimate不同linearize是对模型在某个工作点做数值线性化直接得到一个状态空间模型或传递函数。它比frestimate快得多因为它不需要逐点仿真。但它的前提是模型在指定工作点是连续可微的PLECS里的理想开关、比较器、滞环这些本质不连续直接线性化往往会失败或给出离谱结果。% 设定工作点先让模型在稳态下仿真到时间戳t0.05s op_pts findop(mdl, 0.05); % 定义线性化输入输出端口路径与frestimate一致 io_lin linio([mdl /Plecs_Subsystem/Duty_In], 1, input); io_lin [io_lin; linio([mdl /Plecs_Subsystem/Vout_Measure], 1, output)]; % 执行线性化返回状态空间对象 sys_lin linearize(mdl, io_lin, op_pts);findop的作用是在模型信号线上记录时间戳对应的状态值作为工作点。注意findop要求模型能在该时间戳处完成一次仿真。linearize返回的是ss对象之后可以直接用bode(sys_lin)出图。这条路更适合模型里没有硬开关、或者已经把开关器件替换成平均值模型的情况。常见做法是在PLECS里把MOSFET和二极管换成受控电压源/受控电流源加平均转矩的等效模型或者直接在PLECS Blockset里对功率级使用Average Model构建一个副本。这个副本只用于线性化不回填到原仿真模型避免影响时域波形验证。3.3 路径三PLECS Pro自带AC Sweep纯PLECS工作流如果你用的是PLECS专业版里面自带AC Sweep工具可以不经过Simulink Control Design直接做扫频。它的好处是直接利用了PLECS的自动平均化算法能把开关器件的影响在频域里做平滑处理得到的结果比强行线性化要干净。坏处是结果数据在PLECS侧想把图合到MATLAB报告或与测量数据对比还得导出。% 假设PLECS模型已加载script_control接口可用 % 设置扫频参数并启动AC Sweep pl plecs(get, acsweep); pl.freq_start 10; % 起始频率10Hz pl.freq_end 100e3; % 终止频率100kHz pl.steps_per_decade 25; % 每十倍频程点数 pl.amplitude 1e-3; % 小信号扰动幅值 % 执行扫频返回频域数据 result pl.run();amplitude这个参数值得多说一句。它表示注入扰动的幅值设置太小会淹没在数值噪声里导致高频段增益出现毛刺设置太大则模型进入非线性区得到的小信号增益失真。常规做法是先按系统线性化范围的10%取一个初值看低频段是否平滑再微调。PLECS的AC Sweep内部有平均化处理所以频率响应曲线通常比frestimate更顺滑这也是它在官方技术社区里被推荐作为环路分析首选的原因。4. 把扫频结果画成可以写进报告的图4.1 bodeplot与手绘semilogx两级画图方式拿到频率响应数据后画图是最后一步也是很多人栽跟头的地方。直接用bode函数画默认图能看但报告里需要标余量、标频率点、对比多组曲线这时就得用bodeplot或semilogx自己控制。% 假设已有frd对象 sys_frd来自frestimate % 画带网格的Bode图 figure(Color, white); h bodeplot(sys_frd, {10, 1e5}); grid on; % 设置曲线属性线宽、颜色、相位图单独处理 setoptions(h, PhaseWrapping, on, ... % 相位自动折叠到-180~180 FreqUnits, Hz, ... % 横轴单位用Hz MagUnits, dB, ... % 增益单位用dB PhaseVisible, on); % 直接标出幅值裕度和相位裕度 margin(sys_frd);bodeplot比bode灵活的地方在于它能返回图对象通过setoptions精调显示参数。这里PhaseWrapping做不做很影响阅读如果模型包含了反向相位曲线可能从-150°跳变到180°不折叠的话图面全是斜向锯齿线报告里根本没法看。margin可以直接画出增益裕度和相位裕度标记对环路稳定性判断最直观。如果你想彻底控制画图细节比如把数据导出后放在论文里用semilogx手工绘制更自由。核心是把复数响应拆成幅值和相位两路用mag2db转dB后分两个子图画。这样做的代价是失去bodeplot自带的裕度标注需要自己从数据里算穿越频率。4.2 多组数据叠加与报告级美化工程上很少只看一条曲线。常见的需求是对比不同负载下的输出阻抗、对比补偿前后的环路增益、对比仿真相和实测。这时把多组frd数据用hold叠加到同一张图里再统一图例和颜色。% 多组frd对象合并绘图示例 figure(Color, white); all_sys [sys_frd_10ohm, sys_frd_5ohm, sys_frd_2ohm]; h bodeplot(all_sys, {10, 1e5}); setoptions(h, FreqUnits, Hz, MagUnits, dB, PhaseWrapping, on); grid on; % 调整图例名称 for k 1:3 all_sys(k).Name sprintf(负载%dohm, [10 5 2](k)); end legend(gca, {all_sys.Name}, Location, southwest); % 导出高分辨率PNG给公众号或报告用 exportgraphics(gcf, bode_compare.png, Resolution, 300);画图环节有个常见误区legend在Bode图里经常只识别第一条曲线因为相位图的存在让图例逻辑变复杂。所以我通常会先给每个frd对象设置Name属性再统一传名字数组给legend这样左侧和右侧两张子图的图例一致不会出现两条线共用一个名字的情况。4.3 导出数据到CSV喂给Python或Excel有些项目最终报告是外部团队写的对方指定要CSV或者Excel数据而不是图片。这时可以在画图之后把数据落盘。常见做法是把频率、增益dB、相位三相写成表用writematrix导出。注意相位数据要先做wrapTo180否则以度为单位时会在±180°边界处出现跳变读表的人会以为曲线断裂。% 从frd对象中取数据点 [f, mag_db, phase_deg] freqrespData(sys_frd); % 做相位折叠避免±180跳变 phase_wrapped wrapTo180(phase_deg); % 合并并导出 T table(f(:), mag_db(:), phase_wrapped(:), ... VariableNames, {Freq_Hz, Mag_dB, Phase_deg}); writetable(T, freq_response.csv);freqrespData是控制系统工具箱提供的提取函数适合frd对象。如果你的结果来自PLECS AC Sweep那需要先从PLECS侧把数据导出成.mat或CSV再用这个函数导入。这套流程多用几次后我一般就不再依赖交互式绘图而是写进一个统一的脚本里输入模型名、扫频范围、输出文件名三个参数一键出图、一键出表省掉每天重复的鼠标操作。5. 扫频避坑为什么你的Bode图在高频段乱飞5.1 现象低频段增益幅度与理论计算对不上扫频出来的低频增益如果比理论值低5~10dB先不要怀疑线性化工具多数情况是注入扰动之后没有等到稳态。frestimate的单点仿真时长不足时低频正弦波还没有完成至少两个完整周期幅值读数就会有偏差。原因在于低频扰动周期长仿真步长若按高频要求设置则每一步都要算很久于是很多人为了省时间把SimulationTime改得很小低频精度就丢了。解决方法是把扫频起始频率降低到理论穿越频率的1/10且单点仿真时间设置成不低于5个最低频周期。例如扫频下限10Hz时每个点的仿真时长至少0.5s我通常给1s以上。5.2 现象高频段相位乱跳、增益出现周期性尖峰高频段的尖峰十有八九来自数值振铃而不是真实系统响应。常见原因有两个一是PLECS模型里器件吸收电容、杂散电感的寄生参数设得过于理想二是在扫频范围内包含了采样频率或开关频率的倍频。解决办法是在扫频范围内把上限降下来例如一个250kHz开关频率的变换器扫频上限设100kHz基本够看环路特性设到1MHz就会看到一堆和开关谐波混叠的假峰。如果是寄生参数引起的尖峰回到PLECS里给电容增加等效串联电阻给电感增加并联寄生电容再扫一次对比曲线。5.3 现象linearize直接报错“无法求解”或者返回的状态空间阶数异常linerize对于含理想开关的PLECS模型几乎注定失败因为开关切换瞬间的雅可比矩阵不存在。解决方式有两条路一条是把PLECS模型切换成平均模型再给linearize另一条是放弃linearize改用frestimate。平均模型在PLECS里常见做法是用受控源替代开关网络或者在模型顶层把PWM的调制过程用小信号传递函数描述。阶数异常通常是因为工作点处存在数值噪声引起的额外动态可以先降低线性化时刻的步长或者对结果用balred降阶再出图。5.4 现象扫频点增加之后仿真时间成倍增长frestimate扫101个点如果每个点仿真10秒总时长超过15分钟这还只是单组条件。想批量扫不同工作点时时间成本会立刻变成项目瓶颈。解决方法是并行加粗粒度。第一步开启UseParallel把频点分给多个worker第二步把每个频点的仿真时间压缩先跑3~5个点确认低频段是否能进稳态如果稳态时间远小于预设值就把SimulationTime缩小到原来的三分之一。另外一个更彻底的优化是改用PLECS的AC Sweep它内部用平均化算法通常比frestimate快五倍以上。5.5 现象相位曲线在跨过-180°时出现“拉丝”状锯齿这不是bug是相位数据没有折叠导致的表现。增益曲线正常相位线却在±180°边界反复跨越。解决方法是设置PhaseWrapping为on或者导出数据时对相位做wrapTo180。如果锯齿出现在增益曲线中低频段则是响应幅值接近数值噪声底部可通过增大扰动幅值解决此时优先用PLECS AC Sweep的amplitude参数。6. 把扫频流程固化成脚本批量扫描与结果归档扫频之所以值得做成脚本是因为它的典型使用场景就是批量不同负载、不同输入电压、不同补偿参数。手动改一次跑一次不仅效率低而且容易忘记上次用的扫频范围。我给自己项目组固化了一套脚本输入参数只有模型名、工况表、输出路径三个输出的是一张对比图和一个包含全部频响数据的CSV耗时五分钟以内。mdl plecs_buck_ac; load_system(mdl); % 工况矩阵每行是[负载电阻, 输入电压, 扫频起点, 扫频终点] cases [ 10, 12, 10, 1e5; 5, 12, 10, 1e5; 2, 24, 10, 5e4 ]; % 预分配结构体存放结果 results struct(freq, {}, mag_db, {}, phase_deg, {}); for idx 1:size(cases, 1) Rload cases(idx, 1); Vin cases(idx, 2); f_start cases(idx, 3); f_end cases(idx, 4); % 通过工作区变量把工况传到PLECS模型内部 assignin(base, Rload_value, Rload); assignin(base, Vin_value, Vin); % 生成频点步长取每十倍频程25点 frequencies logspace(log10(f_start), log10(f_end), 25*41); % 定义端口 io_input [mdl /Plecs_Subsystem/Duty_In]; io_output [mdl /Plecs_Subsystem/Vout_Measure]; % 扫频 sys_frd frestimate(mdl, io_input, io_output, frequencies, ... frestimateOptions(SimulationTime, 1)); % 提取数据点 [f, mag_db, phase_deg] freqrespData(sys_frd); results(idx).freq f; results(idx).mag_db mag_db; results(idx).phase_deg wrapTo180(phase_deg); end % 保存所有数据到同一个文件 save(bode_sweep_results.mat, results, cases);这段脚本里用了assignin把负载和输入电压写到基础工作区PLECS模型里的参数直接引用Rload_value和Vin_value这两个变量。这样做的好处是避免每次改模型参数都要打开Mask界面批量扫描时只需改cases矩阵。频点计算公式里25*41保证每十倍频程25个点并且覆盖整个对数区间。扫频完成后的验证习惯我建议至少做一次“闭环对开环”的检查。具体做法是把控制环路断开直接注入占空比开环扫一次和理论主极点位置比对再把环路闭合扫一次看穿越频率处的相位裕度是否与理论一致。这一步能快速暴露模型里通道连错、传感器增益未归一化等低级错误而这类错误在只闭环扫一次的情况下几乎看不出异常。我在一次做某双向变换器阻抗分析时就因为没有先做开环验证拿着闭环曲线反推电感寄生参数折腾了一周才发现是采样延迟模型在低频段引入了误差。现在我的习惯是任何新模型第一次扫频必先开环扫三个典型工作点确认低频增益斜率正确再做闭环。这样看频率响应图时心里才踏实。关于扫频频率上限的选择最后补一个我常用的经验值开关频率的1/4到1/5。比如250kHz开关频率扫到50~60kHz就够了再往上会被开关纹波干扰且对环路设计意义不大。如果项目里确实需要看高频段的EMI滤波特性那就单独建一个不含控制环的阻抗模型来扫别和控制环路混在一个图里。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

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

立即咨询 →