Engee 文档

恩吉功能

在模型中使用Julia代码。

blockType: EngeeFunction

图书馆路径:

/Basic/User-Defined Functions/Engee Function

资料描述

恩吉功能 允许您在 AnyMath 模型中使用Julia代码。

在页面上阅读更多关于Julia编程语言的信息 编程.
在街区里 恩吉功能 使用 Julia 语言的大部分功能是可以接受的。 但是,不提供在块中使用 Pkg 包管理器。

使用

要将Julia代码集成到 AnyMath 模型中,您必须:

  1. 向模型添加块 恩吉功能基本部分/自定义函数 块库 blocks library icon;

  2. 设置窗口 debug article icon 1 在块的 选项卡上 恩吉功能 点击 编辑源代码 按钮打开源代码编辑器(EngeeFunctionCode):

engee function code editor

源代码单元格

EngeeFunctionCode源代码编辑器由带有Julia代码的功能单元组成。 默认情况下,有三个单元格可用:辅助(不可编辑), 元件结构代码步骤方法代码 (单元格可以隐藏):

engee function all start cell

要连接其他源代码文件,您可以使用该函数 包括() 在牢房里 通用代码 (有关单元格的描述,请参阅 下文):

include("/user/engeefunction/source.jl")
整个块代码 恩吉功能 你可以在单元格中写 通用代码 通过获得对组件结构、签名和函数数量的完全控制。

要添加/删除其他功能单元,请单击"管理方法"按钮 engee function all methods 并选中/取消选中相应的单元格。:

engee function choose methodsengee function choose methods 1

每个单元负责块的独特功能 恩吉功能 . 让我们更详细地看看它们:

  • * 信息单元格 (不可编辑)-自动显示块变量 *恩吉功能 ,输入和输出信号的属性(尺寸,类型,离散度)和其他用户定义的参数。 其内容根据块设置动态更新。 单元格始终处于活动状态,但未在"方法管理"菜单中选择该单元格。 engee function all methods. 它有一个半透明的文本,显示提示。

    engee function start cell

    更改块参数不仅会影响信息单元格的内容,还会影响其他单元格中的提示,这些提示也会以半透明文本显示。
  • * 定义组件结构 -添加单元格 *元件结构代码 ,其中定义了块组件的结构 恩吉功能 (继承自类型 AbstractCausalComponent). 结构的字段在不可编辑的行之间定义 结构块<:AbstractCausalComponent结束. 默认情况下,将创建参数 g,由块值初始化 增益,以及构造函数 座() 它不接受论点。

    engee function component struct code

  • * 使用通用代码—-添加单元格 通用代码 ,其中代码以自由形式编写。 默认情况下,单元格为空。 例如,如果标准结构在 元件结构代码 不适合(由于不可编辑 结构块<:AbstractCausalComponent),然后您可以禁用 定义组件结构 删除单元格,并在手动定义组件结构 通用代码 . 这同样适用于方法管理菜单中的任何功能。 engee function all methods -而不是标准的单元格,你可以编写自己的代码 通用代码 .

    engee function common code

    声明一个组件和一个函子是需要工作的。 恩吉功能 . 如果 定义组件结构定义步骤方法 被禁用,那么它们的代码必须设置在 通用代码 否则,该块将不起作用。
    要重新定义继承函数(复盖,见下文),您首先需要包含相应的单元格,擦除其内容,然后在 通用代码 .
  • * 定义步骤方法 -添加单元格 *步骤方法代码 ,其中定义了计算块的输出信号的步进方法 恩吉功能 . 方法签名是根据端口选项卡中相应端口标签的值自动生成的。 该方法表示为函子(有关详细信息,请参阅 这里)并且在模拟的每个步骤中被调用。 字段在不可编辑的行之间定义 函数(c::块)(t::实,in1)结束. 第一个论点 真的 -仿真时间,然后输入信号变量被发送。 通过关键字返回计算的输出值 回来吧.

    engee function define step method

  • * 定义更新方法 -添加一个单元格 更新方法代码 其中的方法 更新! 更新块的内部状态 *恩吉功能 在模拟的每一步。 第一个论点 c::座 -块结构,第二 真的 -仿真时间,然后输入信号被发送。 如果块没有内部状态,那么该方法可以保持为空并简单地返回 c.

    engee function update method code

    如果需要定义多个方法 更新! 或者设置具有不同签名的方法,然后您可以禁用 更新方法代码 单元格并在单元格中编写代码 通用代码 . 编译器将自动检测方法的存在 更新! 并将其用于仿真。
  • * 定义终止方法代码 -添加 终止方法代码*单元格,该单元格在块模拟结束时执行 恩吉功能 (使用方法 终止!). 第一个论点 c::座 -块结构。 默认情况下,该方法不执行任何其他操作,只需返回 c.

    engee function terminate method code

  • * 复盖类型继承方法 *-添加*Types继承方法*单元格,该单元格复盖类型继承方法。

    详细了解类型继承方法

    设置类型继承方法:

    • 如果未选中该复选框(默认情况下),则根据输入/输出端口描述中指定的规则继承输入/输出端口的类型。

    • 如果选中该框,则根据函数中指定的规则继承输入/输出端口类型 传播_类型 源代码中的*类型继承方法*单元格。

      • 功能 传播_类型 它接受一个参数,一个类型的向量,每个输入信号都有一个类型,并返回一个输出类型的向量。

    默认单元格代码:

    function propagate_types(inputs_types::Vector{DataType})::Vector{DataType}
    # Функция, возвращающая массив типов сигналов на выходе.
    # Игнорируется, если используется алгоритм по умолчанию.
    # В данном случае учитываются тип входного сигнала и тип
    # параметра блока `gain`.
        input_type = first(inputs_types)
        # promote_type возвращает тип, к которому приводятся типы-аргументы
        # при арифметических операциях с объектами этих типов.
        output_type = promote_type(input_type, eltype(gain))
        return [output_type]
    end

    这里,输入信号的公共元素和在设置参数部分的块设置中指定的参数的元素被取为继承类型。

  • Override dimensions继承方法 *-添加一个cell*Dimensions继承方法,它重新定义了维度的继承方法。

    详细了解维度继承的方法

    设置维度的继承方法:

    • 如果未选中该复选框(默认情况下),则根据输入/输出端口描述中指定的规则继承输入/输出端口的尺寸。

    • 如果选中该框,则根据函数中指定的规则继承输入/输出端口的尺寸 传播_dimensions 源代码中的*维度继承方法*单元格。

      • 功能 传播_dimensions 它为每个输入信号获取一个元组(维度)数组,并为输出返回一个维度数组。

    默认单元格代码:

    function propagate_dimensions(inputs_dimensions::Vector{<:Dimensions})::Vector{<:Dimensions}
    # Функция, возвращающая массив размерностей сигналов на выходе.
    # Игнорируется, если используется алгоритм по умолчанию.
    # В данном случае учитываются размерности входного сигнала и
    # параметра блока `gain`.
        input_dimensions = first(inputs_dimensions)
        mock_input = zeros(input_dimensions)
        mock_output = mock_input .* gain
        return [size(mock_output)]
    end

    在这里,要继承维度,需要一个具有必要维度(mock_input)的数组,由零组成,并乘以设置参数部分的块设置中指定的参数元素,然后取其维度。

  • * 使用通用方法进行类型和维度继承 -添加 通用类型和维度继承方法*单元格,该单元格使用通用方法同时重新定义类型和维度的继承。

    详细了解类型和维度的继承方法

    与类型(类型继承方法)或维度(维度继承方法)的特定方法不同,一般方法会同时包括类型和维度:

    • 如果未选中(默认情况下),则忽略常规方法,输入/输出端口的维度和类型将根据输入/输出端口描述或继承方法*复盖类型继承方法 (如果启用)和 复盖维度继承

    • 如果选中该框,则根据函数中指定的规则继承输入/输出端口的尺寸和类型 传播_types_and_dimensions 源代码中的单元格*常见类型和维度继承方法*。

    默认单元格代码:

    function propagate_types_and_dimensions(inputs_types::Vector{DataType}, inputs_dimensions::Vector{<:Dimensions})::Tuple{Vector{DataType}, Vector{<:Dimensions}}
    # Функция, возвращающая массив типов сигналов и массив
    # размерностей сигналов на выходе. Эту функцию можно использовать
    # если необходимо одновременно переопределить и алгоритм наследования
    # типов сигналов, и алгоритм наследования размерностей.
        outputs_types = propagate_types(inputs_types)
        outputs_dimensions = propagate_dimensions(inputs_dimensions)
        return outputs_types, outputs_dimensions
    end

    依赖关系

    要使用此单元格,请选中 Override type inheritance methodOverride dimensions inheritance method 框。

  • Override sample time inheritance method-添加单元格*Sample times inheritance method*,该单元格重新定义计算步骤的继承方法。

    详细了解计算步骤的继承方法
    计算步骤的结构代码 采样时间 和功能 传播_sample_times 它们不会自动添加到旧版 AnyMath 模型的EngeeFunctionCode源代码中。 要细化旧模型,请自行添加计算步骤的结构和函数。

    设置计算步骤的继承方法:

    • 如果未选中该复选框(默认情况下),则使用计算步骤的预设继承方法(默认情况下 违约情况)来自高级选项卡的*样本时间继承方法*参数。 阅读有关预安装方法的更多信息。 下面

    • 如果选中该复选框,则忽略高级选项卡的预设方法(该参数不可用),则从EngeeFunctionCode源代码中的*Sample times inheritance method*单元格中使用独立方法。

    要使用独立的方法,您需要找到函数字符串。 传播_sample_times 并手动设置所需的计算步骤。

    默认单元格代码:

    function propagate_sample_times(inputs_sample_times::Vector{SampleTime}, fixed_solver::Bool)::SampleTime
    # Функция, возвращающая время дискретизации блока.
    # Используется только в режиме наследования `Custom`.
    # Параметр fixed_solver говорит о том, используется решатель
    # с постоянным шагом (true) или с переменным (false).
    # Более сложный пример работы с наследованием времени
    # дискретизации блока можно посмотреть в документации.
        return first(inputs_sample_times)
    end

    其中计算步骤具有结构:

    const SampleTime = NamedTuple{(:period, :offset, :mode), Tuple{Rational{Int64}, Rational{Int64}, Symbol}}
  • * 复盖直接馈通设置方法 —添加定义直接端到端连接的单元格 直接馈通设置方法*。

    详细了解直接端到端连接的定义

    定义直接的端到端连接:

    • 如果未选中该复选框(默认情况下),则直接端到端连接不可用。 这意味着输出信号将不受输入端口的值控制,并允许单元开环。

    • 如果选择此选项,则直接端到端连接可用。 这意味着输出信号直接由输入端口的值控制。

    默认单元格代码:

    function direct_feedthroughs()::Vector{Bool}
    # Функция, возвращающая массив булевых значений, определяющих,
    # сквозные соединения. Если i-ый элемент массива равен true,
    # то i-ый порт имеет сквозное соединение.
    # Игнорируется, если используется алгоритм по умолчанию.
        return [true]
    end

    例如_:

    function direct_feedthroughs()::Vector{Bool}
        if gain == 2
            return [false]
        else
            return [true]
        end
    end

