|
汽车零部件采购、销售通信录 填写你的培训需求,我们帮你找 招募汽车专业培训老师
本期文章将介绍数据对象(Data Objects)和数据字典(Data Dictionary)的基本概念和相关的创建方法。
点击以下链接,可以查看MBD的Simulink使用技巧系列的往期文章:
MBD的Simulink使用技巧①:Simulink代码生成的基本概念MBD的Simulink使用技巧②:详解代码生成中的模型与代码MBD的Simulink使用技巧③:虚拟子系统与原子子系统的代码生成MBD的Simulink使用技巧④:详解生成代码的结构与代码的生成流程
MBD的Simulink使用技巧⑤:详解自动代码生成的配置与优化
MBD的Simulink使用技巧⑥:代码生成目标配置工具
MBD的Simulink使用技巧⑦:自动生成代码的集成方法
MBD的Simulink使用技巧⑧:函数原型、传参的控制与修改
MBD的Simulink使用技巧⑧(续):函数接口封装的控制和修改
MBD的Simulink使用技巧⑨:代码数据类型的修改和控制
MBD的Simulink使用技巧⑩:数据存储类的使用方法
特别提示:在本篇文章中使用到的.m脚本等文件,可以在autoMBD资源库的“临时资源分享”文件夹中找到(资源序号为tA34)。资源库链接的获取可以在《autoMBD原创技术文章合集》中找到(见文章开头)。
1 写在前面
使用Simulink建模开发,有一个非常重要的、进阶的思想:数据(Data)和模型(Model)分别开发和管理。
这会带来诸多好处,这里总结主要有以下三点:
独立性:有利于数据和模型分别的迭代开发、管理;
通用性:一份数据供多个模型使用,或一个模型快速变更不同数据;
操作性:可以通过.m脚本实现自动化测试和管理。
上述思想无关乎MBD(代码生成),适用于所有的建模应用。对于初学者来说,他们往往只着眼于模型,而忽视了数据的开发和管理。特别是在大模型、复杂模型中,数据的开发和管理显得尤为重要。
具体而言,在Simulink中数据即数据对象(Data Objects),而管理数据对象的集合被称为数据字典(Data Dictionary)。
有的读者可能对数据对象还不太熟悉,在介绍数据对象如何控制生成代码之前,会先介绍数据对象和数据字典的一些基本概念和使用方法。
2 数据对象的基本概念和创建
一般而言,我们提及的数据(Data),它是一个集合概念;数据由若干的数据对象(Data Objects)构成,即数据对象是数据的基本元素。
数据对象通过其属性(Properties)来描述和表征,例如名称、值、数据类型等。不同的数据对象可能具有不同的属性。
通常把一组特定属性的组合称为类(Class)。一个数据对象只属于一个类,多个数据对象可以属于相同的类,一个数据集合可以有多个不同的类。
更加形象的例子如下图所示:
数据与数据对象的关系 - From autoMBD
上图中展示了数据和数据对象的一般关系,图中数据集合包含四个数据对象;不同的颜色表示数据对象具有不同的属性,即图中包含三个类,数据对象C1和C2属于同一个类。Tips:后文将通过示例来展示数据对象的创建方法,相关脚本可以在autoMBD资源库的“临时资源分享”文件夹中找到(资源序号为tA34)。2.1 创建MATLAB数据对象在MATLAB的命令行中输入如下代码:a = 1;初学者会认为,运行得到了一个名为a的变量,它的值为1。进阶一点,从数据的角度来理解,我们得到一个数据集合,其中包含一个数据对象,该数据对象的名称为a,值为1,数据类型为double(默认),维度为1x1(默认),值域为实数域(默认)。Tips:理解角度不同,所掌握的信息也就不同。“变量”或“数据对象”是从不同的角度来描述数据。上述语句a = 1虽然简单,但在MATLAB中,就已经实现了数据对象的创建。上述得到的数据对象a,属于MATLAB Variable类,该类是MATLAB中最简单、最通用的类。MATLAB Variable类具体属性如下:
MATLAB Variable类对应的数据对象,如果数据类型不同,其具体创建方式还会有所不同。下面给出一些常见的MATLAB Variable类、不同数据类型属性的数据对象创建方法(.m脚本):% autoMBD示例脚本% 展示MATLAB variable class的基本创建方法% 创建时间2023-02-04
%% 清空数据clear; clc;
%% 数值类型a1 = 1; % 普通数值,默认doublea2 = single(1); % 指定数据类型singlea3 = [1 2 3; 4 5 6]; % 数组数值a4 = 1 + 2i; % 复数数值
%% 字符串类型b1 = 'I am a string!'; % 字符数组,注意为单引号b2 = "I am a strings!";% 字符串数组,注意为双引号
%% 结构体类型c1.elm1 = 1; % 通过索引符"."定义结构体c1.elm2 = 2; % 通过索引符"."定义结构体c2 = struct('elm1', 1, 'elm2', 2); % 通过struct()函数定义结构体
%% 元胞数组类型d = {a1, a1, b1, b2}; % 定义元胞数组
%% 时序类型ts = timeseries(); % 定义时序数据对象
%% 在Model Explorer显示结果sfexplr;Tips:这里只展示了常见数据的创建,还有一些其他的数据类型,以及不同的创建方法,读者可以在MATLAB的Help文件中收索关键词“数据类型”,自行学习。在工作空间中,MATLAB Variable类的不同数据类型,会显示不同的图标,如下图所示:
MATLAB Variable类的图标 - From autoMBD
在Model Explorer中(通过语句sfexplr打开),可以更加方便地管理数据对象、查看数据对象的属性,如下图所示:
Model Explorer查看数据对象 - From autoMBD
注意,在Model Explorer中,MATLAB Variable数据对象除了Value属性,其他属性都只是可读 ,不可编辑。
2.2 创建Simulink数据对象
上文介绍的MATLAB Variables类数据对象是最基本的数据对象,在MATLAB和Simulink中都是通用的。
针对Simulink数据对象,有其特有的Simulink类,常用的有以下几个类:
Simulink.Parameter
Simulink.SignalSimulink.AliasTypeSimulink.NumericType
Simulink.Bus
Simulink类不能像MATLAB类那样,通过直接赋值来创建数据对象,需要通过类的相关函数来创建。
Tips:类的相关函数,在MATLAB中也被称为“方法”,不过我还是习惯称为“函数”。
例如,要创建一个Simulink.Parameter类的数据对象,创建方法如下:
paramObj = Simulink.Parameter;
这里的Simulink.Parameter是一个返回对应数据对象的函数,如此这样就创建好了一个名为paramObj的Simulink.Parameter数据对象。
Simulink.Parameter类的属性包括:
CoderInfo
ComplexityDataTypeDescriptionDimensionMaxMinUnitValue
可以看到,它的属性比基础的MATLAB Variable类多,特别是包含了CoderInfo属性,可以控制代码的生成。
要注意的是,刚刚创建的数据对象仅为一个空对象,它的部分属性要进行适当设置后才能使用。
下面给一个对Simulink.Parameter数据对象进行设置的例子:
% 设置属性参数paramObj.Value = 1;paramObj.DataType = 'uint16';paramObj.Max = 10000;paramObj.CoderInfo.StorageClass = 'ExportedGlobal';
上述脚本中,对Simulink.Parameter数据对象的部分属性进行了设置,包括前面文章介绍的极为强大的存储类。
要注意,属性的设置要满足该属性的要求,例如paramObj.DataType就只能设置为'uint16', 'double', 'singl', ...等Simulink支持的数据类型。
不熟悉类的人可能会比较困惑:怎么知道一个类有哪些属性可以设置?怎么知道特定属性的设置要求是什么?
这就要借助强大的MATLAB Help文档了。对于一个不熟悉的类,直接在Help工具中检索该类的名称,找到该类的详细页面,如下所示:
在Help文档中查找类 - From autoMBD
在类的详细介绍页面,找到属性相关内容,该标题下详细列举了该类的所有属性,以及每个属性的作用、设置要求等。
有的详情页中还包括Example示例,可供参考学习。如下所示:
阅读类的属性条目 - From autoMBD
阅读类的属性信息(以DataType为例) - From autoMBD
下面给出一些Simulink类和数据对象的常用方法,供读者参考:
% autoMBD示例脚本% 展示Simukink class的基本创建方法% 创建时间2023-02-04
%% 清空数据clear; clc;
%% Simulink.Parameter类paramObj = Simulink.Parameter;% 设置属性参数paramObj.Value = 1;paramObj.DataType = 'uint16';paramObj.Max = 10000;paramObj.CoderInfo.StorageClass = 'ExportedGlobal';
%% Simulink.Signal类signalObj = Simulink.Signal;% 设置属性参数signalObj.SampleTime = 0.001;signalObj.DataType = 'double';signalObj.Max = 10000;signalObj.CoderInfo.StorageClass = 'ImportedExtern';
%% Simulink.NumericType类typeObj = Simulink.NumericType;% 设置属性参数typeObj.DataTypeMode = 'Boolean';
%% Simulink.AliasType类aliasObj_float = Simulink.AliasType;% 设置属性参数aliasObj_float.BaseType = 'single';
%% Simulink.Bus类busObj = Simulink.Bus;% 创建子类elm1 = Simulink.BusElement;elm1.Name = 'BusElm1';elm1.DataType = 'single';elm2 = Simulink.BusElement;elm2.Name = 'BusElm2';% 设置属性参数busObj.Elements = [elm1 elm2];
%% 在Model Explorer显示结果sfexplr;
上述的脚本中,一共创建了五个不同的数据对象,并对部分属性进行了设置。
Simulink类和MATLAB类除了属性的不同,其操作性也不同。在Model Explorer中,可以对Simulink类数据对象进行更多的操作。
例如,可以通过Model Explorer的属性窗口对Simulink类数据对象进行修改和控制,如下所示:
在Model Explorer中修改Simulink类 - From autoMBD
除了通过脚本创建数据对象,也可以在Model Explorer的工具栏中,通过“Add”菜单创建数据对象。由“Add”菜单创建的数据对象和脚本创建的是一样的。
特别注意,通过“Add”菜单创建的数据对象,一定要保存下来(保存为.mat格式),不然关闭MATLAB/Simulink后,创建的数据对象就会丢失。
Tips:少量数据对象是可以用“Add”菜单来创建,但大量数据对象还是推荐脚本的方法来创建。
“Add”菜单如下所示:
在Model Explorer中添加Simulink类 - From autoMBD
“Add”菜单不仅仅可以创建MATLAB Variable和Simulink数据对象,还可以创建Configuration对象,甚至自定义对象。感兴趣的读者可以自行研究这部分功能。
3 数据字典的基本概念和创建
上述的示例中,运行脚本后创建的数据对象,被放置在Base Workspace中。一般情况下,Simulink模型可以直接使用Base Workspace中的数据对象。
但是当数据对象很多、模型也很多的时候,不同模型使用的数据对象也不一样,这时把所有数据对象都放在Base Workspace中,明显不是一个好的方法。
数据字典(Data Dictionary)这时候就可以派上用场了,数据字典的作用就是用来存储和管理创建的数据对象。
3.1 数据字典的基本概念
数据字典本质上也是一个对象(Object),只不过不是普通的数据对象,它的类为:
它还包含三个重要的子类:
Simulink.data.dictionary.Section
Simulink.data.dictionary.EntrySimulink.data.dictionary.EnumTypeDefinition
数据字典的Section是用来保存“对象”的区域,不仅仅是数据对象,也包括其他对象(例如Configuration、Embedded Coder Dictionary等)。不同的对象被放置在不同的区域,数据字典包含如下四个区域:
Design Data
Configurations
Embedded Coder Dictionary
Other Data
我们常常用到的数据对象被保存在“Design Data”区域当中,可以就把它理解为一个单独的Workspace,可供某一个模型单独使用。在数据字典中,“对象”被称为Entry(可以翻译为“项”)。所以Section中的每一个对象就是一个Entry。第三个重要的子类是枚举类型(Enum Type)的定义。在Simulink中,枚举类型是一个非常特殊的类型。但是,在生成代码中不建议使用Simulink枚举类型,建议使用系统枚举类型。系统枚举类型的创建方法会在后续的文章中进行介绍。关于数据字典的基本信息就介绍到这里,更多关于数据字典的内容,读者可以查看官方Help文档进行学习。
Tips:数据字典相关内容非常丰富,上述只是非常基础的介绍。读者要想熟练使用数据字典,需要在实践中多多练习,勤查Help文档。3.2 创建和管理数据字典下面给出一个简单的示例脚本,展示如何创建和修改数据字典,实现对数据对象的管理:
% autoMBD示例脚本% 展示Data Dictionary的基本创建方法% 创建时间2023-02-04
%% 清空数据clear; clc;
%% 创建数据字典if (exist('myDictionary.sldd', 'file')) ddObj = Simulink.data.dictionary.open('myDictionary.sldd');else ddObj = Simulink.data.dictionary.create('myDictionary.sldd');end
%% 新建一个数据对象paramObj,属Simulink.Parameter类paramObj = Simulink.Parameter;% 设置属性参数paramObj.Value = 1;paramObj.DataType = 'uint16';paramObj.Max = 10000;paramObj.CoderInfo.StorageClass = 'ExportedGlobal';
%% 将创建的数据对象添加到数据字典中% 获取数据字典的'Design Data'区域listEntry(ddObj);sectionObj = getSection(ddObj, 'Design Data');
if (exist(sectionObj, 'paramObj')) paramObjEntry = getEntry(sectionObj, 'paramObj');else paramObjEntry = addEntry(sectionObj, 'paramObj', paramObj);end
saveChanges(ddObj);
%% 打开Model Explorer% 在Model Explorer中显示数据字典show(ddObj);上述的脚本中,展示了如何创建一个数据字典,使用的函数为:
Simulink.data.dictionary.open()
Simulink.data.dictionary.create()
并且在数据字典中添加了一个数据对象paramObj。在数据字典中,每一个数据对象被称为Entry,所以添加数据对象的函数为addEntry()。可以在Model Explorer中查看我们新建的数据字典,如下所示:
Model Explorer中的数据字典 - From autoMBD
可以看到前文介绍的四个区域,如果只看到了“Design Data”区域,可以尝试对数据字典右键单击,将取消Empty Section隐藏,如下所示:
取消Empty Section隐藏 - From autoMBD
“Design Data”和原来的Base Workspace功能上述几乎一样的,所以在Base Workspace能实现的操作,在“Design Data”一样能做。例如:通过工具栏中的“Add”菜单添加数据对象,这里不再继续介绍。
同样地,大量数据对象的操作还是建议使用脚本,而非点击“Add”菜单。在数据字典中使用“Add”菜单,同样要注意保存修改,以免丢失。
可以看到,创建和管理数据字典的脚本已经变得比较复杂了,至少需要对数据字典的类和相关函数非常熟悉,才能写出想要的功能。
Tips:这也是为什么一直强调,要完全掌握MBD开发,一定需要纯代码开发的能力。不过.m脚本比起C语言还是简单不少。
4 本期小结
本期文章介绍了数据对象和数据字典的基本概念和创建方法,但还没有将数据对象和数据字典与模型关联起来。关联起来之后,才能发挥数据对象对代码生成的控制作用。
|
|