Main Content

このページは前リリースの情報です。該当の英語のページはこのリリースで削除されています。

構造体形式での状態のログ

Structure 形式を使用する状態のログには、Array 形式と比べて優れた点があります。Array 形式を使用して状態のログを記録する場合、ログに記録された配列の列に沿った状態の順序は、ブロックの並べ替え順序に左右されます。さまざまな要因によってブロックの並べ替え順序が決まり、これによって状態の順序がシミュレーションごとに変更される場合があります。Structure 形式を使用する場合、ブロック名はそのブロックに対してログに記録された状態データと共に保存されるため、ブロックの並べ替え順序を考慮することなくデータを処理できます。

配列形式での状態のログ

Array 形式を使用して状態をログに記録する場合、ログに記録されたデータは N 列 (N は状態の数)、M 行 (シミュレーション タイム ステップごとに 1 行) の配列に保存されます。M 行 N 列の行列は、MATLAB® で処理しやすい形式です。ただし、ログが作成される行列の列に沿った状態変数の順序は、ブロックの並べ替え順序に左右されます。したがって、モデル内のブロックの状態と、状態行列の列との間のマッピングが固定されていると想定する MATLAB コードは、モデル内の変更が原因でブロックの並べ替え順序が変わると分解されやすくなります。

たとえば、モデル sldemo_state_logging1 および sldemo_state_logging2 について考えます。

mdl1 = 'sldemo_state_logging1';
mdl2 = 'sldemo_state_logging2';
open_system(mdl1);
open_system(mdl2);

2 つのモデルには、同じように接続された同じブロックが含まれています。違いは、出力端子の順序だけです。モデルのシミュレーションを実行し、Array 形式を使用して状態をログに記録します。

simOut1 = sim(mdl1, 'SaveFormat','Array');
simOut2 = sim(mdl2, 'SaveFormat','Array');

シミュレーションでログに記録されたすべてのデータを含んでいる Simulink.SimulationOutput オブジェクトから、状態ベクトルを抽出します。

x1 = simOut1.get('xout');
x2 = simOut2.get('xout');

x1x2 に対してログに記録された状態データが異なるのは、ブロックが、異なる順序になっているためです。それにより、ログに記録された配列の列と、モデルのブロックの間で、マッピングが異なります。

isequal(x1, x2)
ans =

  logical

   0

構造体形式を使用した状態のログ

再びモデルのシミュレーションを実行しますが、今回は、状態を構造体形式でログに記録します。

simOut1=sim(mdl1,'SaveFormat','Structure');
simOut2=sim(mdl2,'SaveFormat','Structure');

SimulationOutput オブジェクトから、ログに記録された状態を含んでいる構造体を抽出します。

x1s = simOut1.get('xout');
x2s = simOut2.get('xout');

2 つのフィールド timesignals を含むこれらの構造体を表示します。time フィールドは、データが StructureWithTime 形式ではなく Structure 形式を使用してログに記録されたため、空です。時間データを状態データと共に保存する必要がある場合は StructureWithTime 形式を使用できます。

disp(x1s);
disp(x2s);
       time: []
    signals: [1x2 struct]

       time: []
    signals: [1x2 struct]

構造体 signals フィールドは、状態データをもつモデル内のブロックごとに 1 つの構造体をもつ構造体の配列です。signals フィールド内の各ブロックのデータ構造体には、状態データをもつ values フィールドと、その状態データを作成したブロックの名前をもつ blockName フィールドが含まれます。状態データを行列に抽出し、Array 形式を使用して状態をログに記録した場合と同様の方法で処理できます。

状態の順序の問題を解決するために、最初にブロック名を使用して状態データを固定順序に並べ替えます。たとえば、ブロックがアルファベット順になるように状態データを並べ替えると、ブロックの並べ替え順序に関係なく、複数のシミュレーション間で一定に保たれます。

[~, idx1] = sort({x1s.signals.blockName});
x1 = [x1s.signals(idx1).values];

[~, idx2] = sort({x2s.signals.blockName});
x2 = [x2s.signals(idx2).values];

isequal(x1, x2)
ans =

  logical

   1

信号フィールドをブロック名でアルファベット順に並べ替えた後、値フィールドのデータを同じ順序で抽出すると、Array 形式を使用した場合と同様の方法でデータを処理できますが、ブロックの状態データの順序は複数のシミュレーション間で変更されません。