Simulink 环境基础知识(二十八)--通过创建变量来共享和重用模块参数值

目录

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

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

定义系统常量

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

控制参数值的作用域

永久性存储工作区变量

管理和编辑工作区变量

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


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

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

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

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

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

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

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

如果模块参数值设置为简单的数值表达式,您可以在 Model Data Editor(在 Modeling 选项卡上,点击 Model Data Editor)中为该表达式创建一个变量。点击对应于该值的单元格右侧的 Simulink 环境基础知识(二十八)--通过创建变量来共享和重用模块参数值,然后选择Create variable。在 Create New Data 对话框中,设置新变量的名称和位置,然后点击Create。单元格现在显示新变量。

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

  1. 打开模型。

    sldemo_fuelsys

     

  2. 在模型中,在Modeling选项卡上,点击Model Data Editor。在 Model Data Editor 中,检查Parameters选项卡。

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

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

     

  4. 在Model Data Editor的Filter contents框中,输入 14.6

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

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

  6. 在 Filter contents框中,输入myParam

  7. 在编辑其中一个参数的值时,点击操作按钮 Simulink 环境基础知识(二十八)--通过创建变量来共享和重用模块参数值 并选择 Create

  8. 在 Create New Data 对话框中,将 Value 设置为 14.6,然后点击 Create

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

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

定义系统常量

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

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

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

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

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

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

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

一般方法

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

  • 交互方式 - 例如,使用 Model Data Editor 或 Model Explorer 在表达式前面加上等号 =。下图显示如何指定表达式 myVar + myOtherVar

    Simulink 环境基础知识(二十八)--通过创建变量来共享和重用模块参数值

  • 编程方式 - 使用 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 的值记录此关系。

  1. 打开模型。

    sldemo_metro

     

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

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

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

     

  4. 在模型中,在Modeling选项卡上,点击Model Data Editor

  5. 在Model Data Editor的Parameters选项卡上,激活Change scope 按钮。

    使用变量的模块位于子系统中,因此必须配置 Model Data Editor 以在子系统中显示数据。

  6. 点击 Show/refresh additional information 按钮。

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

  7. Filter contents框中,输入 J

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

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

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

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

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

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

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

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

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

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

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

控制参数值的作用域

变量的作用域是可以使用该变量的模型和模块的集合。例如,在基础工作区中创建的变量具有全局作用域,因为所有打开模型中的所有模块都可以使用该变量。存储在模型工作区中的变量的作用域受限,因为只有宿主模型中的模块才能使用该变量。不能在同一个作用域中创建两个同名的变量。控制变量的作用域有助于避免名称冲突并建立明确的变量所有关系。

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

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

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

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

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

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

永久性存储工作区变量

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

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

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

    K = 27;

     

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

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

  4. 在对话框中,将 Save as type 设置为 “MATLAB Script”。将File name设置为 loadvar,然后点击Save

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

  5. 在模型中,在 Modeling 选项卡上,选择 Model Settings > Model Properties

  6. 在 Model Properties 对话框的 Callbacks 选项卡中,选择 PreLoadFcn作为要定义的回调。在Model pre-load function窗格中,输入loadvar,然后点击 OK

  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

管理和编辑工作区变量

使用变量设置模块参数值时,需要将变量存储在工作区或数据字典中。可以使用命令提示符、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 对象中,请执行下列操作:

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

    myLUTObj = Simulink.LookupTable;

     

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

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

  4. 在 n-D Lookup Table 模块中,将 Data specification 设置为 “Lookup table object”。

  5. 在 Data specification 的右侧,将 Name 设置为 Simulink.LookupTable 对象的名称。

有关创建和配置 Simulink.LookupTable 对象的方法,参考Simulink.LookupTable将共享数据存储在Simulink.LookupTable 和 Simulink.Breakpoint对象中在使用Prelookup 和 Interpolation Using Prelookup模块来更精细地控制查找算法时,可以共享断点向量和表数据集。例如,可以在两个不同表数据集之间共享一个断点向量。通过将断点数据与表数据分离,可以共享查找表的各个部分,而不是共享整个查找表。

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

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

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

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

  4. 在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模块构成的组合表示唯一的查找表。在两个查找表之间共享断点向量。在这种情况下,每个查找表都具有唯一的表数据,但共享断点数据。

  1. 打开示例模型。

  2. 在Prelookup模块对话框中,将 Specification 设置为 “Breakpoint object”。将 Name 设置为 sharedBkpts

  3. 点击Name参数的值旁边的按钮 Simulink 环境基础知识(二十八)--通过创建变量来共享和重用模块参数值。选择Create Variable

  4. Create New Data对话框中,将Value设置为 Simulink.Breakpoint,然后点击 Create

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

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

  6. 在 Prelookup 模块对话框中,点击 OK

  7. 在 Prelookup1 模块对话框中,将 Specification 设置为 “Breakpoint object”。将 Name 设置为 sharedBkpts

  8. 在 Interpolation Using Prelookup 模块对话框中,将 Specification 设置为 “Lookup table object”。将Name设置为 dataForFirstTable

  9. 点击 Name 参数的值旁边的按钮 Simulink 环境基础知识(二十八)--通过创建变量来共享和重用模块参数值。选择 Create Variable

  10. 在 Create New Data 对话框中,将 Value 设置为 Simulink.LookupTable,然后点击 Create

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

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

  12. 将 Specification 设置为 “Reference”。

  13. 在表中的Specification下,将Name设置为sharedBkpts,然后点击OK

  14. 在Interpolation Using Prelookup模块对话框中,点击 OK

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

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

  • sharedBkpts 和 dataForFirstTable 的一个组合。

  • sharedBkpts 和 dataForSecondTable 的一个组合。

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

 

 

上一篇:17高级、Simulink代码生成技术详解


下一篇:js_ .specified属性