Работа с пользовательскими шинами 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. Этот блок имеет следующие параметры:
Для того чтобы автоматически сформировать типы шин, достаточно задать только количество и имена входных и выходных сигналов через маску.
Для этого откройте маску блока (ПКМ по блоку/Маска/Посмотреть маску), перейти во вкладку «Редактор кода» → 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 укажите программные названия параметров из маски:
Затем функция engee.set_param! автоматически обновляет параметры Output bus type (программное имя InputPort1BusType
) для Input port 1 и Output bus type (программное имя OutputPort1BusType
) для Output port 1 на вкладке Ports, подставляя сгенерированные типы шин для входного и выходного портов:
Таким образом, вся настройка сводится к заполнению полей маски. Типы шин формируются автоматически, без ручного редактирования вкладки Ports. Это делает блок удобным, адаптивным и готовым к повторному использованию.