Engee 文档

在设备模块中使用用户总线 "BusSignal "进行操作

在使用定制轮胎类型之前,建议您熟悉轮胎块总线创建器总线选择器

在*Engee*中,通过 "BusSignal "类型(详见此处)支持自定义结构信号。该类型允许将逻辑上相关的信号组合成一个结构—​总线,其中每个元素都有名称、类型和维度(例如,temperature::Int, position::Vector{Float64}, status::Bool )。

当与外部硬件 交互时,这种结构非常方便,因为它可以返回或接受整组参数。因此,我们可以不以非结构化数据集的形式传递数据:

(10, 3.2, [1, 2, 3])

你可以使用明确定义名称的总线:

(temperature = 10, pressure = 3.2, position = [1, 2, 3])

有了 "总线信号 "类型,就可以在模型层面对这种结构进行准确的描述和类型化,这对于正式确定硬件数据接口非常重要。

总线信号 "类型的写法如下:

BusSignal{Names, Types, Dimensions}

在哪里?

  • Names - 信号名元组((:a, :b, :c));

  • Names - 信号名称元组((:a, :b, :c)); Types - 相应类型(Tuple{Int, Float64, Vector{Float64}} );

  • Names` - 信号名称元组((:a, :b, :c)); Dimensions - 每个元素的尺寸(), (), (3, 表示标量和长度为 3 的矢量)。

一个简单的使用示例:

MyBus = BusSignal{(:a, :b), Tuple{Int, Float64}, ((), ())}
data = MyBus((a = 5, b = 6.4))

允许以命名元组和参数的顺序指定值:

MyBus(5, 6.4)            # по позициям
MyBus(a = 5, b = 6.4)    # по именам

轮胎可以嵌套,例如

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

有分析类型的功能:

get_bus_names(type)             # Возвращает кортеж имен сигналов шины
get_bus_types(type)             # Возвращает кортеж типов данных каждого сигнала
get_bus_dimensions(type)        # Возвращает кортеж размерностей каждого сигнала
get_names_types_dims(type)      # Возвращает три кортежа: имена, типы и размерности одновременно
get_bus_signal_type(value)      # Определяет тип BusSignal по значению NamedTuple (автоматический вывод типа)

函数`get_bus_signal_type`特别方便:它可以根据数值自动确定总线类型,如

bus = (a = 5, b = [1.2, 3.4])
bus_type = get_bus_signal_type(bus)
# → BusSignal{(:a, :b), Tuple{Int64, Vector{Float64}}, ((), (2,))}

这一功能在设备块 中得到了积极应用。为了避免手动指定总线类型,此类模块通过掩码 进行配置,在该接口中只需指定信号的名称和数量即可。

下面我们将讨论该方案的工作原理:从掩码参数到设备块内自动形成的 "总线信号"。

设备模块中的用户总线

让我们来看一个例子—​在 UM Cosimulation 设备模块中动态形成`BusSignal`总线类型。该模块的参数如下

hardware bussignal 1

为了自动生成总线类型,只需通过掩码设置输入和输出信号的数量和名称。

为此,请打开程序块掩码(程序块/掩码/视图掩码上的 PCM),进入 "代码编辑器" -> 全局选项卡,在回调blockChangedCallback 中输入以下代码:

engee.set_param!(engee.gcb(), "InputPort1BusType" => "BusSignal{$(mask.parameters.m_input_signal_names.value), NTuple{$(mask.parameters.m_num_input_signals.value), Float64}, ntuple(_ -> (), $(mask.parameters.m_num_input_signals.value))}")
engee.set_param!(engee.gcb(), "OutputPort1BusType" => "BusSignal{$(mask.parameters.m_output_signal_names.value), NTuple{$(mask.parameters.m_num_output_signals.value), Float64}, ntuple(_ -> (), $(mask.parameters.m_num_output_signals.value))}")

在此代码中

  • m_num_input_signals - 输入信号的数量;

  • m_num_output_signals` - 输出信号的数量;

  • m_input_signal_names - 输入信号的名称;

  • m_output_signal_names` - 输出信号名称。

代码使用 gcb() 函数设置当前程序块的路径,然后读取掩码参数 m_input_signal_namesm_num_input_signalsm_output_signal_namesm_num_output_signals`的值。这些值将被用来组成一个字符串表示类型为 `BusSignal 的信号,其中包含给定的信号名称、类型为 Float64、维数为 ()。要读取这些值,必须在程序块 功能 中声明参数名。为此,请进入设备块的设置,点击 看看面具下面 打开 功能 。然后在 Parameters 标签中指定掩码中参数的程序名称:

hardware bussignal 3

然后,函数engee.set_param! 会自动更新 Ports 选项卡上 Input 端口 1 的参数 Output bus type (程序名 InputPort1BusType )和 Output 端口 1 的参数 Output bus type (程序名 OutputPort1BusType ),将生成的总线类型替换为输入和输出端口:

hardware bussignal 4

这样,整个配置过程就简化为填写掩码字段。母线类型自动生成,无需手动编辑*端口*选项卡。这使得该装置方便、适应性强并可重复使用。