获取属性的常量和函数

为了找出块可执行代码中的类型,大小和其他辅助信息,请在代码中使用以下常量 恩吉功能 :

  • 块名 -块的名称。 添加到AnyMath画布的每个块都有一个可以通过此常量访问的名称。 例如,您可以在错误初始化期间引用BLOCK_NAME来输出其中的块名称。

  • 开始时间 -从模型设置开始模拟。

  • 停止时间 -结束模拟从模型设置。

  • 输入_SIGNAL_ATTRIBUTES -每个输入端口的属性列表。 例如,要找出第一个输入信号的属性,使用 输入_SIGNAL_ATTRIBUTES[1],在哪里 1 -单元的第一输入端口 恩吉功能 .

  • 输出_SIGNAL_ATTRIBUTES -每个输出端口的属性列表。 例如,要找出第一输出信号的属性,使用 输出_SIGNAL_ATTRIBUTES[1],在哪里 1 -块的第一输出端口 恩吉功能 .

变量 开始时间停止时间 可在 AnyMath函数 源代码的所有单元格中使用(包括继承/复盖方法)。 它们包含模型设置中模拟集的开始和结束时间。 常见使用场景:

  • 计算模拟的持续时间 STOP_TIME-START_TIME;

  • 在第一个/最后一个步骤(初始化/完成)中执行操作;

  • 将离散步骤设置为总持续时间的一小部分(例如,获取 N 间隔上的点)。


要了解有关特定块端口的更多信息,您可以通过添加点来参考其信号的属性 . 常数之后 输入_SIGNAL_ATTRIBUTES[i],在哪里 [i] -输入端口的编号,以及 输出_SIGNAL_ATTRIBUTES[i],在哪里 [i] -分别输出端口的编号。 您可以通过以下联系功能了解更多信息:

  • 尺寸 -信号的维度。 可缩短至 暗淡无光.

  • 类型 -信号的类型。 可缩短至 tp.

  • 采样时间 -计算步骤。 它是一种类似于信号属性的结构,可以通过点访问。 .. 提供两种转换功能:

    • 期间 -计算步骤的周期。 全转换功能 — sample_time。期间. 可缩短至 圣.p.

    • 偏移量 -计算步骤的偏移。 全转换功能 — sample_time.偏移量. 可缩短至 圣.o.

  • direct_feedthrough -指示循环端口是否打开。 它仅用于输入端口(仅检查输入端口的属性)。 可缩短至 df.

