以PID控制器为例对控制系统进行建模
在这个例子中,我们将考虑在Engee环境中使用PID控制器控制稳定的二阶对象。 此外,Engee环境中的仿真结果将与Simulink中的仿真结果进行比较。
所研究的控制系统位于pid_controls_tf_stable中。工程师模型:
准备和设置
连接必要的库并运行Simulink:
In [ ]:
Pkg.add(["Statistics"])
In [ ]:
using Plots
using MATLAB
using Statistics
gr( fmt=:png )
mat"start_simulink"
在Engee建模
要在Engee中运行模型,我们需要执行以下操作序列:
- 使用Engee API上传模型
- 使用相同的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]:
我们将提取数据进行分析:
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]:
在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]:
模拟结果比较
让我们比较一下Engee和Simulink中的仿真结果。 首先,我们将把结果的图表叠加在一起:
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]:
然后,我们计算仿真结果之间的差异。 为此,我们将使用计算的绝对和相对平均误差以及相关性:
In [ ]:
println("Корреляция: ", cor(pid_values, PID_res_e_d))
相关性接近统一,即Simulink和Engee中表征结果的两个向量具有非常强的统计关系,换句话说,它们在值上非常接近,现在我们计算误差。
此外,为了清楚起见,我们将绘制绝对误差图,以可视化整个仿真时间的误差。
In [ ]:
difference = pid_values - PID_res_e_d;
In [ ]:
plot(difference)
Out[0]:
In [ ]:
println("Средняя абсолютная погрешность вычислений: ", abs(mean(difference)));
In [ ]:
println("Средняя относительная погрешность вычислений: ", abs(mean(filter(!isnan,(difference)./pid_values)))*100, "%:");
正如我们所看到的,计算误差非常小。
结论
在这个例子中,我们研究了在Engee环境中使用PID控制器控制稳定二阶对象的可能性。 我们还确保Engee在精度上与Matlab相当。



