以编程方式检查和比较数据
您可以从 MATLAB® 命令行以编程方式利用仿真数据检查器的功能。
仿真数据检查器对运行和信号中的数据进行组织,对每个运行和信号赋予一个唯一数值标识符。Simulink.sdi.Run 和 Simulink.sdi.Signal 对象允许您访问数据以及查看和修改运行和信号元数据。当您以编程方式与仿真数据检查器交互时,一些函数需要 Signal 或 Run 对象作为输入,而其他函数则使用信号或运行 ID。要访问工作区中的运行 ID,您可以使用 Simulink.sdi.getAllRunIDs 或 Simulink.sdi.getRunIDByIndex 函数。您可以使用 getSignalIDByIndex 方法通过 Simulink.sdi.Run 对象访问信号 ID。
您可以使用类似 Simulink.sdi.setSubPlotLayout、Simulink.sdi.setRunNamingRule 和 Simulink.sdi.setVisualization 的函数来修改仿真数据检查器预设项。要还原仿真数据检查器默认设置,请使用 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 = [1 0 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");
使用 Simulink.sdi.compareSignals 函数,使用信号 ID 比较 Stick 和 alpha, rad 信号。Stick 信号是基线信号。alpha, rad 信号是与基线信号进行比较的信号。
comparisonResults = Simulink.sdi.compareSignals(stick.ID,alpha.ID); match = comparisonResults.Status
match =
ComparisonSignalStatus enumeration
OutOfTolerance
比较结果超出容差范围。您可以使用 Simulink.sdi.view 函数打开仿真数据检查器来查看和分析比较结果。
Simulink.sdi.view

您可以指定用于比较的时间和幅值容差值。这些比较使用为比较中的基线信号指定的容差值。为了考虑相移,在 Stick 信号上设置时间容差 1。为了考虑幅值差,在 Stick 信号上设置绝对容差值 0.1。
stick.TimeTol = 1; stick.AbsTol = 0.1;
再次比较信号。这次,由于设置了绝对容差和时间容差,信号比较通过。
comparisonResults = Simulink.sdi.compareSignals(stick.ID,alpha.ID); match = comparisonResults.Status
match =
ComparisonSignalStatus enumeration
WithinTolerance

使用全局容差比较各运行
您可以指定在比较两个仿真运行时使用的全局容差值。全局容差值应用于运行中的所有信号。此示例说明如何为运行比较指定全局容差值,以及如何分析和保存比较结果。
加载包含要比较的数据的仿真数据检查器会话文件。该会话文件包含一个飞机纵向飞行控制器的四次仿真的数据。此示例比较使用不同输入滤波器时间常数的两次运行的数据。
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');
对于 q 信号,分别使用 AbsTol 和 TimeTol 属性指定绝对容差 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