模型示例 恩吉功能 具有所有常量和转换函数:

engee function constants

struct Block <: AbstractCausalComponent end

function (c::Block)(t::Real, x1, x2)
    y1 = [START_TIME, STOP_TIME]
    y2 = collect(INPUT_SIGNAL_ATTRIBUTES[1].dimensions)
    y3 = OUTPUT_SIGNAL_ATTRIBUTES[1].dims[1]
    y4 = (INPUT_SIGNAL_ATTRIBUTES[2].type == Int64)
    y5 = (OUTPUT_SIGNAL_ATTRIBUTES[4].tp == Bool)
    y6 = INPUT_SIGNAL_ATTRIBUTES[1].sample_time.period
    y7 = OUTPUT_SIGNAL_ATTRIBUTES[1].st.p
    y8 = INPUT_SIGNAL_ATTRIBUTES[1].sample_time.offset
    y9 = OUTPUT_SIGNAL_ATTRIBUTES[2].st.o
    y10 = INPUT_SIGNAL_ATTRIBUTES[1].direct_feedthrough
    y11 = INPUT_SIGNAL_ATTRIBUTES[2].df
    return (y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11)
end

使用固定点和自定义总线

恩吉功能 ,并且还 命令提示符 img 41 1 2 AnyMath,支持定点操作(固定)和定制轮胎类型(N.公共标志). 这些构造有助于控制处理整数、实数、固定和复杂数据类型时的操作行为。

定点类型和功能(定点)

在文章中 AnyMath中的定点算术 它描述了如何在 AnyMath 中使用固定点。 文章中给出的构造对块也有效 恩吉功能 ,这是块支持的方式:

  • 固定点,固定点 -所有固定数字的抽象类型;

  • 固定 -特定类型的固定数字,使用指定的位表示手动创建;

  • 菲(。..) -创建类型值 固定 使用数值和表示参数;

  • fixdt(。..) -创建固定类型,并指示符号、宽度和小数位数。

例如:

a = fi(5, 1, 16, 4)     # Знаковое число, 16 бит, 4 дробных
b = fi(10, 0, 8, 0)     # Беззнаковое целое 8 бит
T = fixdt(1, 24, 8)     # Тип Fixed с 24 битами, 8 из них — дробные
c = Fixed(0x01ff, T)    # Создание фиксированного числа напрямую по битовому представлению

固定号码 恩吉功能 五月:

使用自定义轮胎类型(N.公共标志)

自定义总线类型允许您以结构化元组的形式指定输入和输出信号的类型(命名的,命名的)与里面的名称,类型和尺寸的描述 恩吉功能 . 可用功能:

  • BusSignal{…​} -具有名称,类型和尺寸的总线类型;

  • get_bus_names(类型) -获取信号名称列表;

  • get_bus_types(类型) -获取信号的类型;

  • get_bus_dimensions(类型) -获取信号的尺寸;

  • get_names_types_dims(类型) -立即得到一切;

  • get_bus_signal_type(::NamedTuple) -识别类型 N.公共标志 按价值计算。

一个确定和分析轮胎类型的例子:

bus = (a = 1, b = [2.0, 3.0], c = (x = 3, y = 4))
bus_type = get_bus_signal_type(bus)

get_bus_names(bus_type)       # => (:a, :b, :c)
get_bus_types(bus_type)       # => (Int64, Vector{Float64},
                              #     BusSignal{(:x, :y), Tuple{Int64, Float64}, ((), ())})
get_bus_dimensions(bus_type)  # => ((), (2,), ((), ()))

你可以明确地描述轮胎:

MyBus = BusSignal{(:s1, :s2), Tuple{Int64, Float64}, ((), ())}
signal = MyBus((s1 = 5, s2 = 6.4))

还支持嵌套总线。:

Inner = BusSignal{(:x, :y), Tuple{Int, Int}, ((), ())}
Outer = BusSignal{(:a, :b), Tuple{Float64, Inner}, ((), ())}

块中的用法 恩吉功能

类别 固定N.公共标志 它可以用于块的不同部分。 恩吉功能 :

  • 在块参数中,您可以使用 菲(。..),并将总线结构转移为 命名的,命名的. 总线的类型可以通过以下方式自动确定 get_bus_signal_type(。..).

  • 在* 通用代码*单元格中,您可以定义数据类型(固定, BusSignal{…​}),组件结构(结构块),创建辅助函数或初始化值。 如果禁用了*步骤方法代码 组件结构代码*,也可以在此处移动主逻辑。

  • 在单元格* 组件结构代码*-描述结构的字段时,可以使用如下值 固定,以及类型 N.公共标志 如果字段是复合信号。

  • * 步骤方法代码*单元实现块的主要逻辑。 在这里,固定数字和总线信号可以参与计算、比较和结构处理。

  • 在* 类型继承方法*单元格中,您可以使用类型 固定N.公共标志 分析输入并指定组件的输出类型。

  • 在* 维度继承方法*单元格中,您可以使用数据 固定 和来自总线的值来确定输出信号的尺寸。

  • 在* 更新方法代码*单元格中,如果块具有内部状态,则字段如下 固定N.公共标志 它可用于在仿真的每个步骤存储或更改此状态。

  • 在*Terminate方法代码*单元格中,如果结构包含适当的字段,则这些类型可用于记录最终状态。

  • 在*Common types and dimensions inheritance method*单元格中,如果需要同时处理两种类型和维度。, 固定N.公共标志 他们也可以参与计算逻辑。

因此, 固定, 菲(。..), fixdt(。..), N.公共标志get_总线 这些功能适用于机组配置和操作的各个方面. 恩吉功能 -无论是在执行阶段还是在信号的类型和维度的生成阶段。 它们可以在所有单元格的参数和源代码中自由使用(如果它们正常工作)。

转换函数和类型化算术运算: [医]经济型, 埃苏姆, emul, 伊迪夫

在街区里 恩吉功能 ,以及在 命令行 img 41 1 2 AnyMath 功能可用,允许您执行指定输出类型的算术运算,在具有舍入和溢出控制的类型之间转换值,并使用专门的规则预先确定结果类型(_promote_类型). 这些函数用于逻辑 恩吉功能 ,写在源代码单元格 步骤方法代码通用代码 和其他。

