本文研究通过回调函数,在打开模型时加载数据字典到工作空间中。

1 问题引入

《Matlab编程技巧:通过脚本导入Excel数据字典》一文中,博主研究了通过脚本将表格里的数据字典导入到Matlab工作空间中。

这种方法需要每次都要手动运行脚本,也有点不太方便。简单研究后发现,可以通过在模型中配置回调函数,使得打开模型的时候自动运行某个脚本,从而自动将表格中的数据字典导入到Matlab工作空间中。

2 简单例程

例程是在《Matlab编程技巧:通过脚本导入Excel数据字典》一文的基础上进行研究的,关于脚本编写就不再赘述。

2.1 模型配置

1)新建一个Simulink空白模型demo.slx,打开File–>Model Properties–>Model Properties
在这里插入图片描述
2)在Model Properties:demo中选中Callbacks选项卡。
在这里插入图片描述
3)点击左侧的PreLoadFcn,在右侧的Model pre-load function窗口中写入函数Import_DD();
在这里插入图片描述
这个函数会后后面步骤中建立的函数相同,表示模型启动时预加载了名为Import_DD()的函数。

4)最后点击OK,保存模型并关闭。

2.2 数据字典表格

这里示范用的数据字典表格的内容和《Matlab编程技巧:通过脚本导入Excel数据字典》一文中一样,这里还是重复说明一下。

1)在模型同路径下建立表格文件demo_DD.xlsx
在这里插入图片描述
这里的表格命名是模型名_DD.xlsx,可以和模型相对应。这个名称对应的概念很关键,在后面的脚本中会利用到。

2)在表格中加上三个工作表:‘Signal’,‘AliasType’,‘Bus’,内容如下。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3 创建脚本

1)新建一个Matlab脚本,命名为Import_DD.m。这里的命名和模型配置的时候相对应。

2)打开Import_DD.m,将如下代码拷贝到文件里面。

function Import_DD()
%% 表格名称
Model_Name = get_param(gcs,'Name');     %模型名称
Excel_Name = [Model_Name,'_DD.xlsx'];        %表格名称
evalin('base','clear');                 %清空工作空间

%% 导入Simulink.Signal
[~,~,Signal_Cell] = xlsread(Excel_Name,'Signal');   %导入Signal工作表为单元数组
for row = 2:size(Signal_Cell,1) %从第2行开始循环处理每一行内容
    % 提取信号名,数据类型,初始值,存储类型
    SignalName = Signal_Cell{row,1};         
    DataType = Signal_Cell{row,2};      
    InitialValue = Signal_Cell{row,3};  
    StorageClass = Signal_Cell{row,4}; 
    % 在工作空间中建立该对象并配置其属性
    evalin('base',[SignalName,' = Simulink.Signal;']);                              
    evalin('base',[SignalName,'.DataType = ''',DataType,''';']);                    
    evalin('base',[SignalName,'.InitialValue = ''',InitialValue,''';']);            
    evalin('base',[SignalName,'.CoderInfo.StorageClass = ''',StorageClass,''';']);  
end

%% 导入Simulink.AliasType
[~,~,AliasType_Cell] = xlsread(Excel_Name,'AliasType');   %导入AliasType工作表为单元数组
for row = 2:size(AliasType_Cell,1) %从第2行开始循环处理每一行内容
    % 提取别名、基础类型
    AliasName = AliasType_Cell{row,1};
    BaseType = AliasType_Cell{row,2};      
    % 在工作空间中建立该对象并配置其属性
    evalin('base',[AliasName,' = Simulink.AliasType;']);
    evalin('base',[AliasName,'.BaseType = ''',BaseType,''';']);
end

%% 导入Simulink.Bus
[~,~,Bus_Cell] = xlsread(Excel_Name,'Bus');   %导入Bus工作表为单元数组
for row = 2:size(Bus_Cell,1) %从第2行开始循环处理每一行内容    
    %更新Bus名称
    if ~isnan(Bus_Cell{row,1})  
        BusName = Bus_Cell{row,1};
        i = 1;
        evalin('base',[BusName,' = Simulink.Bus;']);
    end
    % 提取元素名称、尺寸、类型
    BusElementName = Bus_Cell{row,2};
    Dimensions = Bus_Cell{row,3};
    DataType = Bus_Cell{row,4};
    % 建立元素并加入Bus中
    evalin('base',[BusName,'.Elements(',num2str(i),').Name = ''',BusElementName,''';']);
    evalin('base',[BusName,'.Elements(',num2str(i),').Dimensions = ',Dimensions,';']);
    evalin('base',[BusName,'.Elements(',num2str(i),').DataType = ''',DataType,''';']);
    % Bus元素索引+1
    i = i + 1;
end
end

脚本的前三行会先获取模型的名称,然后通过模型名推算出表格的名称,再获取表格的内容。所以表格和模型必须能按照脚本中的规则对应上。

脚本的第三行以后和《Matlab编程技巧:通过脚本导入Excel数据字典》一文中一样,不再赘述。

3)保存脚本并关闭。

3 效果演示

完成了第2章中的步骤以后,重新打开demo.slx模型文件,就会看到表格中的数据对象被加载到了工作空间中了。
在这里插入图片描述
验证了回调函数的效果。

4 总结

这部分回调函数配置并没有用到很多新的编写脚本的技巧,但是却能达到很实际的效果。

除了模型预加载的回调函数以外,关于模型还有很多其他的回调函数,等到工作中有了需求再去研究。

>>返回个人博客总目录

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