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 [ ]:
# Motor voltage and control system
Udc = 560; Uref = 10;
# Engine Parameters
Ly = 0.00757; Ry = 0.203; In = 370; Imax = 2*In;
# Coefficients of the transfer function of the electric motor circuit
Ky = 1/0.203; Ky = Ly/Ry;
# Coefficients of the thyristor converter transfer function
Ktp = Udc/Uref; Ttp = 0.01;
# Current feedback coefficient
Cbs = Uref/Imax;
# Coefficients of the PI current regulator
Kp = Ty/(2*Ttp*Ktp*Kos/Ry); Ti = Ty/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) # closing the model
        catch err # if there is no model to close and engee.close() is not executed, it will be loaded after catch.
            m = engee.load(joinpath(@__DIR__, "$name.engee")) # loading the model
        end;

    try
        engee.run(m) # launching the model
        catch err # if the model is not loaded and engee.run() is not executed, the bottom two lines after catch will be executed.
            m = engee.load(joinpath(@__DIR__, "$name.engee")) # loading the model
            engee.run(m) # launching the model
        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*, And" "I, And" "Ep, In"], legend = :topright,
    title = "Simulation of the DPT current circuit",
    xlabel = "Time, from", ylabel = "Current, A; emf, V")
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.

Automation of real-time RHYTHM testing

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

Upon successful connection to the RHYTHM, 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 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 = "Time of the calculation step", label = :none,
    xlabel = "The modeling step", ylabel = "Lead time, with")
Out[0]:

Based on the data obtained, we can judge the maintenance of the hard real-time mode during the execution of 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, perform simulations in Engee and on KPM RHYTHM, process simulation results and real-time machine operation data.