可用功能:

  • [医]经济型 -类型之间的值转换;

  • 埃苏姆, [医]esub, emul, 伊迪夫 -输出类型赋值的算术运算;

  • 艾缪尔! -带有结果缓存的矩阵乘法;

  • *_promote_type -基于输入类型的输出功能。

这些函数可以应用于标量和数组。 结果总是以用户显式指定的类型返回(或自动输出),这使得块行为稳定和预期。

支持的类型

此集中的所有函数都适用于以下类型:

  • 真正的: 漂浮物16, 漂浮物32, 漂浮64

  • 整数: Int8, Int16, Int32, Int64, Int128, UInt8, UInt16, UInt32, UInt64, UInt128

  • 合乎逻辑的: 布尔

  • 固定: 固定 (通过创建 菲(。..)fixdt(。..))

  • 综合: 综合体{T},在哪里 T —任何上述类型

函数也可以使用点语法与数组和矢量化表达式一起使用(.). 接下来,让我们更详细地看一下这些功能。

使用以下方法转换数字 [医]经济型

功能 [医]经济型 允许您通过指定舍入方法和溢出处理方法将值转换为指定类型。:

econvert(type::Type{T1}, var::T2; rounding_mode::RoundingMode=RoundDown, overflow::Bool=true)

这里:

  • 类型 -要将值转换为的类型。 如果 瓦尔 -一个复数,基本实数表示。 例如, 经济型(Float32,综合大楼){Int16}(1+2im)) 它会回来的 综合体{Float32};

  • 瓦尔 -转换价值;

  • 圆角/圆角 -舍入法(四舍五入, 综述, RoundNearest拢潞, 往返旅行, 圆托泽罗);

  • 溢出 -如果 真的,则使用溢出行为(wrap);如果 错误 饱和启用-值受类型范围限制。

功能 [医]经济型 它可用于比较前的类型转换,在算术表达式内部,在条件和其他场景中处理信号时。

算术与类型控制使用 埃苏姆, [医]esub, emul, 伊迪夫, 艾缪尔!

类型化算术运算的函数 埃苏姆, [医]esub, emul, 伊迪夫, 艾缪尔! 它们具有相同的接口:

esum(x1, x2, out_type, overflow=true, rm=RoundDown)
esub(x1, x2, out_type, overflow=true, rm=RoundDown)
emul(x1, x2, out_type, overflow=true, rm=RoundDown)
ediv(x1, x2, out_type, overflow=true, rm=RoundDown)
emul!(cache, x1, x2, out_type, overflow=true, rm=RoundDown)

争论:

  • x1, x2 -操作参数(允许标量或数组);

  • out_type -生成和返回结果的类型;

  • 溢出 -启用溢出(真的)或饱和度(错误);

  • rm -舍入方法(见上面的列表)。

功能 埃苏姆, [医]esub, emul, 伊迪夫 返回与指定的值对应的值 out_type.

功能 艾缪尔! 它用于在处理矩阵时加快速度:它不会创建新数组,而是将结果写入已经分配的数组。 缓存. 重要的是 eltype(缓存) 恰逢 out_type.

结果取决于类型 out_type:它不仅影响最终结果,还影响中间计算的行为—这对于 固定综合体.

使用以下方法推断结果的类型 *_promote_type

如果块参数(例如, [医]相类型多类型,多类型)被设置为字符串 "继承",结果的类型是根据使用函数的输入数据类型自动确定的 *_promote_type.

如果需要计算操作的结果类型,请使用列出的函数:

  • 定义添加时的输出类型 n 相同类型的值 T:

    sum_promote_type(::Type{T}, n::Integer=1, hdlsetup::Bool=false)
  • 定义将两个不同类型添加在一起时的输出类型 T1T2n 价值:

    sum_promote_type(::Type{T1}, ::Type{T2}, n::Integer=1, hdlsetup::Bool=false)
  • 定义在添加任意数量的具有不同类型的参数时的输出类型。:

    sum_promote_type_from_inputs(types::Type...; hdlsetup::Bool=false)
  • 确定累加器加起来时的类型 n 相同类型的值 T:

    sum_accumulator_promote_type(::Type{T}, n::Integer=1, hdlsetup::Bool=false)
  • 确定将两种不同类型的电池添加在一起时的电池类型 T1T2n 价值:

    sum_accumulator_promote_type(::Type{T1}, ::Type{T2}, n::Integer=1, hdlsetup::Bool=false)
  • 定义在添加任意数量的具有不同类型的参数时累加器的类型。:

    sum_accumulator_promote_type_from_inputs(types::Type...; hdlsetup::Bool=false)
  • 定义将相同类型的值相乘时的输出类型 T:

    mul_promote_type(::Type{T}, hdlsetup::Bool=false)
  • 定义两种不同类型相乘时的输出类型。 T1T2:

    mul_promote_type(::Type{T1}, ::Type{T2}, hdlsetup::Bool=false)
  • 定义在划分单个类型值时的输出类型 T:

    div_promote_type(::Type{T}, hdlsetup::Bool=false)
  • 在划分类型值时定义输出类型 T1 在类型值上 T2:

    div_promote_type(::Type{T1}, ::Type{T2}, hdlsetup::Bool=false)

    这里:

    • hdlsetup -一个逻辑参数,决定是否考虑到硬件平台的细节(目标器皿). 默认情况下:

      hdlsetup = TargetHardware == "C" ? false : true

这些函数方便地用于 类型继承方法 单元格中,以根据输入和参数准确确定输出块类型。

使用示例

下面是实现表达式的组件的示例 a*x+b. 使用参数设置中间乘法和最终加法的类型 多类型,多类型[医]相类型. 如果指定 "继承",然后自动输出该类型。

使用a*x+b的例子_

engee function example 3

参数 恩吉功能 :

a = fi(5, 1, 16, 4)
b = fi(11, 1, 24, 7)
MulType = "Inherit"
SumType = "Inherit"

块代码(在单元格中 公共代码维度继承方法类型继承方法):

  • 单元格* 通用代码*:

    struct Block{SumType, MulType, aType, bType} <: AbstractCausalComponent
        a::aType
        b::bType
        function Block()
            sum_type = OUTPUT_SIGNAL_ATTRIBUTES[1].type
            mul_type = if MulType == "Inherit"
                mul_promote_type(INPUT_SIGNAL_ATTRIBUTES[1].type, eltype(a))
            else
                MulType
            end
            new{sum_type, mul_type, typeof(a), typeof(b)}(a, b)
        end
    end
  • Cell*Dimensions继承方法*:

    function propagate_dimensions(inputs_dimensions::Vector{<:Dimensions})::Vector{<:Dimensions}
        input_dimensions = first(inputs_dimensions)
        mock_input = zeros(input_dimensions)
        mock_output = mock_input .* a .* b
        return [size(mock_output)]
    end
  • Cell*Types继承方法*:

    function propagate_types(inputs_types::Vector{DataType})::Vector{DataType}
        mul_type = if MulType == "Inherit"
            mul_promote_type(inputs_types[1], eltype(a))
        else
            MulType
        end
        sum_type = if SumType == "Inherit"
            sum_promote_type(mul_type, eltype(b))
        else
            SumType
        end
        return [sum_type]
    end

