В этом примере показано, как настроить параметры в ссылочных моделях, используя sdo.optimize
команда.
Модель показывает управление угловым положением для двух двигателей. Откройте модель Simulink.
open_system('sdoMultipleMotors')
Управление осуществляется двумя двигателями. Модели-ссылки используются для контроллеров, которые являются образцами одной модели. Откройте контроллер.
open_system('sdoRateLimitedController')
Два двигателя в основной модели имеют различные характеристики, поэтому каждый контроллер должен быть адаптирован к своему двигателю. Каждый контроллер имеет коэффициенты ПИД Kp
, Ki
, и Kd
, и скорость нарастания, Slew
. The Slew
значение ограничивает скорость, с которой изменяется сигнал управления. The Slew
значение является общим для обоих образцов контроллера. Напротив, коэффициенты ПИД должен быть различным для каждого образца контроллера, поскольку управляемые двигатели имеют различные характеристики. Поэтому коэффициенты ПИД заданы как аргументы модели в рабочем пространстве модели контроллера. Значения коэффициента ПИД устанавливаются на уровне sdoMultipleMotors
модель.
Управляющий опорный сигнал является шагом изменения положения, которое происходит через 1 секунду. Угловое положение каждого мотора должно следовать за опорным сигналом, но первый двигатель имеет меньший момент инерции и может быстрее реагировать на изменения в опорном сигнале. Кроме того, производная от каждого сигнала контроллера должна быть ограничена, так что токи, вытянутые из источника степени, остаются в пределах источника степени.
Задайте переменные проекты, которые будут настроены стандартной программой оптимизации порядка чтобы удовлетворить требования. The Slew
переменная задается как sdoRateLimitedController:Slew
, что указывает на то, что переменная установлена на уровне sdoRateLimitedController
модель. Двоеточие является разделителем между моделью и переменной. The Slew
переменная имеет то же значение для всех образцов моделей контроллеров. В противоположность этому пропорциональная составляющая для первого контроллера задаётся как sdoMultipleMotors/Control_1:Kp
, что указывает на то, что переменная установлена на уровне sdoMultipleMotors
модель, где она появляется в Control_1
блок. Прямая косая черта является разделителем для блокпутей Simulink.
Задайте, чтобы конструктивные переменные включали коэффициент усиления Kp
, Ki
, и Kd
, для обоих ПИД-регуляторов. Также включите скорость нарастания, Slew
, что является общим для обоих контроллеров. Наконец, задайте, что скорость нарастания не может быть отрицательной.
DesignVars = sdo.getParameterFromModel('sdoMultipleMotors', ... {'sdoRateLimitedController:Slew', ... ... 'sdoMultipleMotors/Control_1:Kp', ... 'sdoMultipleMotors/Control_1:Ki', ... 'sdoMultipleMotors/Control_1:Kd', ... ... 'sdoMultipleMotors/Control_2:Kp', ... 'sdoMultipleMotors/Control_2:Ki', ... 'sdoMultipleMotors/Control_2:Kd' }); DesignVars(1).Minimum = 0;
Угол углового положения каждого мотора должен следовать за опорным сигналом, но первый двигатель имеет меньший момент инерции и может быстрее реагировать на изменения в опорном сигнале. Мы хотим, чтобы угловое положение первого мотора удовлетворяло следующим требованиям:
Время нарастания: 2 секунд
Время урегулирования: 7 секунд
Это требование задано в блоке проверки переходной характеристики в модели Simulink. Мы можем обратиться к блоку и включить требование в переменную, которая будет передана в целевую функцию оптимизации.
Requirements = struct;
bnds = getbounds('sdoMultipleMotors/Motor1_Step_Response');
Requirements.Motor1_StepResponse = bnds{1};
Второй двигатель имеет больший момент инерции, поэтому он не может реагировать так быстро. Мы хотим, чтобы угловое положение второго мотора удовлетворяло следующим требованиям:
Время нарастания: 8 секунд
Время урегулирования: 10 секунд
Это требование также задано в блоке проверки переходной характеристики в модели Simulink, и мы ссылаемся на блок, чтобы включить требование в переменную, которая будет передана в целевую функцию оптимизации.
bnds = getbounds('sdoMultipleMotors/Motor2_Step_Response');
Requirements.Motor2_StepResponse = bnds{1};
Кроме того, производная каждого сигнала контроллера должна быть в области значений от -5 до 5, так что токи, вытянутые из источника степени, остаются в пределах источника степени. Эти требования заданы в связанных проверочных блоках в модели Simulink, и эти требования также должны быть собраны среди требований, которые должны быть переданы в целевую функцию оптимизации.
bnds = getbounds('sdoMultipleMotors/ReqBounds_Derivative_Controller1'); Requirements.Controller1_DerivBound1 = bnds{1}; Requirements.Controller1_DerivBound2 = bnds{2}; bnds = getbounds('sdoMultipleMotors/ReqBounds_Derivative_Controller2'); Requirements.Controller2_DerivBound1 = bnds{1}; Requirements.Controller2_DerivBound2 = bnds{2};
Предотвратите значения контрольных блоков во время оптимизации.
CheckBlockStatus = sdo.setCheckBlockEnabled('sdoMultipleMotors','off');
Функция стоимости требует сценария симуляции, чтобы запустить модель. Создайте сценарий симуляции и добавьте сигналы модели в журнал, чтобы их значения были доступны функции затрат.
Simulator = sdo.SimulationTest('sdoMultipleMotors');
Угловое положение двигателя должно регистрироваться во время оптимизации, чтобы оценить требования к их переходным характеристикам.
Motor1_Position = Simulink.SimulationData.SignalLoggingInfo; Motor1_Position.BlockPath = 'sdoMultipleMotors/Motor1_Step_Response/u'; Motor1_Position.LoggingInfo.LoggingName = 'Motor1_Position'; Motor1_Position.LoggingInfo.NameMode = 1; Motor2_Position = Simulink.SimulationData.SignalLoggingInfo; Motor2_Position.BlockPath = 'sdoMultipleMotors/Motor2_Step_Response/u'; Motor2_Position.LoggingInfo.LoggingName = 'Motor2_Position'; Motor2_Position.LoggingInfo.NameMode = 1;
Производные сигнала контроллера также должны быть записаны, чтобы оценить связанные требования к ним.
Controller1_Derivative = Simulink.SimulationData.SignalLoggingInfo; Controller1_Derivative.BlockPath = 'sdoMultipleMotors/ReqBounds_Derivative_Controller1/u'; Controller1_Derivative.LoggingInfo.LoggingName = 'Controller1_Derivative'; Controller1_Derivative.LoggingInfo.NameMode = 1; Controller2_Derivative = Simulink.SimulationData.SignalLoggingInfo; Controller2_Derivative.BlockPath = 'sdoMultipleMotors/ReqBounds_Derivative_Controller2/u'; Controller2_Derivative.LoggingInfo.LoggingName = 'Controller2_Derivative'; Controller2_Derivative.LoggingInfo.NameMode = 1;
Чтобы записать эти сигналы во время оптимизации, соберите их в сценарий симуляции, Simulator
.
Simulator.LoggingInfo.Signals = [... Motor1_Position ; ... Motor2_Position ; ... Controller1_Derivative ; ... Controller2_Derivative ];
Создайте целевую функцию, которая будет вызываться при каждой итерации оптимизации, чтобы оценить требования проекта по мере настройки конструктивных переменных. Эта функция затрат имеет входные параметры для переменных проекта, сценария симуляции и требований проекта.
type sdoMultipleMotors_Design
function Vals = sdoMultipleMotors_Design(P,Simulator,Requirements) %SDOMULTIPLEMOTORS_DESIGN Objective function for multiple motors % % Function called at each iteration of the optimization problem. % % The function is called with the model named mdl, a set of parameter % values, P, a Simulator, and the design Requirements to evaluate. It % returns the objective value and constraint violations, Vals, to the % optimization solver. % % See the sdoExampleCostFunction function and sdo.optimize for a more % detailed description of the function signature. % % See also sdoMultipleMotors_cmddemo % Copyright 2018 The MathWorks, Inc. %% Model Evaluation % Simulate the model. Simulator.Parameters = P; Simulator = sim(Simulator); % Retrieve logged signal data. SimLog = find(Simulator.LoggedData, get_param('sdoMultipleMotors','SignalLoggingName')); Motor1_Position = find(SimLog,'Motor1_Position'); Motor2_Position = find(SimLog,'Motor2_Position'); Controller1_Derivative = find(SimLog,'Controller1_Derivative'); Controller2_Derivative = find(SimLog,'Controller2_Derivative'); % Evaluate the design requirements. Cleq_Motor1_StepResponse = evalRequirement(Requirements.Motor1_StepResponse, Motor1_Position.Values); Cleq_Motor2_StepResponse = evalRequirement(Requirements.Motor2_StepResponse, Motor2_Position.Values); Cleq_Controller1_DerivBound1 = evalRequirement(Requirements.Controller1_DerivBound1, Controller1_Derivative.Values); Cleq_Controller1_DerivBound2 = evalRequirement(Requirements.Controller1_DerivBound2, Controller1_Derivative.Values); Cleq_Controller2_DerivBound1 = evalRequirement(Requirements.Controller2_DerivBound1, Controller2_Derivative.Values); Cleq_Controller2_DerivBound2 = evalRequirement(Requirements.Controller2_DerivBound2, Controller2_Derivative.Values); %% Return Values. % % Collect the evaluated design requirement values in a structure to % return to the optimization solver. Vals.Cleq = [... Cleq_Motor1_StepResponse(:); ... Cleq_Motor2_StepResponse(:); ... Cleq_Controller1_DerivBound1(:); ... Cleq_Controller1_DerivBound2(:); ... Cleq_Controller2_DerivBound1(:); ... Cleq_Controller2_DerivBound2(:)]; end
Чтобы оптимизировать, задайте указатель на функцию затрат, которая использует Simulator
и Requirements
определено выше. Используйте анонимную функцию, которая принимает один аргумент (переменные проекта) и вызывает целевую функцию. Наконец, вызовите sdo.optimize, чтобы оптимизировать переменные проекты, чтобы попытаться удовлетворить требования.
optimfcn = @(P) sdoMultipleMotors_Design(P, Simulator, Requirements); [Optimized_DesignVars, Info] = sdo.optimize(optimfcn, DesignVars);
Optimization started 27-Jan-2021 14:57:48 max First-order Iter F-count f(x) constraint Step-size optimality 0 15 0 211.8 1 30 0 8.464 2.92 26.5 2 50 0 6.531 0.396 15.1 3 70 0 1.931 0.675 15.7 4 85 0 0.2419 1.67 41.2 5 100 0 0.04524 0.271 1.02e+03 6 110 0 0.04524 0.00399 0 Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance.
Восстановите значения контрольных блоков.
sdo.setCheckBlockEnabled('sdoMultipleMotors', CheckBlockStatus);
Обновите модель с оптимизированными значениями параметров.
sdo.setValueInModel('sdoMultipleMotors',Optimized_DesignVars);
Закройте модели.
bdclose('sdoMultipleMotors') bdclose('sdoRateLimitedController')