Main Content

通过创建变量来共享和重用模块参数值

要设置模块参数值,例如 Gain 模块的增益参数,可以使用您创建的且存储在工作区(例如基础工作区、模型工作区)或 Simulink® 数据字典中的数值变量。您可以使用该变量设置多个模块中的多个参数值,包括不同模型中的模块。要更改这些模块参数的值,只需更改工作区中该变量的值。

使用变量设置模块参数值还使您能够:

  • 更改参数值而无需修改模型文件(如果将变量存储在模型工作区外)。

  • 在扫描或调优参数值时通过有意义的具体名称来识别参数。

有关设置模块参数值的基本信息,请参阅设置模块参数值

在多个模块和模型中重用参数值

您可以在工作区(例如基础工作区)或数据字典中创建一个 MATLAB® 数值变量,并使用它来指定一个或多个模块参数值。

如果模块参数值设置为简单的数值表达式,您可以在模型数据编辑器(在建模选项卡上,点击模型数据编辑器)中为该表达式创建一个变量。点击对应于该值的单元格右侧的 ,然后选择创建变量。在“创建新数据”对话框中,设置新变量的名称和位置,然后点击创建。单元格现在显示新变量。

您也可以创建一个变量来表示在多个表达式中使用的一个常量。示例模型 sldemo_fuelsys 代表一台汽油发动机的供油系统。该模型中的子系统 feedforward_fuel_rate 使用常量数字 14.6 来计算发动机的燃油需求,此数字代表发动机消耗的理想的(化学当量)空燃比。该子系统中有两个模块使用此数字来设置参数的值。在此示例中,要在这两个模块之间共享该数字,请创建名为 myParam 的变量。

  1. 打开 容错燃油控制系统建模 示例模型 sldemo_fuelsys

    openExample('simulink_automotive/ModelingAFaultTolerantFuelControlSystemExample')
    sldemo_fuelsys

  2. 在模型中,在建模选项卡上,点击模型数据编辑器。在模型数据编辑器中,检查参数选项卡。

  3. 在模型中,导航到子系统中。

    open_system(...
        'sldemo_fuelsys/fuel_rate_control/fuel_calc/feedforward_fuel_rate')

  4. 在模型数据编辑器的过滤内容框中,输入 14.6

    数据表包含两行,对应于子系统中两个 Constant 模块的常量值参数。

  5. 使用列将字面数字 14.6 替换为 myParam。对两个参数都执行替换。

  6. 过滤内容框中,输入 myParam

  7. 在编辑其中一个参数的值时,点击操作按钮 并选择创建

  8. 创建新数据对话框中,将设置为 14.6,然后点击创建

    变量 myParam 随即出现在基础工作区中。

由于该变量存在于基础工作区中,因此您可以在多个模型中使用它。但是,当您结束 MATLAB 会话时,基础工作区的内容将丢失。请考虑将变量永久性地存储在模型工作区或数据字典中。

定义系统常量

要定义系统常量(例如表示地球半径的变量),请考虑创建 Simulink.Parameter 对象而不是 MATLAB 数值变量。参数对象允许您指定物理单位和自定义文档及其他特性。

  • 要在模型中创建并使用参数对象,请参阅数据对象

  • 通常,系统常量的值通过数学关系影响其他参数和信号的值。要显式对这些关系建模,请使用表达式设置相关数据的值。请参阅使用数学表达式设置变量值

使用数学表达式设置变量值

您可以将变量的值设置为包含字面数字和其他变量的表达式。使用表达式,您可以:

  • 将值表示为已知物理常数之间的关系,而不是表示为不可识别的字面数字。

  • 对参数数据之间的代数关系进行显式建模。更改自变数据的值时,无需记得调整因变数据的值。

一般方法

将变量转换为 Simulink.Parameter 对象。然后,使用表达式设置对象的 Value 属性:

  • 交互方式 - 例如,使用模型数据编辑器或模型资源管理器在表达式前面加上等号 =。下图显示如何指定表达式 myVar + myOtherVar

  • 编程方式 - 使用 slexpr 函数,以字符向量或字符串形式指定表达式。例如,要将名为 myParam 的参数对象的值设置为表达式 myVar + myOtherVar,则按如下方式设置:

    myParam.Value = slexpr('myVar + myOtherVar')

