Оцените параметры модели символически выведенной модели объекта управления в Simulink

Этот пример использует Simulink Design Optimization™, чтобы оценить неизвестную емкость и начальное напряжение символически выведенной алгебраической модели простой схемы конденсатора резистора (RC). Пример решает ту же задачу и использует те же экспериментальные данные в качестве Оценочных Параметров модели и начальных состояний, но использует решение закрытой формы для схемы RC вместо дифференциальной формы.

Этот пример использует возможности Symbolic Math Toolbox™ для:

  • Решите обыкновенные дифференциальные уравнения (ODE) с помощью dsolve

  • Преобразуйте аналитический результат в блок Simulink с помощью matlabFunctionBlock

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

Решите уравнение для схемы RC

Задайте и решите следующее дифференциальное уравнение для схемы RC.

Здесь, v2(t) выходное напряжение через конденсаторный C1, v1 постоянное напряжение через резистор R1, и v20 начальное напряжение через конденсатор. Используйте dsolve решить уравнение.

syms C1 R1 v1 v20 real 
syms v2(t)
deq = (v1 - v2)/R1 - C1*diff(v2,t);
v2sol = dsolve(deq, v2(0) == v20)
v2sol = 

v1-e-tC1R1v1-v20

Используйте subs оценивать решение для R1 значение 10 кОм и v1 значение 5 В.

v2sol = vpa(subs(v2sol,[R1,v1],[10e3,5]))
v2sol = 

e-0.0001tC1v20-5.0+5.0

Создайте модель с блоком, представляющим схему RC

Во-первых, создайте новую модель Simulink.

myModel = 'rcSymbolic';
new_system(myModel);
load_system(myModel);

Используйте matlabFunctionBlock преобразовывать символьный результат для выходного напряжения к блоку Simulink, представляющему модель объекта управления RC. matlabFunctionBlock добавляет этот новый блок к модели.

blockName = 'closedFormRC_block';
rcBlock = strcat(myModel,'/',blockName);
myVars = [C1,v20,t];
matlabFunctionBlock(rcBlock,v2sol,...
    'vars',myVars,...
    'functionName','myRC',...
    'outputs',{'v2'});

Добавьте больше блоков

Добавьте и расположите другие блоки с положениями и размерами относительно блока RC.

rcBlockPosition = get_param(rcBlock,'position');
rcBlockWidth = rcBlockPosition(3)-rcBlockPosition(1);
rcBlockHeight = rcBlockPosition(4)-rcBlockPosition(2);
constantBlock = 'built-in/Constant';
timeBlock = 'simulink/Sources/Ramp';
outputBlock = 'built-in/Outport';

C1 и v20 параметры должны оценить. Во-первых, введите и инициализируйте эти параметры в рабочем пространстве MATLAB, с помощью начальных значений 460 μF и 1 В, соответственно. Затем создайте постоянные блоки для обоих параметров.

C1val = 460e-6;
v20val = 1.0;
posX = rcBlockPosition(1)-rcBlockWidth*2;
posY = rcBlockPosition(2)-rcBlockHeight*3/4;
pos = [posX,posY,posX+rcBlockWidth/2,posY+rcBlockHeight/2];
add_block(constantBlock,strcat(myModel,'/C1'),'Value','C1val',...
    'Position',pos);
pos = pos + [0 rcBlockHeight 0 rcBlockHeight];
add_block(constantBlock,strcat(myModel,'/v20'),'Value','v20val',...
    'Position',pos);

Добавьте пандус в течение времени.

pos = pos + [0 rcBlockHeight 0 rcBlockHeight];
add_block(timeBlock,strcat(myModel,'/t'),'Slope','1','Position',pos);

Добавьте выходной порт.

pos = [rcBlockPosition(1)+2*rcBlockWidth,...
    rcBlockPosition(2)+rcBlockHeight/4,...
    rcBlockPosition(1)+2*rcBlockWidth+rcBlockWidth/2,...
    rcBlockPosition(2)+rcBlockHeight/4+rcBlockHeight/2];
add_block(outputBlock,strcat(myModel,'/v2'),'Port','1','Position',pos);

Теперь соедините блоки в модели. Модель готова к Simulink Design Optimization.

