В этом примере показано, как к настройкам параметров в моделях, на которые ссылаются, с помощью sdo.optimize
команда.
Модель показывает управление углового положения для двух двигателей. Откройте Модель Simulink.
open_system('sdoMultipleMotors')
Управляют двумя двигателями. Модели - ссылки используются в контроллерах, которые являются экземплярами той же модели. Откройте контроллер.
open_system('sdoRateLimitedController')
Эти два двигателя в основной модели имеют различные характеристики, таким образом, каждый контроллер должен быть адаптирован в соответствии с ее двигателем. У каждого контроллера есть коэффициенты ПИД Kp
, Ki
, и Kd
, и скорость нарастания, Slew
. Slew
значение ограничивает уровень, на котором изменяется управляющий сигнал. Slew
значение характерно для обоих экземпляров контроллера. В отличие от этого коэффициенты ПИД должны отличаться для каждого экземпляра контроллера, поскольку двигатели, которыми управляют, имеют различные характеристики. Поэтому коэффициенты ПИД заданы в качестве аргументов модели в рабочем пространстве модели диспетчера. Значения коэффициента ПИД установлены на уровне sdoMultipleMotors
модель.
Сигнал ссылки управления является ступенчатым изменением в положении, которое происходит в 1 секунду. Угловое положение каждого двигателя должно следовать за ссылочным сигналом, но первый двигатель имеет меньший момент инерции и может более быстро ответить на изменения в ссылочном сигнале. Кроме того, производная каждого сигнала контроллера должна быть ограничена, так, чтобы токи, чертившие от источника питания, остались в пределах источника питания.
Задайте переменные проекта, которые будут настроены стандартной программой оптимизации для того, чтобы удовлетворить требованиям. Slew
переменная задана как sdoRateLimitedController:Slew
, указание, что переменная установлена на уровне sdoRateLimitedController
модель. Двоеточие является разделителем между моделью и переменной. Slew
переменная имеет то же значение для всех экземпляров моделей контроллеров. В отличие от этого пропорциональное усиление для первого контроллера задано как sdoMultipleMotors/Control_1:Kp
, указание, что переменная установлена на уровне sdoMultipleMotors
модель, где это появляется в Control_1
блок. Наклонная черта вправо является разделителем для Simulink blockpaths.
Укажите, что переменные проекта включают усиления 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 26-Jul-2019 21:08:24 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')