nlmpcmoveCodeGeneration

Вычисление нелинейных перемещений MPC управления с поддержкой генерации кода

Описание

пример

[mv,newOnlineData] = nlmpcmoveCodeGeneration(coreData,x,lastMV,onlineData) вычисляет оптимальные нелинейные движения MPC управления и поддерживает генерацию кода для развертывания к целям в реальном времени. Движения управления вычисляются с использованием текущих состояний модели предсказания (x), управление переходит от предыдущего контрольного интервала (lastMV) и структуры входных данных (coreData и nlOnlineData) сгенерирован с использованием getCodeGenerationData.

nlmpcmoveCodeGeneration не проверяет входные параметры на правильные размерности и типы данных.

[___,info] = nlmpcmoveCodeGeneration(___) возвращает дополнительную информацию о результате оптимизации, включая количество итераций и стоимость целевой функции.

Примеры

свернуть все

Создайте нелинейный контроллер MPC с четырьмя состояниями, двумя выходами и одним входом.

nlobj = nlmpc(4,2,1);
In standard cost function, zero weights are applied by default to one or more OVs because there are fewer MVs than OVs.

Укажите шаг расчета и горизонты контроллера.

Ts = 0.1;
nlobj.Ts = Ts;
nlobj.PredictionHorizon = 10;
nlobj.ControlHorizon = 5;

Задайте функцию состояния для контроллера, которая находится в файле pendulumDT0.m. Эта модель в дискретном времени интегрирует модель в непрерывном времени, заданную в pendulumCT0.m использование многостадийного прямого метода Эйлера.

nlobj.Model.StateFcn = "pendulumDT0";
nlobj.Model.IsContinuousTime = false;

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

nlobj.Model.NumberOfParameters = 1;
params = {Ts};

Задайте выходную функцию модели, передав параметр времени расчета как входной параметр.

nlobj.Model.OutputFcn = "pendulumOutputFcn";

Задайте стандартные ограничения для контроллера.

nlobj.Weights.OutputVariables = [3 3];
nlobj.Weights.ManipulatedVariablesRate = 0.1;
nlobj.OV(1).Min = -10;
nlobj.OV(1).Max = 10;
nlobj.MV.Min = -100;
nlobj.MV.Max = 100;

Проверьте функции модели предсказания.

x0 = [0.1;0.2;-pi/2;0.3];
u0 = 0.4;
validateFcns(nlobj,x0,u0,[],params);
Model.StateFcn is OK.
Model.OutputFcn is OK.
Analysis of user-provided model, cost, and constraint functions complete.

Только два из состояний объекта можно измерить. Поэтому создайте расширенный фильтр Калмана для оценки четырех состояний объекта. Его функция перехода к состоянию задана в pendulumStateFcn.m и его функция измерения определена в pendulumMeasurementFcn.m.

EKF = extendedKalmanFilter(@pendulumStateFcn,@pendulumMeasurementFcn);

Задайте начальные условия для симуляции, инициализируйте расширенное состояние фильтра Калмана и задайте нуль начальный манипулированное значение переменных.

x0 = [0;0;-pi;0];
y0 = [x0(1);x0(3)];
EKF.State = x0;
mv0 = 0;

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

[coreData,onlineData] = getCodeGenerationData(nlobj,x0,mv0,params);

Задайте значение выхода ссылки в интерактивной структуре данных.

onlineData.ref = [0 0];

Чтобы проверить операцию контроллера, запустите симуляцию для 10 секунд. Во время каждого контрольного интервала:

  1. Исправьте предыдущее предсказание с помощью измерения тока.

  2. Вычисление оптимального управления перемещается с помощью nlmpcmoveCodeGeneration. Эта функция возвращает вычисленные оптимальные последовательности в onlineData. Передача обновленной структуры данных в nlmpcmoveCodeGeneration в следующем контрольном интервале обеспечивают начальные догадки для оптимальных последовательностей.

  3. Спрогнозируйте состояния модели.

  4. Примените первое вычисленное оптимальное перемещение управления к объекту, обновляя состояния объекта.

  5. Сгенерируйте данные датчика с белым шумом.

  6. Сохраните состояния объекта.

