主要内容

每个实验的估算模型参数(代码)

这个例子展示了如何使用多个实验来估计模型参数值的混合;有些是用所有实验来估计的有些是用单个实验来估计的。该示例还展示了如何配置与实验相关的参数值的估计实验。

你估计一个可充电电池的参数,基于在放电和充电的实验中收集的数据。

打开模型,获取实验数据

这个例子估计了一个简单的充电电池模型的参数,sdoBattery这个model input is the battery current and the model output, the battery terminal voltage, is computed from the battery state-of-charge.

开放式系统(“斯多巴特里”);

该模型基于该方程

E 1 - 损失 V - K 最大值 1 - 年代 年代

在方程式中:

E 为电池端电压,单位为伏特。

V 为电池恒压,单位为伏特。

K 为电池极化电阻,单位为欧姆。

最大值 是以安培小时为单位的最大电池容量。

年代 是蓄电池充电状态,1充满电,0放电。蓄电池充电状态由蓄电池电流的积分计算得出,正极电流表示放电,负极电流表示充电。蓄电池初始充电状态由 0 以安培小时为单位。

损失 为充电时的压降,用电池恒压的分数表示。当电池放电时,这个值为零。

VK最大尿流率Q0,及损失是在模型工作区中定义的变量。

加载实验数据。对1.2V(6500mAh)电池进行了放电实验和充电实验。

负载sdoBattery_ExperimentData

变量Charge_DataDCharge_Data加载到工作区中。第一列Charge_Data包含时间数据。第二列和第三列Charge_Data描述电池充电实验中的电流和电压。DCharge_Data结构类似,并包含电池放电实验的数据。

绘制实验数据

