[忤旭]《MATLAB》Simulink自动更改参数示例

大家好,我是忤旭!
今天分享的是关于MATLAB仿真中利用脚本和回调函数来实现一键多次仿真,并且每次仿真都自动修改参数。需要注意的文中脚本只针对每次仿真数据是定值的模型,如果要保存时变数据请自行修改脚本。
修改当前工作文件夹
进入MATLAB后,先将当前工作文件夹切换到你想要的文件夹。


新建脚本文件



脚本编写
完整的脚本,在文章的最后会进行代码分析。

仿真模型搭建
搭建你的仿真模型,这里只是举个例子。





设置直流电源的参数为变量inp,后续每次仿真都修改它的值。


设置回调函数
通过设置回调函数来建立Simulink模块与MABLAB工作空间的联系。


我选择预加载函数来建立桥梁,并在预加载函数中定义了MATLAB工作空间中的变量inp,也就是模型每次加载时都会创建一个inp的工作空间变量,同时直流电源的参数由这个变量决定。

记录数据到MATLAB工作空间
为了保存每次仿真的数据,必须将每次仿真的数据记录到MATLAB工作空间以写入Excel。右键信号线并选择Log Selected Signals以将这条信条线的数据记录到MATLAB工作空间。

需要注意的是哪条信条线先进行记录根据你自己而定,比如这张图里我选择先记录电流,再记录电压,这将与最后仿真结果中数据的顺序有关。

脚本运行
运行脚本后,等待一段时间,这与你设置的仿真次数有关,当脚本运行完毕后你就会得到图中保存了所有你记录的信号线的data.xlsx,右边的simOut是单次仿真的数据,下面会讲解如何在simOut中找到你要的数据。

单次仿真数据保存的地方

注意观察图中右框中显示的内容,是否是你想要的数据顺序,如果不是请重新返回模型修正记录顺序。


这就是你记录的第1条信号线的单次仿真数据,红框中是数据地址,在最后加上数据索引就可以得到一个具体数值了。比如图中第1个数值1需要使用.Data(1,1)来进行索引,而这一列的数值你可以使用.Data(:,1)来索引。

查看所有仿真数据保存的Excel文件

可以从图中看到第1列数据为记录的电流,第2列数据为记录的电压,与预期的数据顺序符合。

代码分析

model = 'Test'; %仿真模型名称,不用加.slx后缀
定义存放模型名的变量,根据你模型名字进行修改。
inp = 1; %变量初始化
定义仿真模型中每次要改变的参数,你也可以定义好几个。
inp_series = 1:1:10; %设置变量的数组
定义一个数组,用来存放参数准备更改的值,比如1:1:10就是inp将从1仿真到10,每次步长为1。
Excel_name = 'data.xlsx'; %保存数据的Excel文件名
定义存放Excel名字的变量,你可以改名。
head1 = "1"; %数据1的头
定义数据1的头,也就是一列数据的名字。
head2 = "2"; %数据2的头
定义数据2的头,也就是一列数据的名字。
Excel_data_head = [head1, head2]; %存放数据头的变量
定义存放数据头的变量,你可以按你需要增加或减少数据头。
%%
open_system(model);
打开Simulink模块。
load_system(model);
加载model仿真模型。
for i = 1:1:length(inp_series)
循环参数数组。
inp = inp_series(i);
从参数数组中取一个新参数赋给参数inp。
simOut = sim(model);
对model仿真模型开始仿真。
if exist(Excel_name, 'file')==0
判断当前工作文件夹中是否存在名为Excel_name的Excel。
disp('no Excel file');
如果不存在就打印不存在Excel文件。
Excel_data_head_position = strcat(['A', '1', ':', char('A' + length(Excel_data_head) - 1), '1']);
根据定义的数据头变量长度来创建数据头位置变量。
xlswrite(Excel_name, Excel_data_head, 'sheet1', Excel_data_head_position);
根据数据头位置变量将数据头变量写入名为Excel_name的Excel文件中。
disp('Excel has been created');
打印Excel已经创建。
end
load = xlsread(Excel_name, 'sheet1');
加载名为Excel_name的Excel文件的sheet1工作表。
[m, n] = size(load);
计算Excel的形状并赋值给m和n。
m = m + 1;
行数加1。
write_position = strcat(['A', num2str(m), ':', char('A' + length(Excel_data_head) - 1), num2str(m)]);
根据当前行数和数据头变量长度来定义数据位置变量。
data = [];
定义数据变量为一维数组。
for j = 1:1:length(Excel_data_head)
根据数据头长度进行循环。
data = [data simOut.logsout{j}.Values.Data(1:1)];
从仿真数据中依次取得信号线数据,并存放进数据变量中。需要注意虽然文中(1:1)与(1,1)等价,但单个数据索引应使用(1,1),列向量数据索引应使用(:,1)。
end
result = xlswrite(Excel_name, data, 'sheet1', write_position);
根据将数据data写入名为Excel_name的Excel的sheet1的write_position位置。
end