前言
在用Simulink进行仿真时,经常会需要研究某一参数变化时,模型仿真结果的变化情况。此时,需要不断地改变仿真模型中的某一参数,仿真,记录数据,依次循环,非常麻烦。实际上,这一工作完全可以通过代码来完成。下面介绍方法。
实验平台
Matlab R2023b
案例
研究传统三相全桥逆变器和分裂电容式三相全桥逆变器在带三相不平衡负载时,输出电压的变化情况。输出负载均为电阻负载,星形连接。
输入电压:750V
输出电压:三相50Hz,220
V
r
m
s
\mathrm{V_{rms}}
Vrms正弦波
额定输出功率:单相2kW,三相6kW。即单相额定负载
22
0
2
/
2000
=
24.2
Ω
220^2/2000=24.2\Omega
2202/2000=24.2Ω,记为
R
L
R_\mathrm{L}
RL
由于本文核心在于介绍Simulink自动化仿真的方法,三相逆变器控制直接使用简单的开环控制,调制方式直接使用SPWM调制方式。
分别在Simulink中搭建仿真模型。传统三相全桥逆变器的仿真模型命名为Inverter3ph.slx
:
开关频率设置为50kHz,仅对三相负载电压进行测量,保存在变量vo中。
在Simulink仿真界面按快捷键Ctrl+E
,对数据导出进行设置:
这样,在我们模型仿真完毕时,在工作区会出现vo这个变量而不是out变量,更方便我们操作。
分裂电容式三相全桥逆变器仿真模型命名为Inverter3ph_SepCap.slx
:
其余设计与传统三相全桥逆变器完全相同。
研究两种拓扑结构,四种负载状况下输出电压的变化情况:
- 三相平衡负载,三相均满载,即RLA、RLB与RLC均设置为 R L R_\mathrm{L} RL
- 三相平衡负载,三相均空载,本次仿真中,将RLA、RLB与RLC均设置为 1 0 9 Ω 10^9\Omega 109Ω
- 三相不平衡负载,A相空载,BC相满载,即RLA设置为 1 0 9 Ω 10^9\Omega 109Ω,RLB与RLC均设置为 R L R_\mathrm{L} RL
- 三相不平衡负载,AB相空载,C相满载,即RLA与RLB均设置为 1 0 9 Ω 10^9\Omega 109Ω,RLC设置为 R L R_\mathrm{L} RL
因此,总计需要仿真八次。
代码实现
%% Simulink变参数批量仿真
simPath='E:\Files\Files\Files\documents\Master1\CSDN\SimulinkBatchSim\Simulation\'; %仿真文件所在文件夹路径
simModels={'Inverter3ph','Inverter3ph_SepCap'}; %仿真模型名称,不需要带扩展名
savePath='E:\Files\Files\Files\documents\Master1\CSDN\SimulinkBatchSim\Data\'; %数据存储路径
RL=220^2/2e3; %额定负载
strRL=num2str(RL); %额定负载数值转化为字符串
% 仿真负载情况
RLAList={strRL,'1e9','1e9','1e9'};
RLBList={strRL,'1e9',strRL,'1e9'};
RLCList={strRL,'1e9',strRL,strRL};
% 存储数据名称
saveVarList={'vo','vo_LightLoad','vo_BC','vo_C'}; %保存变量名称
saveVars={'Data.mat','Data_SepCap.mat'}; %保存数据名称
% 开始批量仿真
cd(simPath); %将工作目录切换到仿真文件所在文件夹目录下
for i=1:1:length(simModels)
model=simModels{i}; %选择模型
open_system(model); %打开模型
load_system(model); %加载模型
for j=1:1:length(saveVarList)
set_param([model,'/RLA'],'Resistance',RLAList{j}); %设置模型内RLA的模块的Resistance参数
set_param([model,'/RLB'],'Resistance',RLBList{j});
set_param([model,'/RLC'],'Resistance',RLCList{j});
sim(model); %开始仿真
eval([saveVarList{j},'=vo']); %将仿真完成后工作区保存到vo数据另存
end
save_system(model); %保存模型
close_system; %关闭模型
save([savePath,saveVars{i}],'vo*'); %保存数据
end
核心流程就是:
- 找到模型,用
open_system(model)
打开模型; load_system(model)
加载模型;- 找到要改变的参数所在的模块名称,本例中,即为RLA、RLB、RLC(首次拖入模型时,单击模型可以看到模型的默认名称,点击即可修改。例如,下图中,Series RLC Branch1即为默认名称。已修改过的名称会像上面的仿真模型图一样显示在模块左侧,鼠标单击可以进行再一次修改)
- 定位模块在模型中的层级。例如,在本例中,RLA、RLB与RLC没有嵌套在子系统中,因此直接在
set_param
的第一个参数中,写成[model,'/RLA']
。如果嵌套了子系统,则要逐级嵌套。例如,将三相负载封装到一个子系统内:
此时,要改变RLA、RLB和RLC的参数,则set_param
的第一个参数应该写成[model,'/Load/RLA']
,其中,Load
为子系统名称。更多级的子系统嵌套依此类推。
5. 定位参数在模块中的参数名称。一般情况下,双击模块时,填入参数的输入栏上面的描述就是。
不确定时,也可以用get_param
获取模块的所有参数名称:
% 获取模块所有参数名称
h=getSimulinkBlockHandle([model,'/RLA'],true);
get_param(h,'DialogParameters')
输出结果:
显然,我们要设置的参数是Resistance
。
值得注意的是,set_param
的最后一个参数用于设置参数的值,但类型必须设定为字符类型!
代码运行后,会自动变参数在Simulink中进行仿真,并将仿真得到的数据保存在Data.mat
与Data_SepCap.mat
中,每个mat
文件内包含vo
,vo_LightLoad
,vo_BC
和vo_C
四个变量,变量均为带时间的结构体。可以对数据进行进一步处理:
% 数据进一步处理
clear;
clc;
load('E:\Files\Files\Files\documents\Master1\CSDN\SimulinkBatchSim\Data\Data.mat');
plot(vo.time,vo.signals.values(:,1),'LineWidth',4);
hold on;
plot(vo_LightLoad.time,vo_LightLoad.signals.values(:,1),'LineWidth',4);
plot(vo_BC.time,vo_BC.signals.values(:,1),'LineWidth',4);
plot(vo_C.time,vo_C.signals.values(:,1),'LineWidth',4);
legend('三相满载','三相空载','A相空载BC相满载','AB相空载C相满载')
扩展
有时候,当模型参数很多时,会使用数据字典进行管理。那么,这种情况下如何改变数据字典中的参数,进行变参数批量仿真呢?
例如,Inverter3ph.slx
和Inverter3ph_SepCap.slx
中的一些共性参数放置在Inverter3ph.sldd
中进行统一管理。仿真时,对Inverter3ph.sldd
中的开关频率fs(仅作演示说明,一般不会改变开关频率)进行修改与仿真:
dataDictPath='E:\Files\Files\Files\documents\Master1\CSDN\SimulinkBatchSim\Simulation\Inverter3ph.sldd'; %数据字典所在路径
fsList=['50e3','20e3','10e3'];
% 打开模型,加载模型
% …………
% 修改数据字典中的耦合系数
for i=1:1:length(fsList):
dictData=Simulink.data.dictionary.open(dataDictPath); %打开数据字典
dataSec=getSection(dictData,'Design Data'); %获取数据字典中,Design Data的Section,通常设置的参数默认都在这一Section
evalin(dataSec,['fs=',fsList{i},';']); %修改数据字典参数
saveChanges(dictData); %保存更改
close(dictData); %关闭数据字典
% 进行仿真
% …………
% 保存数据
% …………
end