Документация 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 такая структура может быть точно описана и типизирована на уровне модели, что важно для формализации интерфейса данных оборудования.

Тип BusSignal записывается следующим образом:

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,))}

Эта функциональность активно применяется в блоках оборудования. Чтобы не задавать типы шин вручную, такие блоки настраиваются масками — интерфейсом, в котором достаточно указать только имена и количество сигналов.

Далее рассмотрим, как работает эта схема: от параметров маски до автоматического формирования BusSignal внутри блока оборудования.

Пользовательские шины в блоках оборудования

Рассмотрим пример — динамическое формирование типов шин BusSignal в блоке оборудования UM Cosimulation. Этот блок имеет следующие параметры:

hardware bussignal 1

Для того чтобы автоматически сформировать типы шин, достаточно задать только количество и имена входных и выходных сигналов через маску.

Для этого откройте маску блока (ПКМ по блоку/Маска/Посмотреть маску), перейти во вкладку «Редактор кода» → Global и в обратном вызове 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_names, m_num_input_signals, m_output_signal_names и m_num_output_signals. Эти значения используются для формирования строкового представления типа BusSignal с заданными именами сигналов, типом Float64 и размерностями (). Чтобы значения считывались — имена параметров необходимо объявить в блоке Engee Function. Для этого перейдите в настройки блока оборудования и нажмите Посмотреть под маску, чтобы открыть Engee Function. Далее на вкладке Parameters укажите программные названия параметров из маски:

hardware bussignal 3

Затем функция engee.set_param! автоматически обновляет параметры Output bus type (программное имя InputPort1BusType) для Input port 1 и Output bus type (программное имя OutputPort1BusType) для Output port 1 на вкладке Ports, подставляя сгенерированные типы шин для входного и выходного портов:

hardware bussignal 4

Таким образом, вся настройка сводится к заполнению полей маски. Типы шин формируются автоматически, без ручного редактирования вкладки Ports. Это делает блок удобным, адаптивным и готовым к повторному использованию.