mv = mv0;
y = y0;
x = x0;
Duration = 10;
xHistory = x0;
for ct = 1:(Duration/Ts)
    % Correct previous prediction
    xk = correct(EKF,y);
    % Compute optimal control move
    [mv,onlineData] = nlmpcmoveCodeGeneration(coreData,xk,mv,onlineData);
    % Predict prediction model states for the next iteration
    predict(EKF,[mv; Ts]);
    % Implement first optimal control move
    x = pendulumDT0(x,mv,Ts);
    % Generate sensor data
    y = x([1 3]) + randn(2,1)*0.01;
    % Save plant states
    xHistory = [xHistory x];
end

Сгенерируйте MEX-функцию с Coder™ MATLAB ®, определяя coreData как константа.

func = 'nlmpcmoveCodeGeneration';
funcOutput = 'nlmpcmoveMEX';
Cfg = coder.config('mex');
Cfg.DynamicMemoryAllocation = 'off';
codegen('-config',Cfg,func,'-o',funcOutput,'-args',...
    {coder.Constant(coreData),xk,mv,onlineData});
Code generation successful.

Входные параметры

свернуть все

Нелинейные параметры конфигурации MPC, которые являются постоянными во время исполнения, заданы как структура, сгенерированная с помощью getCodeGenerationData.

Примечание

При использовании codegen (MATLAB Coder), coreData должно быть определено как coder.Constant (MATLAB Coder).

Текущие состояния модели предсказания, заданные как вектор длины Nx, где Nx - количество состояний модели предсказания. Функция состояния модели предсказания задана в nlobj.Model.StateFcn.

Поскольку нелинейный контроллер MPC не выполняет оценку состояния, необходимо либо измерить, либо оценить текущие состояния модели предсказания на каждом контрольном интервале. Для получения дополнительной информации о нелинейных моделях прогнозирования MPC, смотрите Задайте Модель Предсказания для нелинейного MPC.

Управляющие сигналы, используемые в объекте в предыдущем контрольном интервале, задаются как вектор-столбец длины Nmv, где Nmv - количество манипулируемых переменных.

Примечание

Задайте lastMV как управляемые сигналы переменной, примененные к объекту в предыдущем контрольном интервале. Обычно эти сигналы являются значениями, генерируемыми контроллером (mv). Однако это не всегда так. Например, если ваш контроллер работает в автономном режиме и работает в режиме отслеживания; то есть контроллер выход не управляет объектом, затем подает фактический сигнал управления на last_mv может помочь достичь бесшумной передачи, когда контроллер переключается обратно в оперативном режиме.

Данные сетевого контроллера, которые необходимо обновить во время выполнения, заданные как структура со следующими полями. Сгенерируйте начальную структуру используя getCodeGenerationData. Некоторые поля структуры не требуются, в зависимости от строения контроллера и от того, какие веса или ограничения варьируются во время выполнения.

Объект выходные ссылки значения, заданные как вектор-строка длины Ny или массив с Ny столбцами, где Ny - количество переменных выходов.

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

Чтобы изменить значения ссылок на горизонте предсказания от времени k + 1 до времени k + p, задайте массив с до p строками. Здесь k - текущее время, а p - горизонт предсказания. Каждая строка содержит ссылочные значения для одного шага горизонта предсказания. Если вы задаете меньше p строк, значения в последней строке используются для остальных шагов горизонта предсказания.

Если ваша функция стоимости контроллера не использует ref, оставить ref по его значению по умолчанию.

Манипулируемые переменные цели, заданные как вектор-строка длины Nmv или массив с Nmv столбцами, где Nmv - количество манипулируемых переменных.

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

Чтобы изменять цели над горизонтом предсказания (предварительный просмотр) время k от времени k + p -1, задайте массив с до p строками. Здесь k - текущее время, а p - горизонт предсказания. Каждая строка содержит цели для одного шага горизонта предсказания. Если вы задаете меньше p строк, конечные цели используются для остальных шагов горизонта предсказания.

Если ваша функция стоимости контроллера не использует mvTarget, оставить mvTarget по его значению по умолчанию.