显式对变量之间的代数关系建模

示例 sldemo_metro(请参阅Exploring the Solver Jacobian Structure of a Model)对一个系统进行建模,该系统由移动平台上悬挂的三个相同的钟摆式节拍器构成。模型中的模块使用基础工作区中的以下 MATLAB 变量:

  • m - 每个节拍器的质量,初始值为 0.1 kg

  • r - 每个节拍器的长度,初始值为 1.0 m

  • J - 每个节拍器的惯性矩,初始值为 0.1 kg/m2

这些变量具有代数关系:每个节拍器的惯性矩等于质量乘以长度的平方。在此示例中,您以 J 的值记录此关系。

  1. 打开模型。

    sldemo_metro

  2. 更新模块图。模型回调在基础工作区中创建变量。

  3. 在此示例中,要防止回调覆盖您对变量所做的更改,请删除回调代码。

    set_param('sldemo_metro','InitFcn','')

  4. 在模型中,在建模选项卡上,点击模型数据编辑器

  5. 在模型数据编辑器的参数选项卡上,激活更改范围按钮。

    使用变量的模块位于子系统中,因此必须配置模型数据编辑器以在子系统中显示数据。

  6. 点击显示/刷新其他信息按钮。

    数据表包含与基础工作区中的变量对应的行。

  7. 过滤内容框中,输入 J

  8. 在数据表中,找到与 J 对应的行。在列中,将变量的值设置为 Simulink.Parameter(J)

    Simulink 将 J 转换为 Simulink.Parameter 对象。

  9. 列中,将参数对象的值设置为 =m*r^2

  10. (可选)使用不同节拍器质量和长度对模型进行仿真。当您更改 mr 的值时,您不必记得更正 J 的值。

其他建模目标限制和注意事项

  • 如果表达式包含定点数据或枚举类型的数据,则表达式只能对一个变量或对象进行运算。

  • 您不能在将使用表达式的参数对象的数据类型(DataType 属性)设置为 auto(默认值)时,将表达式中出现的参数对象的数据类型设置为非 auto 值。例如,在表达式 J = m*r^2 中,不能在将 J 的数据类型设置为 auto 时,将 mr 的数据类型设置为 single

    • 要保留将使用表达式的对象设置为 auto(在Context-Sensitive Data Typing中说明)所带来的好处,请将表达式中对象的数据类型设置为 auto。换句话说,对所有涉及的对象使用 auto。表达式中的对象会获取与使用该表达式的对象相同的数据类型。

    • 要对表达式中出现的对象使用 auto 以外的值,请将所有相关参数对象的数据类型设置为 auto 以外的值。换句话说,不要对任何涉及的对象使用 auto

      必须对表达式中使用的所有对象使用相同的数据类型。

  • 如果您有 Simulink Coder™ 和 Embedded Coder® 许可证,则可以生成使用表达式初始化全局变量的代码。但是,代码生成器仅在表达式符合某些要求时才能保留表达式。请参阅Expression Preservation (Simulink Coder)

控制参数值的作用域

变量的作用域是可以使用该变量的模型和模块的集合。例如,在基础工作区中创建的变量具有全局作用域,因为所有打开模型中的所有模块都可以使用该变量。存储在模型工作区中的变量的作用域受限,因为只有宿主模型中的模块才能使用该变量。

您不能在同一个作用域中创建两个同名的变量。控制项变量的作用域有助于避免名称冲突并建立明确的变量所有关系。

下表说明用于控制可重用参数值的作用域的不同方法。

作用域方法
所有打开模型在基础工作区创建一个变量。
一个或多个目标模型在数据字典中创建一个变量。要在多个模型中重用该变量,请创建一个引用字典。请参阅 什么是数据字典?
一个模型,包括该模型中的所有子系统在模型工作区中创建一个变量。请参阅模型工作区
一个子系统内的多个模块,包括嵌套子系统中的模块

封装子系统并创建一个封装参数而不是工作区变量。

要防止一个子系统内的模块使用工作区变量,请在子系统模块对话框中将允许层次解析设置为。此方法允许您使用相同的名称在工作区中创建一个变量和在子系统封装中创建一个封装参数。子系统中的模块只能使用该封装参数。

