Документация Engee
Notebook

Моделирование систем управления на примере ПИД-регулятора

В этом примере мы рассмотрим управление устойчивым объектом второго порядка c помощью ПИД-регулятора в среде Engee. Дополнительно будет проведено сравнение результатов моделирования в среде Engee с результатами моделирования в Simulink.

Исследуемая система управления находится в модели pid_controls_tf_stable.engee:

engee_pid.png

Подготовка и настройка

Подключим необходимые библиотеки и запустим Simulink:

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. Загрузить модель с помощью API Engee
  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

Для связи 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

Сравнение результатов моделирования

Сравним результаты симуляции в 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]:
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%:

Как мы видем погрешность вычислений крайне мала.

Выводы

В этом примере мы рассмотрели возможности управления устойчивым объектом второго порядка c помощью ПИД-регулятора в среде Engee. А так же убедились, что Engee сопоставим по точности с Matlab.

Блоки, использованные в примере