Начальные догадки для оптимальных решений состояния, заданные как вектор-строка длины Nx или массив с Nx столбцами, где Nx - количество состояний.

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

Чтобы изменить начальные догадки над горизонтом предсказания от времени k + 1 до времени k + p, задайте массив с до p строками. Здесь k - текущее время, а p - горизонт предсказания. Каждая строка содержит начальные предположения для одного шага горизонта предсказания. Если вы задаете меньше p строк, конечные догадки используются для остальных шагов горизонта предсказания.

В целом, во время симуляции с обратной связью вы не задаете X0 сам. Вместо этого при вызове nlmpcmoveCodeGeneration, верните newOnlineData выходной аргумент, содержащий обновленные X0 оценки. Затем можно пройти newOnlineData в качестве onlineData входной параметр в nlmpcmoveCodeGeneration для следующего контрольного интервала.

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

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

Чтобы варьировать начальные догадки над горизонтом предсказания от времени k времени k + p -1, задайте массив с до p строками. Здесь k - текущее время, а p - горизонт предсказания. Каждая строка содержит начальные предположения для одного шага горизонта предсказания. Если вы задаете меньше p строк, конечные догадки используются для остальных шагов горизонта предсказания.

В целом, во время симуляции с обратной связью вы не задаете MV0 сам. Вместо этого при вызове nlmpcmoveCodeGeneration, верните newOnlineData выходной аргумент, содержащий обновленные MV0 оценки. Затем можно пройти newOnlineData в качестве onlineData входной параметр в nlmpcmoveCodeGeneration для следующего контрольного интервала.

Начальное предположение для переменной slack в решении, заданное как неотрицательный скаляр.

В целом, во время симуляции с обратной связью вы не задаете Slack0 сам. Вместо этого при вызове nlmpcmoveCodeGeneration, верните newOnlineData выходной аргумент, содержащий обновленные Slack0 оценки. Затем можно пройти newOnlineData в качестве onlineData входной параметр в nlmpcmoveCodeGeneration для следующего контрольного интервала.

Измеренные нарушения порядка значения, заданные как вектор-строка длины Nmd или массив с Nmd столбцами, где Nmd - количество измеренных нарушений порядка. Если ваш контроллер имеет измеренные нарушения порядка, вы должны задать md. Если у вашего контроллера нет измеренных нарушений порядка, то getCodeGenerationData опускает это поле.

Чтобы использовать те же нарушения порядка значения на горизонте предсказания, задайте вектор-строку.

Чтобы варьировать значения нарушения порядка по горизонту предсказания от времени k времени k + p, задайте массив с до p + 1 строками. Здесь k - текущее время, а p - горизонт предсказания. Каждая строка содержит значения нарушения порядка для одного шага горизонта предсказания. Если вы задаете меньше p строк, значения в последней строке используются для остальных шагов горизонта предсказания.

Значения параметров, используемые моделью предсказания, пользовательской функцией стоимости и пользовательскими ограничениями, заданные как вектор камеры с длиной, равной Model.NumberOfParameters свойство контроллера. Если у контроллера нет параметров, то getCodeGenerationData опускает это поле.

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

Выход веса настройки переменных, которые заменяют веса настройки по умолчанию во время исполнения, заданные как вектор-строка длины Ny или массив с Ny столбцами, где Ny количество переменных выходов. Если вы ожидаете, что веса выходных переменных изменятся во время исполнения, необходимо добавить это поле к онлайн-структуре данных при вызове getCodeGenerationData.

Чтобы использовать те же веса на горизонте предсказания, задайте вектор-строку.

Чтобы варьировать веса над горизонтом предсказания от времени k + 1 до времени k + p, задайте массив с до p строками. Здесь k - текущее время, а p - горизонт предсказания. Каждая строка содержит веса для одного шага горизонта предсказания. Если вы задаете меньше p строк, конечные веса используются для остальных шагов горизонта предсказания.

