Main Content

以编程方式检查和比较数据

您可以使用仿真数据检查器 API 从 MATLAB® 命令行利用仿真数据检查器的功能。

仿真数据检查器对运行和信号中的数据进行组织,对每个运行和信号赋予一个唯一数值标识。一些仿真数据检查器 API 函数使用运行和信号 ID 来引用数据,而不是接受运行或信号本身作为输入。要访问工作区中的运行 ID,您可以使用 Simulink.sdi.getAllRunIDsSimulink.sdi.getRunIDByIndex。您可以使用 getSignalIDByIndex 方法通过 Simulink.sdi.Run 对象访问信号 ID。

Simulink.sdi.RunSimulink.sdi.Signal 类提供对数据的访问,并允许您查看和修改运行和信号元数据。您可以使用类似 Simulink.sdi.setSubPlotLayoutSimulink.sdi.setRunNamingRuleSimulink.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 对象的 NameDescription 属性将有关运行的信息添加到其元数据中。

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 对象属性来指定信号的线型和颜色,并将其绘制在仿真数据检查器中。为每个信号指定 LineColorLineDashed 属性。

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 函数访问 qalpha 信号的比较结果。

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');

使用 AbsTolTimeTol 属性,为 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

另请参阅

相关主题