Оценка параметров модели на эксперимент (код)

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

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

Откройте модель и получите экспериментальные данные

Этот пример оценивает параметры простой, перезаряжаемой модели батареи, sdoBattery. Вход модели является током батареи, и выход модели, напряжение на клемме батареи, вычисляется из состояния заряда батареи.

open_system('sdoBattery');

Модель основана на уравнении

E=(1-Loss)V-KQmax1-ss

В уравнении:

E - напряжение на клемме батареи в вольтах.

V - постоянное напряжение батареи в вольтах.

K - сопротивление поляризации батареи в Омсе.

Qmax - максимальная емкость батареи в ампер-часах.

s - состояние заряда батареи, причем 1 полностью заряжен и 0 разряжен. Состояние заряда батареи вычисляется из интеграла тока батареи с положительным током, указывающим на разряд и отрицательным током, указывающим на зарядку. Начальное состояние заряда батареи определяется Q0 в ампер-часах.

Loss - падение напряжения при зарядке, выраженное в виде части постоянного напряжения батареи. Когда батарея разряжает это значение равняется нулю.

V, K, Qmax, Q0, и Loss являются переменными, заданными в рабочем пространстве модели.

Загрузите данные эксперимента. 1.2V (6500mAh) батарея была подвергнута эксперименту по разрядке и эксперименту по зарядке.

load sdoBattery_ExperimentData

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

Постройте график данных эксперимента

subplot(221), 
plot(DCharge_Data(:,1)/3600,DCharge_Data(:,2))
title('Experiment: Discharge')
xlabel('Time (hours)')
ylabel('Current (A)')
subplot(223)
plot(DCharge_Data(:,1)/3600,DCharge_Data(:,3))
xlabel('Time (hours)')
ylabel('Voltage (V)')
subplot(222), 
plot(Charge_Data(:,1)/3600,Charge_Data(:,2))
title('Experiment: Charge')
xlabel('Time (hours)')
ylabel('Current (A)')
subplot(224)
plot(Charge_Data(:,1)/3600,Charge_Data(:,3))
xlabel('Time (hours)')
ylabel('Voltage (V)')

Figure contains 4 axes. Axes 1 with title Experiment: Discharge contains an object of type line. Axes 2 contains an object of type line. Axes 3 with title Experiment: Charge contains an object of type line. Axes 4 contains an object of type line.

Определите эксперименты по оценке

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

Создайте объект эксперимента для эксперимента по разрядке аккумулятора. Данные измеренного тока заданы как timeseries в объекте эксперимента.

DCharge_Exp = sdo.Experiment('sdoBattery');

Задайте входные данные (ток) как объект timeseries.

DCharge_Exp.InputData = timeseries(DCharge_Data(:,2),DCharge_Data(:,1));

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

VoltageSig = Simulink.SimulationData.Signal;
VoltageSig.Name      = 'Voltage';
VoltageSig.BlockPath = 'sdoBattery/SOC -> Voltage';
VoltageSig.PortType  = 'outport';
VoltageSig.PortIndex = 1;
VoltageSig.Values    = timeseries(DCharge_Data(:,3),DCharge_Data(:,1));

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

DCharge_Exp.OutputData = VoltageSig;

Задайте начальное состояние заряда батареи для эксперимента. Состояние заряда батареи моделируется Q (Ah) блок и его начальное значение задается переменной Q0. Создайте параметр для Q0 переменная и добавить параметр к эксперименту. Q0 зависит от эксперимента и принимает различные значения в экспериментах по разрядке и зарядке.

Q0 = sdo.getParameterFromModel('sdoBattery','Q0');
Q0.Value = 6.5;    
Q0.Free  = false;

Q0.Free установлено в false поскольку начальный заряд батареи известен и не должен быть оценен.

Добавьте Q0 параметр к эксперименту.

DCharge_Exp.Parameters = Q0;

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

Charge_Exp = sdo.Experiment('sdoBattery');
Charge_Exp.InputData  = timeseries(Charge_Data(:,2),Charge_Data(:,1));
VoltageSig.Values     = timeseries(Charge_Data(:,3),Charge_Data(:,1));
Charge_Exp.OutputData = VoltageSig;

Добавьте в эксперимент параметры начального заряда батареи и фракции потерь зарядки. Для этого эксперимента начальный заряд (Q0) известно (0 Ач), но значение фракции потерь при зарядке (Loss) не известно.

Q0.Value = 0;   

Loss = sdo.getParameterFromModel('sdoBattery','Loss');
Loss.Free    = true;
Loss.Minimum = 0;
Loss.Maximum = 0.5;

Charge_Exp.Parameters = [Q0;Loss];

Loss.Free установлено значение true, чтобы значение Loss оценивается.

Соберите оба эксперимента в один вектор.

Exp = [DCharge_Exp; Charge_Exp];

Сравнение измеренного выхода и начального моделируемого выхода

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

Simulator  = createSimulator(Exp(1));
Simulator  = sim(Simulator);

Поиск сигнала напряжения в записанных данных моделирования.

