Этот пример показывает, как использовать несколько экспериментов для оценки смеси значений параметров модели; одни, которые оцениваются с использованием всех экспериментов, и другие, которые оцениваются с использованием отдельных экспериментов. Пример также показывает, как сконфигурировать эксперименты по оценке с зависимыми от эксперимента значениями параметров.
Вы оцениваете параметры аккумуляторной батареи на основе данных, собранных в экспериментах, которые разряжают и заряжают батарею.
Этот пример оценивает параметры простой, перезаряжаемой модели батареи, sdoBattery
. Вход модели является током батареи, и выход модели, напряжение на клемме батареи, вычисляется из состояния заряда батареи.
open_system('sdoBattery');
Модель основана на уравнении
В уравнении:
- напряжение на клемме батареи в вольтах.
- постоянное напряжение батареи в вольтах.
- сопротивление поляризации батареи в Омсе.
- максимальная емкость батареи в ампер-часах.
- состояние заряда батареи, причем 1 полностью заряжен и 0 разряжен. Состояние заряда батареи вычисляется из интеграла тока батареи с положительным током, указывающим на разряд и отрицательным током, указывающим на зарядку. Начальное состояние заряда батареи определяется в ампер-часах.
- падение напряжения при зарядке, выраженное в виде части постоянного напряжения батареи. Когда батарея разряжает это значение равняется нулю.
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)')
Создайте 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')
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')
Обновите модель V
, K
, и Loss
значений параметров.
sdo.setValueInModel('sdoBattery',vOpt);
Чтобы узнать, как оценить параметры батареи с помощью Parameter Estimator, смотрите Estimate Model Parameters Per Experiment (GUI).
Закройте модель
bdclose('sdoBattery')