このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。
コマンド ライン検証のチュートリアル
この例では、Adjustable Rate Limiter の 3 つのテスト ケースを作成し、モデル カバレッジ ツールのコマンド ライン API を使用して、結果のモデル カバレッジを解析します。
Adjustable Rate Limiter の Simulink® モデル
Simulink® サブシステムの Adjustable Rate Limiter は、モデル 'slvnvdemo_ratelim_harness' 内の Rate Limiter です。これは、3 つの Switch ブロックを使用して、出力を制限するタイミングと、適用する制限のタイプを制御します。
入力は、From Workspace ブロック 'gain'、'rising limit' および 'falling limit' で生成され、これによって区分的線形信号が生成されます。入力の値は、MATLAB® ワークスペースで定義されている 6 つの変数 (t_gain、u_gain、t_pos、u_pos、t_neg および u_neg) で指定されます。
モデルと Adjustable Rate Limiter サブシステムを開きます。
modelName = 'slvnvdemo_ratelim_harness'; open_system(modelName); open_system([modelName,'/Adjustable Rate Limiter']);
最初のテスト ケースの作成
最初のテスト ケースは、入力値が急激に変化しないときは出力が入力と一致することを検証します。正弦波を時変信号として使用し、立ち上がりと立ち下がりの制限に定数を使用します。
t_gain = (0:0.02:2.0)'; u_gain = sin(2*pi*t_gain);
MATLAB 関数 diff を使用して、時変入力の最小変化と最大変化を計算します。
max_change = max(diff(u_gain)) min_change = min(diff(u_gain))
max_change = 0.1253 min_change = -0.1253
信号の変化は 1 よりはるかに小さく -1 よりはるかに大きいため、変化率の制限を 1 と -1 に設定します。変数はすべて、シミュレーション前に読み込まれる MAT ファイル 'within_lim.mat' に保存されます。
t_pos = [0;2]; u_pos = [1;1]; t_neg = [0;2]; u_neg = [-1;-1]; save('within_lim.mat','t_gain','u_gain','t_pos','u_pos','t_neg','u_neg');
追加のテスト ケース
2 番目のテスト ケースでは、最初のケースに補足して、変化率の制限を超える立ち上がりゲインを使用します。直後に、変化率の制限を拡大し、ゲインの変化が制限未満になるようにします。
t_gain = [0;2]; u_gain = [0;4]; t_pos = [0;1;1;2]; u_pos = [1;1;5;5]*0.02; t_neg = [0;2]; u_neg = [0;0]; save('rising_gain.mat','t_gain','u_gain','t_pos','u_pos','t_neg','u_neg');
3 番目のテスト ケースは 2 番目の鏡像で、立ち上がりゲインが立ち下がりゲインに置き換えられています。
t_gain = [0;2]; u_gain = [-0.02;-4.02]; t_pos = [0;2]; u_pos = [0;0]; t_neg = [0;1;1;2]; u_neg = [-1;-1;-5;-5]*0.02; save('falling_gain.mat','t_gain','u_gain','t_pos','u_pos','t_neg','u_neg');
カバレッジ テストの定義
テスト ケースは、
を使用して編成され、実行されます。sim
この例では、シミュレーション入力オブジェクトを使用してカバレッジ構成を設定します。
covSet = Simulink.SimulationInput(modelName); covSet = setModelParameter(covSet,'CovEnable','on'); covSet = setModelParameter(covSet,'CovMetricStructuralLevel','Decision'); covSet = setModelParameter(covSet,'CovSaveSingleToWorkspaceVar','on'); covSet = setModelParameter(covSet,'CovScope','Subsystem'); covSet = setModelParameter(covSet,'CovPath','/Adjustable Rate Limiter'); covSet = setModelParameter(covSet,'StartTime','0.0'); covSet = setModelParameter(covSet,'StopTime','2.0');
カバレッジ テストの実行
1 番目のテスト ケースを読み込み、カバレッジの変数名を設定して、sim
を使用してモデルを実行します。
load within_lim.mat covSet = setModelParameter(covSet,'CovSaveName','dataObj1'); simOut1 = sim(covSet); dataObj1
dataObj1 = ... cvdata version: (R2022b) id: 342 type: TEST_DATA test: cvtest object rootID: 344 checksum: [1x1 struct] modelinfo: [1x1 struct] startTime: 25-Jul-2022 00:04:40 stopTime: 25-Jul-2022 00:04:40 intervalStartTime: 0 intervalStopTime: 0 simulationStartTime: 0 simulationStopTime: 2 filter: simMode: Normal
出力が入力と一致することをチェックすることにより、最初のテスト ケースを検証します。
subplot(211) plot(simOut1.tout,simOut1.yout(:,1),simOut1.tout,simOut1.yout(:,4)) xlabel('Time (sec)'), ylabel('Value'), title('Gain input and output'); subplot(212) plot(simOut1.tout,simOut1.yout(:,1)-simOut1.yout(:,4)) xlabel('Time (sec)'),ylabel('Difference'), title('Difference between the gain input and output');
同じ方法で 2 番目のテスト ケースを実行し、結果をプロットします。
制限された出力が入力から離れた場合は、最大スルー レートでのみ復元可能になります。このため、プロットには異常なねじれがあります。出力と入力が一致したら、2 つは同時に変化します。
load rising_gain.mat covSet = setModelParameter(covSet,'CovSaveName','dataObj2'); simOut2 = sim(covSet); dataObj2 subplot(211) plot(simOut2.tout,simOut2.yout(:,1),simOut2.tout,simOut2.yout(:,4)) xlabel('Time (sec)'), ylabel('Value'), title('Gain input and output'); subplot(212) plot(simOut2.tout,simOut2.yout(:,1)-simOut2.yout(:,4)) xlabel('Time (sec)'), ylabel('Difference'), title('Difference between the gain input and output');
dataObj2 = ... cvdata version: (R2022b) id: 458 type: TEST_DATA test: cvtest object rootID: 344 checksum: [1x1 struct] modelinfo: [1x1 struct] startTime: 25-Jul-2022 00:04:44 stopTime: 25-Jul-2022 00:04:44 intervalStartTime: 0 intervalStopTime: 0 simulationStartTime: 0 simulationStopTime: 2 filter: simMode: Normal
3 番目のテスト ケースを実行して結果をプロットします。
load falling_gain.mat covSet = setModelParameter(covSet,'CovSaveName','dataObj3'); simOut3 = sim(covSet); dataObj3 subplot(211) plot(simOut3.tout,simOut3.yout(:,1),simOut3.tout,simOut3.yout(:,4)) xlabel('Time (sec)'), ylabel('Value'), title('Gain input and output'); subplot(212) plot(simOut3.tout,simOut3.yout(:,1)-simOut3.yout(:,4)) xlabel('Time (sec)'), ylabel('Difference'), title('Difference between the gain input and output');
dataObj3 = ... cvdata version: (R2022b) id: 580 type: TEST_DATA test: cvtest object rootID: 344 checksum: [1x1 struct] modelinfo: [1x1 struct] startTime: 25-Jul-2022 00:04:46 stopTime: 25-Jul-2022 00:04:46 intervalStartTime: 0 intervalStopTime: 0 simulationStartTime: 0 simulationStopTime: 2 filter: simMode: Normal
カバレッジ レポートの生成
すべてのテストがパスしたと仮定して、すべてのテスト ケースを組み合わせたレポートを生成し、100% カバレッジの達成を検証します。各テストのカバレッジ率は、[モデルの階層構造] という見出しの下に表示されます。どのテストも単独では 100% カバレッジを達成していませんが、累計ではフル カバレッジを達成しています。
cvhtml('combined_ratelim',dataObj1,dataObj2,dataObj3);
カバレッジ データの保存
cvsave
を使用して、収集されたカバレッジ データをファイル "ratelim_testdata.cvt" に保存します。
cvsave('ratelim_testdata',dataObj1,dataObj2,dataObj3);
モデルを閉じてカバレッジ環境を終了します。
close_system('slvnvdemo_ratelim_harness',0); clear dataObj*
カバレッジ データの読み込み
モデルを開いた後に、cvload
を使用して、保存したカバレッジ テストをファイル "ratelim_testdata.cvt" から復元します。データおよびテストは cell 配列で取得されます。
open_system('slvnvdemo_ratelim_harness'); [SavedTests,SavedData] = cvload('ratelim_testdata')
SavedTests = 1x3 cell array {1x1 cvtest} {1x1 cvtest} {1x1 cvtest} SavedData = 1x3 cell array {1x1 cvdata} {1x1 cvdata} {1x1 cvdata}
カバレッジ データ オブジェクトの操作
オーバーロードされた演算子、+、- および * を使用して cvdata オブジェクトを操作します。* 演算子は、2 つのカバレッジ データ オブジェクトの共通部分を見つけるために使用します。これにより、もう 1 つの cvdata オブジェクトが生成されます。たとえば、次のコマンドを実行すると、3 つすべてのテストの共通カバレッジの HTML レポートが生成されます。
common = SavedData{1} * SavedData{2} * SavedData{3}
cvhtml('intersection',common)
common = ... cvdata version: (R2022b) id: 0 type: DERIVED_DATA test: [] rootID: 705 checksum: [1x1 struct] modelinfo: [1x1 struct] startTime: 25-Jul-2022 00:04:40 stopTime: 25-Jul-2022 00:04:46 intervalStartTime: 0 intervalStopTime: 0 filter: simMode: Normal
カバレッジ データ オブジェクトからの情報の抽出
decisioninfo
を使用して、ブロック パスまたはブロック ハンドルから判定カバレッジ情報を取得します。出力は、単一のモデル オブジェクトのそれぞれの達成された結果と全体の結果を含むベクトルです。
cov = decisioninfo(SavedData{1} + SavedData{2} + SavedData{3}, ... 'slvnvdemo_ratelim_harness/Adjustable Rate Limiter')
cov = 6 6
取得したカバレッジ情報を使用して、カバレッジのパーセンテージにアクセスします。
percentCov = 100 * (cov(1)/cov(2))
percentCov = 100
2 つの出力引数が使用されている場合、decisioninfo
は、Simulink ブロックまたは Stateflow® オブジェクト内で判定と結果をキャプチャする構造体を返します。
[blockCov,desc] = decisioninfo(common, ... 'slvnvdemo_ratelim_harness/Adjustable Rate Limiter/Delta sign') descDecision = desc.decision outcome1 = desc.decision.outcome(1) outcome2 = desc.decision.outcome(2)
blockCov = 0 2 desc = struct with fields: isFiltered: 0 justifiedCoverage: 0 isJustified: 0 filterRationale: '' decision: [1x1 struct] descDecision = struct with fields: text: 'Switch trigger' filterRationale: '' isFiltered: 0 isJustified: 0 outcome: [1x2 struct] outcome1 = struct with fields: text: 'false (out = in3)' executionCount: 0 executedIn: [] isFiltered: 0 isJustified: 0 filterRationale: '' outcome2 = struct with fields: text: 'true (out = in1)' executionCount: 0 executedIn: [] isFiltered: 0 isJustified: 0 filterRationale: ''