Манипулируемые веса настройки переменных, которые заменяют веса настройки по умолчанию во время выполнения, заданные как вектор-строка длины Nmv или массив с Nmv столбцами, где Nmv - количество манипулируемых переменных. Если вы ожидаете, что ваши манипулируемые веса переменных будут варьироваться во время исполнения, необходимо добавить это поле к онлайн-структуре данных при вызове getCodeGenerationData.

Чтобы использовать те же веса на горизонте предсказания, задайте вектор-строку.

Чтобы варьировать веса над горизонтом предсказания от времени k + 1 до времени k + p, задайте массив с до p строками. Здесь k - текущее время, а p - горизонт предсказания. Каждая строка содержит веса для одного шага горизонта предсказания. Если вы задаете меньше p строк, конечные веса используются для остальных шагов горизонта предсказания.

Манипулируемые веса настройки переменной скорости, которые заменяют веса настройки по умолчанию во время выполнения, заданные как вектор-строка длины Nmv или массив с Nmv столбцами, где Nmv - количество манипулируемых переменных. Если вы ожидаете, что ваши манипулируемые веса переменной скорости будут варьироваться во время исполнения, необходимо добавить это поле к онлайн-структуре данных при вызове getCodeGenerationData.

Чтобы использовать те же веса на горизонте предсказания, задайте вектор-строку.

Чтобы варьировать веса над горизонтом предсказания от времени k + 1 до времени k + p, задайте массив с до p строками. Здесь k - текущее время, а p - горизонт предсказания. Каждая строка содержит веса для одного шага горизонта предсказания. Если вы задаете меньше p строк, конечные веса используются для остальных шагов горизонта предсказания.

Уменьшите вес настройки переменной скорости, который заменяет значение по умолчанию во время исполнения, заданное как положительная скалярная величина. Если вы ожидаете, что ваш вес переменной ослабления будет варьироваться во время исполнения, необходимо добавить это поле к онлайн-структуре данных при вызове getCodeGenerationData.

Выход переменные нижние границы, которые заменяют нижние границы по умолчанию во время исполнения, заданные как вектор-строка длины Ny или массив с Ny столбцами, где Ny количество переменных выходов. Если вы ожидаете, что ваши выходные переменные нижние границы будут варьироваться во время исполнения, необходимо добавить это поле к онлайн-структуре данных при вызове getCodeGenerationData.

Чтобы использовать те же границы между горизонтом предсказания, задайте вектор-строку.

Чтобы изменить границы над горизонтом предсказания от времени k + 1 до времени k + p, задайте массив с до p строками. Здесь k - текущее время, а p - горизонт предсказания. Каждая строка содержит ограничения для одного шага горизонта предсказания. Если вы задаете меньше p строк, конечные границы используются для остальных шагов горизонта предсказания.

Выход верхние границы, которые заменяют верхние границы по умолчанию во время исполнения, заданные как вектор-строка длины Ny или массив с Ny столбцами, где Ny количество переменных выходов. Если вы ожидаете, что ваши верхние границы выходной переменной изменятся во время исполнения, необходимо добавить это поле к онлайн-структуре данных при вызове getCodeGenerationData.

Чтобы использовать те же границы между горизонтом предсказания, задайте вектор-строку.

Чтобы изменить границы над горизонтом предсказания от времени k + 1 до времени k + p, задайте массив с до p строками. Здесь k - текущее время, а p - горизонт предсказания. Каждая строка содержит ограничения для одного шага горизонта предсказания. Если вы задаете меньше p строк, конечные границы используются для остальных шагов горизонта предсказания.

Состояния нижних границ, которые заменяют нижние границы по умолчанию во время исполнения, заданные как вектор-строка длины Nx или массив с Nx столбцами, где Nx количество состояний. Если вы ожидаете, что нижние границы вашего состояния изменятся во время исполнения, необходимо добавить это поле к онлайн-структуре данных при вызове getCodeGenerationData.

Чтобы использовать те же границы между горизонтом предсказания, задайте вектор-строку.

Чтобы изменить границы над горизонтом предсказания от времени k + 1 до времени k + p, задайте массив с до p строками. Здесь k - текущее время, а p - горизонт предсказания. Каждая строка содержит ограничения для одного шага горизонта предсказания. Если вы задаете меньше p строк, конечные границы используются для остальных шагов горизонта предсказания.