有关子系统的信息,请参阅 Subsystem。有关封装的信息,请参阅封装基础知识

对于在同一作用域内具有许多变量的大型模型,为了避免出现名称冲突,请考虑将这些变量打包到单个结构体中。有关详细信息,请参阅 在结构体中组织相关的模块参数定义

有关模块如何使用您指定的变量名称的基本信息,请参阅符号解析

永久性存储工作区变量

您在基础工作区中创建的变量不会在各 MATLAB 会话之间保留。但是,您可以将变量存储在 MAT 文件或脚本文件中,每次打开模型时,使用模型回调加载该文件。模型回调是一组命令,当您以特定方式与模型交互(例如打开模型)时 Simulink 会执行这些命令。可以使用回调以在打开模型时加载变量。在学习使用 Simulink 和尝试模型时,可以使用此方法来存储变量。

  1. 在包含 Gain 模块的模型中,将增益参数的值设置为 K

  2. 在命令提示符下,在基础工作区中创建变量 K

    K = 27;

  3. 在工作区浏览器中,右键点击该变量并选择另存为

    要将多个变量保存在一个文件中,请在工作区浏览器中选择所有目标变量,然后右键点击任一所选变量。

  4. 在对话框中,将另存类型设置为 MATLAB 脚本。将文件名设置为 loadvar,然后点击保存

    脚本文件 loadvar.m 随即出现在当前文件夹中。您可以打开该文件以查看创建变量 K 的命令。

  5. 在模型中,在建模选项卡上,选择模型设置 > 模型属性

  6. 在“模型属性”对话框的回调选项卡中,选择 PreLoadFcn 作为要定义的回调。在模型预加载函数窗格中,输入 loadvar,然后点击确定

  7. 保存模型。

下次您打开该模型时,PreloadFcn 回调会将变量 K 加载到基础工作区中。您也可以将该变量保存到 MAT 文件,例如 loadvar.mat,并将模型回调设置为 load loadvar

有关回调的信息,请参阅使用回调自定义模型行为。要以编程方式定义用于加载变量的回调,请参阅以编程方式存储模型的工作区变量

将变量保存到文件时,必须保存在 MATLAB 会话期间对变量所做的更改。要永久性存储模型的变量,请考虑使用模型工作区或数据字典而不是 MAT 文件或脚本文件。有关永久性存储变量的详细信息,请参阅确定在何处存储 Simulink 模型的变量和对象

以编程方式存储模型的工作区变量

在上面的示例中,您定义了一个模型回调,它会在您打开模型时创建变量。您可以通过编程方式保存该变量并设置模型回调。

  1. 在命令提示符下,在基础工作区中创建变量 K

    K = 27;
  2. 将变量保存到名为 loadvar.m 的新脚本文件中。

    matlab.io.saveVariablesToScript('loadvar.m','K')

  3. 设置模型回调以加载该脚本文件。

    set_param('mymodel','PreloadFcn','loadvar')

  4. 保存模型。

    save_system('myModel')

函数 matlab.io.saveVariablesToScript 将变量保存到一个脚本文件中。要将变量保存到 MAT 文件,请使用函数 save。要以编程方式设置模型属性(如回调),请使用函数 set_param

管理和编辑工作区变量

使用变量设置模块参数值时,需要将变量存储在工作区或数据字典中。您可以使用命令提示符、模型资源管理器和模型数据编辑器来创建、移动、复制和编辑变量。您还可以确定模型中变量的使用位置,列出模型使用的所有变量,以及列出模型不使用的所有变量。有关详细信息,请参阅创建、编辑和管理工作区变量

为查找表打包共享断点和表数据

要在多个 n-D Lookup TablePrelookupInterpolation Using Prelookup 模块之间共享断点向量或表数据,请考虑将数据存储在 Simulink.LookupTableSimulink.Breakpoint 对象中,而不是存储在 MATLAB 变量或 Simulink.Parameter 对象中。这种方法通过清楚地将数据标识为查找表的一部分,并将断点数据与表数据显式关联,从而提高了模型的可读性。

Simulink.LookupTable 对象中存储独立查找表

独立查找表包含一组表数据和一个或多个断点向量。您不能与其他查找表共享表数据或任何断点向量。

