估计模型参数和初始状态(代码)
这个例子展示了如何估算模型的初始状态和参数。
这个例子需要Simscape™软件。
RC电路模型
Simu金宝applink仿真®模型,sdoRCCircuit
模型的一个简单的电阻电容(RC)电路。
open_system (“sdoRCCircuit”);
估计问题
您使用测量数据估计RC模型参数和状态值。
测量输出数据:
电容器电压,PS-Simulink转换器的输出块金宝app
参数:
电容,
C1
,使用的C1块
状态:
初始电压的电容器
定义评估实验
测量数据。
负载sdoRCCircuit_ExperimentData
的变量时间
和数据
被加载到工作区,在哪里数据
次测量电容器电压吗时间
。
创建一个实验对象存储实验电压数据。
经验= sdo.Experiment (“sdoRCCircuit”);
创建一个对象来存储测量电容器电压输出。
电压= Simuli金宝appnk.SimulationData.Signal;电压。Name =“电压”;电压。BlockPath =“sdoRCCircuit / P金宝appS-Simulink转换器”;电压。PortType =“输出港”;电压。PortIndex = 1;电压。值= timeseries(数据、时间);
测量电容数据添加到实验预期的输出数据。
Exp.OutputData =电压;
比较测量输出和最初的模拟输出
创建一个模拟场景中使用实验,获得模拟输出。
模拟器= createSimulator (Exp);模拟器= sim(模拟器);
电压信号的搜索记录的仿真数据。
SimLog =找到(Simulator.LoggedData get_param (“sdoRCCircuit”,“SignalLoggingName”));电压=找到(SimLog,“电压”);
图测量和模拟数据。
模型响应不匹配实验输出数据。
情节(时间、数据“罗”Voltage.Values.Time Voltage.Values.Data,“b”)标题(模拟和测量反应之前估计的)传说(测量电压的,模拟电压的)
指定的参数估计
选择电容参数的模型。指定一个初始猜测电容值(460 uF)和最低(0 F)。
p = sdo.getParameterFromModel (“sdoRCCircuit”,“C1”);p。值= 460 e-6;p。最小值= 0;
定义评估目标函数
创建一个估计目标函数来评估仿真输出,使用估计的参数值,生成匹配的测量数据。
使用一个匿名函数调用的一个输入参数sdoRCCircuit_Objective
函数。通过匿名函数sdo.optimize
在每个迭代优化,评估函数。
estFcn = @ (v) sdoRCCircuit_Objective (v,模拟器,Exp);
的sdoRCCircuit_Objective
功能:
有一个输入参数,用于指定估计电路电容值。
有一个输入参数,用于指定包含测量数据的实验对象。
返回一个向量模拟和实验输出之间的误差。
的sdoRCCircuit_Objective
函数需要两个输入,但是sdo.optimize
需要一个函数和一个输入参数。为了解决这一问题,estFcn
是一个匿名函数输入参数,v
,但它调用sdoRCCircuit_Objective
使用两个输入参数,v
和经验值
。
有关匿名函数的更多信息,请参阅匿名函数。
优化求解最小化剩余错误。更多细节关于如何编写一个目标/约束函数使用sdo.optimize
命令,键入帮助sdoExampleCostFunction
在MATLAB®命令提示符。
更详细地检查估计目标函数,类型编辑sdoRCCircuit_Objective
在MATLAB命令提示符。
类型sdoRCCircuit_Objective
函数vals = sdoRCCircuit_Objective (v,模拟器,Exp) % sdoRCCircuit_Objective % % % sdoRCCircuit_Objective函数是用来比较模型输出实验数据。% % vals = sdoRCCircuit_Objective v (v, Exp) % % | |输入参数是一个向量的估计模型参数值%和初始状态。% % | |模拟器的输入参数是一个模拟对象使用%模拟模型估计参数值。% % | Exp |输入参数包含评估实验数据。% % | vals |返回参数包含有关如何%模型仿真结果与实验数据和使用% | sdo。优化|函数来估计模型参数。% %也看到sdo。优化、sdoExampleCostFunction sdoRCCircuit_cmddemo % % 2012 - 2015版权MathWorks, Inc . % % %定义一个信号跟踪要求计算,模型输出%匹配实验数据。配置跟踪要求%这样返回跟踪误差残差(而不是% sum-squared-error)和不正常的错误。% 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. % Simulator = createSimulator(Exp,Simulator); Simulator = sim(Simulator); SimLog = find(Simulator.LoggedData,get_param('sdoRCCircuit','SignalLoggingName')); Voltage = find(SimLog,'Voltage'); VoltageError = evalRequirement(r,Voltage.Values,Exp.OutputData(1).Values); %% % Return the residual errors to the optimization solver. % vals.F = VoltageError(:); end
估计的参数
使用sdo.optimize
函数来估算电容值。
指定优化选项。估计函数sdoRCCircuit_Objective
返回模拟和实验数据之间的误差残差,不包括任何约束,使这个问题的理想| lsqnonlin |解算器。
选择= sdo.OptimizeOptions;opt.Method =“lsqnonlin”;
估计的参数。
pOpt = sdo.optimize (estFcn p选择)
2023 - 3月- 03优化开始,09:06:03一阶Iter F-count f (x)步长最优0 3 1 1 6 21.0148 0.2124 17.3 55.0017 2 9 11.5069 0.1272 6.1 3 12 15 9.27804 0.0275 0.43 9.56554 0.06554 - 2 4 5 18 9.27316 0.006987 0.0788局部最小值。lsqnonlin停止是因为最后的平方和的变化相对于其初始值小于公差的值函数。pOpt =名字:C1的值:1.1346 e-04最低:0最大:正自由:1比例:0.0020信息:[1 x1 struct] 1 x1 param.Continuous
比较测量的输出和模拟输出
更新实验估计电容值。
经验= setEstimatedValues (Exp、pOpt);
创建一个模拟场景中使用实验,获得模拟输出。
模拟器= createSimulator (Exp、模拟器);模拟器= sim(模拟器);
电压信号的搜索记录的仿真数据。
SimLog =找到(Simulator.LoggedData get_param (“sdoRCCircuit”,“SignalLoggingName”));电压=找到(SimLog,“电压”);
图测量和模拟数据。
模拟和测量信号匹配得很好,除了在时间为零。这种不匹配是由于电容器初始电压模型中定义的初始电压不匹配实验。
情节(时间、数据“罗”Voltage.Values.Time Voltage.Values.Data,“b”)标题(“模拟和测量反应后评估”)传说(测量电压的,模拟电压的)
估计初始状态
添加电容初始电压C1
块的实验。初始猜测值设置为1 V。
Exp.InitialStates = sdo.getStateFromModel (“sdoRCCircuit”,“C1”);Exp.InitialStates。值= 1;
重新评估函数使用实验初始状态估计
estFcn = @ (v) sdoRCCircuit_Objective (v,模拟器,Exp);
得到初始状态和电容值估计的实验。
v = getValuesToEstimate (Exp);
估计的参数。
vOpt = sdo.optimize (estFcn, v,选择)
2023 - 3月- 03优化开始,09:06:16一阶Iter F-count f (x)步长最优0 5 4.74867 - 1 1 10 15 1.34958 0.1262 0.0713 2.1196 - 1.537 22.7 - 2 3 20 25 1.34363 0.001378 0.000765 1.34365 0.05718 0.129 4局部最小值。优化完成因为梯度的大小小于最优值的宽容。vOpt(1, - 1) =名字:“sdoRCCircuit / C1: sdoRCCircuit.C1。vc' Value: 2.3597 Minimum: -Inf Maximum: Inf Free: 1 Scale: 1 dxValue: 0 dxFree: 1 Info: [1x1 struct] vOpt(2,1) = Name: 'C1' Value: 2.2638e-04 Minimum: 0 Maximum: Inf Free: 1 Scale: 0.0020 Info: [1x1 struct] 2x1 param.Continuous
比较测量输出和最后的模拟输出
更新实验估计电容和电容初始电压值。
经验= setEstimatedValues (Exp、vOpt);
模拟模型与初始状态估计和参数值和模拟输出与实验数据进行比较。
模拟器= createSimulator (Exp、模拟器);模拟器= sim(模拟器);SimLog =找到(Simulator.LoggedData get_param (“sdoRCCircuit”,“SignalLoggingName”));电压=找到(SimLog,“电压”);情节(时间、数据“罗”Voltage.Values.Time Voltage.Values.Data,“b”)标题({模拟和测量响应的;…在初始状态和模型参数估计的})(传说测量电压的,模拟电压的)
更新模型参数值
更新模型估计的电容值。不更新模型电容器初始电压(第一个元素的vOpt
),因为它依赖于实验。
sdo.setValueInModel (“sdoRCCircuit”vOpt (2));
相关的例子
学习如何使用估计模型参数sdo.optimize
命令,看到估计模型参数和初始状态(GUI)。
关闭模式
bdclose (“sdoRCCircuit”)