以编程方式检查和比较数据
您可以使用仿真数据检查器 API 从 MATLAB® 命令行利用仿真数据检查器的功能。
仿真数据检查器对运行和信号中的数据进行组织,对每个运行和信号赋予一个唯一数值标识。一些仿真数据检查器 API 函数使用运行和信号 ID 来引用数据,而不是接受运行或信号本身作为输入。要访问工作区中的运行 ID,您可以使用 Simulink.sdi.getAllRunIDs
或 Simulink.sdi.getRunIDByIndex
。您可以使用 getSignalIDByIndex
方法通过 Simulink.sdi.Run
对象访问信号 ID。
Simulink.sdi.Run
和 Simulink.sdi.Signal
类提供对数据的访问,并允许您查看和修改运行和信号元数据。您可以使用类似 Simulink.sdi.setSubPlotLayout
、Simulink.sdi.setRunNamingRule
和 Simulink.sdi.setMarkersOn
的函数来修改仿真数据检查器预设项。要还原仿真数据检查器的默认设置,请使用 Simulink.sdi.clearPreferences
。
创建运行并查看数据
此示例说明如何创建一次运行,向其中添加数据,然后在仿真数据检查器中查看数据。
为运行创建数据
创建 timeseries
对象以包含正弦信号和余弦信号的数据。为每个 timeseries
对象指定一个描述性名称。
time = linspace(0,20,100); sine_vals = sin(2*pi/5*time); sine_ts = timeseries(sine_vals,time); sine_ts.Name = 'Sine, T=5'; cos_vals = cos(2*pi/8*time); cos_ts = timeseries(cos_vals,time); cos_ts.Name = 'Cosine, T=8';
创建运行并添加数据
使用 Simulink.sdi.view
函数打开仿真数据检查器。
Simulink.sdi.view
要从工作区将数据导入仿真数据检查器,请使用 Simulink.sdi.Run.create
函数创建一个 Simulink.sdi.Run
对象。使用 Run
对象的 Name
和 Description
属性将有关运行的信息添加到其元数据中。
sinusoidsRun = Simulink.sdi.Run.create; sinusoidsRun.Name = 'Sinusoids'; sinusoidsRun.Description = 'Sine and cosine signals with different frequencies';
使用 add
函数将您在工作区中创建的数据添加到空运行中。
add(sinusoidsRun,'vars',sine_ts,cos_ts);
在仿真数据检查器中绘制数据
使用 getSignalByIndex
函数访问包含信号数据的 Simulink.sdi.Signal
对象。您可以使用 Simulink.sdi.Signal
对象属性来指定信号的线型和颜色,并将其绘制在仿真数据检查器中。为每个信号指定 LineColor
和 LineDashed
属性。
sine_sig = getSignalByIndex(sinusoidsRun,1); sine_sig.LineColor = [0 0 1]; sine_sig.LineDashed = '-.'; cos_sig = sinusoidsRun.getSignalByIndex(2); cos_sig.LineColor = [0 1 0]; cos_sig.LineDashed = '--';
使用 Simulink.sdi.setSubPlotLayout
函数在仿真数据检查器绘图区域中配置 2
×1
子图布局。然后使用 plotOnSubplot
函数在顶部子图上绘制正弦信号,在下部子图上绘制余弦信号。
Simulink.sdi.setSubPlotLayout(2,1); plotOnSubPlot(sine_sig,1,1,true); plotOnSubPlot(cos_sig,2,1,true);
关闭仿真数据检查器并保存您的数据
检查完绘制的信号数据后,可以关闭仿真数据检查器并将会话保存到 MLDATX 文件中。
Simulink.sdi.close('sinusoids.mldatx')
比较同一运行中的两个信号
您可以使用仿真数据检查器编程接口比较一次运行中的信号。此示例比较飞机纵向控制器的输入和输出信号。
首先,加载包含数据的会话。
Simulink.sdi.load('AircraftExample.mldatx');
使用 Simulink.sdi.Run.getLatest
函数访问最后一次运行的数据。
aircraftRun = Simulink.sdi.Run.getLatest;
然后,您可以使用 Simulink.sdi.getSignalsByName
函数访问表示控制器输入的 Stick
信号和表示输出的 alpha, rad
信号。
stick = getSignalsByName(aircraftRun,'Stick'); alpha = getSignalsByName(aircraftRun,'alpha, rad');
在比较信号之前,您可以指定用于比较的容差值。比较使用在比较中为基线信号指定的容差值,因此请在 Stick
信号上设置绝对容差值 0.1
。
stick.AbsTol = 0.1;
现在,使用 Simulink.sdi.compareSignals
函数比较信号。Stick
信号是基线,alpha, rad
信号是要与基线进行比较的信号。
comparisonResults = Simulink.sdi.compareSignals(stick.ID,alpha.ID); match = comparisonResults.Status
match = ComparisonSignalStatus enumeration OutOfTolerance
比较结果超出容差范围。您可以使用 Simulink.sdi.view
函数打开仿真数据检查器来查看和分析比较结果。
使用全局容差比较各运行
您可以指定在比较两个仿真运行时使用的全局容差值。全局容差值应用于运行中的所有信号。此示例说明如何为运行比较指定全局容差值,以及如何分析和保存比较结果。
首先,加载包含要比较的数据的会话文件。该会话文件包含一个飞机纵向控制器的四次仿真的数据。此示例比较使用不同输入滤波器时间常量的两次运行的数据。
Simulink.sdi.load('AircraftExample.mldatx');
要访问要比较的运行数据,请使用 Simulink.sdi.getAllRunIDs
函数获取对应于最后两次仿真运行的运行 ID。
runIDs = Simulink.sdi.getAllRunIDs; runID1 = runIDs(end - 1); runID2 = runIDs(end);
使用 Simulink.sdi.compareRuns
函数来比较运行。指定全局相对容差值为 0.2
,全局时间容差值为 0.5
。
runResult = Simulink.sdi.compareRuns(runID1,runID2,'reltol',0.2,'timetol',0.5);
检查返回的 Simulink.sdi.DiffRunResult
对象的 Summary
属性,查看信号是在容差值内还是超出容差。
runResult.Summary
ans = struct with fields:
OutOfTolerance: 0
WithinTolerance: 3
Unaligned: 0
UnitsMismatch: 0
Empty: 0
Canceled: 0
EmptySynced: 0
DataTypeMismatch: 0
TimeMismatch: 0
StartStopMismatch: 0
Unsupported: 0
所有三个信号比较结果都在指定的全局容差内。
您可以使用 saveResult
函数将比较结果保存到一个 MLDATX 文件中。
saveResult(runResult,'InputFilterComparison');
使用信号容差分析仿真数据
您可以通过编程方式指定信号容差值,以便在使用仿真数据检查器进行比较时使用。在此示例中,您将比较通过仿真飞机纵向飞行控制系统模型收集的数据。每次仿真使用不同的输入滤波器时间常量值,并记录输入和输出信号。通过使用仿真数据检查器和信号容差比较结果,可以分析时间常量变化的影响。
首先,加载包含仿真数据的会话文件。
Simulink.sdi.load('AircraftExample.mldatx');
该会话文件包含四次运行。在此示例中,您将比较文件中前两次运行的数据。访问从文件加载的前两次运行的 Simulink.sdi.Run
对象。
runIDs = Simulink.sdi.getAllRunIDs; runIDTs1 = runIDs(end-3); runIDTs2 = runIDs(end-2);
现在,在不指定任何容差的情况下比较这两次运行。
noTolDiffResult = Simulink.sdi.compareRuns(runIDTs1,runIDTs2);
使用 getResultByIndex
函数访问 q
和 alpha
信号的比较结果。
qResult = getResultByIndex(noTolDiffResult,1); alphaResult = getResultByIndex(noTolDiffResult,2);
检查每个信号结果的 Status
,查看比较结果是否在我们的容差范围内。
qResult.Status
ans = ComparisonSignalStatus enumeration OutOfTolerance
alphaResult.Status
ans = ComparisonSignalStatus enumeration OutOfTolerance
该比较对所有容差使用值 0
,因此 OutOfTolerance
结果意味着信号不同。
通过为信号指定容差值,可以进一步分析时间常量的影响。通过设置与所比较信号对应的 Simulink.sdi.Signal
对象的属性来指定容差。这些比较使用为基线信号指定的容差。此示例指定时间容差和绝对容差。
要指定容差,首先请访问来自基线运行的 Signal
对象。
runTs1 = Simulink.sdi.getRun(runIDTs1); qSig = getSignalsByName(runTs1,'q, rad/sec'); alphaSig = getSignalsByName(runTs1,'alpha, rad');
使用 AbsTol
和 TimeTol
属性,为 q
信号指定绝对容差 0.1
和时间容差 0.6
。
qSig.AbsTol = 0.1; qSig.TimeTol = 0.6;
为 alpha
信号指定绝对容差 0.2
和时间容差 0.8
。
alphaSig.AbsTol = 0.2; alphaSig.TimeTol = 0.8;
再次比较结果。访问比较结果,并检查每个信号的 Status
属性。
tolDiffResult = Simulink.sdi.compareRuns(runIDTs1,runIDTs2); qResult2 = getResultByIndex(tolDiffResult,1); alphaResult2 = getResultByIndex(tolDiffResult,2); qResult2.Status
ans = ComparisonSignalStatus enumeration WithinTolerance
alphaResult2.Status
ans = ComparisonSignalStatus enumeration WithinTolerance