英国面具
面具可以让你:
-
创建您自己的参数对话框,以便快速配置单元/子系统;
-
更改块/子系统的外观;
-
隐藏块/子系统的内容。
蒙版编辑器*是自定义蒙版的工具。 要打开编辑器,请右键单击块并选择 *面罩 → 添加面具 :
编辑器将在新的浏览器窗口中打开:
保存遮罩后,遮罩参数显示在块设置中。 要查看块本身的参数,请单击 看看面具下面 . 要返回,请单击 查看面具 :
对于子系统,选项 看看面具下面 它在子系统内部传输它,而不是显示块参数。 使用方法 模型导航面板 以退出子系统。 |
要编辑或删除蒙版,请右键单击已创建蒙版的块的图标,然后选择 编辑掩码 或 取下面具 :
可以容易地调整掩模,使得当其参数的值改变时,块参数的值自动改变。 然而,相反的效果是不可能的:块参数的值不能改变掩模参数的值。 此限制通过掩码提供对块设置的控制,并防止对掩码本身的意外更改。 |
蒙版编辑器的界面
掩码编辑器包含两组选项卡:
-
界面编辑器
-
代码编辑器
界面编辑器
界面编辑器 -在"设置"窗口中添加控件、结构元素和选项卡掩码的部分。
-
操作-用于根据指定条件执行操作的控件。
-
1.1*按钮*
-单击时执行指定操作的控件。
-
-
结构元素 -用于放置和隐藏控件的容器:
-
2.1. 隐藏部分
-可以通过单击隐藏或打开的容器,允许您同时控制多个元素的显示。
隐藏部分 如果没有添加的控件,它将不会显示在蒙版中。 默认部分可以重命名。
-
-
控件 -从其形成块掩模的界面的主要部件。 每个控件有三个参数:
-
参数名称 -必须匹配需要配置的掩码中变量的名称;
-
字段名称 -将显示在设置窗口中;
-
值或列表项-定义默认值。
除了参数,您还可以配置属性:
-
隐藏 -隐藏控件;
-
计算 -分析输入的值,解释它,并存储适当的数据类型(例如,数字,字符串或数组)。 如果输入不正确的数据类型,系统将返回错误。
-
-
3.1. 输入字段
-添加带有输入文本或数值的掩码参数。 数据类型:任何;
-
3.2. 复选框
-用于标记框的区域。 数据类型:Bool;
-
3.3. 下拉列表
-显示可用选项列表,从中选择一个。 要将项目添加到下拉列表中,请在*列表项目*字段中一次输入一个,然后在每个值后按Enter。 数据类型:字符串;
没有参数的下拉列表返回错误,并且不允许您保存掩码。
-
*遮罩空间*是使用控件和结构元素创建遮罩的区域。 添加到该区域的所有元素将在保存后准确转移到蒙版。 要添加项目,请用鼠标拖动它们。:
要删除项目,请选择它并按 Delete.
要添加新选项卡,请单击蒙版空间右上角的*+*。:
-
保存按钮-保存蒙版。 或者,您可以使用键盘快捷键。 Ctrl+S (Win/Linux)和 ⌘+S (macOS)。
-
回调编辑器按钮打开部分 代码编辑器 .
-
隐藏左侧面板/显示左侧面板。
-
隐藏右侧面板/显示右侧面板。
代码编辑器
代码编辑器 -控制设置部分使用 回调函数(回调)。 每个控件元素都有自己独特的回调。
-
掩码参数的名称(您可以在界面编辑器中更改它们)。
-
字段名称-指示参数字段的标签或类型(您可以在界面编辑器中更改它)。 它提供了参数的目的或功能的更详细的描述。
-
*回调代码空间*是为特定掩码参数配置回调的区域。
-
保存按钮-保存蒙版。 或者,您可以使用键盘快捷键。 Ctrl+S (Win/Linux)和 ⌘+S (macOS)。
-
隐藏左侧面板/显示左侧面板。
-
隐藏右侧面板/显示右侧面板。
回调
回调是响应某些操作而自动调用的函数。 *Engee*中的回调写入 Julia,在仿真过程中不执行,用于控制单个参数和整个掩码作为一个整体。 本地回调用于控制单个参数,全局调用用于整个掩码。:
-
全局回调与整个掩码相关联,并且独立于特定参数执行。 全局回调是 iconDrawCallback 和 blockChangedCallback . 全球呼叫可以访问所有本地呼叫并可以管理它们。 例如,您可以将数据从本地呼叫传输到全局呼叫。 blockChangedCallback . 这将允许您使用全局调用来配置本地调用的操作。
-
本地回调链接到特定的掩码参数,并且只有在更改这些参数时才会触发。 除此以外的所有回调 iconDrawCallback 和 blockChangedCallback ,是本地的。 本地回调只能在接口编辑器中使用它们绑定到的参数,而不能直接更改其他回调的参数( 复选框 无法管理下拉列表,全局回调用于此)。
要使用mask参数,首先需要获取它。 为此,使用了一个特殊的参数对象,它存储在’mask’变量中。 例如,获取参数 输入字段 使用名称’text_input_1',您可以使用以下代码:
mask.parameters.text_input_1
参数对象有三个主要属性:
-
'name::String'-字段名称(只读);
-
'value::Any'-参数值(可用于读写);
-
'hidden::Bool`—参数的可见性(可用于读取和写入)。
要更改参数,请始终为`value`属性分配一个新值。 您不能直接更改现有值,因为这不会被视为更改。 例如:
|
要获取带有掩码的块的路径,请使用函数 恩吉。gcb()。 路径作为字符串返回。 这允许您使用代码控制块及其内部组件。 假设你需要从一个参数传递一个值 下拉列表 ('dropdown_1')至室内机 LDL 因式分解:
LDLPath = engee.gcb() * "/LDL Factorization"
engee.set_param!(LDLPath, "NonPositive" => mask.parameters.dropdown_1.value)
给你。gcb()'获取当前块的路径。 该路径用于查找LDL因式分解块,之后将`dropdown_1’中的值传递给该块的`NonPositive’参数。 因此,'engee。gcb()'函数有助于将掩码参数链接到模型的其他部分。
除了恩吉。gcb()`获取当前块,'engee。gcm()`得到当前模型和’engee。也使用gcs()`来获取当前系统。 |
回调概述
启动掩码回调的顺序:
-
对于每个更改的参数,它被称为 validateCallback . 首先发生,以确保参数在执行任何进一步操作之前具有有效值。;
-
对于每个更改的参数,它被称为 valueChangedCallback . 每次回调后,都会调用 validateCallback 对于每个新改变的参数,作为改变值可能会影响其他参数。;
-
开始了 blockChangedCallback . 对于每个新更改的参数,它被称为 validateCallback .
-
开始了 iconDrawCallback .
了解回调的运行顺序对于块掩码正常工作非常重要,因为更改一个参数可能会影响其他参数。 错误的顺序可能导致检查值的错误或图标的不正确更新。 按照正确的顺序确保所有依赖关系都被考虑在内,并且块正常工作。
iconDrawCallback — 块外观的形成
Details
与之合作 iconDrawCallback 那个工程师。必须使用show()'函数。 错误的图标 iconDrawCallback 它看起来像这样:
iconDrawCallback 它可以显示文本,数字,图形,图像或公式(LaTeX)。 例如:
-
数字输出(文本类似):
engee.show(text_input_1)
→
-
SVG输出:
engee.show( svg""" <svg xmlns:ns0="http://www.w3.org/2000/svg" width="78%" height="80%" viewBox="0 0 26 27" fill="none"> <path vector-effect="non-scaling-stroke" d="M13 0.5L13 25.7282" stroke="#DDDDDD" stroke-linecap="round" /> <path vector-effect="non-scaling-stroke" d="M0.5 13H25.5" stroke="#DDDDDD" stroke-linecap="round" /> <path vector-effect="non-scaling-stroke" d="M24.1894 8.46273L13 8.46273L13 17.4628L2.18942 17.4627" stroke="#212121" stroke-linecap="round" /> </svg> """ )
建议对块使用SVG图标,因为它们占用更少的空间并自动调整到块大小而不会损失质量。 -
胶乳配方的输出。 为此,请使用大写字母 和引号`""`。 公式是按照经典的LaTeX语法用引号写成的。:
engee.show(L"\lvert u \rvert")
-
图形输出:
x = range(0, 2*pi, 1000); y = sin.(x); engee.show(plot(x, y))
-
图像输出:
img = "...base64-text..." engee.show(Images.load(IOBuffer(base64decode(img))))
有不同的方法来获得图像的’base64’表示:
-
通过Julia脚本:
image_data = read("path_to_file") base64_encoded = base64encode(image_data) println(base64_encoded)
-
通过 命令提示符
(首先,通过按下切换到shell模式 ;):
base64 --wrap 0 "path_to_file"
-
通过外部服务,例如 脧锚脧赂base64decode.org。
您可以使用"engee"更改块的端口签名。port_label()'函数。'通过回调机制。 下面的示例演示如何在块图标上显示文本并为不同端口设置签名。:
engee.show("Some text") # 块图标上的文本输出
engee.port_label("input", 1, "foo_1") # 第一个输入端口的签名'foo_1'
engee.port_label("input", 2, "foo_2") # 第二个输入端口的签名'foo_2'
engee.port_label("output", 1, "bar") # 输出端口的'bar'签名
也可以为非定向端口设置签名。 您可以输入空名称。:
engee.port_label("acausal", 1, "") # 无向端口的空名称
SVG文件和LaTeX公式可以在端口签名中输出。:
engee.port_label("input", 1, svg="...")
engee.port_label("input", 1, L="...")
端口编号与程序控制相同。 如果指定了不正确的端口号或类型,该函数将被忽略。
blockChangedCallback — 更改任何遮罩参数后执行
Details
它在任何掩码参数更改时启动,但在执行所有其他回调之后。 作为一个全局回调,它可以访问变量和掩码对象。
例子::
-
更改子系统中的参数:
LDLPath = engee.gcb() * "/LDL Factorization" mode = dropdown_1 if mode == "Ignore" engee.set_param!(LDLPath, "NonPositive" => "Ignore") elseif mode == "Warning" engee.set_param!(LDLPath, "NonPositive" => "Warning") elseif mode == "Error" engee.set_param!(LDLPath, "NonPositive" => "Error") end
这里,掩模参数的值与*LDL因式分解*块的参数同步。 'mode’是一个变量,用于存储’dropdown_1’参数的当前值。 例如,如果您将下拉列表中某个参数的值从`Warning’更改为’Error',则相同的参数将在子系统中的*LDL因子分解*块中类似地更改。
valueChangedCallback — 参数值更改时执行
Details
valueChangedCallback 需要使用"engee"隐藏参数或更改子系统状态。gcb()'函数。 当关联参数的值更改时,将触发回调。 如果相应控件的参数名称与回调代码匹配,则会链接参数,例如:
→
例子::
-
隐藏参数:
mask.parameters.text_input_1.hidden = checkbox_1
这里按下时参数是隐藏的 复选框 它是可见的,当 复选框 被压住了。
-
更改子系统状态(使用 软件控制功能):
if checkbox mask.parameters.checkbox.hidden = false engee.add_block("/Basic/Ports & Subsystems/Model", engee.gcb() * "/Model") else mask.parameters.checkbox.hidden = true engee.delete_block(engee.gcb() * "/Model") end
连接在这里设置有 复选框 (`checkbox_1'),启用时(复选框处于活动状态),它将*Model*块添加到子系统中,并在关闭时删除(复选框未选中)。
validateCallback — 检查参数值的正确性(验证)
Details
回调验证值的有效性 validateCallback 并且,如果值不正确,则显示错误。 除了AssertionError之外的所有错误消息都将被视为回调本身的错误,而不是输入数据的错误。:
使用`value`变量检查参数值的正确性。 validateCallback 它总是从宏开始 @assert。
validateCallback 仅适用于控件 输入字段 它附加到他的回调。 valueChangedCallback .
例子::
-
检查值的正确性:
@assert value > 0 "值必须大于零"
-
检查输入的类型:
@assert value isa Number "该值必须是一个数字。"
例子:
当使用掩码块(例如,块 3DOF (体轴))重要的是要考虑掩码参数和工作区变量的相互作用:
如果使用了未知变量或参数包含无效值(例如,未声明的变量或不适合的数据类型),则界面会报告错误-参数以红色框突出显示,并附带说明: |
将mask参数传递给C功能块的源代码的示例
-
将*C函数*块放在*Engee*工作区中。 右键单击块并选择 面罩 → 添加面具 .
-
在掩码界面编辑器中,添加*输入字段*
.
-
转到掩码代码编辑器并选择左侧选项菜单中的选项 输入字段 (默认情况下,这是’text_input_1`)并将其移动到掩码空间。 这样做两次,以便*C函数*块的每个参数都有自己的输入字段。:
-
在回调 blockChangedCallback使用以下代码:
# 设置当前块的路径 CFunctionPath = engee.gcb() # 获取掩码参数值 param1 = text_input_1 param2 = text_input_2 # 根据参数值生成C代码 c_code = """ int add_numbers(int param1, int param2) { return param1 + param2; } int result = add_numbers($param1, $param2); """ # 在C功能块中设置"OutputCode"参数 engee.set_param!(CFunctionPath, "OutputCode" => c_code)
在此代码中,使用"engee"设置当前*C函数*块的路径。gcb()'函数,之后读取来自’text_input_1’和’text_input_2’的值,它们对应于param1和param2块的参数。 然后创建一行c代码,定义’add_numbers’函数,该函数添加两个整数,并使用输入的值来计算结果。 使用"engee"。set_param! *C函数*块的"OutputCode"参数更新,设置生成的代码。
-
现在,在编辑掩码参数时,*C函数*块的参数也会发生变化,并且它们的更改值最终会出现在OutputCode选项卡中的源代码中。:
对于*C函数*块的源代码的其他选项卡-StartCode`和`TerminalCode ,以及*Engee函数*块的选项卡—`ExeCode`和`InhMethodsCode',也实现了类似的方法。
|
您可以使用的不仅仅是数字值,例如:
engee.set_param!(engee.gcb(), "OutputCode"=>"print($text_input_1)")
为此,在掩码界面编辑器中,创建或编辑参数时,必须指定一个值,该值的数据类型随后将更改。 如果数据类型不匹配,系统将显示错误。:
确保选中"计算"复选框非常重要,因为这将允许掩码在保存后保存参数数据类型。:
将mask参数传递给Engee函数块的源代码的示例
-
从块组装模型 正弦波, 功能 和 终结者 并打开 录音
信号如图:
-
在*Engee函数*块的源代码中,添加以下代码:
struct Block <: AbstractCausalComponent end function (c::Block)(t::Real, x) return gain .* x end
-
打开*Engee函数*块的掩码编辑器,为此,单击该块,选择 面罩 → 添加面具 . 在掩码编辑器中,添加 输入字段
,命名增益参数并设置其值,例如3:
-
在*Engee函数*块的参数中,设置增益参数的值,如图所示:
此方法允许您使用块设置中的掩码参数的值,将其添加到源代码并应用参数名称以获取指定的值。:
-
让我们通过运行模型的模拟来使用图表来测试这种方法。:
-
增益参数的值确实为3,这意味着掩码与*Engee函数*块的源代码完美配合。
可配置子系统的_example(*Subsystem*块)_
-
默认情况下,子系统除了*Treat as atomic unit之外没有其他参数*:
转到子系统并将*正弦波*块添加到其中。
-
右键单击子系统图标并选择 面罩 → 添加面具 .
-
在掩码界面编辑器中,添加 下拉列表
. 将基于样本和基于时间的参数添加到列表中。:
-
在掩码代码编辑器中,转到全局选项卡和回调 iconDrawCallback添加如下代码:
engee.show(dropdown_1)
此代码将在子系统图标上显示dropdown_1参数(下拉列表参数)的当前值。
-
在回调 blockChangedCallback使用以下代码:
SinePath = engee.gcb() * "/Sine Wave" mode = dropdown_1 if mode == "Time based" engee.set_param!(SinePath, "SineType" => "Time based") elseif mode == "Sample based" engee.set_param!(SinePath, "SineType" => "Sample based") end
此代码根据dropdown_1掩码参数的值更改子系统中*正弦波*块的`SineType`参数:如果选择了`Time based`,则设置`SineType`⇒`"Time based"`,如果`"Sample based"`,则`"SineType"`⇒`"Sample based"`。
通过更改屏蔽子系统中*Sine type*参数的值,此参数会在*Sine Wave*块中自动更改。
基于时间的选择 |
选择基于样本的 |
将mask参数传递给Chart块的示例
-
*local_input*值为"input";
-
*local_c*值为’c'。
这些变量将从子系统掩码接收值。
之后,创建 条件 . 给它一个名称,并使用局部变量,输入和输出编写表达式。 确保状态中的变量名称与*Chart*块的设置中指定的名称匹配。 结果是具有配置的输入、输出和变量的有限状态机模型。:
现在子系统内部的模型将如下所示:
使用蒙版,创建以下内容 输入字段 对于*图表块*:
使用以下方法导航到模型的顶层 导航栏对于*Subsystem*块,使用以下内容创建掩码 输入字段 :
运行模型 . 在模拟结束时 文件浏览器
将创建一个CSV文件,显示时间模拟的结果。:
time,1
0.0,22.0
0.01,22.0
0.02,22.0
0.03,22.0
0.04,22.0
0.05,22.0
0.06,22.0
0.07,22.0
0.08,22.0
...
9.96,22.0
9.97,22.0
9.98,22.0
9.99,22.0
10.0,22.0
结果是'22`,这证实了在*Chart*块的状态中计算表达式的正确性:local_c=c=6
(来自*Subsystem*掩码),local_input=input=15
(来自*Chart*块掩码),它们的总和是`21`,而*常量块*再加一个`1`,得到'22’的总