当您共享独立查找表时,即是在多个 n-D Lookup Table 模块中一起使用所有表数据和断点数据。要将此数据存储在 Simulink.LookupTable 对象中,请执行下列操作:

  1. 在工作区或数据字典中创建该对象。例如,在命令提示符下,输入:

    myLUTObj = Simulink.LookupTable;

  2. 使用该对象的属性来存储表数据和断点数据的值。

  3. 使用该对象的属性为生成的代码中的结构体类型配置唯一名称。在属性对话框中的结构体类型定义下,指定名称

  4. n-D Lookup Table 模块中,将数据设定设置为查找表对象

  5. 数据设定的右侧,将名称设置为 Simulink.LookupTable 对象的名称。

有关创建和配置 Simulink.LookupTable 对象的方法,请参阅 Simulink.LookupTable

将共享数据存储在 Simulink.LookupTableSimulink.Breakpoint 对象中

在使用 PrelookupInterpolation Using Prelookup 模块来更精细地控制查找算法时,可以共享断点向量和表数据集。例如,您可以在两个不同表数据集之间共享一个断点向量。通过将断点数据与表数据分离,您可以共享查找表的各个部分,而不是共享整个查找表。

要存储断点数据和表数据,请执行下列操作:

  1. 为每个唯一的表数据集创建一个 Simulink.LookupTable 对象。为每个唯一的断点向量创建一个 Simulink.Breakpoint 对象,包括您不打算共享的断点向量。

  2. 使用对象的属性来存储表数据和断点数据的值。

  3. 配置 Simulink.LookupTable 对象以引用 Simulink.Breakpoint 对象来获取断点数据。在 Simulink.LookupTable 对象中,将设定设置为引用。指定 Simulink.Breakpoint 对象的名称。

  4. Interpolation Using Prelookup 模块中,将设定设置为查找表对象。将名称设置为 Simulink.LookupTable 对象的名称。

    Prelookup 模块中,将设定设置为断点对象。将名称设置为 Simulink.Breakpoint 对象的名称。

示例模型 fxpdemo_lookup_shared_param 包含两个 Prelookup 模块和两个 Interpolation Using Prelookup 模块。配置这些模块,使得每个由一个 Prelookup 模块和一个 Interpolation Using Prelookup 模块构成的组合表示唯一的查找表。在两个查找表之间共享断点向量。在这种情况下,每个查找表都具有唯一的表数据,但共享断点数据。

  1. 打开示例模型。

  2. Prelookup 模块对话框中,将设定设置为断点对象。将名称设置为 sharedBkpts

  3. 点击名称参数的值旁边的按钮 。选择创建变量

  4. 创建新数据对话框中,将设置为 Simulink.Breakpoint,然后点击创建

    基础工作区中将显示一个 Simulink.Breakpoint 对象。

  5. sharedBkpts 的属性对话框中,将指定为一个向量,例如 [1 2 3 4 5 6 7 8 9 10]。点击确定

  6. Prelookup 模块对话框中,点击确定

  7. Prelookup1 模块对话框中,将设定设置为断点对象。将名称设置为 sharedBkpts

  8. Interpolation Using Prelookup 模块对话框中,将设定设置为查找表对象。将名称设置为 dataForFirstTable

  9. 点击名称参数的值旁边的按钮 。选择创建变量

  10. 创建新数据对话框中,将设置为 Simulink.LookupTable,然后点击创建

    基础工作区中将显示一个 Simulink.LookupTable 对象。

  11. dataForFirstTable 的属性对话框中,将指定为向量,例如 [10 9 8 7 6 5 4 3 2 1]

  12. 设定设置为引用

  13. 在表中的设定下,将名称设置为 sharedBkpts,然后点击确定

  14. Interpolation Using Prelookup 模块对话框中,点击确定

  15. 配置 Interpolation Using Prelookup1 模块以使用名为 dataForSecondTableSimulink.LookupTable 对象。在对象属性对话框中,将指定为向量,例如 [0 0.5 1 1.5 2 2.5 3 3.5 4 4.5]。配置对象以引用 sharedBkpts 来获取断点数据。

该模型现在表示两个唯一的查找表:

  • sharedBkptsdataForFirstTable 的一个组合。

  • sharedBkptsdataForSecondTable 的一个组合。

这些查找表通过 sharedBkpts 共享相同的断点数据。

相关主题