在 Simulink 模型中使用枚举数据
枚举数据是指仅限于一组有限值的数据。枚举数据类型是一个 MATLAB® 类,它定义一组枚举值。每个枚举值包括一个枚举名称和一个基础整数,该数字由软件在内部以及生成的代码中使用。
有关 Simulink® 中的枚举的基本概念信息,请参阅Simulink 枚举。
有关使用枚举生成代码的信息,请参阅在生成的代码中使用枚举数据 (Simulink Coder)。
定义 Simulink 枚举
要定义您可以在 Simulink 模型中使用的枚举数据类型,请使用以下方法之一:
使用
classdef
模块在 MATLAB 文件中定义枚举类。使用函数
Simulink.defineIntEnumType
。不需要使用脚本文件来定义枚举数据类型。有关详细信息,请参阅函数参考页。使用函数
Simulink.importExternalCTypes
为您的外部 C 代码定义的枚举数据类型 (enum
) 创建 Simulink 表示。
用于定义 Simulink 枚举类的工作流
(可选)将枚举定义永久存储到 Simulink 数据字典中。请参阅永久存储枚举类型定义。
创建 Simulink 枚举类
要创建 Simulink 枚举类,请在类定义中执行以下操作:
将该类定义为
Simulink.IntEnumType
的子类。您也可以基于下面这些内置的整数数据类型来创建枚举类型:int8
、uint8
、int16
、uint16
、int32
和uint32
。添加
enumeration
模块,以指定枚举值和基础整数值。
请参考以下示例:
classdef BasicColors < Simulink.IntEnumType enumeration Red(0) Yellow(1) Blue(2) end end
其中第一行定义基于整数的枚举,它从内置类 Simulink.IntEnumType
派生而来。该枚举基于整数,因为 IntEnumType
是从 int32
派生而来。
enumeration
部分指定三个枚举值。
枚举值 | 枚举名称 | 基础整数 |
---|---|---|
Red(0) | Red | 0 |
Yellow(1) | Yellow | 1 |
Blue(2) | Blue | 2 |
定义要在 Simulink 环境中使用的枚举类时,请注意以下事项:
有关超类的详细信息,请参阅转换为超类值。有关一个基值存在多个名称时如何处理枚举类的信息,请参阅How to Alias Enumeration Names。
自定义 Simulink 枚举
关于 Simulink 枚举自定义. 您可以通过在类定义中实现特定的静态方法来自定义 Simulink 枚举。如果您使用正确的语法定义这些方法,则可以在仿真过程中以及在生成的代码中更改类的行为。
下表显示为了自定义枚举可以实现的方法。
静态方法 | 用途 | 未实现方法时的默认值 | 自定义返回值 | 使用环境 |
---|---|---|---|---|
getDefaultValue | 指定类的默认枚举成员。 | 枚举定义中指定的第一个成员 | 包含类中某个枚举成员的名称的字符向量(请参阅对枚举进行实例化) | 仿真和代码生成 |
getDescription | 指定枚举类的描述。 | '' | 包含类型描述的字符向量 | 代码生成 |
getHeaderFile | 指定头文件的名称。方法 getDataScope 决定该文件的重要性。 | '' | 包含定义枚举类型的头文件的名称的字符向量 | 代码生成 |
getDataScope | 指定生成的代码是导出还是导入枚举数据类型的定义。使用方法 getHeaderFile 指定定义该类型的生成的或包含的头文件。 | 'Auto' | 以下值之一:'Auto' 、'Exported' 或 'Imported' | 代码生成 |
addClassNameToEnumNames | 指定在生成的代码中是否为类名称添加前缀。 | false | true 或 false | 代码生成 |
有关在代码生成中使用这些方法的更多示例,请参阅自定义枚举数据类型 (Simulink Coder)。
指定默认枚举值. 当您未提供其他初始值时,Simulink 和相关的生成代码将使用枚举的默认值对枚举数据进行接地值初始化。例如,条件执行子系统内尚未执行的枚举信号具有枚举的默认值。如果安全转换失败,生成的代码将使用枚举的默认值,如枚举的类型转换 (Simulink Coder)所述。
除非您另有指定,否则枚举的默认值是枚举类定义中的第一个值。要指定不同的默认值,请在 methods
部分添加您自己的 getDefaultValue
方法。下面的代码显示了 getDefaultValue
方法的 shell:
function retVal = getDefaultValue() % GETDEFAULTVALUE Specifies the default enumeration member. % Return a valid member of this enumeration class to specify the default. % If you do not define this method, Simulink uses the first member. retVal = ThisClass.EnumName; end
要自定义此方法,请为
提供一个值,以指定所需的默认值。ThisClass.EnumName
ThisClass
必须是该方法所在的类的名称。EnumName
必须是该类中定义的枚举值的名称。
例如:
classdef BasicColors < Simulink.IntEnumType enumeration Red(0) Yellow(1) Blue(2) end methods (Static) function retVal = getDefaultValue() retVal = BasicColors.Blue; end end end
本示例将默认值定义为 BasicColors.Blue
。如果没有使用此方法,默认值将为 BasicColors.Red
,因为这是枚举类定义中列出的第一个值。
该类定义中看似多余的 ThisClass
指定是必要的,因为 getDefaultValue
返回默认枚举值的实例,而不仅仅是值的名称。因此,该方法需要完整地指定要实例化的内容。有关详细信息,请参阅 对枚举进行实例化。
将枚举保存到 MATLAB 文件中
您可以在 MATLAB 文件中定义枚举。
定义文件的名称必须与枚举的名称完全匹配,包括大小写。例如,枚举
BasicColors
的定义必须在名为BasicColors.m
的文件中。否则,MATLAB 将找不到该定义。每个类定义都必须在一个单独的文件中定义。
将每个定义文件保存到 MATLAB 搜索路径中。MATLAB 将在必要时通过搜索该路径来查找定义。
要将文件或文件夹添加到 MATLAB 搜索路径中,请在 MATLAB 命令提示符下键入
addpath
。有关详细信息,请参阅什么是 MATLAB 搜索路径?、pathname
addpath
和savepath
。您不需要执行枚举类定义即可使用枚举。唯一的要求(如上一条所述)是定义文件必须在 MATLAB 搜索路径中。
更改和重新加载枚举类
可以通过编辑并保存包含枚举定义的文件来更改枚举定义。您不需要告诉 MATLAB 类定义已更改。当您保存文件时,MATLAB 会自动读取修改后的定义。但是,如果存在反映以前的类定义的任何类实例(枚举值),类定义更改将不会完全生效。此类实例可能存在于基础工作区或缓存中。
下表解释了从基础工作区和缓存中删除枚举实例的选项。
如果在基础工作区中... | 如果在缓存中... |
---|---|
执行以下操作之一:
|
|
同样,如果您使用 Simulink.defineIntEnumType
定义枚举类,您可以使用相同的函数重新定义该类,即使实例存在也是如此。但是,当实例存在时,您不能更改该类的 StorageType
。
有关应用枚举更改的详细信息,请参阅Automatic Updates for Modified Classes。
将在外部定义的枚举导入到 MATLAB 中
要导入您在 MATLAB 外部定义的枚举以便在 Simulink 环境中使用,您可以通过调用以下函数之一以编程方式实现此目的。
Simulink.defineIntEnumType
- 定义的枚举可以像由类定义文件所定义的枚举一样在 MATLAB 中使用。除了指定枚举类名称和值外,每个函数调用还可以指定:用于描述枚举类的字符向量。
哪个枚举值是默认值。
对于代码生成,您可以指定:
为生成的代码定义枚举的头文件。
代码生成器是否使用类名称作为枚举成员的前缀 - 例如
BasicColors_Red
或Red
。
以下面的类定义为例:
classdef BasicColors < Simulink.IntEnumType enumeration Red(0) Yellow(1) Blue(2) end methods (Static = true) function retVal = getDescription() retVal = 'Basic colors...'; end function retVal = getDefaultValue() retVal = BasicColors.Blue; end function retVal = getHeaderFile() retVal = 'mybasiccolors.h'; end function retVal = addClassNameToEnumNames() retVal = true; end end end
下面的函数调用定义了在 MATLAB 中使用的同一个类:
Simulink.defineIntEnumType('BasicColors', ... {'Red', 'Yellow', 'Blue'}, [0;1;2],... 'Description', 'Basic colors', ... 'DefaultValue', 'Blue', ... 'HeaderFile', 'mybasiccolors.h', ... 'DataScope', 'Imported', ... 'AddClassNameToEnumNames', true);
Simulink.importExternalCTypes
- 为您的现有 C 代码定义的枚举数据类型 (enum
) 创建 Simulink 表示。
如果模型中的 MATLAB Function 模块使用枚举类型,请将模型配置参数配置为包含 (#include
) 来自外部头文件的类型定义。请参阅控制导入的总线和枚举类型定义。
永久存储枚举类型定义
不管您是使用类文件还是函数 Simulink.defineIntEnumType
定义枚举,都可以将枚举定义永久存储到 Simulink 数据字典中。与字典链接的模型可以使用该枚举。有关详细信息,请参阅 Enumerations in Data Dictionary。
使用枚举进行仿真
请参考以下枚举类定义 - BasicColors
的枚举值包括 Red
、Yellow
和 Blue
,Blue
为默认值:
classdef BasicColors < Simulink.IntEnumType enumeration Red(0) Yellow(1) Blue(2) end methods (Static) function retVal = getDefaultValue() retVal = BasicColors.Blue; end end end
一旦 MATLAB 获知此类定义,您即可在 Simulink 和 Stateflow® 模型中使用该枚举。Stateflow 中特定于枚举的信息显示在枚举数据 (Stateflow)中。以下 Simulink 模型使用上面定义的枚举:
模型输出如下所示:
Data Type Conversion 模块 OrigToInt 将输出数据类型指定为 int32
并将整数舍入模式: 指定为 Floor
,因此该模块将 Scope 显示画面的最上面一个图中显示的 Sine Wave 模块输出转换为以下整数的循环:1
、2
、1
、0
、1
、2
、1
。Data Type Conversion 模块 IntToColor 使用这些值通过引用它们的基础整数从枚举类型 BasicColors
中选择颜色。
结果是一个颜色循环:Yellow
、Blue
、Yellow
、Red
、Yellow
、Blue
、Yellow
,如中间的图所示。Enumerated Constant 模块 EnumConst 输出 Yellow
,它在第二个图中显示为一条直线。Relational Operator 模块将常量 Yellow
与颜色循环中的每个值进行比较。当 Yellow
小于当前颜色时,它输出 1
(true
);否则,输出 0
(false
),如第三个图所示。
进行比较时使用的排序顺序是所比较值的基础整数的数值顺序,不是枚举类定义中显示枚举值的词典式顺序。此示例中两种顺序相同,但这并不是必需的。有关详细信息,请参阅将枚举指定为数据类型和 计算中的枚举值。
将枚举指定为数据类型
定义枚举之后,您可以像使用其他任何数据类型一样使用它。由于枚举是一个类而不是实例,所以将枚举指定为数据类型时,必须使用前缀 ? 或 Enum:
。在 MATLAB 命令行窗口中,必须使用前缀 ?
。但在 Simulink 模型中,两个前缀都可以使用。Enum:
与 ?
前缀的效果相同,但 Enum:
是首选,因为它在图形用户界面上下文中更加一目了然。
根据上下文,键入 Enum:
后跟枚举名称,或者从菜单中选择 Enum: <类名称>(例如,对于输出数据类型模块参数),并替换 <类名称>。
要使用数据类型助手,请将模式设置为 Enumerated
,然后输入枚举的名称。例如,在上一个模型中,Data Type Conversion 模块 IntToColor(输出 BasicColors
类型的信号)具有以下输出信号设定:
您不能为定义为枚举的信号设置最小值或最大值,因为最小值和最大值的概念与枚举的用途无关。如果您更改枚举信号的默认最小值或最大值 []
,更新模型时将会发生错误。有关详细信息,请参阅 计算中的枚举值。
获取有关枚举数据类型的信息
函数 enumeration
和 Simulink.data.getEnumTypeInfo
返回有关枚举数据类型的信息。
获取有关枚举成员的信息
使用函数 enumeration
可以:
在 MATLAB 命令行窗口中返回包含枚举类的所有枚举值的数组
以编程方式获取枚举值
为接受枚举值数组或向量的 Simulink 模块参数(如 Switch Case 模块的 Case 条件参数)提供值
获取有关枚举类的信息
使用函数 Simulink.data.getEnumTypeInfo
返回有关枚举类的信息,例如:
默认的枚举成员
在生成的代码中定义类型的头文件的名称
生成的代码中用来存储枚举成员的基础整数值的数据类型
枚举值的显示
Simulink 通常显示枚举值的名称,而不是基础整数值。但基础整数可能会影响 Scope 和 Floating Scope 模块中值的显示。
模块... | 对值显示的影响... |
---|---|
Scope | 显示枚举信号时,枚举值的名称在 Y 轴上显示为标签。名称的显示顺序由它们的基础整数决定,最小值显示在最下面。 |
Floating Scope | 显示具有相同枚举的信号时,名称在 Y 轴上的显示与在 Scope 模块中相同。如果 Floating Scope 模块显示混合数据类型,则不显示名称,而且任何枚举值都以其基础整数表示。 |
具有非唯一整数的枚举值
一个枚举中的多个值可以具有相同的基础整数值,如将枚举指定为数据类型中所述。出现这种情况时,Scope 模块输出或 Display 模块输出的坐标轴上显示的值始终是枚举类定义中列出的具有相同基础整数的第一个值。例如:
虽然 Enumerated Constant 模块输出 True
,但 On
和 True
具有相同的基础整数,而 On
在类定义 enumeration
部分定义为第一个值。因此,Display 模块显示 On
。同样,无论为 Scope 模块输入这两个值中的哪一个,Scope 坐标轴都只会显示 On
,永远不会显示 True
。
对枚举进行实例化
使用枚举之前,必须对其进行实例化。您可以在 MATLAB、Simulink 模型或 Stateflow 表中对枚举进行实例化。所有这三种情况下的语法都相同。
在 MATLAB 中对枚举进行实例化
要在 MATLAB 中对枚举进行实例化,请在 MATLAB 命令行窗口中输入 ClassName
.EnumName
。将在基础工作区中创建实例。例如,如果按照创建 Simulink 枚举类中所述定义了 BasicColors
,您可以键入:
bcy = BasicColors.Yellow bcy = Yellow
Tab 键自动填充功能适用于枚举。例如,如果您输入:
bcy = BasicColors.<tab>
MATLAB 将按字母顺序显示 BasicColors
的元素和方法:
双击某个元素或方法,以将其插入到您按下 <tab>
键的位置。有关详细信息,请参阅 Code Suggestions and Completions。
在 MATLAB 中转换枚举
在 MATLAB 中,您可以直接将整数转换为枚举值:
bcb = BasicColors(2) bcb = Blue
还可以将枚举值转换为基础整数:
>> bci = int32(bcb) bci = 2
在任一情况下,MATLAB 都会以相关数据类型的 1x1 数组形式返回转换结果。
虽然可以进行转换,但在为枚举类定义的枚举值和对应的整数可能改变的情况下,使用枚举值并不可靠。
在 Simulink(或 Stateflow)中对枚举进行实例化
要在 Simulink 模型中对枚举进行实例化,您可以在对话框中输入 ClassName
.EnumName
作为一个值。例如,请参考以下模型:
输出枚举值 Yellow
的 Enumerated Constant 模块 EnumConst 按如下所示定义该值:
您可以输入计算结果为枚举值的任何有效的 MATLAB 表达式,包括数组和工作区变量。例如,您可以输入 BasicColors(1)
;如果您之前已经在 MATLAB 命令行窗口中执行 bcy = BasicColors.Yellow
,则可以输入 bcy
。您还可以输入数组,例如 [BasicColors.Red, BasicColors.Yellow, BasicColors.Blue]
。
您可以使用 Constant 模块来输出枚举值。但是,该模块显示的参数不适用于枚举类型,例如输出最小值和输出最大值。
如果您创建一个 Simulink.Parameter
对象作为枚举,则必须将值参数指定为枚举成员,并使用 Enum:
或 ? 前缀指定数据类型,如将枚举指定为数据类型中所述。
您不能为值参数指定枚举成员的整数值。有关详细信息,请参阅 计算中的枚举值。因此,即使 BasicColors.Yellow
的整数值为 1
,以下指定也会失败。
这些语法和注意事项在 Stateflow 中同样适用。有关详细信息,请参阅 枚举数据 (Stateflow)。
计算中的枚举值
按照设计,Simulink 不允许在数学计算中将枚举值作为数值使用,即使枚举类是 MATLAB int32
类的子类也是如此。因此,尽管枚举类型存在基础整数,也不能作为数值类型使用。例如,您不能直接为 Gain 模块输入枚举信号。
您可以使用 Data Type Conversion 模块在整数类型和枚举类型之间进行双向转换,或在两个枚举类型之间进行转换。也就是说,您可以使用 Data Type Conversion 模块将枚举信号转换为整数信号(包含枚举信号值的基础整数),并将生成的整数信号输入给 Gain 模块。有关详细信息,请参阅 转换枚举信号。
Simulink 中的枚举类型用来表示模块(如 Relational Operator 模块和 Switch 模块)中的程序状态和控制程序逻辑。当 Simulink 模块比较枚举值时,比较的值必须具有相同的枚举类型。模块将基于枚举值的基础整数(而不是它们在枚举类定义中的顺序)对枚举值进行比较。
当一个模块(如 Switch 模块或 Multiport Switch 模块)从多个数据信号中进行选择时,只要有任一数据信号是枚举类型,则所有数据信号都必须具有与之相同的枚举类型。当一个模块同时输入控制信号和数据信号时,就像 Switch 和 Multiport Switch 一样,则控制信号类型不需要与数据信号类型匹配。
转换枚举信号
您可以使用 Data Type Conversion 模块将枚举信号转换为任何数值类型的信号,前提是输入到该模块的所有枚举值的基础整数都在该数值类型的范围内。否则,仿真过程中将发生错误。
同样,可以使用 Data Type Conversion 模块将任何整数类型的信号转换为枚举信号,前提是输入到 Data Type Conversion 模块的每个值都是枚举类型中某个值的基础整数。否则,仿真过程中将发生错误。
不能使用 Data Type Conversion 模块将任何非整数数据类型的数值信号转换为枚举类型。例如,使用枚举进行仿真中使用的模型需要两个 Data Conversion 模块将正弦波转换为枚举值。
第一个模块将 double
转换为 int32
,第二个模块将 int32
转换为 BasicColors
。对于复信号,不管其实部和虚部的数据类型是什么,都不能转换为枚举类型。
转换枚举模块参数
您不能将任何数值数据类型的模块参数转换为枚举数据类型。例如,假设 Enumerated Constant 模块将值指定为 2
,并将输出数据类型指定为 Enum: BasicColors
:
这种情况下将会发生错误,因为该指定将 double
值隐式转换为枚举类型。即使该数值从算术意义上对应于枚举类型中的某个枚举值,也会发生错误。
您不能将枚举类型的模块参数转换为其他任何数据类型。例如,假设 Constant 模块将常量值指定为 BasicColors.Blue
,并将输出数据类型指定为 int32
。
这种情况下将会发生错误,因为该指定将枚举值隐式转换为数值类型。即使枚举值的基础整数是有效的 int32
,也会发生错误。
另请参阅
enumeration
| Simulink.defineIntEnumType
| Simulink.data.getEnumTypeInfo