目录
通过创建变量来共享和重用模块参数值
要设置模块参数值,例如 Gain 模块的 Gain 参数,可以使用您创建的且存储在工作区(例如基础工作区、模型工作区)或 Simulink® 数据字典中的数值变量。可以使用该变量设置多个模块中的多个参数值,包括不同模型中的模块。要更改这些模块参数的值,只需更改工作区中该变量的值。
使用变量设置模块参数值还使您能够:
-
更改参数值而无需修改模型文件(如果将变量存储在模型工作区外)。
-
在扫描或调优参数值时通过有意义的具体名称来识别参数。
在多个模块和模型中重用参数值
可以在工作区(例如基础工作区)或数据字典中创建一个 MATLAB® 数值变量,并使用它来指定一个或多个模块参数值。
如果模块参数值设置为简单的数值表达式,您可以在 Model Data Editor(在 Modeling 选项卡上,点击 Model Data Editor)中为该表达式创建一个变量。点击对应于该值的单元格右侧的 ,然后选择Create variable。在 Create New Data 对话框中,设置新变量的名称和位置,然后点击Create。单元格现在显示新变量。
也可以创建一个变量来表示在多个表达式中使用的一个常量。示例模型sldemo_fuelsys
代表一台汽油发动机的供油系统。该模型中的子系统feedforward_fuel_rate
使用常量数字14.6
来计算发动机的燃油需求,此数字代表发动机消耗的理想的(化学当量)空燃比。该子系统中有两个模块使用此数字来设置参数的值。在此示例中,要在这两个模块之间共享该数字,请创建名为 myParam
的变量。
-
打开模型。
sldemo_fuelsys
-
在模型中,在Modeling选项卡上,点击Model Data Editor。在 Model Data Editor 中,检查Parameters选项卡。
-
在模型中,导航到 子系统中。
open_system(... 'sldemo_fuelsys/fuel_rate_control/fuel_calc/feedforward_fuel_rate')
-
在Model Data Editor的Filter contents框中,输入
14.6
。数据表包含两行,对应于子系统中两个Constant模块的Constant value参数。
-
使用Value列将字面数字
14.6
替换为myParam
。对两个参数都执行替换。 -
在 Filter contents框中,输入
myParam
。 -
在编辑其中一个参数的值时,点击操作按钮 并选择 Create。
-
在 Create New Data 对话框中,将 Value 设置为
14.6
,然后点击 Create。变量
myParam
随即出现在基础工作区中。
由于该变量存在于基础工作区中,因此可以在多个模型中使用它。但是,当结束MATLAB会话时,基础工作区的内容将丢失。请考虑将变量永久性地存储在模型工作区或数据字典中。
定义系统常量
要定义系统常量(例如表示地球半径的变量),请考虑创建 Simulink.Parameter
对象而不是 MATLAB 数值变量。参数对象允许指定物理单位和自定义文档及其他特性。
-
要在模型中创建并使用参数对象,参考数据对象。
-
通常,系统常量的值通过数学关系影响其他参数和信号的值。要显式对这些关系建模,请使用表达式设置相关数据的值。参考使用数学表达式设置变量值。
使用数学表达式设置变量值
可以将变量的值设置为包含字面数字和其他变量的表达式。使用表达式,您可以:
-
将值表示为已知物理常数之间的关系,而不是表示为不可识别的字面数字。
-
对参数数据之间的代数关系进行显式建模。更改自变数据的值时,无需记得调整因变数据的值。
一般方法
将变量转换为Simulink.Parameter对象。然后,使用表达式设置对象的 Value
属性:
-
交互方式 - 例如,使用 Model Data Editor 或 Model Explorer 在表达式前面加上等号
=
。下图显示如何指定表达式myVar + myOtherVar
。 -
编程方式 - 使用
slexpr
函数,以字符向量或字符串形式指定表达式。例如,要将名为myParam
的参数对象的值设置为表达式myVar + myOtherVar
,则按如下方式设置:
myParam.Value = slexpr('myVar + myOtherVar')
显式对变量之间的代数关系建模
示例 sldemo_metro
对一个系统进行建模,该系统由移动平台上悬挂的三个相同的钟摆式节拍器构成。模型中的模块使用基础工作区中的以下 MATLAB 变量:
-
m
- 每个节拍器的质量,初始值为 0.1 kg -
r
- 每个节拍器的长度,初始值为 1.0 m -
J
- 每个节拍器的惯性矩,初始值为 0.1 kg/m2
这些变量具有代数关系:每个节拍器的惯性矩等于质量乘以长度的平方。在此示例中,以 J
的值记录此关系。
-
打开模型。
sldemo_metro
-
更新模块图。模型回调在基础工作区中创建变量。
-
在此示例中,要防止回调覆盖您对变量所做的更改,请删除回调代码。
set_param('sldemo_metro','InitFcn','')
-
在模型中,在Modeling选项卡上,点击Model Data Editor。
-
在Model Data Editor的Parameters选项卡上,激活Change scope 按钮。
使用变量的模块位于子系统中,因此必须配置 Model Data Editor 以在子系统中显示数据。
-
点击 Show/refresh additional information 按钮。
数据表包含与基础工作区中的变量对应的行。
-
在Filter contents框中,输入
J
。 -
在数据表中,找到与
J
对应的行。在Value列中,将变量的值设置为Simulink.Parameter(J)
。Simulink 将
J
转换为Simulink.Parameter
对象。 -
在Value列中,将参数对象的值设置为
=m*r^2
。 -
(可选)使用不同节拍器质量和长度对模型进行仿真。当更改
m
和r
的值时,不必记得更正J
的值。
其他建模目标限制和注意事项
-
如果表达式包含定点数据或枚举类型的数据,则表达式只能对一个变量或对象进行运算。
-
不能在将使用表达式的参数对象的数据类型(
DataType
属性)设置为auto
(默认值)时,将表达式中出现的参数对象的数据类型设置为非auto
值。例如,在表达式J = m*r^2
中,不能在将J
的数据类型设置为auto
时,将m
和r
的数据类型设置为single
。-
要保留将使用表达式的对象设置为
auto
所带来的好处,请将表达式中对象的数据类型设置为auto
。换句话说,对所有涉及的对象使用auto
。表达式中的对象会获取与使用该表达式的对象相同的数据类型。 -
要对表达式中出现的对象使用
auto
以外的值,请将所有相关参数对象的数据类型设置为auto
以外的值。换句话说,不要对任何涉及的对象使用auto
。必须对表达式中使用的所有对象使用相同的数据类型。
-
-
如果有Simulink Coder™ 和Embedded Coder® 许可证,则可以生成使用表达式初始化全局变量的代码。但是,代码生成器仅在表达式符合某些要求时才能保留表达式。
控制参数值的作用域
变量的作用域是可以使用该变量的模型和模块的集合。例如,在基础工作区中创建的变量具有全局作用域,因为所有打开模型中的所有模块都可以使用该变量。存储在模型工作区中的变量的作用域受限,因为只有宿主模型中的模块才能使用该变量。不能在同一个作用域中创建两个同名的变量。控制变量的作用域有助于避免名称冲突并建立明确的变量所有关系。
下表说明用于控制可重用参数值的作用域的不同方法。
作用域 | 方法 |
---|---|
所有打开模型 | 在基础工作区创建一个变量。 |
一个或多个目标模型 | 在数据字典中创建一个变量。要在多个模型中重用该变量,请创建一个引用字典。参考什么是数据字典?。 |
一个模型,包括该模型中的所有子系统 | 在模型工作区中创建一个变量。参考模型工作区。 |
一个子系统内的多个模块,包括嵌套子系统中的模块 | 封装子系统并创建一个封装参数而不是工作区变量。 要防止一个子系统内的模块使用工作区变量,请在子系统模块对话框中将 Permit Hierarchical Resolution 设置为 “ 有关子系统的信息,参考Subsystem。有关封装的信息,参考封装基础知识。 |
对于在同一作用域内具有许多变量的大型模型,为了避免出现名称冲突,请考虑将这些变量打包到单个结构体中。参考在结构体中组织相关的模块参数定义。有关模块如何使用您指定的变量名称的基本信息,参考符号解析。
永久性存储工作区变量
在基础工作区中创建的变量不会在各 MATLAB 会话之间保留。但是,可以将变量存储在 MAT 文件或脚本文件中,每次打开模型时,使用模型回调加载该文件。模型回调是一组命令,当以特定方式与模型交互(例如打开模型)时Simulink会执行这些命令。可以使用回调以在打开模型时加载变量。在学习使用 Simulink 和尝试模型时,可以使用此方法来存储变量。
-
在包含 Gain 模块的模型中,将 Gain 参数的值设置为
K
。 -
在命令提示符下,在基础工作区中创建变量
K
。K = 27;
-
在工作区浏览器中,右键点击该变量并选择 Save As。
要将多个变量保存在一个文件中,请在工作区浏览器中选择所有目标变量,然后右键点击任一所选变量。
-
在对话框中,将 Save as type 设置为 “
MATLAB Script
”。将File name设置为loadvar
,然后点击Save。脚本文件
loadvar.m
随即出现在当前文件夹中。可以打开该文件以查看创建变量K
的命令。 -
在模型中,在 Modeling 选项卡上,选择 Model Settings > Model Properties。
-
在 Model Properties 对话框的 Callbacks 选项卡中,选择
PreLoadFcn
作为要定义的回调。在Model pre-load function窗格中,输入loadvar
,然后点击 OK。 -
保存模型。
下次打开该模型时,PreloadFcn
回调会将变量K
加载到基础工作区中。也可以将该变量保存到MAT文件,例如loadvar.mat
,并将模型回调设置为load loadvar
。有关回调的信息,参考针对自定义模型行为的回调。要以编程方式定义用于加载变量的回调,参考以编程方式存储模型的工作区变量。
将变量保存到文件时,必须保存在 MATLAB 会话期间对变量所做的更改。要永久性存储模型的变量,请考虑使用模型工作区或数据字典而不是 MAT 文件或脚本文件。有关永久性存储变量的详细信息,参考确定在何处存储Simulink模型的变量和对象。
以编程方式存储模型的工作区变量
在上面的示例中,定义了一个模型回调,它会在您打开模型时创建变量。可以通过编程方式保存该变量并设置模型回调。
-
在命令提示符下,在基础工作区中创建变量
K
。K = 27;
-
将变量保存到名为
loadvar.m
的新脚本文件中。matlab.io.saveVariablesToScript('loadvar.m','K')
-
设置模型回调以加载该脚本文件。
set_param('mymodel','PreloadFcn','loadvar')
-
保存模型。
save_system('myModel')
函数matlab.io.saveVariablesToScript将变量保存到一个脚本文件中。要将变量保存到 MAT 文件,请使用函数save。要以编程方式设置模型属性(如回调),请使用函数set_param。
管理和编辑工作区变量
使用变量设置模块参数值时,需要将变量存储在工作区或数据字典中。可以使用命令提示符、Model Explorer 和 Model Data Editor 来创建、移动、复制和编辑变量。还可以确定模型中变量的使用位置,列出模型使用的所有变量,以及列出模型不使用的所有变量。有关详细信息,参考创建、编辑个管理工作区变量。
为查找表打包共享断点和表数据
要在多个 n-D Lookup Table、Prelookup 和 Interpolation Using Prelookup 模块之间共享断点向量或表数据,请考虑将数据存储在 Simulink.LookupTable
和 Simulink.Breakpoint
对象中,而不是存储在 MATLAB 变量或 Simulink.Parameter
对象中。这种方法通过清楚地将数据标识为查找表的一部分,并将断点数据与表数据显式关联,从而提高了模型的可读性。
在 Simulink.LookupTable
对象中存储独立查找表
独立查找表包含一组表数据和一个或多个断点向量。您不能与其他查找表共享表数据或任何断点向量。当共享独立查找表时,即是在多个 n-D Lookup Table 模块中一起使用所有表数据和断点数据。要将此数据存储在 Simulink.LookupTable
对象中,请执行下列操作:
-
在工作区或数据字典中创建该对象。例如,在命令提示符下,输入:
myLUTObj = Simulink.LookupTable;
-
使用该对象的属性来存储表数据和断点数据的值。
-
使用该对象的属性为生成的代码中的结构体类型配置唯一名称。在属性对话框中的 Struct Type definition 下,指定 Name。
-
在 n-D Lookup Table 模块中,将 Data specification 设置为 “
Lookup table object
”。 -
在 Data specification 的右侧,将 Name 设置为
Simulink.LookupTable
对象的名称。
有关创建和配置 Simulink.LookupTable
对象的方法,参考Simulink.LookupTable将共享数据存储在Simulink.LookupTable
和 Simulink.Breakpoint
对象中在使用Prelookup 和 Interpolation Using Prelookup模块来更精细地控制查找算法时,可以共享断点向量和表数据集。例如,可以在两个不同表数据集之间共享一个断点向量。通过将断点数据与表数据分离,可以共享查找表的各个部分,而不是共享整个查找表。
要存储断点数据和表数据,请执行下列操作:
-
为每个唯一的表数据集创建一个
Simulink.LookupTable
对象。为每个唯一的断点向量创建一个Simulink.Breakpoint
对象,包括不打算共享的断点向量。 -
使用对象的属性来存储表数据和断点数据的值。
-
配置
Simulink.LookupTable
对象以引用Simulink.Breakpoint
对象来获取断点数据。在Simulink.LookupTable
对象中,将Specification设置为“Reference
”。指定Simulink.Breakpoint
对象的名称。 -
在Interpolation Using Prelookup 模块中,将Specification设置为 “
Lookup table object
”。将Name设置为Simulink.LookupTable
对象的名称。在 Prelookup 模块中,将Specification设置为 “
Breakpoint object
”。将Name 设置为Simulink.Breakpoint
对象的名称。
示例模型fxpdemo_lookup_shared_param
包含两个Prelookup模块和两个Interpolation Using Prelookup模块。配置这些模块,使得每个由一个Prelookup模块和一个Interpolation Using Prelookup模块构成的组合表示唯一的查找表。在两个查找表之间共享断点向量。在这种情况下,每个查找表都具有唯一的表数据,但共享断点数据。
-
打开示例模型。
-
在Prelookup模块对话框中,将 Specification 设置为 “
Breakpoint object
”。将 Name 设置为sharedBkpts
。 -
点击Name参数的值旁边的按钮 。选择Create Variable。
-
在Create New Data对话框中,将Value设置为
Simulink.Breakpoint
,然后点击 Create。基础工作区中将显示一个
Simulink.Breakpoint
对象。 -
在
sharedBkpts
的属性对话框中,将 Value 指定为一个向量,例如[1 2 3 4 5 6 7 8 9 10]
。点击 OK。 -
在 Prelookup 模块对话框中,点击 OK。
-
在 Prelookup1 模块对话框中,将 Specification 设置为 “
Breakpoint object
”。将 Name 设置为sharedBkpts
。 -
在 Interpolation Using Prelookup 模块对话框中,将 Specification 设置为 “
Lookup table object
”。将Name设置为dataForFirstTable
。 -
点击 Name 参数的值旁边的按钮 。选择 Create Variable。
-
在 Create New Data 对话框中,将 Value 设置为
Simulink.LookupTable
,然后点击 Create。基础工作区中将显示一个
Simulink.LookupTable
对象。 -
在
dataForFirstTable
的属性对话框中,将Value指定为向量,例如[10 9 8 7 6 5 4 3 2 1]
。 -
将 Specification 设置为 “
Reference
”。 -
在表中的Specification下,将Name设置为
sharedBkpts
,然后点击OK。 -
在Interpolation Using Prelookup模块对话框中,点击 OK。
-
配置 Interpolation Using Prelookup1 模块以使用名为
dataForSecondTable
的Simulink.LookupTable
对象。在对象属性对话框中,将 Value 指定为向量,例如[0 0.5 1 1.5 2 2.5 3 3.5 4 4.5]
。配置对象以引用sharedBkpts
来获取断点数据。
该模型现在表示两个唯一的查找表:
-
sharedBkpts
和dataForFirstTable
的一个组合。 -
sharedBkpts
和dataForSecondTable
的一个组合。
这些查找表通过 sharedBkpts
共享相同的断点数据。