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:
Preparing and setting up¶
Connect the necessary libraries and start Simulink:
Pkg.add(["Statistics"])
using Plots
using MATLAB
using Statistics
gr( fmt=:png )
mat"start_simulink"
Modelling in Engee¶
To run a model in Engee we need to perform the following sequence of actions:
- Load the model using the Engee API
- Run the simulation using the same API
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 )
Let's extract the data to analyse it:
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:
plot(PID_res_e_t , PID_res_e_d, legend = false)
plot!(title = "Результаты моделирования в Engee", ylabel = "Отклик", xlabel="Время, c")
Running the simulation in Simulink¶
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
:
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!):
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:
pid_values = mat"traj.Data";
pid_times = mat"traj.Time";
plot(pid_times, pid_values, legend = false)
plot!(title = "Результаты моделирования в Simulink", ylabel = "Отклик", xlabel="Время, c")
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:
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")
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:
println("Корреляция: ", cor(pid_values, PID_res_e_d))
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.
difference = pid_values - PID_res_e_d;
plot(difference)
println("Средняя абсолютная погрешность вычислений: ", abs(mean(difference)));
println("Средняя относительная погрешность вычислений: ", abs(mean(filter(!isnan,(difference)./pid_values)))*100, "%:");
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.