Документация Engee
Notebook

Автоматизация тестирования в реальном времени на КПМ РИТМ

Введение

В этом примере рассматривается рабочий процесс тестирования модели в реальном времени с несколькими подходами к автоматизации: программное параметрирование модели, управление моделированием в Engee, обработка результатов симуляции, управление моделированием на РИТМ, сбор данных тестирования в реальном времени. Большее внимание в примере такого подхода к автоматизации уделено работе с РИТМ из Engee посредством методов работы с внешним оборудованием.

Модель примера

Модель примера ritm_dcm_current_control воспроизводит контур регулирования тока двигателя постоянного тока (ДПТ) независимого возбуждения. Объект управления - электрическая цепь якоря ДПТ и тиристорный преобразователь (ТП), они представлены непрерывными передаточными функциями - апериодическими звеньями первого порядка. В обратной связи по току установлен датчик тока, который представлен пропорциональным звеном. Управляющее воздействие - ступенчатая функция. В начальный момент времени формируется пусковой ток ДПТ, в момент времени 0.5 с - формируется нулевой ток якоря.

Контур тока настроен на модульный оптимум, тип регулятора - ПИ. Это дискретная система, собранная в подсистему для последующей генерации кода.

image_2.png

Кроме блоков системы автоматического управления, в модели присутствуют блоки Си-функции (RITM-PLOT, RITM-PLOT-1) для вывода графиков переменных модели на экран РИТМа.

Моделирование в Engee

Параметры модели определены в функции предзагрузки обратных вызовов модели, дополнительно их можно определить в ячейке ниже:

In [ ]:
# Напряжение двигателя и системы управления
Udc = 560; Uref = 10;
# Параметры двигателя
 = 0.00757;  = 0.203;  = 370; Imax = 2*;
# Коэффициенты передаточной функции электрической цепи двигателя
 = 1/0.203;  = /;
# Коэффициенты передаточной функции тиристорного преобразователя
Kтп = Udc/Uref; Tтп = 0.01;
# Коэффициент обратной связи по току
Kос = Uref/Imax;
# Коэффициенты ПИ-регулятора тока
Kp = /(2*Tтп*Kтп*Kос/); Ti = /Kp;

Определим имя модели для автоматизации моделирования при помощи программного управления:

In [ ]:
name = "ritm_dcm_current_control";

Следующая пользовательская функция используется для запуска моделирования.

In [ ]:
"""
Function by @mikhailpetrov
"""
function start_model_engee(name::String)
    try
        engee.close(name, force=true) # закрытие модели 
        catch err # в случае, если нет модели, которую нужно закрыть и engee.close() не выполняется, то будет выполнена её загрузка после catch
            m = engee.load(joinpath(@__DIR__, "$name.engee")) # загрузка модели
        end;

    try
        engee.run(m) # запуск модели
        catch err # в случае, если модель не загружена и engee.run() не выполняется, то будут выполнены две нижние строки после catch
            m = engee.load(joinpath(@__DIR__, "$name.engee")) # загрузка модели
            engee.run(m) # запуск модели
        end
end
Out[0]:
start_model_engee

Запустим моделирование, после чего проведём программную обработку результатов симуляции:

In [ ]:
start_model_engee(name)
data = collect(simout);
t = collect(data[1].time)[:,1];
Iref = collect(data[1].value)[:,1];
Ep = collect(data[2].value)[:,1];
I = collect(data[3].value)[:,1];

Выведем на график полученные сигналы:

In [ ]:
gr()
plot(t, [Iref.*(Imax/Uref), I, Ep],
    label = ["I*, А" "I, А" "Ep, В"], legend = :topright,
    title = "Моделирование контура тока ДПТ",
    xlabel = "Время, с", ylabel = "Ток, А; эдс, В")
Out[0]:

Здесь, I* - сигнал заданного тока якоря, I - фактического тока якоря, Ep - фактического эдс ТП. По виду графика тока можно визуально предположить, что переходный процесс соответствует настройке на модульный оптимум. Требуется дополнительная аналитика переходного процесса, выходящая за рамки текущего примера.

Автоматизация тестирования в реальном времени на РИТМ

Перейдём к выполнению модели на РИТМ в реальном времени. Такой шаг предваряет перенос модели системы управления на целевое устройство (микроконтроллер) и полноценное полунатурное тестирование (HIL).

Подготовка к работе

Включим КПМ РИТМ и подготовимся к работе с ним. Все необходимые шаги для подготовки описаны в соответствующем примере.

Установим пакет поддержки для работы с внешним оборудованием при необходимости. Подробную, пошаговую справку по подключению Engee к низкоуровневым интерфейсам можно получить из соответствующего примера.

In [ ]:
# Engee.Package.install("Engee-Device-Manager")

Подключим необходимые модули для программного управления КПМ РИТМ:

In [ ]:
using Main.EngeeDeviceManager.Targets
using Main.EngeeDeviceManager.Targets.RITM_API

Создадим объект целевой платформы:

In [ ]:
ritm = Targets.RITM.Ritm()
Out[0]:
Main.EngeeDeviceManager.Targets.RITM.Ritm("Ritm", UUID("e206f345-42f3-4902-bb12-a102420135d2"), ["set_url", "get_access_token", "is_connected", "generate_executable_code", "compile_model", "upload_model", "start_model", "start_stream", "stop_model", "get_running_model", "read_file", "get_file", "get_files_list", "model_mem_info", "fetch_log_ritmpipe", "is_running", "get_ritm_screenshot", "get_profiling_data"])

Подключение к КПМ РИТМ

Зададим IP-адрес и номер порта целевой платформы, передав команде EngeeDeviceManager.Targets.RITM.set_url 🔗 созданный объект ritm.

