内容:【单次运行 / 用脚本批量运行 / 保存特定时刻信号值 / 完整代码】
一、搭建模型
1. RC电路为例
放置如下电路。电路相关元件在simscape→Foudation库,solver configuration和PS-S Converter在simscape→Utilities库,Scope在simulink→sink库。求解器需连接到电路网络内任意一个位置,把物理信号(电路内)转换到Simulink环境需要PS-S Converter。
将模型保存为 example_RC 。
设置Vdc=1V,将阻值和容值设置成变量res和cap,此后修改阻值和容值进行批量仿真。设置后会提示变量不存在,单次仿真时可以单击右键→模型属性→回调→InitFcn里设置参数的值,如res=1k,cap=1n。
2. 运行仿真
时间常数RC=1e3*1e-9=1e-6,在界面上方仿真栏,设置停止时间为5*RC=5e-6,点击运行,双击scope查看波形。在scope界面“游标测量值”可以查看数据点,如下图,如果要修改RC参数来获取波形,或者读取波形某个时刻的值,需要在InitFcn反复修改,很不方便。
二、用脚本批量运行仿真
用脚本批量运行simulink仿真前,介绍用到的主要函数和代码
1. myConfig = getActiveConfigSet(‘modelName’)
根据输入的模型名,返回该模型的ConfigSet,ConfigSet是“配置模型”,对应simulink界面里“模型设置”选项的GUI内容,“模型设置”界面内所有的选项都可以通过ConfigSet用代码来配置。
2. set_param(ConfigSetName, para1, value1, para2, value2, …)
设置ConfigSet参数,第一个参数是ConfigSet变量名,para名可以在“模型设置”选项GUI内右键查看,比如仿真停止时间是StopTime:
例:set_param(myConfig, 'StopTime', '8e-9'); % 配置仿真结束时间为8ns
3. Simout = sim(modelName, ConfigSetName)
在模型中设置想要保存的信号 :回到模型里,鼠标放到要记录的信号线上,点击“记录所选信号”。
根据输入的模型名和ConfigSet名运行仿真。
SimOut = sim(‘example_RC’, myConfig); % 用myConfig的配置运行example_RC
SimOut = sim(‘example_RC’); % 用默认配置运行
sim函数返回的是Simulink.SimulationOutput对象,仿真结果存储在该对象内。
① 运行仿真,SimulationOutput对象中logsout是前面标记的信号线信息,tout是仿真时间步。 ② 进入logsout,只包含标记的一个数据, ③ 用花括号进行访问, ④ 进入Values,其中 Data和Time就是信号和对应的时间。
4. 设置扫描参数值,批量运行仿真
模型包含变量res和cap,在脚本中直接对这两个变量赋值即可。 注意删除回调的 InitFcn 中的内容 ,否则每次sim都会运行InitFcn,覆盖掉脚本中的变量设置。
用数组保存想仿的res和cap值,在for循环修改res和cap,再运行sim函数,完成批量运行。
三、保存特定时刻信号值
1. 遍历时间步
从SimulationOutput类里可以获得信号Data和Time,遍历数组可以找到对应时刻值,可以配置MaxStep来调节Time时间步长。
这种方法在数据量大的时候慢,要遍历整个数组来找时间值。
2. 在模型中存储特定时刻值
实现方式有很多,这里介绍用 if模块实现, 保存 3us 时刻的信号值 。图中模块名称都显示了,对着检索就行。If和If Action Subsystem在Simulink/Ports and Subsystems库,Clock在Simulink/Source,Data Store Write和Data Store Memory在Simulink/Signal Routing库。
Clock会输出当前仿真时间,if模块对时间进行判断,允许0.1us的取值时间偏差偏差,则处于2.9u~3.1u内就执行If Action Subsystem模块,Action模块相当于指定范围内闭合的开关,把要存储的信号和Data Store Write模块连线,Write模块获得的信号会写入到Memory模块里,一直存储到仿真结束。
① 取值时间偏差和仿真时间步大小需对应,否则可能跳过判别条件对应时间,用MaxStep参数修改时间步:set_param(myConfig, 'MaxStep', '1e-7'); % 仿真最大时间步0.1u,则一定会有一个时间点落入2.9u~3.1u
② 如果要在多个时间存储值,多用几个elseif就行。
③ 同名的Data Store Write模块和Data Store Memory模块链接起来,双击Memory模块,可以看到对应关系:
④ 要手动选择记录Memory模块的信息,打开模块,在记录栏中选中记录数据。
⑤ Memory的信息记录在SimulationOutput对象的dsmout里,和信号线信息logsout是并列关系。
用Simout.dsmout{1}.Values.Data(end)获取Memory的值,信号会存储到仿真结束,直接取最后一个值。
完整代码
modelName = 'example_RC'; % 模型名称为example_RC
load_system(modelName); % 加载模型
% 配置ConfigSet
myConfig = getActiveConfigSet(modelName);
set_param(myConfig, 'StopTime', '5e-6'); % 配置仿真结束时间5us
% 要批量扫描的变量数组
resVal = [1e3 2e3 3e3];
capVal = [1e-9 2e-9];
% excel标题
xlswrite('C:\Users\shuanQ\Desktop\example_RC.xlsx', ["res(Ohm)" "Cdec(nF)" "vout_3us"], 1, 'A1');
% 批量运行
groupNum = length(resVal)*length(capVal); % 运行次数
rows = 1; % excel行数
for i = 1:length(resVal)
for j =1:length(capVal)
res = resVal(i);
cap = capVal(j);
Simout = sim(modelName, myConfig) % 运行仿真
vout_3us = Simout.dsmout{1}.Values.Data(end) % 获取3us时刻的值
rows = rows + 1;
% 把结果打印到excel
xlswrite('C:\Users\shuanQ\Desktop\example_RC.xlsx', res, 1, strcat('A', num2str(rows))); % res
xlswrite('C:\Users\shuanQ\Desktop\example_RC.xlsx', cap*1e9, 1, strcat('B', num2str(rows))); % cap
xlswrite('C:\Users\ shuanQ \Desktop\example_RC.xlsx', vout_3us, 1, strcat('C', num2str(rows))); % vout_3us
end
end
excel结果