このページは前リリースの情報です。該当の英語のページはこのリリースで削除されています。
構造体形式での状態のログ
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');
x1
と x2
に対してログに記録された状態データが異なるのは、ブロックが、異なる順序になっているためです。それにより、ログに記録された配列の列と、モデルのブロックの間で、マッピングが異なります。
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 つのフィールド time
と signals
を含むこれらの構造体を表示します。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
形式を使用した場合と同様の方法でデータを処理できますが、ブロックの状態データの順序は複数のシミュレーション間で変更されません。