因此,功能 [医]经济型, 埃苏姆, emul, 伊迪夫 和规则 promote_type 它们允许您控制块内计算的类型和行为。 恩吉功能 . 它们支持所有主要的数值类型,包括固定点和复杂值,并可用于计算、比较、继承逻辑和使用块的组件行为调整。 恩吉功能 .

诊断功能 警告, 停止模拟, 暂停模拟, 资料

块的源代码中 恩吉功能 功能也可用 警告, 停止模拟, 暂停模拟资料,它允许您在模拟阶段与模型的诊断系统进行交互,允许您在 诊断窗口 model diagnosis main. 这些函数可以在以下源代码单元中使用:

  • * 组件结构代码*

  • * 步骤方法代码*

  • * 更新方法代码*

  • * 终止方法代码*

  • * 通用代码*

功能 警告, 停止模拟, 暂停模拟, 资料 它只能用于在模型仿真期间执行的代码的那些部分。

因此,尽管这些函数在 Component struct code 单元格中被正式允许,但实际上它们在那里的放置没有意义:此单元格仅用于描述块结构,而不是用于可执行逻辑。 为了使诊断函数正常工作,必须将它们放在支持的仿真方法中:步骤方法更新方法终止方法公共代码 中,如果在那里重新定义了相应的方法。 正确放置的例子:

  • * 组件结构代码*:

    #
    struct Block <: AbstractCausalComponent
        g::Real
        function Block()
            new(gain)
        end
    end
  • * 通用代码*,函数函子 (c::Block)(t::Real,in1) 取自*Step方法代码*,方法本身被禁用:

    function (c::Block)(t::Real, in1)
        if t == 5.0
            warning("time == $t")
        end
        return c.g .* in1
    end

通过类推,您可以复盖在模拟期间调用的任何受支持的方法(例如, 更新!, 终止;终止, 步骤),在 通用代码 单元格手动-如果禁用相应的标准单元格(例如,定义更新方法定义步骤方法 等。).

为了在单元格中正确操作 公共代码 功能 警告, 停止模拟, 暂停模拟资料 可以使用:

  • 内部函数重新定义负责执行模型的方法的行为,例如 步骤, 更新!, 终止!. 例如,如果在*步骤方法代码 单元格中正常指定的函子是在 公共代码*中定义的,那么它内部的诊断函数将正常工作。

  • 从负责执行模型的方法调用的辅助函数内部。 也就是说,如果辅助函数在*公共代码*中定义,并且例如在 步骤,那么对其内部诊断函数的调用也将被正确执行。

    重新定义 更新! 或其他方法不替换所要求的实现。 步骤 (函数(c::块)(t,in…​)). AnyMath 需要此功能作为模拟的入口点。

正确重新定义的一个例子 更新!通用代码:

# Структура с Component struct code (если отключена, то должна быть обязательно вынесена в Common code)
struct Block <: AbstractCausalComponent
    g::Real
    function Block()
        new(gain)
    end
end

# Step method (обязательный метод, вызываемый на каждом шаге симуляции)
function (c::Block)(t::Real, in1)
    c = update!(c, t, in1)
    return c.g .* in1
end

# Переопределенный метод update!
function update!(c::Block, t::Real, in1)
    if t == 5.0
        info("update triggered at t = $t")  # диагностическое сообщение
    end
    return c
end

因此,将在模型的诊断窗口中收到以下消息:

engee function continue 1


接下来,让我们仔细看看诊断功能本身。:

  • 警告 -功能 警告(msg::String) 显示警告消息。 模拟仍在继续。 这对于指出需要注意但不会停止执行的非关键问题或条件非常有用。 例子::

    if t == 5.0 || t == 7.5
        warning("time == $t")
    end
  • 停止模拟 -功能 stop_simulation(msg::String) 立即结束模拟并显示完成消息。 它用于指示一个临界条件,在该条件下,继续建模是不可能的或不希望的。 例子::

    if t == 5.0
        stop_simulation("time == $t")
    end
  • 暂停模拟 -功能 pause_simulation(msg::String) 暂停模拟并显示指定的暂停消息。 可以使用按钮手动恢复模拟 继续 :

    engee function continue

    此函数对于分析给定时间的模型状态非常有用。 例子::

    if t == 5.0
        pause_simulation("time == $t")
    end
  • 资料 -功能 信息(msg::字符串) 显示信息消息。 它用于在不影响仿真执行的情况下显示中间值。 例子::

    if t == 5.0 || t == 7.5
        info("time == $t")
    end

港口

入口处

输入端口 — 输入端口

+ 标量,标量 | 向量资料 | 矩阵

Details

指定为标量、矢量或矩阵的输入端口。

使用以下选项在块的 Ports 选项卡中配置输入端口:

  • * 标签*-指定输入端口的名称。 默认情况下,*Label*单元格为空(未指定名称)。

  • * 类型*-输入信号数据类型。 选择其中一个选项:

    • 某一类型(除 继承)-检查某种类型的信号正在发送到输入端口。 为输入端口选择特定的数据类型。 支持的信号: 漂浮物16, 漂浮物32, 漂浮64, 复杂的32, 复杂的f64, 布尔, Int8, Int16, Int32, Int64, Int128, UInt8, UInt16, UInt32, UInt64, UInt128.

    • 继承 (默认情况下)—从关联块继承数据类型。 它可以是任何类型的数据。

  • * 尺寸*-输入信号的尺寸:

    • 所有维度的继承-1 默认情况下)-继承施加到输入端口的信号的维度(信号可以具有任何维度)。

    • 定义的尺寸-输入信号必须具有指定数量的元素。 维度以Julia表示法(作为元组)指定,例如, (2,) 为由两个元素组成的一维信号,或 (2, 3, 4) 对于多维。 如果指定 -1,则维度被继承。

    • 继承其中一个维度-继承发送到输入端口的信号的维度,并带有数据结构的显式指示。 例如, (-1, 2) -预计第一个维度是继承的,第二个维度是显式设置的。

  • * 输出总线类型*-输入总线类型,替换输入信号的维度*大小 如果选择了输入信号的数据类型 类型* N.公共标志 (轮胎)。 默认值为 BusSignal{(),元组{},()}. 阻止 恩吉功能 我意识到哪个总线会来到输入,将类型设置为值就足够了 继承. 显式类型指示仅对输出信号是必要的。

    恩吉功能 它不继承总线到输出端口,虽然它可以接收它们到输入。 要继承输出端口上的总线(用于传输到其他块),必须在 Output bus type 参数中显式指定总线类型。
  • * 直接馈通*-定义直接端到端连接:

    • 如果选中该复选框(默认情况下),则直接端到端连接可用。 这意味着输出信号直接由输入端口的值控制。

    • 如果未选中该复选框,则直接端到端连接不可用。 这意味着输出信号将不受输入端口的值控制,并允许单元开环。

