Engee 文档
Notebook

以PID控制器为例对控制系统进行建模

在这个例子中,我们将考虑在Engee环境中使用PID控制器控制稳定的二阶对象。 此外,Engee环境中的仿真结果将与Simulink中的仿真结果进行比较。

所研究的控制系统位于pid_controls_tf_stable中。工程师模型:

engee_PID.png

准备和设置

连接必要的库并运行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>.] 

在Engee建模

要在Engee中运行模型,我们需要执行以下操作序列:

  1. 使用Engee API上传模型
  2. 使用相同的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

我们将提取数据进行分析:

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

让我们为仿真结果构建一个图表。:

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

在Simulink中运行仿真

该库用于Engee和MATLAB之间的通信 MATLAB.jl. 该命令负责调用MATLAB脚本和命令 mat. 要运行模拟,请使用以下命令 sim:

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

为了将仿真结果上传到Engee,您首先需要拆卸对象。 out 班级 Simulink.SimulationData (并且不要忘记删除不必要的数据!):

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

我们来看看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

模拟结果比较

让我们比较一下EngeeSimulink中的仿真结果。 首先,我们将把结果的图表叠加在一起:

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

然后,我们计算仿真结果之间的差异。 为此,我们将使用计算的绝对和相对平均误差以及相关性:

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

相关性接近统一,即Simulink和Engee中表征结果的两个向量具有非常强的统计关系,换句话说,它们在值上非常接近,现在我们计算误差。

此外,为了清楚起见,我们将绘制绝对误差图,以可视化整个仿真时间的误差。

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%:

正如我们所看到的,计算误差非常小。

结论

在这个例子中,我们研究了在Engee环境中使用PID控制器控制稳定二阶对象的可能性。 我们还确保Engee在精度上与Matlab相当。

示例中使用的块