SimLog     = find(Simulator.LoggedData,get_param('sdoBattery','SignalLoggingName'));
Voltage(1) = find(SimLog,'Voltage');

Получите имитированный сигнал напряжения для второго (зарядного) эксперимента.

Simulator  = createSimulator(Exp(2),Simulator);
Simulator  = sim(Simulator);
SimLog     = find(Simulator.LoggedData,get_param('sdoBattery','SignalLoggingName'));
Voltage(2) = find(SimLog,'Voltage');

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

subplot(211)
plot(...
    Voltage(1).Values.Time/3600,Voltage(1).Values.Data, ...
    Exp(1).OutputData.Values.Time/3600, Exp(1).OutputData.Values.Data,'-.')
title('Discharging Experiment: Simulated and Measured Responses Before Estimation')
ylabel('Voltage (V)')
legend('Simulated Voltage','Measured Voltage','Location','SouthWest')

Figure contains 3 axes. Axes 1 contains an object of type line. Axes 2 contains an object of type line. Axes 3 with title Discharging Experiment: Simulated and Measured Responses Before Estimation contains 2 objects of type line. These objects represent Simulated Voltage, Measured Voltage.

subplot(212)
plot(...
    Voltage(2).Values.Time/3600,Voltage(2).Values.Data, ...
    Exp(2).OutputData.Values.Time/3600, Exp(2).OutputData.Values.Data,'-.')
title('Charging Experiment: Simulated and Measured Responses Before Estimation')
xlabel('Time (hours)')
ylabel('Voltage (V)')
legend('Simulated Voltage','Measured Voltage','Location','SouthEast')

Задайте параметры для оценки

Оцените значения напряжения батареи V, сопротивление поляризации батареи K, и долю потерь зарядки Loss. The V и K параметры оцениваются с использованием всех данных эксперимента, в то время как Loss параметр оценивается, используя только данные тарификации.

Выберите напряжение батареи V и сопротивление поляризации батареи K параметры из модели. Задайте минимальные и максимальные границы для этих параметров.

p = sdo.getParameterFromModel('sdoBattery',{'V','K'});

p(1).Minimum = 0;
p(1).Maximum = 2;

p(2).Minimum = 1e-6;
p(2).Maximum = 1e-1;

Получите специфичную для эксперимента Loss параметр из эксперимента.

s = getValuesToEstimate(Exp);

Сгруппировать все параметры, которые будут оценены.

v = [p;s]
 
v(1,1) =
 
       Name: 'V'
      Value: 1.2000
    Minimum: 0
    Maximum: 2
       Free: 1
      Scale: 2
       Info: [1x1 struct]

 
v(2,1) =
 
       Name: 'K'
      Value: 1.0000e-03
    Minimum: 1.0000e-06
    Maximum: 0.1000
       Free: 1
      Scale: 0.0020
       Info: [1x1 struct]

 
v(3,1) =
 
       Name: 'Loss'
      Value: 0.0100
    Minimum: 0
    Maximum: 0.5000
       Free: 1
      Scale: 0.0156
       Info: [1x1 struct]

 
3x1 param.Continuous
 

Определите цель оценки

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

Используйте анонимную функцию с одним входным параметром, который вызывает sdoBattery_Objective функция. Передаем анонимную функцию в sdo.optimize, который оценивает функцию при каждой итерации оптимизации.

estFcn = @(v) sdoBattery_Objective(v,Simulator,Exp);

The sdoBattery_Objective функция:

  • Имеет один входной параметр, который задает предполагаемые значения параметров батареи.

  • Имеет один входной параметр, который задает объект эксперимента, содержащий измеренные данные.

  • Возвращает вектор ошибок между моделируемым и экспериментальным выходами.

The sdoBattery_Objective функция требует двух входов, но sdo.optimize требует функцию с одним входным параметром. Чтобы обойти это, estFcn является анонимной функцией с одним входным параметром, v, но он звонит sdoBattery_Objective используя два входных параметров, v и Exp.

Для получения дополнительной информации об анонимных функциях см. «Анонимные функции».

The sdo.optimize команда минимизирует возвращаемый аргумент анонимной функции estFcn, то есть остаточные ошибки, возвращенные sdoBattery_Objective. Для получения дополнительной информации о том, как написать функцию objective/constraint для использования со sdo.optimize команда, введите help sdoExampleCostFunction в командной строке MATLAB ®.

Чтобы изучить целевую функцию оценки более подробно, введите edit sdoBattery_Objective в командной строке MATLAB.

type sdoBattery_Objective
function vals = sdoBattery_Objective(v,Simulator,Exp) 
%SDOBATTERY_OBJECTIVE
%
%    The sdoBattery_Objective function is used to compare model
%    outputs against experimental data.
%
%    vals = sdoBattery_Objective(v,Exp) 
%
%    The |v| input argument is a vector of estimated model parameter values
%    and initial states.
%
%    The |Simulator| input argument is a simulation object used 
%    simulate the model with the estimated parameter values.
%
%    The |Exp| input argument contains the estimation experiment data.
%
%    The |vals| return argument contains information about how well the
%    model simulation results match the experimental data and is used by
%    the |sdo.optimize| function to estimate the model parameters.
%
%    See also sdo.optimize, sdoExampleCostFunction
%
 