出口;出口

输出端口 — 输出端口

+ 标量,标量 | 向量资料 | 矩阵

Details

指定为标量、矢量或矩阵的输出端口。

使用以下选项在块的 Ports 选项卡中配置输出端口:

  • * 标签*-指定输出端口的名称。 默认情况下,*Label*单元格为空(未指定名称)。

  • * 类型*-输出信号的数据类型。 选择其中一个选项:

    • 某种类型(除 继承)-我们确定输出信号的数据类型。 为输出信号选择特定的数据类型。 支持的信号: 漂浮物16, 漂浮物32, 漂浮64, 复杂的32, 复杂的f64, 布尔, Int8, Int16, Int32, Int64, Int128, UInt8, UInt16, UInt32, UInt64, UInt128.

    • 继承 (默认情况下)-继承输出信号的数据类型。 当有多个不同类型的输入信号时,计算最小的公共类型。 它可以是任何类型的数据。

  • * 尺寸*-输出信号的尺寸:

    • 所有维度的继承-1 默认情况下)-继承施加到输出端口的信号的维度。 输出信号将具有作为广播机制的结果而获得的维度-Julia将自动将较小数据数组的维度扩展到较大的维度,以便正确继承维度。

    • 定义的尺寸-输出信号必须具有指定数量的元素。 维度在Julia表示法中指定(作为元组),例如, (2,) 为由两个元素组成的一维信号,或 (2, 3, 4) 对于多维。 如果指定 -1,则维度被继承。

    • 继承其中一个维度-继承发送到输出端口的信号的维度,并带有数据结构的显式指示。 例如, (-1, 2) -预计第一个维度是继承的,第二个维度是显式设置的。

  • * 输出总线类型*-输出总线类型,替换输入信号的尺寸*尺寸 如果选择了输出信号的数据类型 类型* N.公共标志 (轮胎)。 默认值为 BusSignal{(),元组{},()}. 阻止 恩吉功能 如果您已向出口发出轮胎,则必须明确指定其类型。

参数

主要

输入端口数 — 定义输入端口的数量

+ 1(默认)

Details

定义块的输入端口数。 输入端口数 参数的值将对应于输入端口数。

输出端口数 — 定义输出端口的数量

+ 1(默认)

Details

定义块的输出端口数。 输出端口数 参数的值将对应于输出端口数。

采样时间 — 计算步骤之间的间隔

+ -1(默认)

Details

将计算步骤之间的间隔指定为非负数。 要继承计算步骤,请将此参数设置为 −1.

高级

使用外部缓存进行非标量输出 — 对非标量输出使用外部缓存

+ 禁用(默认情况下) | 已启用

Details

指定对非标量(多维)输出信号使用外部高速缓存来保存 AnyMath*RAM。 使用,如果块有 *恩吉功能 只有一个输出端口:

  • 如果未选中该复选框(默认情况下),则不使用外部缓存。

  • 如果标志被检查,输出信号可以接受一个额外的参数。 缓存,在EngeeFunctionCode源代码中必须考虑到这一点。 如果单元具有一个输出端口,则在单元 步骤方法代码 论点 缓存 它会自动添加到函数参数列表中,除非将端口维度显式指定为 () (标量)。 在源代码中,要求根据输出信号的维度编写函子。 函子可以在单元格中定义 通用代码 :

    • 如果输出信号是标量:

      function (c::Block)(t::Real, x)
          return c.g * x
      end
    • 如果输出信号是非标量的:

      function (c::Block)(t::Real, cache, x)
          cache .= c.g .* x
          nothing
      end

      哪里 t -时间, x -参数(来自输入端口的信息)。 必须指定time参数,即使它不包含在块参数中。

样本时间继承方法 — 计算步骤的继承方法的定义

+ 默认(默认情况下) | 离散的,离散的 | 连续不断

Details
如果在EngeeFunctionCode源代码中选中了 Override sample time inheritance method 复选框,则 Sample time inheritance method 设置从 Advanced 选项卡中消失。 在这种情况下,计算步骤的继承方法由函数单元格的代码 样本时间继承方法 确定。

根据所选值定义计算步骤的继承方法:

如果在 采样时间 字段中指定了该值 -1,然后根据 样本时间继承方法 字段中指定的方法继承计算步骤,具体取决于所选值(违约情况, 离散的,离散的, 连续不断). 在所有其他情况下(采样时间不等于 -1 且采样时间大于等于 0)-区块 恩吉功能 它使用 Sample Time 字段的指定值,忽略 Sample time继承方法
  • 违约情况 -计算步骤的默认继承方法。 继承的方法 违约情况 它总是在块时使用 恩吉功能 它不是离散的或连续的。 法得到任何一种计算步骤。 选择此方法时,块 恩吉功能 它将根据以下原则继承计算步骤:

    • 如果块没有输入端口,则在输出处有一个连续的计算步骤。

    • 如果所有计算步骤在输入处相同,则输出处的计算步骤与输入相同。

    • 如果在输入步骤中存在连续的计算步骤,则在输出处也存在连续的计算步骤。

    • 如果在输入计算步骤中存在固定次要(FiM,Fixed-In-Minor),则不存在连续计算步骤和 求解器与可变间距-输出是一个固定的小一个。

    • 如果在输入处没有连续且固定数量的计算步骤并且并非所有计算步骤都相等,则仅考虑输入处的离散计算步骤,对于其中一个选项是有效的。:

      • 如果离散计算步骤的最大公约数与输入计算步骤之一重合或使用恒定步长求解器,则输出是具有最大公约数的步长的离散计算步骤。

      • 如果变步求解器和输入离散计算步骤的最大公约数与任何输入计算步骤不匹配,则输出为固定小的。

  • 离散的,离散的 -种获得离散计算步骤的继承方法。 选择此方法时,块 恩吉功能 它将根据以下原则继承计算步骤:

    • 如果输入端有连续或固定的小计算步长,则输出为带有求解器步长的离散计算步长(即使求解器带有可变步长)。

    • 如果在输入处存在离散计算步骤,则输出是与输入离散计算步骤具有最大公约数的离散计算步骤。

  • 连续不断 —种用于获得与输入计算步骤无关的连续计算步骤的继承方法。

