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

Синтез регулятора

Пример из вебинара "Возможности Engee для моделирования Систем управления"

In [ ]:
using ControlSystems

Способы соединения систем

In [ ]:
W1 = tf(10, [9, 0.04, 0.01]);
W2 = tf(15, [2, 0.01, 0.7]);
Последовательное соединение
Послед.png
In [ ]:
W = W1 * W2
Out[0]:
TransferFunction{Continuous, ControlSystemsBase.SisoRational{Float64}}
                                  150.0
-------------------------------------------------------------------------
18.0s^4 + 0.17s^3 + 6.320399999999999s^2 + 0.0281s + 0.006999999999999999

Continuous-time transfer function model
In [ ]:
W = series(W1, W2)
Out[0]:
TransferFunction{Continuous, ControlSystemsBase.SisoRational{Float64}}
                                                150.0
------------------------------------------------------------------------------------------------------
18.0s^4 + 0.16999999999999998s^3 + 6.320399999999999s^2 + 0.028099999999999997s + 0.006999999999999999

Continuous-time transfer function model
Параллельное соединение
паралл.png
In [ ]:
W = W1 + W2
Out[0]:
TransferFunction{Continuous, ControlSystemsBase.SisoRational{Float64}}
                         155.0s^2 + 0.7s + 7.15
-------------------------------------------------------------------------
18.0s^4 + 0.17s^3 + 6.320399999999999s^2 + 0.0281s + 0.006999999999999999

Continuous-time transfer function model
In [ ]:
W = parallel(W1, W2)
Out[0]:
TransferFunction{Continuous, ControlSystemsBase.SisoRational{Float64}}
                         155.0s^2 + 0.7s + 7.15
-------------------------------------------------------------------------
18.0s^4 + 0.17s^3 + 6.320399999999999s^2 + 0.0281s + 0.006999999999999999

Continuous-time transfer function model

Последовательный регулятор

В первом примере воспользуемся частотными характеристиками, чтобы подобрать последовательный регулятор.

image.png
Объект управления
In [ ]:
s = tf("s")
sys = (1s+2)/(0.2*s^2 +1.2*s+1)
Out[0]:
TransferFunction{Continuous, ControlSystemsBase.SisoRational{Float64}}
    1.0s + 2.0
-------------------
0.2s^2 + 1.2s + 1.0

Continuous-time transfer function model
Характеристики Объекта управления
In [ ]:
p1 = ControlSystems.marginplot(sys)
p2 = plot(stepinfo(step(feedback(sys),0:0.01:5); settling_th=0.05), legend=:bottomright)
plot(p1, p2, layout = (1, 2))
Out[0]:
Требования:
  • Отсутствие статической ошибки
  • Перерегулирование <15%
  • Время переходного процесса <2 с
  • Запас по фазе >60°
Регулятор - интегрирующее звено

Система с нулевым порядком астатизма, поэтому для того, чтобы удовлетворить требованию отсутствия статической ошибки, для начала добавим в качестве регулятора интегрирующее звено:

In [ ]:
controller = 1/s
p1 = ControlSystems.marginplot(sys*controller)
p2 = plot(stepinfo(step(feedback(sys*controller),0:0.01:10); settling_th=0.05), legend=:bottomright)
plot(p1, p2, layout = (1, 2))
Out[0]:
Регулятор - интегрирующее звено + Коэффициент усиления

Система стала точной. Но она довольно медленная, поэтому добавим коэффициент усиления.

In [ ]:
k = 5.6 # @param {type:"slider",min:0,max:10,step:0.1}
controller = k*1/s
p1 = ControlSystems.marginplot(sys*controller)
p2 = plot(stepinfo(step(feedback(sys*controller),0:0.01:5); settling_th=0.05), legend=:bottomright)
plot(p1, p2, layout = (1, 2))
Out[0]:
Регулятор - интегрирующее звено + Коэффициент усиления + Последовательное корректирующее устройство с опережением по фазе

Осталось увеличить запас по фазе. Необходимо изменить наклон ЛАЧХ в области средних частот, чтобы повысить устойчивость системы. Для этого добавим последовательное корректирующее устройство с опережением по фазе.

In [ ]:
wz = 6.6 # @param {type:"slider",min:1,max:10,step:0.1}
wp = 20.6 # @param {type:"slider",min:1,max:100,step:0.1}
k = 6.8 # @param {type:"slider",min:0,max:10,step:0.1}
controller = k*1/s*(s+wz)/(s+wp)
p1 = ControlSystems.marginplot(sys*controller)
ControlSystems.bodeplot!(sys*k*1/s)
p2 = plot(stepinfo(step(feedback(sys*controller),0:0.01:5); settling_th=0.05), legend=:bottomright)
annotate!(p2, 2, 0.8, text("Регулятор = $k*s*(s + "* string(round(1/wz, digits=3))*")/(s + "*string(round(1/wp, digits=3))*")", :left, 8, :black))
plot(p1, p2, layout = (1, 2))
Out[0]:

Получившиеся параметры регулятора можно использовать и в модели, например в блоке Нули и полюса передаточной функции. Вы можете убедиться в этом, изучив модель synthesis.engee.

ПИД-регулятор

In [ ]:
using EngeeControlSystems
ПИД-регулятор в параллельной форме
In [ ]:
kp = 1.0
ki = 1.0
kd = 1.0
Tf = 0.01
pid_prl = Pid(kp, ki, kd, Tf) # непрерывный ПИД-регулятор с фильтром первого порядка
Out[0]:
Pid(1.0, 1.0, 1.0, 0.01, nothing, nothing, nothing)
ПИД-регулятор в стандартной форме
In [ ]:
kp = 1.0
ti = 1.0
td = 1.0
n = 100
ts = 0.01
pid_std = PidStd(kp, ti, td, n, ts) # дискретный ПИД-регулятор с фильтром первого порядка
Out[0]:
PidStd(1.0, 1.0, 1.0, 100.0, 0.01, :forward_euler, :forward_euler)
In [ ]:
discr = c2d(pid_prl, ts)
Out[0]:
Pid(1.0, 1.0, 1.5819767068693265, 0.015819767068693265, 0.01, :forward_euler, :forward_euler)
In [ ]:
d2c(discr)
Out[0]:
Pid(1.0, 1.0, 1.0, 0.01, nothing, nothing, nothing)
In [ ]:
Ts_new = 0.02
d2d(pid_std, Ts_new)
Out[0]:
PidStd(1.0, 1.0, 2.0, 100.0, 0.02, :forward_euler, :forward_euler)
Автонастройка ПИД-регулятора
In [ ]:
pi_c, info = pidtune(sys, :pi, :parallel)
Out[0]:
(Pid(0.3258464350718974, 3.352296639805523, 0.0, 0.0, nothing, nothing, nothing), (true, 3.2914794672549705, 59.999999999999986))
In [ ]:
Wzam = feedback(pi_c*sys)
t = 0:0.005:12.0
plot(stepinfo(step(Wzam, t)))
Out[0]:
In [ ]:
Wraz = pi_c*sys
ControlSystems.marginplot(Wraz)
Out[0]:

Результат работы функции pidtune можно использовать в модели, например в параметрах блока ПИД регулятор: Пропорциональный коэффициент: pi_c.kp и Интегральный коэффициент: pi_c.ki. Пример показан в модели synthesis.engee.