Engee documentation
Notebook

Real-time testing automation at KPM RHYTHM

Introduction

This example examines the workflow of testing a model in real time with several automation approaches: software parameterization of the model, simulation management in Engee, simulation results processing, RHYTHM simulation management, and real-time test data collection. In the example of this automation approach, more attention is paid to working with the RHYTHM from Engee through the methods of [working with external equipment] (https://engee.com/helpcenter/stable/ru-en/ritm/working-with-RITM.html ).

The example model

The example model ritm_dcm_current_control reproduces the current control circuit of a DC motor (DCT) of independent excitation. The control object is the DPT armature electrical circuit and a thyristor converter (TP), they are represented by continuous transfer functions - aperiodic links of the first order. A current sensor is installed in the current feedback, which is represented by a proportional link. The control action is a step function. At the initial moment of time, the starting current of the DPT is formed, at a time of 0.5 s, the zero armature current is formed.

The current circuit is set to a modular optimum, the type of regulator is PI. This is a discrete system assembled into a subsystem for subsequent code generation.

image_2.png

In addition to the automatic control system blocks, the model contains the following blocks: Си-функции (RITM-PLOT, RITM-PLOT-1) to display graphs of model variables on the rhythm screen.

Modeling in Engee

The model parameters are defined in the preload function reverse вызовов models, additionally they can be defined in the cell below:

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;

Let's define the name of the model for automating modeling using software control:

In [ ]:
name = "ritm_dcm_current_control";

The following custom function is used to run the simulation.

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

Let's run the simulation, and then we'll do software processing simulation results:

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];

We will display the received signals on the graph:

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

Here, I* is the signal of the set armature current, I is the actual armature current, Ep is the actual EMF TP. By the type of current graph, it can be visually assumed that the transient process corresponds to the setting to the modular optimum. Additional analysis of the transition process beyond the current example is required.

Real-time testing automation for RHYTHM

Let's move on to executing the model on RHYTHM in real time. This step is preceded by the transfer of the control system model to the target device (microcontroller) and full-fledged semi-natural testing (HIL).

Preparation for work

Let's turn on the KPM RHYTHM and get ready to work with it. All the necessary steps for preparation are described in [relevant example] (https://engee.com/community/ru/catalogs/projects/kpm-ritm-bystryi-start ).

We will install a support package for working with external hardware if necessary. Detailed, step-by-step help on connecting Engee to low-level interfaces can be obtained from corresponding примера.

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

Connect the necessary modules for software control KPM RHYTHM:

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

Creating the target platform object:

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"])

Connecting to KPM RHYTHM

We will set the IP address and port number of the target platform by passing the command EngeeDeviceManager.Targets.RITM.set_url 🔗 the created object ritm.

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

If the connection to the RHYTHM is successful, the command EngeeDeviceManager.Targets.RITM_API.isConnected [🔗](https://engee.com/helpcenter/stable/ru-en/ritm/ritm-functions.html#EngeeDeviceManager.Targets.RITM_API.isConnected-Tuple{ (%7D) will return true:

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

Engee's connection to KPM RHYTHM has been established, let's move on to real-time testing automation.

Modeling management

First, upload the model to Engee, and then upload it using the command EngeeDeviceManager.Targets.RITM.upload_model 🔗 on KPM RHYTHM.

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

The download was successful, let's proceed to generating executable code from the model using the command EngeeDeviceManager.Targets.RITM.generate_executable_code 🔗.

The model will run in independent mode (Standalone), therefore, the third attribute of the command takes the value false.

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

The code generation was successful, we will assemble the model for execution on the RHYTHM with the command EngeeDeviceManager.Targets.RITM.compile_model 🔗.

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

According to the received message, the project was assembled successfully, and we will proceed to executing the model in independent mode. The program start of the simulation on the RHYTHM is carried out by the command EngeeDeviceManager.Targets.RITM.start_model 🔗.

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

If successful, as can be seen, there is no error output from the model. Let's move on to collecting and analyzing data from the execution of the RHYTHM model.

Getting simulation results

Team EngeeDeviceManager.Targets.RITM_API.getLog 🔗 returns the specified number of log lines.:

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

In the output of the command, we see the messages that accompanied the execution of the model.

The same logs can be observed on the screen connected to the RHYTHM. Using the command EngeeDeviceManager.Targets.RITM_API.getScreenshot 🔗 take a screenshot of the screen:

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

The screenshot with the specified name is saved in the temporary files folder in the RHYTHM memory. The screenshot file downloaded from the RHYTHM's memory is shown below

model_2.png

In RITM.Monitor The current version of [RTOS] is displayed.The real thing время](https://engee.com/helpcenter/stable/ru/ritm/intro.html#осрв-ритм-реальное-время) , The IP address of KPMG, the name and status of the model, as well as the calculation step and the time of the calculation step, the current and final simulation time. The graphs correspond to those obtained during modeling in Engee.

Using the function EngeeDeviceManager.Targets.RITM_API.readFile 🔗you can output the contents of the file located in the memory of the KPM RHYTHM, and using EngeeDeviceManager.Targets.RITM_API.getFile 🔗 - download this file in Engee.

Let's read it and then get the file. install_manifest.txt from the memory of KPM RHYTHM:

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/

Also, using the command EngeeDeviceManager.Targets.RITM_API.getData 🔗 it is possible to get data from the memory of the KPM RHYTHM, for example - profiling data models. Save them to a file:

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

We will process the obtained model profiling data and display it on a graph.:

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]:

Based on the data obtained, we can judge the maintenance of the hard real-time mode when executing the model.

Conclusion

In this example, we have reviewed sequentially the steps for automating the testing of the Engee model for RHYTHM. Directly in the Engee script, you can calculate the model parameters, run simulations in Engee and on KPM RHYTHM, process simulation results and real-time machine operation data.