腳本批量運行Simulink仿真/保存特定時間信號值

內(nèi)容:【單次運行 / 用腳本批量運行 / 保存特定時刻信號值 / 完整代碼】
?
一、搭建模型
1. RC電路為例
? ? 放置如下電路。電路相關(guān)元件在simscape→Foudation庫,solver configuration和PS-S Converter在simscape→Utilities庫,Scope在simulink→sink庫。求解器需連接到電路網(wǎng)絡(luò)內(nèi)任意一個位置,把物理信號(電路內(nèi))轉(zhuǎn)換到Simulink環(huán)境需要PS-S Converter。
????將模型保存為example_RC。

????設(shè)置Vdc=1V,將阻值和容值設(shè)置成變量res和cap,此后修改阻值和容值進(jìn)行批量仿真。設(shè)置后會提示變量不存在,單次仿真時可以單擊右鍵→模型屬性→回調(diào)→InitFcn里設(shè)置參數(shù)的值,如res=1k,cap=1n。

2. 運行仿真
????時間常數(shù)RC=1e3*1e-9=1e-6,在界面上方仿真欄,設(shè)置停止時間為5*RC=5e-6,點擊運行,雙擊scope查看波形。在scope界面“游標(biāo)測量值”可以查看數(shù)據(jù)點,如下圖,如果要修改RC參數(shù)來獲取波形,或者讀取波形某個時刻的值,需要在InitFcn反復(fù)修改,很不方便。

?
二、用腳本批量運行仿真
????用腳本批量運行simulink仿真前,介紹用到的主要函數(shù)和代碼
1.???? myConfig = getActiveConfigSet(‘modelName’)
????根據(jù)輸入的模型名,返回該模型的ConfigSet,ConfigSet是“配置模型”,對應(yīng)simulink界面里“模型設(shè)置”選項的GUI內(nèi)容,“模型設(shè)置”界面內(nèi)所有的選項都可以通過ConfigSet用代碼來配置。

?2.???? set_param(ConfigSetName, para1, value1, para2, value2, …)
????設(shè)置ConfigSet參數(shù),第一個參數(shù)是ConfigSet變量名,para名可以在“模型設(shè)置”選項GUI內(nèi)右鍵查看,比如仿真停止時間是StopTime:

????例:set_param(myConfig, 'StopTime', '8e-9'); % 配置仿真結(jié)束時間為8ns
?
3.???? Simout = sim(modelName, ConfigSetName)
????在模型中設(shè)置想要保存的信號:回到模型里,鼠標(biāo)放到要記錄的信號線上,點擊“記錄所選信號”。

????根據(jù)輸入的模型名和ConfigSet名運行仿真。
????SimOut = sim(‘example_RC’, myConfig); % 用myConfig的配置運行example_RC
????SimOut = sim(‘example_RC’); % 用默認(rèn)配置運行
????sim函數(shù)返回的是Simulink.SimulationOutput對象,仿真結(jié)果存儲在該對象內(nèi)。
????①運行仿真,SimulationOutput對象中l(wèi)ogsout是前面標(biāo)記的信號線信息,tout是仿真時間步。②進(jìn)入logsout,只包含標(biāo)記的一個數(shù)據(jù),③用花括號進(jìn)行訪問,④進(jìn)入Values,其中 Data和Time就是信號和對應(yīng)的時間。

?4.???? 設(shè)置掃描參數(shù)值,批量運行仿真
????模型包含變量res和cap,在腳本中直接對這兩個變量賦值即可。注意刪除回調(diào)的InitFcn中的內(nèi)容,否則每次sim都會運行InitFcn,覆蓋掉腳本中的變量設(shè)置。
????用數(shù)組保存想仿的res和cap值,在for循環(huán)修改res和cap,再運行sim函數(shù),完成批量運行。
?
三、保存特定時刻信號值
1.???? 遍歷時間步
????從SimulationOutput類里可以獲得信號Data和Time,遍歷數(shù)組可以找到對應(yīng)時刻值,可以配置MaxStep來調(diào)節(jié)Time時間步長。

????這種方法在數(shù)據(jù)量大的時候慢,要遍歷整個數(shù)組來找時間值。
?
2.???? 在模型中存儲特定時刻值
????實現(xiàn)方式有很多,這里介紹用if模塊實現(xiàn),保存3us時刻的信號值。圖中模塊名稱都顯示了,對著檢索就行。If和If Action Subsystem在Simulink/Ports and Subsystems庫,Clock在Simulink/Source,Data Store Write和Data Store Memory在Simulink/Signal Routing庫。

????Clock會輸出當(dāng)前仿真時間,if模塊對時間進(jìn)行判斷,允許0.1us的取值時間偏差偏差,則處于2.9u~3.1u內(nèi)就執(zhí)行If Action Subsystem模塊,Action模塊相當(dāng)于指定范圍內(nèi)閉合的開關(guān),把要存儲的信號和Data Store Write模塊連線,Write模塊獲得的信號會寫入到Memory模塊里,一直存儲到仿真結(jié)束。
????① 取值時間偏差和仿真時間步大小需對應(yīng),否則可能跳過判別條件對應(yīng)時間,用MaxStep參數(shù)修改時間步:set_param(myConfig, 'MaxStep', '1e-7'); % 仿真最大時間步0.1u,則一定會有一個時間點落入2.9u~3.1u
????② 如果要在多個時間存儲值,多用幾個elseif就行。
????③ 同名的Data Store Write模塊和Data Store Memory模塊鏈接起來,雙擊Memory模塊,可以看到對應(yīng)關(guān)系:

????④ 要手動選擇記錄Memory模塊的信息,打開模塊,在記錄欄中選中記錄數(shù)據(jù)。

????⑤ Memory的信息記錄在SimulationOutput對象的dsmout里,和信號線信息logsout是并列關(guān)系。

????用Simout.dsmout{1}.Values.Data(end)獲取Memory的值,信號會存儲到仿真結(jié)束,直接取最后一個值。
?
完整代碼
modelName = 'example_RC'; % 模型名稱為example_RC
load_system(modelName); % 加載模型
?
% 配置ConfigSet
myConfig = getActiveConfigSet(modelName);
set_param(myConfig, 'StopTime', '5e-6'); % 配置仿真結(jié)束時間5us
?
% 要批量掃描的變量數(shù)組
resVal = [1e3 2e3 3e3];
capVal = [1e-9 2e-9];
?
% excel標(biāo)題
xlswrite('C:\Users\shuanQ\Desktop\example_RC.xlsx', ["res(Ohm)" "Cdec(nF)" "vout_3us"], 1, 'A1');
?
% 批量運行
groupNum = length(resVal)*length(capVal); % 運行次數(shù)
rows = 1; % excel行數(shù)
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;
??????? % 把結(jié)果打印到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結(jié)果