子地块(221),地块(收费数据(:,1)/3600,收费数据(:,2))标题(“实验:放电”)xlabel(的时间(小时))伊拉贝尔("现时(甲)") subplot(223) plot(DCharge_Data(:,1)/3600,DCharge_Data(:,3)) xlabel(的时间(小时))伊拉贝尔(‘电压(V)’) subplot(222), plot(Charge_Data(:,1)/3600,Charge_Data(:,2)) title(实验:电荷的)xlabel(的时间(小时))伊拉贝尔("现时(甲)") subplot(224) plot(Charge_Data(:,1)/3600,Charge_Data(:,3)) xlabel(的时间(小时))伊拉贝尔(‘电压(V)’

图中包含4个轴。带有标题的轴1实验:放电包含一个类型为line的对象。Axes 2包含一个类型为line的对象。标题为“实验:电荷”的轴3包含一个类型为线的对象。Axes 4包含一个类型为line的对象。

定义估计实验

创建一个2元素的实验对象数组,以指定两个实验的测量数据。

创建电池放电实验的实验对象。测量到的电流数据在实验对象中指定为时间序列。

DCharge_Exp = sdo。实验(“斯多巴特里”);

将输入数据(当前)指定为timeseries对象。

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

创建一个对象以指定测量的电压输出数据。

VoltageSig = 金宝appSimulink.SimulationData.Signal;VoltageSig。Name =“电压”;VoltageSig。BlockPath =‘sdoBattery/SOC->电压’;VoltageSig。PortType =“输出港”;VoltageSig。PortIndex = 1;VoltageSig。Values = timeseries(DCharge_Data(:,3),DCharge_Data(:,1));

将电压信号作为预期输出数据添加到放电实验中。

DCharge_Exp.OutputData=电压信号;

指定实验的电池初始充电状态。电池充电状态由问(啊)块,它的初始值由变量指定Q0.的参数Q0变量,并将参数添加到实验中。Q0是依赖于实验的,在放电和充电实验中假设不同的值。

Q0 = sdo.getParameterFromModel (“斯多巴特里”“Q0处”);Q0处。Value = 6.5; Q0.Free = false;

Q0处。免费的设置为因为初始电池电量是已知的,不需要估计。

添加Q0参数的实验。

DCharge_Exp.Parameters=Q0;

创建一个实验对象来存储充电实验数据。将测量的电流输入和测量的电压输出数据添加到对象。

Charge_Exp = sdo。实验(“斯多巴特里”);Charge_Exp。InputData = timeseries (Charge_Data (:, 2), Charge_Data (: 1));VoltageSig。Values = timeseries(Charge_Data(:,3),Charge_Data(:,1)); Charge_Exp.OutputData = VoltageSig;

实验中加入电池初始充电和充电损耗率参数。在本实验中,初始电荷(Q0)是已知的(0ah),但充电损耗率(损失)不知道。

Q0.Value=0;Loss=sdo.getParameterFromModel(“斯多巴特里”“损失”);的损失。免费的=true; Loss.Minimum = 0; Loss.Maximum = 0.5; Charge_Exp.Parameters = [Q0;Loss];

的损失。免费的的值设置为true,以便损失估计。

将两个实验收集到一个向量中。

经验= [DCharge_Exp;Charge_Exp];

比较测量输出和初始模拟输出

使用第一个(放电)实验创建模拟场景,并获得模拟输出。

模拟器= createSimulator (Exp (1));模拟器= sim(模拟器);

在记录的仿真数据中查找电压信号。

SimLog =找到(模拟器。LoggedData get_param (“斯多巴特里”“SignalLoggingName”));电压(1)=找到(SimLog“电压”);

获得第二次(充电)实验的模拟电压信号。

模拟器= createSimulator (Exp(2),模拟器);模拟器= sim(模拟器);SimLog =找到(模拟器。LoggedData get_param (“斯多巴特里”“SignalLoggingName”));电压(2)=找到(SimLog,“电压”);

绘制测量和模拟数据。模型响应与实验输出数据不匹配。

子地块(211)地块(...电压(1).Values.Time / 3600、电压(1).Values.Data,...实验(1).OutputData.Values。时间/ 3600、Exp (1) .OutputData.Values.Data“-”。)头衔(“放电实验:估算前的模拟和测量响应”)伊拉贝尔(‘电压(V)’)传说(模拟电压的测量电压的“位置”“西南”

图中包含3个轴。轴1包含线型对象。轴2包含线型对象。轴3带有标题放电实验:估算前的模拟和测量响应包含2个线型对象。这些对象表示模拟电压、测量电压。

次要情节(212)图(...电压(2).Values.Time / 3600、电压(2).Values.Data,...Exp(2).OutputData.Values.Time/3600,Exp(2).OutputData.Values.Data,“-”。)头衔(“充电实验:在评估前模拟和测量反应”)xlabel(的时间(小时))伊拉贝尔(‘电压(V)’)传说(模拟电压的测量电压的“位置”‘东南’

指定估算参数

估计电池电压值V,电池极化电阻K,充电损耗率损失这个VK利用所有的实验数据进行参数估计损失参数仅使用充电数据进行估计。

选择电池电压V和电池的极化电阻K模型的参数。为这些参数指定最小和最大界限。

p = sdo.getParameterFromModel (“斯多巴特里”,{“V”“K”});(1页)。最小值= 0;(1页)。最大= 2;(2页)。最小值= 1 e-6;(2页)。最大= 1 e 1;

让实验具体化损失参数来自实验。

s = getValuesToEstimate (Exp);

将所有要估计的参数分组。

v = (p, s)
v(1, - 1) =名字:“v”值:1.2000最低:0最大:2自由:1规模:2信息:[1 x1 struct] v(2, 1) =名字:“K”值:1.0000 e 03最低:1.0000 e-06最大:0.1000自由:1比例:0.0020信息:[1 x1 struct] v(3,1) =名字:“损失”值:0.0100最低:0最高:0.5000自由:1比例:0.0156信息:[1 x1 struct] 3 x1参数。连续

确定评估目标

创建一个估计目标函数,以评估使用估计参数值生成的模拟输出与测量数据的匹配程度。

使用带有一个输入参数的匿名函数来调用sdoBattery_Objective我们将匿名函数传递给sdo.optimize,它在每次优化迭代时计算函数。

estFcn = @(v) sdoBattery_Objective(v,模拟器,Exp);

sdoBattery_Objective功能:

  • 有一个输入参数,指定估计的电池参数值。

  • 有一个输入参数,指定包含测量数据的实验对象。

  • 返回模拟和实验输出之间的误差向量。

sdoBattery_Objective函数需要两个输入,但是sdo.optimize需要具有一个输入参数的函数。为了解决这个问题,estFcn是具有一个输入参数的匿名函数,v,但它调用sdoBattery_Objective使用两个输入参数,v费用

有关匿名函数的更多信息,请参阅匿名函数

sdo.optimize命令最小化匿名函数的返回参数estFcn,即返回的剩余错误sdoBattery_Objective.有关如何编写目标/约束函数的更多细节sdo.optimize命令,键入帮助sdoExampleCostFunction在MATLAB®命令提示符。

为了更详细地检查估计目标函数,类型编辑sdoBattery_Objective在MATLAB命令提示符处。

类型sdoBattery_Objective
函数VAL=sdoBattery_目标(v,模拟器,Exp)%sdoBattery_目标%%sdoBattery_目标函数用于将模型%输出与实验数据进行比较VAL=sdoBattery_Objective(v,Exp)%%输入参数是估计模型参数值%和初始状态的向量。%%|Simulator |输入参数是一个模拟对象,用于%使用估计的参数值模拟模型。%%|Exp |输入参数包含估算实验数据。%%|vals | return参数包含有关%模型模拟结果与实验数据匹配程度的信息,并由| sdo.optimize |函数%用于估计模型参数%%另请参见sdo.optimize,sdoExampleCostFunction%%版权所有2012-2015 MathWorks,Inc.%%定义信号跟踪要求,以计算模型输出%与实验数据的匹配程度。配置跟踪要求,以便%返回跟踪误差残差(而不是%平方和误差),并且不规范化误差r=sdo.requirements.SignalTracking;r、 类型='='=';r、 方法=‘残差’;r、 规格化='off';%%%使用估计的参数值更新实验。%Exp=设置估计值(Exp,v);%%模拟模型并将模型输出与测量的实验%数据进行比较错误=[];对于ct=1:numel(Exp)模拟器=createSimulator(Exp(ct),模拟器);模拟器=sim(模拟器);SimLog=find(Simulator.LoggedData,get_param('sdoBattery','SignalLoggingName');电压=查找(SimLog,'Voltage');电压误差=评估要求(r,电压值,经验(ct).输出数据(1).值);错误=[错误;电压错误(:)];结束%%%将剩余错误返回给优化解算器。%vals.F=错误(:);结束

估计参数

使用sdo.optimize功能来估计电池参数值。

指定优化选项。估计函数sdoBattery_Objective返回模拟数据和实验数据之间的误差残差,并且不包含任何约束条件,使这个问题成为“lsqnonlin”求解器的理想问题。

选择= sdo.OptimizeOptions;opt.Method =“lsqnonlin”;

估计的参数。

vOpt = sdo.optimize (estFcn, v,选择)
优化开始于2021年2月23日19:26:38一阶Iter F计数F(x)步长优化0 7 3272.22 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局部最小可能值。lsqnonlin停止,因为平方和相对于其初始值的最终变化小于函数公差值。vOpt(1,1)=名称:“V”值:1.3083最小值:0最大值:2自由值:1比例:2信息:[1x1结构]vOpt(2,1)=名称:“K”值:0.0010最小值:1.0000e-06最大值:0.1000自由值:1比例:0.0020信息:[1x1结构]vOpt(3,1)=名称:“损失”值:5.1801e-05最小值:0最大值:0.5000自由值:1比例:0.0156信息:[1x1结构]3x1参数连续

比较测量输出和最终模拟输出

使用估计的参数值更新实验。

Exp=设置的估计值(Exp,vOpt);

获得第一次(放电)实验的模拟输出。

模拟器= createSimulator (Exp(1)模拟器);模拟器= sim(模拟器);SimLog =找到(模拟器。LoggedData get_param (“斯多巴特里”“SignalLoggingName”));电压(1)=找到(SimLog“电压”);

获得第二次(充电)实验的模拟输出。

模拟器= createSimulator (Exp(2),模拟器);模拟器= sim(模拟器);SimLog =找到(模拟器。LoggedData get_param (“斯多巴特里”“SignalLoggingName”));电压(2)=找到(SimLog,“电压”);

绘制测量和模拟数据。仿真结果与实验数据吻合较好,除了在电池充满电的区域。这是意料之中的,因为简单的电池模型没有模型的指数电压下降时,电池完全充电。

子地块(211)地块(...电压(1).Values.Time / 3600、电压(1).Values.Data,...实验(1).OutputData.Values。时间/ 3600、Exp (1) .OutputData.Values.Data“-”。)头衔(放电实验:估计后的模拟和测量响应)伊拉贝尔(‘电压(V)’)传说(模拟电压的测量电压的“位置”“西南”情节)次要情节(212)(...电压(2).Values.Time / 3600、电压(2).Values.Data,...Exp(2).OutputData.Values.Time/3600,Exp(2).OutputData.Values.Data,“-”。)头衔(“充电实验:估算后的模拟和测量响应”)xlabel(的时间(小时))伊拉贝尔(‘电压(V)’)传说(模拟电压的测量电压的“位置”‘东南’

图中包含2个轴。标题为“放电实验:模拟和估计后的测量响应”的轴1包含2个类型线的对象。这些对象代表模拟电压,测量电压。标题为“充电实验:估算后的模拟和测量响应”的坐标轴2包含2个线型对象。这些对象代表模拟电压,测量电压。

更新模型参数值

更新模型VK,及损失参数值。

sdo.setValueInModel(“斯多巴特里”, vOpt);

相关的例子

学习如何估计电池参数使用参数估计量,请参阅每次实验估计模型参数(GUI)

关闭模型

bdclose (“斯多巴特里”