Итеративное обучающее управление
В этом примере будет спроектирована итерационная схема Итеративное обучающее управление (ИОУ). ИОУ можно рассматривать как простую стратегию обучения с подкреплением, которая подходит в ситуациях, когда необходимо многократно выполнять повторяющуюся задачу, и возмущения, действующие на систему, также повторяются и являются предсказуемыми, но неизвестными. Существует несколько версий ИОУ. В этом руководстве мы рассмотрим как эвристическую схему, так и схему, основанную на модели.
Алгоритм
Итерационная схема ИОУ обычно выглядит следующим образом (существует множество вариантов) при итерации ИОУ :
где — оператор сдвига по времени, — передаточная функция от эталонных данных к выходным данным , т. е. обычно замкнутая передаточная функция, — ошибка управления, — корректирующий сигнал ИОУ, аддитивная поправка к эталону, которая учится на протяжении всех итераций ИОУ с целью минимизации ошибки управления. и являются устойчивыми фильтрами, управляющими динамикой обучения. Интересно, что эти фильтры не обязательно должны быть каузальными, поскольку они работают с сигналами и между итерациями ИОУ, когда для акаузальной фильтрации доступны сразу все сигналы.
При моделировании (моделируется развертывание ) эта схема представляет собой не что иное, как стратегию оптимального управления с разомкнутым контуром, а если равносильно проведению реального эксперимента над процессом, ИОУ становится обучением с подкреплением на основе эпизодов или адаптивным управлением.
В данном примере управляемая система представляет собой систему двойной массы с пружиной и демпфером между ними. Эта система представляет собой обычную модель сервосистемы, в которой одна масса представляет собой двигатель, а другая — нагрузку. Пружина и демпфер представляют гибкую передачу между ними. Мы создадим два экземпляра модели системы. представляет собой номинальную модель, а — реальную (неизвестную) динамику. Так имитируется модельный подход, когда в модели имеется небольшая погрешность. Погрешность будет заключаться в массе груза, имитируя, например, тот факт, что с помощью двигателя нужно приводить в движение более тяжелый груз, чем указано.
Модель системы и регулятор
using ControlSystemsBase, Plots
function double_mass_model(;
Jm = 1, # инерция двигателя
Jl = 1, # инерция груза
k = 100, # жесткость
c0 = 1, # демпфирование двигателя
c1 = 1, # демпфирование передачи
c2 = 1, # демпфирование груза
)
A = [
0.0 1 0 0
-k/Jm -(c1 + c0)/Jm k/Jm c1/Jm
0 0 0 1
k/Jl c1/Jl -k/Jl -(c1 + c2)/Jl
]
B = [0, 1/Jm, 0, 0]
C = [1 0 0 0]
ss(A, B, C, 0)
end
G = double_mass_model(Jl = 1)
Gact = double_mass_model(Jl = 1.5) # груз на 50 % больше, чем в модели
bodeplot([G, Gact], lab=["G model" "G actual"], plotphase=false)
Мы разработаем ПИД-регулятор с фильтром для системы. Регулятор плохо настроен и не очень хорошо отслеживает быстрые эталонные ступенчатые сигналы. На практике, вероятно, можно было бы разработать и регулятор с прямой связью, чтобы улучшить этот момент, но пока мы остановимся на простом регуляторе с обратной связью.
C = pid(10, 1, 1, form = :series) * tf(1, [0.02, 1])
Ts = 0.02 # Интервал выборки
Gc = c2d(feedback(G*C), Ts) |> tf
Gcact = c2d(feedback(Gact*C), Ts) |> tf
plot(step(Gc, 10), title="Closed-loop step response", lab="model")
plot!(step(Gcact, 10), lab="actual")
Заданная траектория
Далее мы проектируем заданную траекторию и моделируем реальную динамику замкнутого контура.
T = 3pi # Длительность
t = 0:Ts:T # Вектор времени
function funnysin(x)
x = sin(x)
s,a = sign(x), abs(x)
s*((a + 0.01)^0.2 - 0.01^0.2)
end
r = funnysin.(t)' |> Array # Эталонный сигнал
res = lsim(Gcact, r, t)
plot(res, plotu=true, layout=1, sp=1, title="Closed-loop simulation with actual dynamics", lab=["y" "r"])
Производительность низкая… Используйте ИОУ!
Акаузальная фильтрация
Для корректной работы ИОУ определим две вспомогательные функции. Одну, которая применяет нуль-фазовый фильтр для фильтрации как вперед, так и назад (filtfilt
). Это возможно, поскольку ИОУ работает с сигналами в автономном режиме между итерациями в схеме ИОУ. Мы также определим специальную функцию lsim
, которая работает с некаузальными системами, позволяя «заглядывать» в будущее. Это, как правило, значительно повышает производительность ИОУ, что опять же возможно, поскольку ИОУ работает с заранее записанными сигналами.
function lsim_zerophase(G, u, args...; kwargs...)
res = lsim(G, u[:, end:-1:1], args...; kwargs...)
lsim(G, res.y[:, end:-1:1], args...; kwargs...).y
end
function lsim_noncausal(L::LTISystem{<:Discrete}, u, args...; kwargs...)
np = length(denpoly(L)[])
nz = length(numpoly(L)[])
zeroexcess = nz-np
if zeroexcess <= 0
return lsim(L, u, args...; kwargs...)
end
integrators = tf(1, [1, 0], L.Ts)^zeroexcess
res = lsim(L*integrators, u, args...; kwargs...)
res.y[1:end-zeroexcess] .= res.y[1+zeroexcess:end]
res.y
end
nothing # скрыть
Выбор фильтров
Следующим шагом является определение фильтров ИОУ и .
Фильтр выступает в роли частотно-зависимого шага. Для того чтобы процедура выполнялась с меньшим шагом, достаточно масштабировать по константе < 1. При уменьшении масштаба процесс обучения замедляется, но становится более устойчивым. Эвристическим выбором является некоторая форма масштабированного упреждения, например , где — число выборок упреждения. В подходе на основе модели может использоваться некоторая форма инверсии модели системы, которую мы и будем использовать в данном случае. [^нелинейные]
Фильтр позволяет сделать процедуру устойчивой к шумам и погрешностям моделирования. окончательно решает, какие частоты появятся в , поэтому рекомендуется выбрать с низкочастотными свойствами. Здесь будет применяться в нуль-фазовом режиме, поэтому эффективная передаточная функция будет иметь вид .
z = tf("z", Ts)
Q = c2d(tf(1, [0.05, 1]), Ts)
# L = 0,9z^1 # Более консервативный и эвристический вариант
L = 0.5inv(Gc) # Уменьшение коэффициента масштабирования, чтобы делать меньшие шаги
Теорема Норрлофа гласит, что для сходимости итераций ИОУ необходимо, чтобы выполнялось условие , в чем мы можем убедиться, посмотрев на кривые Боде двух сторон неравенства
bodeplot([inv(Q), (1 - L*Gc)], plotphase=false, lab=["Stability boundary \$Q^{-1}\$" "\$1 - LG\$"])
bodeplot!((1 - L*Gcact), plotphase=false, lab="\$1 - LG\$ actual")
Выше мы построили эту кривую и для реальной динамики. Конечно, это невозможно в реальном сценарии, где эта величина неизвестна, но можно построить график для нескольких правдоподобных моделей и убедиться, что все они находятся ниже границы. Руководство по этому вопросу см. на странице Моделирование неопределенности с помощью RobustAndOptimalControl.jl. Если посмотреть на условие устойчивости, то становится очевидным, как малая величина в условиях неопределенности модели благоприятно сказывается на надежности схемы ИОУ.
Итерация ИОУ
Следующим шагом является реализация схемы ИОУ и ее выполнение:
function ilc(Gc, Q, L)
a = zero(r) # Сигнал регулировки ИОУ начинается с 0
fig = plot(t, vec(r), sp=1, layout=(3,1), l=(:black, 3), lab="Ref")
for iter = 1:5
ra = r .+ a
res = lsim(Gc, ra, t) # Моделирование системы, заменяемое реальным экспериментом при работе в реальном процессе
y = res.y # Отклик системы
e = r .- y # Погрешность
Le = lsim_noncausal(L, e, t)
a = lsim_zerophase(Q, a + Le, t) # Обновление корректировки ИОУ
plot!(res, plotu=true, sp=[1 2], title=["Output \$y(t)\$" "Adjusted reference \$r + a\$"], lab="Iter $iter", c=iter)
plot!(e[:], sp=3, title="Tracking error \$e(t)\$", lab="err: $(round(sum(abs2, e), digits=2))", c=iter)
end
fig
end
ilc(Gc, Q, L)
При выполнении в модели результат выглядит очень хорошо. Видно, что погрешность отслеживания на последнем графике быстро уменьшается и становится значительно меньше уже через пару итераций. Отметим также, что скорректированный эталон фактически немного сдвинут по фазе, чтобы компенсировать запаздывание в динамике системы. Это эффект акаузальной фильтрации, обусловленной .
Как это работает в «реальной» динамике?
ilc(Gcact, Q, L)
Результат несколько хуже, но с учетом достаточно большой погрешности модели итог все равно неплохой.
Сводка
Мы узнали, как ИОУ можно использовать для повышения эффективности отслеживания в сценарии, когда повторяющаяся задача должна быть выполнена несколько раз. При моделировании, как в данном случае, ИОУ можно рассматривать как стратегию оптимального управления, направленную на поиск оптимальной эталонной траектории для минимизации ошибки управления, а при реализации в физическом процессе эта схема является простым, но эффективным подходом к обучению с подкреплением или адаптивному управлению. ИОУ часто очень хорошо работает на практике и применяется, в частности, в робототехнике и механообработке.
Эффективность ИОУ снижается, если стохастические возмущения определяют особенности управления или задача должна быть выполнена небольшое количество раз. Например, при механической обработке каждая итерация ИОУ может привести к разрушительной обработке дорогостоящего материала с неоптимальным результатом до сходимости. Экономическая эффективность достигается только в том случае, если после первоначальной настройки с помощью ИОУ задача будет выполняться многократно.