In [ ]:
Targets.RITM_API.setUrl(ritm, "http://192.168.56.3:8000/")

При успешном подключении к РИТМу команда EngeeDeviceManager.Targets.RITM_API.isConnected 🔗 вернёт true:

In [ ]:
RITM_API.isConnected(ritm)
Out[0]:
true

Соединение Engee с КПМ РИТМ установлено, перейдём к автоматизации тестирования в реальном времени.

Управление моделированием

Сначала загрузим модель в Engee, после чего загрузим её при помощи команды EngeeDeviceManager.Targets.RITM.upload_model 🔗 на КПМ РИТМ.

In [ ]:
model = engee.load(joinpath(@__DIR__, "$name.engee"))
Targets.upload_model(ritm, model)
Out[0]:
TargetResponse("success", nothing)

Загрузка прошла успешно, перейдём к генерации исполняемого кода из модели при помощи команды EngeeDeviceManager.Targets.RITM.generate_executable_code 🔗.

Модель будет выполняться в независимом режиме (Standalone), поэтому третий атрибут команды принимает значение false.

In [ ]:
Targets.generate_executable_code(ritm, model, false)
Out[0]:
TargetResponse("Code generated successfully", nothing)

Генерация кода прошла успешно, соберём модель для выполнения на РИТМ командой EngeeDeviceManager.Targets.RITM.compile_model 🔗.

In [ ]:
Targets.compile_model(ritm, model)
Out[0]:
TargetResponse("Model compiled successfully", nothing)

Согласно полученному сообщению, сборка проекта прошла успешно, перейдём к выполнению модели в независимом режиме. Программный запуск моделирования на РИТМ осуществляется командой EngeeDeviceManager.Targets.RITM.start_model 🔗.

In [ ]:
Targets.start_model(ritm, model)

В случае успешного выполнения, как видно, отсутствует вывод ошибок из модели. Перейдём к сбору и анализу данных выполнения модели на РИТМ.

Получение результатов моделирования

Команда EngeeDeviceManager.Targets.RITM_API.getLog 🔗 возвратит нам заданное число строк лога:

In [ ]:
println(RITM_API.getLog(ritm, 13))
** starting model ritm_dcm_current_control (Standalone)
2025-25-06 09:16:58.605 | Expected non-existent /builds/0/RITM_Team/Julia-RealTime/julia to be your Julia directory.
Certain functionality will be disabled.
To fix this, try deleting Revise's cache files in ~/.julia/compiled/v1.10/Revise, then restart Julia and load Revise.
If this doesn't fix the problem, please report an issue at https://github.com/timholy/Revise.jl/issues.
2025-25-06 09:17:02.399 | Using arrays or dicts to store parameters of different types can hurt performance.
Consider using tuples instead.
; maxlog = 1
2025-25-06 09:17:04.136 | Using arrays or dicts to store parameters of different types can hurt performance.
Consider using tuples instead.
; maxlog = 1
Profiling data stored.
** stopping model ritm_dcm_current_control

В выводе команды мы видим сообщения, сопровождавшие выполнение модели.

Те же логи можно наблюдать на экране, подключенном к РИТМу. При помощи команды EngeeDeviceManager.Targets.RITM_API.getScreenshot 🔗 сделаем скриншот экрана:

In [ ]:
RITM_API.getScreenshot(ritm, "model.png")
Out[0]:
"/tmp/model.png"

Скриншот с заданным именем сохраняется в папке временных файлов в памяти РИТМа. Скачанный из памяти РИТМа файл скриншота приведён ниже

model_2.png

В RITM.Monitor отображается текущая версия ОСРВ РИТМ.Реальное время, IP-адрес КПМ РИТМ, имя и статус модели, а также шаг расчёта и время выполнения шага расчёта, текущее и конечное время симуляции. Графики соотетствуют тем, что были получены при моделировании в Engee.

При помощи функции EngeeDeviceManager.Targets.RITM_API.readFile 🔗можно вывести содержимое файла, находящегося в памяти КПМ РИТМ, а при помощи EngeeDeviceManager.Targets.RITM_API.getFile 🔗 - скачать этот файл в Engee.

Прочитаем, а затем получим файл install_manifest.txt из памяти КПМ РИТМ:

In [ ]:
RITM_API.readFile(ritm, "install_manifest.txt"; path = "/home/ritm/build/$name/build/")
Out[0]:
"/home/ritm/run/ritm_dcm_current_control.elf"
In [ ]:
RITM_API.getFile(ritm, "install_manifest.txt"; from = "/home/ritm/build/$name/build/", to = @__DIR__)
/user/start/examples/devices/ritm_dc_motor_current_control/

Также, при помощи команды EngeeDeviceManager.Targets.RITM_API.getData 🔗 есть возможность получить данные из памяти КПМ РИТМ, например - данные профилирования модели. Сохраним их в файл:

In [ ]:
RITM_API.getData(ritm, "$name", @__DIR__, true)
[ Info: Данные с профилированием модели были записаны в файл: ritm_dcm_current_control.txt

Полученные данные профилирования модели обработаем и выведем на график:

In [ ]:
profiling = parse.(Int64, split(strip(read(joinpath(@__DIR__, "$name.txt"), String)), '\n')).*1e-9;
gr()
plot(profiling;
    title = "Время выполнения шага расчёта", label = :none,
    xlabel = "Шаг моделирования", ylabel = "Время выполнения, с")
Out[0]:

По полученным данным мы можем судить о поддержании режима жёсткого реального времени при выполнении модели.

Заключение

В этом примере мы рассмотрели последовательно шаги для автоматизации тестирования модели Engee на РИТМ. Непосредственно в скрипте Engee можно рассчитать параметры модели, провести моделирование в Engee и на КПМ РИТМ, обработать результаты симуляции и данные работы машины реального времени.