В этом примере показано, как к настройкам параметров в моделях, на которые ссылаются, с помощью 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 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')