myAddLine = @(k) add_line(myModel,...
    strcat(char(myVars(k)),'/1'),...
    strcat(blockName,'/',num2str(k)),...
    'autorouting','on');
arrayfun(myAddLine,(1:numel(myVars)));
add_line(myModel,strcat(blockName,'/1'),'v2/1','autorouting','on');
open_system(myModel);

Оцените параметры

Получите результаты измерений.

load sdoRCCircuit_ExperimentData

Переменные time и data загружаются в рабочую область. data измеренное конденсаторное напряжение в течение многих времен time.

Создайте sdo.Experiment объект хранить экспериментальные данные о напряжении.

Exp = sdo.Experiment(myModel);

Создайте объект сохранить измеренное конденсаторное напряжение выход.

Voltage = Simulink.SimulationData.Signal;
Voltage.Name      = 'Voltage';
Voltage.BlockPath = rcBlock;
Voltage.PortType  = 'outport';
Voltage.PortIndex = 1;
Voltage.Values    = timeseries(data,time);

Добавьте измеренные конденсаторные данные в эксперимент как ожидаемые выходные данные.

Exp.OutputData = Voltage;

Получите параметры. Установите минимальное значение для C1. Обратите внимание на то, что вы уже задали исходные предположения.

c1param = sdo.getParameterFromModel(myModel,'C1val');
c1param.Minimum = 0;
v20param = sdo.getParameterFromModel(myModel,'v20val');

Задайте целевую функцию для оценки. Код для sdoRCSymbolic_Objective используемый в этом примере дан в разделе Helper Functions в конце примера.

estFcn = @(v) sdoRCSymbolic_Objective(v,Exp,myModel);

Соберите параметры модели, которые будут оценены.

v = [c1param;v20param];

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

set_param(myModel,'SolverPrmCheckMsg','none');

Оцените параметры.

opt = sdo.OptimizeOptions;
opt.Method = 'lsqnonlin';
vOpt = sdo.optimize(estFcn,v,opt);
 Optimization started 25-Aug-2021 21:02:24

                                          First-order 
 Iter F-count        f(x)      Step-size  optimality
    0      5      27.7093            1                                         
    1     10      2.86889        1.919         2.94
    2     15      1.53851       0.3832        0.523
    3     20      1.35137       0.3347        0.505
    4     25      1.34473      0.01374      0.00842
    5     30      1.34472     0.002686      0.00141
Local minimum possible.

lsqnonlin stopped because the final change in the sum of squares relative to 
its initial value is less than the value of the function tolerance.

Покажите ориентировочные стоимости.

fprintf('C1 = %e v20 = %e\n',vOpt(1).Value, vOpt(2).Value);
C1 = 2.261442e-04 v20 = 2.359446e+00

Сравните симулированные и экспериментальные данные

Обновите эксперимент с предполагаемой емкостью и конденсаторными начальными значениями напряжения.

Exp = setEstimatedValues(Exp,vOpt);

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

Simulator = createSimulator(Exp);
Simulator = sim(Simulator);
SimLog    = find(Simulator.LoggedData,get_param(myModel,'SignalLoggingName'));
Voltage   = find(SimLog,'Voltage');
plot(time,data,'ro',Voltage.Values.Time,Voltage.Values.Data,'b')
title('Simulated and Measured Responses')
legend('Measured Voltage','Simulated Voltage','Location','Best')

Figure contains an axes object. The axes object with title Simulated and Measured Responses contains 2 objects of type line. These objects represent Measured Voltage, Simulated Voltage.

close_system(myModel,0);

Функции помощника

function vals = sdoRCSymbolic_Objective(v,Exp,myModel) 
    r = sdo.requirements.SignalTracking;
    r.Type      = '==';
    r.Method    = 'Residuals';
    r.Normalize = 'off';
    Exp  = setEstimatedValues(Exp,v);
    Simulator = createSimulator(Exp);
    Simulator = sim(Simulator);
    SimLog  = find(Simulator.LoggedData,get_param(myModel,'SignalLoggingName'));
    Voltage = find(SimLog,'Voltage');
    VoltageError = evalRequirement(r,Voltage.Values,Exp.OutputData(1).Values);
    vals.F = VoltageError(:);
end