Идентификация объекта системы управления с нечетким ПИД-регулятором
В этом примере решается сразу две задачи. Во-первых, мы идентифицируем объект управления на основе экспериментальных данных. Во-вторых, реализуем систему нечёткого вывода для ПИД-регулятора.
Pkg.add(["ControlSystemIdentification", "FuzzyLogic"])
using ControlSystemIdentification, FuzzyLogic
Напомню, что рабочий процесс идентификации выглядит следующим образом:
-
Сбор данных эксперимента
-
Выбор структуры модели
-
Идентификация модели
-
Валидация модели
Идентификация объекта управления
Сбор экспериментальных данных с объекта управления
Имитация экспериментальной установки объекта управления представлена в модели plant.engee. Объект управления - это дискретная система с одним входом и одним выходом. Также в модель добавлен шум и небольшое запаздывание.
Идентификация объекта будет производиться по переходному процессу, для этого на вход системы подадим ступеньку.

Запишем данные для идентификации:
mode = 1; # Запись данных для идентификации
if "Plant" in [m.name for m in engee.get_all_models()]
m = engee.open( "Plant" ) # загрузка модели
else
m = engee.load( "Plant.engee" )
end
results = engee.run(m, verbose=true)
dataout = collect(results["out"]);
datain = collect(results["in"]);
# Частота дискретизации системы из вектора времени
Ts = dataout.time[2] - dataout.time[1]
ident_data = iddata(dataout.value, datain.value, Ts)
plot(ident_data)
Запишем данные для валидации модели:
mode = 0; # Запись данных для валидации
if "Plant" in [m.name for m in engee.get_all_models()]
m = engee.open( "Plant" ) # загрузка модели
else
m = engee.load( "Plant.engee" )
end
results = engee.run(m, verbose=true)
dataout = collect(results["out"]);
datain = collect(results["in"]);
# Частота дискретизации системы из вектора времени
Ts = dataout.time[2] - dataout.time[1]
val_data = iddata(dataout.value, datain.value, Ts)
plot(val_data)
Выбор структуры модели и идентификация
Будем идентифицировать линейную стационарную систему в пространстве состояний. Порядок системы выберем равным 3.
Для идентификации выберем метод ошибки прогнозирования PEM ( prediction-error method). Это простой, но эффективный алгоритм идентификации линейных стационарных систем с дискретным временем в форме пространства состояний. Метод также позволяет получить начальные состояния системы.
nx = 3; # порядок системы
sys, x0 = newpem(ident_data,nx)
Валидация модели
Проверим идентификацию на тех же данных, на которых проводилась идентификация
simplot(ident_data, sys)
И проверим на специальном валидационном наборе данных
simplot(val_data, sys)
Метод показал хороший результат идентификации.
Система управления с нечетким ПИД-регулятором
Вернемся к моделированию системы управления с нечетким контроллером. Мы получили модель объекта управления из экспериментальных данных.

Результат идентификации будет использоваться в блоке Дискретное пространство состояний (Discrete State Space) для моделирования объекта управления.

Осталось добавить контроллер в контур системы управления. В этом примере используется следующая структура контроллера с нечёткой логикой:

На вход системы нечеткого вывода поступают нормализованные значения ошибки и производной ошибки . Входные значения нормализуются с помощью коэффициентов масштабирования и так, чтобы они находились в диапазоне [-1,1].
Система нечеткого вывода выдает результат в диапазоне [-1, 1], который масштабируется коэффициентами и .
CE = 10;
CD = 4.9829;
C0 = 2.5179;
C1 = 1.8103;
Система нечеткого вывода представлена в виде блока Табличной функции (Lookup table). Процесс формирования поверхности отклика для этой таблицы показан ниже:
fis = @sugfis function FCtrl(E, delE)::U
E := begin
domain = -10.0:10.0
N = GaussianMF(-10.0, 7.0)
P = GaussianMF(10.0, 7.0)
end
delE := begin
domain = -10.0:10.0
N = GaussianMF(-10.0, 7.0)
P = GaussianMF(10.0, 7.0)
end
U := begin
domain = -20.0:20.0
Min = -20.0
Zero = 0.0
Max = 20.0
end
# Работающие правила
E == N && delE == N --> U == Min
E == N && delE == P --> U == Zero
E == P && delE == N --> U == Zero
E == P && delE == P --> U == Max
end;
plot(fis, :E, ylabel="Функция принадлежности", w = 2)
plot(fis, :delE, ylabel="Функция принадлежности", w = 2)
Сформируем поверхность отклика для того, чтобы поместить ее в блок Табличной функции (Lookup table).
errBrkpts = -10.0:0.5:10.0
rateBrkpts = -10.0:0.5:10.0
LookUpTableData = zeros(length(errBrkpts), length(rateBrkpts))
i = 0;
for e in errBrkpts
i = i+1
j = 0;
for de in rateBrkpts
j = j+1
LookUpTableData[i, j] = fis([e, de])[:U]
end
end
surface(errBrkpts, rateBrkpts, LookUpTableData, xlabel="ΔE", ylabel="E", zlabel="U", title="Поверхность отклика", camera=(30, 30))
Запустим модель системы управления и проверим работу регулятора.
if "Fuzzycontroller" in [m.name for m in engee.get_all_models()]
m = engee.open( "Fuzzycontroller" ) # загрузка модели
else
m = engee.load( "Fuzzycontroller.engee" )
end
fuzzyresults = engee.run(m, verbose=true)
fuzzydataout = collect(fuzzyresults["out"]);
fuzzydatain = collect(fuzzyresults["in"]);
На графики мы видим реакцию системы управления на ступенчатое воздействие.
plot(fuzzydataout.time, fuzzydataout.value, titel = "Система управления с нечетким ПИД-регулятором", label="выход")
plot!(fuzzydatain.time, fuzzydatain.value, label="вход")
Вывод
В результате мы получили работающую систему управления с нечетким ПИД-регулятором. Модель объекта управления не была заранее известна, а получена идентификацией на основе экспериментальных данных.