Корректное оформление минимизируемого функционала для Response Optimization
Дорогие друзья!
Рассматривается нелинейная система с двумя входами и двумя выходами с перекрёстными связями. Необходимо настроить два ПИД регулятора так, чтобы отклик на ступенчатое изменение уставки по обоим входам отвечал критерию оптимальности. Критерий оптимальности я записываю в функцию стоимости, например, пусть это будет интеграл абсолютного значения ошибки. Параметрами оптимизации является вектор К = [Kpx Kix Kdx Kpy Kiy Kdy] <- коэффициенты двух ПИДов. Моя первая попытка была использование fmincon с ограниченичем для всех элементов К>=0, однако функция выбирает очень мелкие шаги и ищет минимум где-то очень близко к начальным условиям. Выбор пал на Response Optimization тулбокс.
В качестве DesignVariables я выбираю все элементы К поочерёдно, при этом создается структура DesignVars с шестью элементами, у каждого кроме всех прочих есть поле Value. Далее я указываю свою функцию стоимости в качестве пользовательского сценария. Отмечаю входы/выходы. Краткий псевдокод для функции стоимости такой:
J = function(DesignVars, <ряд переменных для воркспейса модели в Simulink>)
Kpx=DesignVars(i,j).Value; <- i, j потому, что элементы К сортируются по алфавиту, такая же строка для остальных элементов К.
simOut=sim('model',...) <- запуск модели с текущим воркспейсом, на выходе значения на двух выходах и соответствующие уставки
ex=simOut.refx - simOut.x;
ey=simOut.refy - simOut.y;
J=(sum(ex,'all') + sum(ey,'all'))*ts; <- вычисление интеграла, ts - шаг по времени
end
Жму "оптимизировать". Выскакивает ошибка, что я обращаюсь к несуществующему полю Value, а когда я обращаюсь к элементам DesignVars как DesignVars(i,j).Value, мне говорится про то, что индекс вне диапазона.
Я понимаю, что, вероятно, моё описание так себе, но я думаю, что я делаю какую-то концептуальную ошибку в оформлении этой функции стоимости. Я смотрел в документации о том, как написать правильный код функции стоимости https://www.mathworks.com/help/sldo/ug/writing-a-custom-cost-function.html?s_tid=srchtitle
но пример там приведён довольно простой, хотя обращение к полю Value тоже есть.
Пожалуйста, посоветуйте какой-нибудь материал почитать, как подойти к этой проблеме правильно, если я что-то слишком поверхностно описал, пишите.
Ответы
Почему бы GUI не использовать? Нужно именно кодом сделать?
Что, если я хочу использовать не встроенный функционал с интегралом квадрата ошибки (если я правильно помню), а другие индексы типа ITAE
Хммм, не могу сейчас представить, где вы увидели квадрат ошибки, потому что во встроенном функционале все устроено чуть сложнее. Первый раз хорошо начинать с Responce Optimization App, это сэкономит кучу времени. Как минимум в приложении можно накликать какой-нибудь вариант оптимизации, и сгенерировать из этого MATLAB-код. Это гораздо быстрее, чем разбираться в классах по документации, и писать вручную. Там же можно задать пользовательскую функцию стоимости.
https://www.mathworks.com/help/sldo/ug/how-the-optimization-algorithm-formulates-minimization-problems.html раздел tracking problem. Минимизируемый функционал - интегральная l2 норма ошибки.
Вот и вопрос мой, как правильно сформулировать функцию стоимости для этого тулбокса, если я хочу внести некоторые другие переменные в функцию стоимости, например, квадрат управляющего сигнала, который является одним из полей структуры simOut
Здесь описано создание пользовательских требований:
https://www.mathworks.com/help/releases/R2020a/sldo/ug/design-optimization-to-meet-a-custom-objective-using-the-gui.html#d120e15242
Окно Custom Requirements выбрасывает сразу в шаблон кода, который нужно заполнить. Только для работы с кастомным сигналом вместо этого
должно быть что-то такое:
И ещё: как соотнесется написанный мной функционал со встроенным при использовании check against the reference?
если вы про Simulink-блок, то ничего не изменится, он по-прежнему будет выдавать предупреждения, если сигнал вне диапазона.
Спасибо большое! Объясните, если не сложно, в трех словах поля data: почему nominal, что если у 'у' несколько полей, и нет поля Data, a есть Value? Или так не может быть?
y - это вектор, и поэтому у него не может быть полей