一个重新定义函数的例子 传播_sample_times 具有类似于继承方法的作业 违约情况:

+

function propagate_sample_times(inputs_sample_times::Vector{SampleTime}, fixed_solver::Bool)::SampleTime
    nonnegative_sample_times = filter(
        st -> st.period >= 0,
        collect(values(inputs_sample_times)),
    )
    finite_periods = filter(
        st -> !isinf(st.period),
        nonnegative_sample_times,
    ) .|> (st -> st.period)
    output_sample_time = if !isempty(nonnegative_sample_times)
        if allequal(nonnegative_sample_times)
            first(nonnegative_sample_times)
        elseif any(st -> st.period == 0 // 1 && st.mode == :Continuous, nonnegative_sample_times)
            (period = 0 // 1, offset = 0 // 1, mode = :Continuous)
        elseif any(st -> st.mode == :FiM, nonnegative_sample_times) && !fixed_solver
            (period = 0 // 1, offset = 0 // 1, mode = :FiM)
        elseif (
            all(x -> x.period > 0 // 1, nonnegative_sample_times) &&
            (fixed_solver || gcd(finite_periods) in finite_periods)
            )
            (period = gcd(finite_periods), offset = 0 // 1, mode = :Discrete)
        else
            (period = 0 // 1, offset = 0 // 1, mode = :FiM)
        end
    else
        (period = 0 // 1, offset = 0 // 1, mode = :Continuous)
    end
    return output_sample_time
end
如果功能 传播_sample_times 申报表 (周期=0//1,偏移=0//1,模式=:离散),那么这样的计算步骤将被视为具有求解器步骤的离散。

设置参数

参数数量 — 指定参数的数量

+ 1(默认)

Details

块中使用的参数的数量。

参数 — 将参数定义为变量

+ 标量,标量 | 向量资料 | 阵列

Details

定义要在块源代码中使用的参数 恩吉功能 . 在参数中,您可以设置:

  • 姓名 -参数名称;

  • 价值 -参数的值。 任何Julia表达式都可以设置为值。

参数的值和名称可以在参数选项卡中更改。 第一个参数的名称(默认存在) — 增益,其值为 2. 新参数被调用 参数2 然后上升。 新参数的默认值为 0.

AnyMath变量窗口中可用的全局变量 variables icon 您可以将参数选项卡设置为插入块源代码的变量。 恩吉功能 . 如果参数的名称和全局变量匹配,参数值将自动从全局变量中替换。

要设置总线参数,请为参数设置 价值 以命名元组形式的总线值,例如 (s1=5,s2=4).


区分在"参数"选项卡中设置的块参数和源代码中的全局变量非常重要。 恩吉功能 ,来自变量窗口中的全局变量 AnyMath variables icon. 虽然可以在块参数中使用global*AnyMath* 变量的值和名称,但这些实体完全不同。 全局 AnyMath 变量不能通过块参数或从其源代码进行控制。 但是,对于源代码,块参数(来自参数选项卡)是全局变量,可以在其任何部分中使用,而无需引用特定函数或代码块。

让我们考虑全局变量完全对应于源代码中的变量的情况。 例如,设置了三个全局变量 , , 与价值观 1, 2, 3 相应地。 所有三个全局变量都用作块参数。 恩吉功能 :

engee function param explain 1

然后添加参数的源代码将如下所示:

struct Block <: AbstractCausalComponent
    a::Real
    b::Real
    c::Real

    function Block()
        new(a_param, b_param, c_param)
    end
end

function (c::Block)(t::Real, x::Vector{<:Real})
    return (c.a .* x .+ c.b) ./ c.c
end

此源代码定义了结构 ,它允许您自定义组件的行为。 该示例使用块参数的名称。 a_param, b_帕拉姆,而 c_param 设置结构参数 , ,而 相应地。 代码还定义了一个方法 function(c::Block)(t::Real,x::Vector{<:Real}),其中缩放向量的每个元素 x 到块参数 ,补充 并将结果除以 . 这允许您灵活地更改和归一化矢量。 x 据块参数的值。


让我们考虑一个仅使用参数选项卡的参数的情况。:

struct Block <: AbstractCausalComponent end

function (c::Block)(t::Real, x::Vector{<:Real})
    return (a_param .* x .+ b_param) ./ c_param
end

这些参数将是块代码中的全局变量。 这意味着它们将始终在块代码的任何部分中可用,而不必在每个函数或代码块中重复定义它们。 这大大简化了代码,并且可以轻松更改参数选项卡中的参数,而不会影响源代码。


让我们考虑参数与源代码不完全匹配的情况。 例如,有一个参数 a_param,等于 100. 源代码中有一个结构字段 :

struct Block <: AbstractCausalComponent
    a::Real

    功能块()
        新(a_param/10)
    结束
结束

function(c::Block)(t::Real,x::Vector{<:Real})
    c.a
结束

在这段代码中,参数 a_param 用于初始化字段 结构 结构块 通过它的构造函数,它将参数值划分为 10. 在这种情况下,该字段在块的函子中返回 .


变量可以在源代码中全局化。:

a = 1;
b = 2;
с = 3;

struct Block <: AbstractCausalComponent; end

function (c::Block)(t::Real, x::Vector{<:Real})
    return (a .* x .+ b) ./ c
end

在代码中创建一个结构 并且定义了一个函数,该函数用全局变量执行数学运算。 , 通过将它们应用于变量 x.


如果您 不想 使用参数选项卡中的参数,则可以直接在源代码中初始化变量。:

struct Block <: AbstractCausalComponent; end

function (c::Block)(t::Real, x)
    a = 1;
    b = 2;
    c = 3;
    return (a .* x .+ b) ./ c
end

在代码中创建一个结构 并定义了一个用局部变量进行数学运算的函数。 , 通过将它们应用于变量 x.

让我们考虑最有效和正确的方法来做到这一点。 阻止 恩吉功能 它工作正常,选中选项框 使用外部缓存进行非标量输出 在块的主选项卡上 恩吉功能 . 源代码将如下所示:

struct Block{Ta, Tb, Tc} <: AbstractCausalComponent
    a::Ta
    b::Tb
    c::Tc

    功能块()
        Ta=typeof(a_param);Tb=typeof(b_param);Tc=typeof(c_param)
        all(isreal,(a_param,b_param,c_param))||
          错误("块参数必须是真实的")
all(x->isempty(size(x)),(a_param,b_param,c_param))||
          错误("块参数必须是标量")
新的{Ta, Tb, Tc}(a_param,b_param,c_param)
    结束
结束

function(c::Block)(t::Real,cache::Vector{<:Real},x::向量{<:Real})
    缓存。=(c.a.*x.+c.b)。/c.c
    什么都没有
结束
此代码只能在单元格中编写。 通用代码 ,由于标准单元格不允许编辑组件结构的定义和函子的签名。

字段 , 结构是在构造函数中严格检查类型的块参数。 这些参数中的每一个都必须是一个真正的标量(真实的),从而保证了执行过程中计算的准确性。

设计师 座() 检查传递参数的类型 , . 如果其中至少有一个不是真正的标量或具有不适当的维度(它们必须是标量),则构造函数会生成带有相应消息的错误。 验证后,构造函数使用值初始化结构的字段 , 指定的类型 Ta, 结核病Tc技术.

为块实例定义的计算函数需要时间 t,外部缓存和矢量 x 实数。 字段用于此函数 , 结构 计算值,然后将其写入缓存。 这通过重用提供的缓存来避免不必要的内存分配。

因此,结构 通过使用外部缓存来存储计算结果,提供对数据类型的严格管理和资源的有效使用。


如果要更改块参数,则必须使用 可变的 的结构。 考虑一个例子:

mutable struct Counter{T} <: AbstractCausalComponent
    limit::T
    iter::T

    function Counter()
      isempty(size(limit)) || error("Предел блока $BLOCK_NAME должен быть 标量ом")
      isreal(limit) || error("Предел блока $BLOCK_NAME должен быть вещественным числом")
      T = typeof(limit)
      iter = zero(T)
      new{T}(limit, iter)
    end
end

function (c::Counter)(t::Real)
    return c.iter
end

function update!(c::Counter, t::Real)
  c.iter += 1
  if c.iter > c.limit
    c.iter = zero(c.iter)
  end
  c
end

结构 柜台 -这是 可变的 用于计算具有指定限制的迭代的数据类型,为强类型。 字段 限额伊特尔 结构表示块参数:

  • 限额 -这是计数器的极限值;

  • 伊特尔 -计数器的当前值。

在结构构造函数中检查(验证)参数。 限额 参数是否为标量和真实数据类型。 之后,该字段被初始化。 伊特尔 具有相应类型的零值 T. 功能 更新! 更新标签状态 ,增加价值 伊特尔 每个电话一个。 如果当前值为 伊特尔 超过 限额,然后将其重置为零,并允许计数器循环回到其初始状态。

块的源代码中 恩吉功能 您可以使用 包括,参考外部代码。 这允许您从源代码中的外部代码(如果有的话)初始化变量。
实际的数据类型以及对可能的数据类型的支持取决于块内的用户代码。

示例代码

该示例示出了块的简化实现。 离散时间积分器,基于Julia代码集成到 AnyMath 模型中。 选择直接欧拉法作为积分法。 在块的 高级 选项卡上 恩吉功能 设置值 离散的,离散的 样本时间继承方法 参数。 接下来,填写源代码单元格,如下所示:

  • 在牢房里 通用代码 :

    mutable struct Block{T} <: AbstractCausalComponent
        const dt::Float64
        state::T
        gain::Float64
    
        function Block()
            dt = OUTPUT_SIGNAL_ATTRIBUTES[1].sample_time.period
            state = initial_condition
            gain = k
            new{typeof(state)}(dt, state, gain)
        end
    end
  • 在牢房里 步骤方法代码 :

        return c.state
  • 在* 更新方法代码单元格中*:

        c.state += in1 * c.dt * c.gain
        return c

因此,将获得以下源代码:

engee function example 1

参数 初始化_条件k 它们在块设置的 参数 选项卡中初始化 恩吉功能 :

engee function example 2

在模型仿真的第一步,块的内部状态为 c.国家 由参数值初始化 初始化_条件.

之后,在每个计算步骤,块返回内部状态。 c.国家 作为输出信号并重新计算其值的方法 更新!.

组件结构在单元格中重新定义 通用代码 ,而不是在 元件结构代码 ,因为需要更灵活的定义:结构必须是可变的,并由与状态类型对应的类型 T 参数化。 标准定义在 元件结构代码 它仅适用于不可变和非参数化结构。

高级用法

恩吉功能 允许您使用自己的代码设置组件的行为,而无需从现成的块组装它。 这使得可以手动控制输出信号的类型和尺寸,使用缓存来提高性能,禁用输入到输出的直接传输,并设置自己的数据更新周期。

所以,在发布的页面上 工程师社区链接提供了块的高级用法的实际示例 恩吉功能 :

  • 通过重新定义输出参数将输入数据转换为矢量;

  • 使用缓存和强类型结构来提高性能;

  • 用于打破代数循环的没有直接馈通的块的实现;

  • 设置输出信号的用户采样周期。

说明

注释在 恩吉功能 它们允许您在模型中直接在其名称下显示块参数。 要添加它们,请打开 设置窗口 debug article icon 1 街区 恩吉功能 然后转到 Annotation 选项卡。 选择所需的块属性标记并将其添加到文本编辑器中。

engee function annotations

在这个标签上:

  • 左侧显示可用选项列表(隐藏选项除外)。

  • 右边是一个文本编辑器,您可以在其中设置带有格式标记的注释 %<参数名称>.

  • 参数可以手动传输,通过自动完成,或使用按钮 engee function annotations 1.

退出编辑器后(例如,在其外部单击时),将应用注释:标记将自动替换为实际参数值,最终文本显示在块名称下(或在其上方,如果名称放在顶部)。

要删除批注,必须在编辑器中删除相应的标记。

可用标记

属性标记将自动替换为当前参数值。 以下标记可用:

  • * 港口*: %<输入>, %<输出> -输入输出端口数; %<输入端口1类型>, %<输出端口1类型>, %<输入端口1大小>, %<输出端口1大小> -数据的类型和信号的维度。

  • * 临时特性*: %<采样时间> -离散化; %<采样时间> -离散继承的方法。

  • * 代码块*: %<组件结构码>, %<StepMethodCode> -步骤结构和方法的代码。

  • * 参数*: %<参数>, %<参数名称>, %<参数1值> -参数的名称和值。

  • * 启用标志*: %<定义组件结构>, %<UseCommonCode>, %<DefineStepMethod>, %<DefineUpdateMethod>, %<DefineTerminateMethod> -纳入守则的有关部分。

  • * 重新定义方法*: %<超负荷类型>, %<OverrideDimsInhMethod>, %<重写时间> -类型继承设置。

  • * 其他*: %<UseExternalCache> -使用外部缓存。