Верхние границы состояния, которые заменяют верхние границы по умолчанию во время выполнения, заданные как вектор-строка длины Nx или массив с Nx столбцами, где Nx количество состояний. Если вы ожидаете, что верхние границы вашего состояния изменятся во время исполнения, необходимо добавить это поле к онлайн-структуре данных при вызове getCodeGenerationData.

Чтобы использовать те же границы между горизонтом предсказания, задайте вектор-строку.

Чтобы изменить границы над горизонтом предсказания от времени k + 1 до времени k + p, задайте массив с до p строками. Здесь k - текущее время, а p - горизонт предсказания. Каждая строка содержит ограничения для одного шага горизонта предсказания. Если вы задаете меньше p строк, конечные границы используются для остальных шагов горизонта предсказания.

Манипулируемые нижние границы переменной, которые заменяют нижние границы по умолчанию во время исполнения, заданные как вектор-строка длины Nmv или массив с Nmv столбцами, где Nmv - количество манипулируемых переменных. Если вы ожидаете, что ваши манипулируемые переменные нижние границы будут варьироваться во время исполнения, необходимо добавить это поле к онлайн-структуре данных при вызове getCodeGenerationData.

Чтобы использовать те же границы между горизонтом предсказания, задайте вектор-строку.

Чтобы изменить границы над горизонтом предсказания от времени k + 1 до времени k + p, задайте массив с до p строками. Здесь k - текущее время, а p - горизонт предсказания. Каждая строка содержит ограничения для одного шага горизонта предсказания. Если вы задаете меньше p строк, конечные границы используются для остальных шагов горизонта предсказания.

Манипулируемые верхние границы переменной, которые заменяют верхние границы по умолчанию во время исполнения, заданные как вектор-строка длины Nmv или массив с Nmv столбцами, где Nmv - количество манипулируемых переменных. Если вы ожидаете, что ваши манипулируемые верхние границы переменной изменятся во время исполнения, необходимо добавить это поле к онлайн-структуре данных при вызове getCodeGenerationData.

Чтобы использовать те же границы между горизонтом предсказания, задайте вектор-строку.

Чтобы изменить границы над горизонтом предсказания от времени k + 1 до времени k + p, задайте массив с до p строками. Здесь k - текущее время, а p - горизонт предсказания. Каждая строка содержит ограничения для одного шага горизонта предсказания. Если вы задаете меньше p строк, конечные границы используются для остальных шагов горизонта предсказания.

Манипулируемые более низкие границы переменной скорости, которые заменяют нижние границы по умолчанию во время исполнения, заданные как вектор-строка длины Nmv или массив с Nmv столбцами, где Nmv - количество манипулируемых переменных. Если вы ожидаете, что ваши манипулируемые более низкие ограничения переменной скорости будут варьироваться во время исполнения, необходимо добавить это поле к онлайн-структуре данных при вызове getCodeGenerationData.

Чтобы использовать те же границы между горизонтом предсказания, задайте вектор-строку.

Чтобы изменить границы над горизонтом предсказания от времени k + 1 до времени k + p, задайте массив с до p строками. Здесь k - текущее время, а p - горизонт предсказания. Каждая строка содержит ограничения для одного шага горизонта предсказания. Если вы задаете меньше p строк, конечные границы используются для остальных шагов горизонта предсказания.

Манипулируемые верхние границы переменной скорости, которые заменяют верхние границы по умолчанию во время исполнения, заданные как вектор-строка длины Nmv или массив с Nmv столбцами, где Nmv - количество манипулируемых переменных. Если вы ожидаете, что ваши манипулируемые верхние границы скорости изменятся во время исполнения, необходимо добавить это поле к онлайн-структуре данных при вызове getCodeGenerationData.

Чтобы использовать те же границы между горизонтом предсказания, задайте вектор-строку.

Чтобы изменить границы над горизонтом предсказания от времени k + 1 до времени k + p, задайте массив с до p строками. Здесь k - текущее время, а p - горизонт предсказания. Каждая строка содержит ограничения для одного шага горизонта предсказания. Если вы задаете меньше p строк, конечные границы используются для остальных шагов горизонта предсказания.

