Engee documentation
Notebook

Modelling of control systems on the example of 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 results of the Engee simulation will be compared with the results of the Simulink simulation.

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

engee_pid.png

Preparing and setting up

Connect the necessary libraries and start 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>.] 

Modelling in Engee

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

  1. Load 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

Let's extract the data to analyse it:

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

Let's construct a graph for the results of the modelling:

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

The library MATLAB.jl is used to link Engee and MATLAB. The command mat is responsible for calling MATLAB scripts and commands. To run the simulation we use the command sim:

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

In order to load the results of the simulation into Engee, we first need to disassemble the out object of Simulink.SimulationData class (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 let's superimpose the plots of the results on 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 will calculate the discrepancy between the simulation results. For this purpose, we will use both absolute and relative average calculation errors, as well as correlation:

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

The correlation is close to unity, i.e. the two vectors characterising the results in Simulink and Engee have a very strong statistical relationship, in other words they are very close in values, now let us calculate the errors.

Also, for clarity, let's plot the absolute error to visualise the error over the whole 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 error of calculations is extremely small.

Conclusions

In this example we have considered the possibilities of controlling a stable second-order object with PID controller in Engee environment. We have also seen that Engee is comparable in accuracy to Matlab.

Blocks used in example