% Copyright 2012-2015 The MathWorks, Inc.

%%
% Define a signal tracking requirement to compute how well the model output
% matches the experiment data. Configure the tracking requirement so that
% it returns the tracking error residuals (rather than the
% sum-squared-error) and does not normalize the errors.
%
r = sdo.requirements.SignalTracking;
r.Type      = '==';
r.Method    = 'Residuals';
r.Normalize = 'off';

%%
% Update the experiments with the estimated parameter values.
%
Exp  = setEstimatedValues(Exp,v);

%%
% Simulate the model and compare model outputs with measured experiment
% data.
%
Error = [];
for ct=1:numel(Exp)
    
    Simulator = createSimulator(Exp(ct),Simulator);
    Simulator = sim(Simulator);

    SimLog  = find(Simulator.LoggedData,get_param('sdoBattery','SignalLoggingName'));
    Voltage = find(SimLog,'Voltage');

    VoltageError = evalRequirement(r,Voltage.Values,Exp(ct).OutputData(1).Values);
    
    Error = [Error; VoltageError(:)];
end

%%
% Return the residual errors to the optimization solver.
%
vals.F = Error(:);
end

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

Используйте sdo.optimize функция для оценки значений параметров батареи.

Задайте опции оптимизации. Функция оценки sdoBattery_Objective возвращает невязки ошибок между моделируемыми и экспериментальными данными и не включает никаких ограничений, что делает эту задачу идеальной для решателя 'lsqnonlin'.

opt = sdo.OptimizeOptions;
opt.Method = 'lsqnonlin';

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

vOpt = sdo.optimize(estFcn,v,opt)
 Optimization started 22-Apr-2021 20:11:49

                                          First-order 
 Iter F-count        f(x)      Step-size  optimality
    0      7      3272.22            1                                         
    1     14      619.356       0.1634     3.15e+05
    2     21      411.131       0.2175         28.7
    3     28      405.529       0.3838     2.16e+03
    4     35      403.727       0.2767         15.2
    5     42      403.379       0.1645     1.14e+03
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.
 
vOpt(1,1) =
 
       Name: 'V'
      Value: 1.3083
    Minimum: 0
    Maximum: 2
       Free: 1
      Scale: 2
       Info: [1x1 struct]

 
vOpt(2,1) =
 
       Name: 'K'
      Value: 0.0010
    Minimum: 1.0000e-06
    Maximum: 0.1000
       Free: 1
      Scale: 0.0020
       Info: [1x1 struct]

 
vOpt(3,1) =
 
       Name: 'Loss'
      Value: 5.1801e-05
    Minimum: 0
    Maximum: 0.5000
       Free: 1
      Scale: 0.0156
       Info: [1x1 struct]

 
3x1 param.Continuous
 

Сравнение измеренного выхода и итогового моделируемого выхода

Обновите эксперименты с оцененными значениями параметров.

Exp  = setEstimatedValues(Exp,vOpt);

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

Simulator  = createSimulator(Exp(1),Simulator);
Simulator  = sim(Simulator);
SimLog     = find(Simulator.LoggedData,get_param('sdoBattery','SignalLoggingName'));
Voltage(1) = find(SimLog,'Voltage');

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

Simulator  = createSimulator(Exp(2),Simulator);
Simulator  = sim(Simulator);
SimLog     = find(Simulator.LoggedData,get_param('sdoBattery','SignalLoggingName'));
Voltage(2) = find(SimLog,'Voltage');

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

subplot(211)
plot(...
    Voltage(1).Values.Time/3600,Voltage(1).Values.Data, ...
    Exp(1).OutputData.Values.Time/3600, Exp(1).OutputData.Values.Data,'-.')
title('Discharging Experiment: Simulated and Measured Responses After Estimation')
ylabel('Voltage (V)')
legend('Simulated Voltage','Measured Voltage','Location','SouthWest')
subplot(212)
plot(...
    Voltage(2).Values.Time/3600,Voltage(2).Values.Data, ...
    Exp(2).OutputData.Values.Time/3600, Exp(2).OutputData.Values.Data,'-.')
title('Charging Experiment: Simulated and Measured Responses After Estimation')
xlabel('Time (hours)')
ylabel('Voltage (V)')
legend('Simulated Voltage','Measured Voltage','Location','SouthEast')

Figure contains 2 axes. Axes 1 with title Discharging Experiment: Simulated and Measured Responses After Estimation contains 2 objects of type line. These objects represent Simulated Voltage, Measured Voltage. Axes 2 with title Charging Experiment: Simulated and Measured Responses After Estimation contains 2 objects of type line. These objects represent Simulated Voltage, Measured Voltage.

Обновите значения параметров модели

Обновите модель V, K, и Loss значений параметров.

sdo.setValueInModel('sdoBattery',vOpt);

Похожие примеры

Чтобы узнать, как оценить параметры батареи с помощью Parameter Estimator, смотрите Estimate Model Parameters Per Experiment (GUI).

Закройте модель

bdclose('sdoBattery')