Выходные аргументы

свернуть все

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

Если решатель сходится к локальному оптимальному решению (info.ExitFlag положительно), тогда mv содержит оптимальное решение.

Если решатель достигает максимального количества итераций, находит допустимое неоптимальное решение (info.ExitFlag = 0) и:

  • coredata.usesuboptimalsolution является true, затем mv содержит неоптимальное решение

  • coredata.usesuboptimalsolution является false, затем mv содержит lastMV

Если решатель не может найти возможное решение (info.ExitFlag отрицательно), тогда mv содержит lastMV.

Обновленные онлайн- контроллером данные, возвращенные как структура. Эта структура такая же, как и onlineData, за исключением того, что переменная принятия решения начальная догадки (X0, MV0, и Slack0) обновляются.

Для последующих контрольных интервалов теплый запуск решателя путем изменения оперативных данных в newOnlineData и передачи обновленной структуры в nlmpcmoveCodeGeneration как onlineData. Это позволяет решателю использовать начальные догадки переменной принятия решений в качестве начальной точки для своего решения.

Подробные данные решения, возвращенные как структура со следующими полями.

Оптимальная манипулированная последовательность переменных, возвращенная как (p + 1) -by - Nmv массив, где p - горизонт предсказания, а Nmv - количество манипулированных переменных.

MVopt(i,:) содержит вычисленные оптимальные манипулированные значения переменных во времени k+i-1, для i = 1,...,p, где k - текущее время. MVopt(1,:) содержит те же манипулированные значения переменных, что и выходной аргумент mv. Поскольку контроллер не вычисляет оптимальные движения управления в момент времени k+p, MVopt(p+1,:) равно MVopt(p,:).

Оптимальная последовательность состояний модели предсказания, возвращенная как (p + 1) -by - Nx массив, где p - горизонт предсказания, а Nx - количество состояний в модели предсказания.

Xopt(i,:) содержит вычисленные значения состояния во время k+i-1, для i = 2,...,p+1, где k - текущее время. Xopt(1,:) совпадает с текущими состояниями в x.

Оптимальная выходная последовательность переменной, возвращенная как массив (p + 1) -by - Ny, где p - горизонт предсказания, а Ny - количество выходов.

Yopt(i,:) содержит вычисленные выходные значения в то время k+i-1, для i = 2,...,p+1, где k - текущее время. Yopt(1,:) вычисляется на основе текущих состояний в x и измеренные по току нарушения порядка в md, если таковые имеются.

Временная последовательность горизонта предсказания, возвращенная как вектор-столбец длины p + 1, где p - горизонт предсказания. Topt содержит временную последовательность от времени k до времени k + p, где k - текущее время.

Topt(1) = 0 представляет текущее время. Последующие временные шаги Topt(i) являются Ts*(i-1), где Ts - шаг расчета контроллера.

Использование Topt при построении графика MVopt, Xopt, или Yopt последовательности.

Ослабьте переменную в оптимуме, ε, используемый в ограничительном смягчении, возвращенном как неотрицательное скалярное значение.

  • .r= 0 - Все мягкие ограничения выполняются на протяжении всего горизонта предсказания.

  • .r> 0 - нарушается по крайней мере одно мягкое ограничение. Когда больше чем одно ограничение нарушено, ε представляет худший случай мягкое нарушение ограничений (измеренный Вашими значениями ECR для каждого ограничения).

Код выхода оптимизации, возвращенный как одно из следующего:

  • Положительное целое число - Найдено оптимальное решение

  • 0 - Допустимое неоптимальное решение, найденное после максимального количества итераций

  • Отрицательное целое число - не найдено возможного решения

Количество итераций, используемых решателем, возвращаемое как положительное целое число.

Стоимость целевой функции, возвращенная как неотрицательное скалярное значение. Стоимость определяет степень достижения контроллером своих целей.

Значение стоимости имеет значение только при ExitFlag неотрицательная.

Расширенные возможности

.
Введенный в R2020a