コード生成時のモデリング セマンティクスの考慮
データの伝播
コード生成の第 1 ステージでは、ブロック線図をコンパイルします。このステージは C または C++ プログラムと類似しています。コンパイラはデータ型のチェックと前処理を実行します。同様に、Simulink® エンジンは、ブロック端子の入力と出力のデータ型が一致していること、ブロック間のライン幅が期待どおりの太さであること、接続するブロックのサンプル時間が一致していることをチェックします。
Simulink エンジンは、1 つのブロックから信号線に沿って次のブロックにデータを伝播します。伝播されるデータの構成は次のとおりです。
データ型
ライン幅
サンプル時間
次のように入力すると、Simulink ブロックがサポートするデータ型を確認できます。
と MATLAB® のプロンプトで入力するか、ヘルプ ブラウザーから上記のコマンドをクリックします。
通常、Simulink エンジンはソース ブロックから信号属性を得ます。たとえば、Inport ブロックのパラメーター ダイアログ ボックスがブロックの信号属性を指定しています。
この例では、Inport ブロックの端子幅は 3、サンプル時間は 0.01 秒、データ型は double、信号は複素数です。
この図は、シンプルなブロック線図を通じて、Inport ブロックに関連付けられている信号属性を伝播する様子を示しています。
この例で、Gain ブロックと Outport ブロックは、Inport ブロックとして指定された属性を継承します。
サンプル時間の伝播
ソース ブロック (例: ルート Inport ブロック) に継承されたサンプル時間は、予測も意図もしないサンプル時間割り当てとなる場合があります。ブロックが、継承されたサンプル時間を指定する場合があるため、初期段階の情報は不十分で、ブロック線図を完全にコンパイルできない可能性があります。
このような場合、Simulink エンジンは、既知または割り当てられたサンプル時間をこれらのブロックに伝播します。これらのブロックではサンプル時間を継承しますが、サンプル時間は割り当てられていません。そのためエンジンは、できるだけ多くのブロックにサンプル時間が割り当てられるまで空白 (不明なサンプル時間) を満たし続けます。サンプル時間をもたないブロックには既定のサンプル時間が割り当てられます。
完全に確定的なモデル (上記のルールに従ってサンプル時間が設定されないモデル) を得るには、ソース ブロックのサンプル時間を明示的に指定しなければなりません。ソース ブロックには、ルート Inport ブロックと、入力端子をもたないブロックが含まれます。サブシステムの入力端子のサンプル時間を設定する必要はありません。ただし、モジュール システムを作成するときはサンプル時間を設定することもできます。
未接続の入力は、暗黙的に Ground ブロックに接続されます。Ground ブロックおよびグラウンド接続の場合、サンプル時間は常に一定です (inf
)。
すべてのブロックが継承サンプル時間 (Ts = -1) をもちます。ブロックには (Tf - Ti)/50 のサンプル時間が割り当てられます。
出力に定数値があるブロック
サンプル時間の色を表示すると、既定では、Constant ブロックがマゼンタで表示され、シミュレーション時のブロック出力に定数値があることを示します。Gain ブロックなど、シミュレーション時の出力値が定数である下流ブロックも、継承したサンプル時間を使用する場合は同様にマゼンタで表示されます。これらのブロック用に生成されたコードは、ブロック パラメーターの調整可能性に部分的に依存します。
モデル コンフィギュレーション パラメーター [既定のパラメーター動作] を [インライン]
に設定すると、ブロック パラメーターは生成されたコードで調整可能になりません。ブロック出力は定数であるため、コード ジェネレーターは定数畳み込みによりブロック符号を除去します。コード ジェネレーターでコードを折りたたむことができない場合や、定数畳み込みを無効にする設定を選択した場合は、ブロック符号がモデル初期化関数に表示されます。これらのブロックの出力は実行中に計算されないため、生成されたコードはより効率的になります。
ただし、ブロック パラメーターが調整可能な変数として生成されたコードに表示されるようにブロックまたはモデルを構成すると、コード ジェネレーターは異なる方法でブロックを表します。ブロック パラメーターは以下のような場合に調整可能になります。
パラメーター [既定のパラメーター動作] を
[調整可能]
に設定した場合。既定では、数値ブロック パラメーターはグローバル パラメーター構造体の調整可能なフィールドとして表示されます。Simulink.Parameter
オブジェクトなど、Auto
以外のストレージ クラスを使用する調整可能なパラメーターを、1 つ以上の数値ブロック パラメーターの値として使用する場合。これらのブロック パラメーターは、モデル コンフィギュレーション パラメーター [既定のパラメーター動作] に選択した設定に関係なく、調整可能になります。
ブロック パラメーターが調整可能な場合、実行中に生成されたコードでブロック出力を計算しなければなりません。したがって、ブロック符号はモデルの関数 step
に表示されます。モデルで複数の離散レートを使用する場合、ブロック符号はブロック出力を使用する最も速い下流レートの出力関数に表示されます。
Subsystem ブロックのラッチ
Inport ブロックが Triggered Subsystem または Function-Call Subsystem の信号ソースである場合は、ラッチ オプションを使用して、サブシステムを実行中に入力値を保持することができます。Inport ブロックのラッチ オプションには、次のものが含まれます。
適用対象 | 使用 |
---|---|
Triggered Subsystem | 外部信号を遅延して入力をラッチ |
Function-Call Subsystem | Function-Call Subsystem 出力のフィードバック信号の入力をラッチする |
Function-Call Subsystem に対してサブシステム ブロック パラメーター [Function-Call Subsystem 出力のフィードバック信号の入力をラッチする] を選択すると、コード ジェネレーターは以下を行います。
設定された最適化にかかわらず、生成コード内でラッチを保持します。
ラッチ対象のコードをサブシステムの出力/更新関数の先頭に置きます。
これらのオプションの詳細については、Inport のブロックの説明を参照してください。
ブロックの実行順序
Simulink エンジンによってブロック線図がコンパイルされると、
ファイル (C または C++ ファイルから生成されたオブジェクト ファイルと類似している) が作成されます。model
.rtw
ファイルには、モデルのすべての接続情報と信号属性が含まれています。そのため、タイミング エンジンは、レートの異なるブロックをいつ実行するかを決定できます。model
.rtw
手書きのコード内のブロックをモデルに直接呼び出しても、この実行順序をオーバーライドすることはできません。たとえば、次の図の左側の disconnected_trigger
モデルでは、トリガー端子が接地されています。これにより、ブロックに定数サンプル時間が継承されるようになります。ユーザー コードからトリガー関数 f()
を直接呼び出しても機能しません。代わりに、右側の connected_trigger
モデルに示すように、関数呼び出しジェネレーターを使用して、f()
が実行されるレートを指定してください。
関数呼び出しジェネレーターの代わりに、トリガー端子を駆動できる別のブロックを使用することもできます。その後で、モデルのメイン エントリ ポイントを呼び出して、トリガー関数を実行してください。
マルチレート モデルの場合、コード ジェネレーターの一般的な利用法は、個々のモデルにコードを別々に作成してから生成されたコード モジュール間の I/O を手動でコーディングすることです。この方法でのモデル間のデータの整合性は、モデルの開発者が責任を負わなければなりません。別の方法として、Simulink とコード ジェネレーターを使ってレート間のデータの整合性を維持し、マルチタスク環境で使用できるようにマルチレート コードを生成する方法があります。Rate Transition ブロックには、周期的信号と非同期信号を接続できます。Simulink Coder™ のブロック ライブラリの詳細については、非同期イベントを参照してください。マルチレート コード生成の詳細については、マルチタスク実行のモデル化を参照してください。
代数ループ
代数ループは、変数間の循環依存関係です。代数ループがあると、値を直接計算できません。たとえば、次の方程式系の場合、
x = y + 2
y = -x
x
と y
の値を直接計算することはできません。
これを解くには、x
と y
のどちらか一方に対して可能性のある解を反復して試します (探索に基づいた勾配を使用するなどの高度な処理方法で)。すなわち方程式系を "解き" ます。前の例では、明示的な形式にシステムを解くと次のようになります。
2x = 2
y = -x
x = 1
y = -1
直達のあるブロック (Gain、Sum、Product、Transfer Fcn など) の出力が入力として同じブロックにフィードバックされる場合は常に、代数ループが存在します。次のブロック線図のように、Simulink エンジンは、代数ループを含むモデルを解くことができます。
コード ジェネレーターは代数ループを解くコードを生成しません。この制約には、フィードバック パスに Algebraic Constraint ブロックを使用するモデルが含まれます。しかし多くの場合、Simulink エンジンは、モデルに含まれる方程式を特定方法でグループ化することにより、発生する代数ループを除去できます。更新関数と出力関数を分割することで代数ループを除去して、循環依存関係を回避します。詳細については、代数ループの概念を参照してください。
Triggered Subsystem 内の代数ループ
Simulink エンジンは Atomic Subsystem と Enabled Subsystem に関与する代数ループを最小に削減できますが、一部の Triggered Subsystem には特別な配慮が必要です。コードを生成できる例を、次のモデルと Triggered Subsystem に示します。
既定の Simulink の動作とは、サブシステムの出力メソッドと更新メソッドを組み合わせることです。サブシステム内の Unit Delay ブロックに直達がなくても、ここでは見かけの代数ループが作成されます。
可能であれば Triggered Subsystem と Enabled-Triggered Subsystem の出力と更新メソッドを分けることで、Simulink エンジンを使用して問題を解くことができます。コード ジェネレーターでこの機能を利用するには、サブシステム ブロック パラメーター [代数ループの発生の最小化] を選択します。このパラメーターを選択して、ループに関与している Triggered Subsystem での代数ループ警告を回避します。
メモ
このボックスをオンにすると、実際にそのサブシステムがループに関与していなくても、サブシステムの生成コードには分割された出力および更新メソッドが含まれています。また、直達ブロック (Gain ブロックなど) を上記の Triggered Subsystem 内の Inport に接続している場合も、Simulink エンジンは問題を解くことができず、コード ジェネレーターもコードを生成できません。
モデル コンフィギュレーション パラメーター [代数ループの発生の最小化] も利用できます。これを選択すると、コード ジェネレーターは、代数ループに関与している Model ブロックを含んでいるモデルのコードを生成することができます。