Conveyor management system
This example continues the development of the pipeline modeling project. Using the Engee Function and Chart blocks, we simulate the movement of loads of various weights on a belt and a conveyor control system based on a programmable logic controller (PLC). Finally, we test the physical model with the control algorithm in real time on the KPM RHYTHM.
Introduction
In the previous example of the project, we calculated and modeled the electrical and mechanical conveyor systems in conditions of varying belt loads. Now it's time to move on to automating the conveyor. At this stage of the project development, we will expand the initial model.:
- 
add an engine braking system, 
- 
we will develop a block for calculating the position and total load of loads on the belt, 
- 
add subsystems: - 
determining the arrival of cargo at the edge of the belt, 
- 
placing new cargo on the belt, 
 
- 
- 
We will develop a conveyor management system. 
The example model
The model of the current example eventually looks like the one shown in the figure below.:
 
Let's consider the model elements in detail below.
Changes in the physical block chain
Dynamic braking circuits have been added to the system of physical blocks - by signal on_off The AC power supply is turned off, and in the next step of the simulation, a constant voltage is applied to the two phases of the motor from the source. Uдт.
Subsystem "Loads on the conveyor"
The main element of the subsystem "Loads on the conveyor" is the [Engee Function] block (https://engee.com/helpcenter/stable/ru/base-lib-user-defined-function/engee-function.html ), in which the Julia code describes the behavior of loads on the tape during the simulation process. This unit receives signals:
- 
"placement of new cargo" (variable in1) - the duration of one simulation step, and the amount of tension of the new load being placed,
- 
"tape movement" (variable in2) is the distance traveled by the conveyor belt since the start of the simulation,
- 
"remove incoming cargo" (variable in3) is a logical signal that serves as a command to remove the cargo that was delivered to the edge of the tape from the description model of the goods on the tape.
At the output of the block, we receive the following signals:
- 
"positions" is a static vector that contains all the values of the current location of the loads associated with the movement of the belt. At the subsystem's output from this vector, the first element corresponding to the load with the largest position value is allocated, i.e., standing furthest from the beginning of the belt. 
- 
"loads" is a vector of static size that contains all the load values from each load corresponding to the "position" vector. 
- 
"total load" - the total amount of load from all loads on the belt. The output of the subsystem is transmitted with a minus sign to form the correct load vector. 
 
Below is the code from the tab Step method Code the Engee Function block with comments to explain how the subsystem works.
 if any(w -> w != 0.0, c.wght) # if there is at least one load on the tape
        idx = findfirst(w -> w == 0.0, c.wght) # we find its index in the vector
        c.pos[1:(idx-1)] = c.pos[1:(idx-1)] .+ (in2 - c.mov[1]) # increase the movement of each load by increments of the belt movement
    end
    
    c.mov[1] = in2 # save the current tape movement
    
    if in3 == true # if you need to remove the first load
        for i in 1:length(c.wght)-1 # moving all loads in the load vector to idx-1
            c.wght[i] = c.wght[i+1]
        end
        c.wght[end] = 0.0
for i in 1:length(c.pos)-1 # moving all weights in the position vector to idx-1
            c.pos[i] = c.pos[i+1]
        end
        c.pos[end] = 0.0
    end
    if (in1 > 0.0) && (0.0 in c.wght) # if a new shipment arrives
        idx = findfirst(w -> w == 0.0, c.wght) 
        c.wght[idx] = in1 # we place his load on the vacant position
        c.pos[idx] = 0.0 # set the position to "0.0"
end
    return c.pos, c.wght, sum(c.wght) # output: vector of positions, loads, total load
Variables c.pos, c.wght, sum(c.wght) they are defined in the block structure and initialized with zero values.
Subsystem "Ultrasonic sensor"
The value of the load position furthest from the beginning of the belt, calculated in the "Loads on the conveyor" block, is transmitted to the "Ultrasonic sensor" subsystem. If the load position is equal to the location of the sensor L, a high-level logical signal "load can be removed" is generated. The location of the sensor L in this example is equal to the distance between the conveyor drums.
 
Subsystem "Cargo placement"
Another auxiliary subsystem is "Cargo placement". In it, according to the "place a new load" signal from the programmable logic controller, a signal with a duration of one simulation step and a random load value in the range previously set in the original example is generated.
 
The received "load from new" signal is then sent to the "loads on the conveyor" subsystem.
Subsystem "Programmable logic controller"
The conveyor control algorithm is defined in the Programmable Logic Controller (PLC) subsystem using the [Chart] block (https://engee.com/helpcenter/stable/ru/state-machines/chart.html ).
The working principle of the algorithm is intuitive, but additionally we will fix the main points.:
- 
There are 2 main processes in the state diagram: - 
Tape movement (condition mov),
- 
Handling cargo removal. 
 
- 
- 
Condition movIt includes three substates:- 
start- performed only at the beginning of the simulation, starts the engine (motor = 0), 1 second after it, the following state turns on:
- 
give- generates a load placement signal (put = 1), immediately after it, the transition to the next state is performed:
- 
wait- removing the load placement signal (put = 1), we form a 3-second wait for a new load to be placed.
 
- 
- 
Cargo removal is handled as follows: - 
if the load sensor is triggered ( sensor == 1), there is a transition to the statestop,
- 
in stopthe engine stops (motor = 1), after 1 second, there will be a transition to the next state:
- 
a signal for the removal of incoming cargo is generated in take ( rem = 1),
- 
Immediately after that, the load removal signal is removed ( rem = 0),
- 
after 1 second, the chart returns to the state mov.
 
- 
 
Let's move on to modeling in Engee.
Modeling in Engee
Let's run the model using software modeling control and pre-prepared functions for ease of working with the model and simulation results:
(example_path = @__DIR__) |> cd; # Получаем абсолютный путь к директории, содержащей текущий скрипт и переходим в неё
include("useful_functions.jl"); # Подключаем скрипт Julia со вспомогательными функциями
simout = get_sim_results("conveyor_control.engee", example_path) #запускаем моделирование
Simulation results - engine
We will receive and reduce the signals recorded in the model, measured on the engine:
t = thin(get_sim_data(simout, "Ток статора", 1, "time"), 100);
Is = thin(get_sim_data(simout, "Ток статора", 1, "value"), 100);
n = thin(get_sim_data(simout, "Обороты (у.е)", 1, "value"), 100);
Let's plot these variables:
gr(fmt=:png, size = (900,400))
I_graph = plot(t, Is; label = "I(t)", title = "Ток статора", ylabel = "I [A]", xlabel = "t [с]")
n_graph = plot(t, n; label = "n(t)", title = "Частота вращения ротора", ylabel = "n [у.е.]", xlabel = "t [с]")
plot(I_graph, n_graph)
If we compare these graphs with those presented in the original example, it can be seen that when a certain load is reached on the engine, after about 50 seconds, the engine begins to stop and start periodically - it stops to remove the load. After starting the engine, the load continues to change due to the addition of new loads to the belt.
Simulation results - pipeline
We will receive and reduce the signals recorded in the model on the conveyor belt:
Vл = thin(get_sim_data(simout, "Скорость ленты", 1, "value"), 100);
Sл = thin(get_sim_data(simout, "Перемещение ленты", 1, "value"), 100);
Let's plot these variables:
V_graph = plot(t, Vл; label = "V(t)", title = "Скорость ленты", ylabel = "V [м/с]", xlabel = "t [с]")
S_graph = plot(t, Sл; label = "S(t)", title = "Перемещение ленты", ylabel = "S [м]", xlabel = "t [с]")
plot(V_graph, S_graph)
The kinematic graphs of the conveyor belt also show stops and moments where the movement does not change, which is necessary to remove the load from the belt.
Simulation results - PLC
We will receive and reduce the signals recorded in the model at the input and output of the PLC:
start_stop = thin(get_sim_data(simout, "старт/стоп двигаталя", 1, "value"), 100);
rem = thin(get_sim_data(simout, "Программируемый логический контроллер.rem", 1, "value"), 100);
pos = map(p -> p[1], thin(get_sim_data(simout, "позиции", 1, "value"), 100)) .>= L;
Let's plot these variables:
plot(t, start_stop; label = "Старт/стоп", width = 2, linestyle=:dot,
        title = "Сигналы контроллера", xlabel = "t [с]", legend = :outerright,
        yticks=([0, 1], ["False", "True"]), st=:steppost)
plot!(t, pos; label = "Груз на месте", width = 1)
plot!(t, rem; label = "Удалить", width = 1)
The controller receives a signal of the cargo's presence, and the controller uses this signal to generate signals of influence on the control object, according to the algorithm.
Finally, before testing the model in a system with a real PLC, we will check the operation of the model in real time.
Real-time simulation
Real-time simulation is available thanks to the integration of Engee and [real-time machine RHYTHM] (https://engee.com/community/catalogs/projects/kpm-ritm-bystryi-start ).
In [early examples](https://engee.com/community/ru/catalogs/projects/a90fd264-cf08-4c7b-93f5-350bd434fee3 It has already been shown how to simulate a control object with an assessment of its performance in hard real time. We have conducted a simulation of our facility with a control system in Engee at KPM RHYTHM, now we will evaluate TET:
Pkg.add(["StatsBase", "Printf"]) # установка необходимых пакетов
import StatsBase.mean, Printf.@printf # импорт необходимых функции и макроса
As a result of real-time modeling, model profiling data was collected, which was subsequently recorded in a file. profile.txt . Add this data to the workspace and thin it out to save memory.
tet = TxtToVec("$(@__DIR__)/profile.txt");  # Получаем вектор значений из файла
tet = filter(t -> t>0, tet);                    # Удаляем артефакты
thintet = thin_vector(tet, 20, 0.2);            # Прореживаем вектор на 95% с отклонением до 20%
StepTime = 1e3; # шаг расчёта модели, мкс
Let's analyze the profiling data.
@printf "Количество точек профилирования: %d\n" length(tet)
@printf "Прореживание: %d --> %d (%.2f %%)\n\n" l1 = length(tet) l2 = length(thintet) (l1-l2)/l1*100
@printf "Минимальное TET:   %.3f мс\n" tet_min = (minimum(tet)/1e6)
@printf "Среднее TET:       %.3f мс\n" tet_mean = (mean(tet)/1e6)
@printf "Максимальное TET:  %.3f мс\n\n" tet_max = (maximum(tet)/1e6)
@printf "Число превышений TET:  %d (%.2f %%)" tet_exc = count(>(StepTime*1e3), tet) tet_exc/l1*100
When evaluating TET, it was revealed that at some points the task execution time is exceeded by up to 480% relative to the calculation step. Let's build a graph of TET changes, check where such rolls appear.
gr(format = :png, legend=:bottomright, title="Время выполнения модели\n на КПМ РИТМ",
    xlabel="Время модели, мс", ylabel="Время выполнения, мкс")
plot(thintet./1000;  label="TET", yaxis=:log, ylims=(10,1e5))
plot!([0, length(thintet)], [StepTime,  StepTime];  label="StepTime",   color=:green)
As can be seen from the TET graph, significant surges occur at certain moments of events in electrical circuits.
For the "combat" application of the model of this example, it will be necessary to refine the model to comply with real time. The following steps can be taken:
- 
optimize the model, 
- 
Adjust the solver, 
- 
increase the computing power of the machine, 
- 
Contact the developers of the blocks that trigger events to upgrade the blocks. 
Conclusion
In this example, we looked at using Engee Function and Chart to develop custom blocks and control systems. We conducted a simulation of a conveyor with cargo delivery systems and accounting for the movement of goods of various weights, as well as a prototype control system. Finally, we conducted a real-time simulation and estimated the task completion time.



