Engee documentation
Notebook

Modeling of control systems using the example of a PID controller

In this example, we will consider the control of a stable second-order object using a PID controller in the Engee environment. Additionally, the simulation results in the Engee environment will be compared with the simulation results in Simulink.

The control system under study is located in the pid_controls_tf_stable.engee model:

engee_PID.png

Preparation and setup

Connect the necessary libraries and run Simulink:

In [ ]:
Pkg.add(["Statistics"])
In [ ]:
using Plots
using MATLAB
using Statistics
gr( fmt=:png )

mat"start_simulink"
>> [Warning: MATLAB has disabled some advanced graphics rendering features by
switching to software OpenGL. For more information, click <a
href="matlab:opengl('problems')">here</a>.] 

Modeling in Engee

To run the model in Engee, we will need to perform the following sequence of actions:

  1. Upload the model using the Engee API
  2. Run the simulation using the same API
In [ ]:
modelName = "pid_controls_tf_stable";
PID_model = modelName in [m.name for m in engee.get_all_models()] ? engee.open( modelName ) : engee.load( "$(@__DIR__)/$(modelName).engee");

results = engee.run( modelName )
Out[0]:
Dict{String, DataFrames.DataFrame} with 2 entries:
  "out" => 200001×2 DataFrame…
  "ref" => 200001×2 DataFrame

We will extract the data for their analysis:

In [ ]:
PID_res_e_t = results["out"].time;
PID_res_e_d = results["out"].value;

Let's build a graph for the simulation results.:

In [ ]:
plot(PID_res_e_t , PID_res_e_d, legend = false)
plot!(title = "Результаты моделирования в Engee", ylabel = "Отклик", xlabel="Время, c")
Out[0]:
No description has been provided for this image

Running simulations in Simulink

The library is used for communication between Engee and MATLAB MATLAB.jl. The command is responsible for calling MATLAB scripts and commands mat. To run the simulation, use the command sim:

In [ ]:
mat"cd $(@__DIR__)"
mat"out = sim('pid_controls_tf_stable');";

In order to upload the simulation results to Engee, you first need to disassemble the object. out class Simulink.SimulationData (and don't forget to delete unnecessary data!):

In [ ]:
mat""" res = out.yout;
       sig = res.getElement(1);
       assignin('base',sig.Name,sig.Values)
       clear res sig
   """

Let's look at the simulation results in Simulink:

In [ ]:
pid_values = mat"traj.Data";
pid_times = mat"traj.Time";

plot(pid_times, pid_values, legend = false) 
plot!(title = "Результаты моделирования в Simulink", ylabel = "Отклик", xlabel="Время, c")
Out[0]:
No description has been provided for this image

Comparison of simulation results

Let's compare the simulation results in Engee and Simulink. First, we will overlay the graphs of the results on top of each other:

In [ ]:
plot(PID_res_e_t,PID_res_e_d, label = "Engee")
plot!(title = "Сравнение результатов моделирования")
plot!(pid_times, pid_values, label = "Simulink")
plot!(legend = :outertopright,ylabel = "Отклик", xlabel="Время, c")
Out[0]:
No description has been provided for this image

Then, we calculate the discrepancy between the simulation results. To do this, we will use both absolute and relative average errors of calculations, as well as correlation:

In [ ]:
println("Корреляция: ", cor(pid_values, PID_res_e_d))
Корреляция: 1.0

The correlation is close to unity, that is, the two vectors characterizing the results in Simulink and Engee have a very strong statistical relationship, in other words, they are very close in values, now we calculate the errors.

Also, for clarity, we will plot the absolute error graph to visualize the error for the entire simulation time.

In [ ]:
difference = pid_values - PID_res_e_d;
In [ ]:
plot(difference)
Out[0]:
No description has been provided for this image
In [ ]:
println("Средняя абсолютная погрешность вычислений: ", abs(mean(difference)));
Средняя абсолютная погрешность вычислений: 1.9695099104476718e-17
In [ ]:
println("Средняя относительная погрешность вычислений: ", abs(mean(filter(!isnan,(difference)./pid_values)))*100, "%:"); 
Средняя относительная погрешность вычислений: 1.81497090313774e-15%:

As we can see, the calculation error is extremely small.

Conclusions

In this example, we examined the possibilities of controlling a stable second-order object using a PID controller in the Engee environment. We also made sure that Engee is comparable in accuracy to Matlab.

Blocks used in example