| Real-Time Workshop User's Guide | ![]() |
モデルの実行
生成コードの2つのスタイルを説明する前に、生成モデルコードがどのように実行されるかを理解する必要があります。Real-Time Workshopは、モデルで定義されたようにアルゴリズム的なコードを生成します。S-ファンクションを使ってユーザ独自のコードをモデルに含めることができます。S-ファンクションの範囲は、上流の信号操作アルゴリズムから下流のデバイスドライバまでです。
Real-Time Workshopは、生成されたモデルコードを実行するランタイムインタフェースも提供します。ランタイムインタフェースおよびモデルコードは、モデルの実行ファイルを作成するため、一緒にコンパイルされます。下図は、実行ファイルの高水準のオブジェクト指向を表示しています。

図 6-1: リアルタイムプログラムのオブジェクト指向の表示
一般的に、モデルの実行ドライバの概念的な設計は、生成されたコードのラピッドプロトタイピングスタイルと組み込みシステムスタイルとで変わりません。つぎの節では、シミュレーション(非リアルタイム)およびリアルタイムの両方について、シングルタスクおよびマルチタスク環境でのモデルの実行を説明します。ほとんどのモデルに対して、マルチタスク環境は、最も効率的なモデルの実行(すなわち最速のサンプルレート)を提供します。
つぎの概念は、モデルがどのように実行されるかを説明するために役立ちます。
Initialization -- ランタイムインタフェースコードとモデルコードの初期化ModelOutputs -- カレントポイントでヒットする時間をもつモデル内のすべてのブロックを呼び出し、それらの出力を生成します。ModelOutputsは、メジャー時間ステップまたはマイナー時間ステップで行うことができます。メジャー時間ステップでは、出力は与えられたシミュレーション時間ステップです。マイナー時間ステップでは、ランタイムインタフェースは微係数を積分して連続状態をアップデートします。ModelUpdate -- カレントポイントでサンプルヒットするモデル内のすべてのブロックを呼び出し、離散状態または同様のタイプのオブジェクトを更新します。ModelDerivatives -- 連続状態をもつモデル内のすべてのブロックを呼び出し、それらの微係数を更新します。ModelDerivativesは、マイナー時間ステップでのみ呼び出されます。下記のコードは、シングルタスクシミュレーション(非リアルタイム)用のモデルの実行を示しています。
main()
{
Initialization
While (time < final time)
ModelOutputs -- メジャー時間ステップ
LogTXY -- 時間、状態、ルートのoutportをロギング
ModelUpdate -- メジャー時間ステップ
Integrate: -- 連続状態をもつモデルに対して、マイナー
-- 時間ステップで積分
ModelDerivatives
Do 0 or more:
ModelOutputs
ModelDerivatives
EndDo (ソルバに応じた繰り返し回数)
微係数を積分して連続状態をアップデート
EndIntegrate
EndWhile
Shutdown
}
初期化フェーズが最初に開始されます。これは、モデルの状態の初期化と、実行エンジンの設定で構成されます。モデルはその後1つの時間で1ステップ実行されます。最初に、ModelOutputsは時間tで実行され、ワークスペースI/Oデータがロギングされ、その後ModelUpdateは離散状態をアップデートします。つぎに、モデルは連続状態をもつ場合は、ModelDerivativesは連続状態微係数を積分して時間
に対する状態を生成します。ここで、hはステップサイズです。その後時間は
に進行し、プロセスを繰り返します。
モデル実行のModelOutputs およびModelUpdateフェーズ中に、カレントポイントをヒットするブロックのみが実行されます。サンプルヒットをチェックするマクロ(ssIsSampleHitまたはssIsSpecialSampleHit)を使って、ヒットしたかどうかを決定します。
つぎのコードは、マルチタスクシミュレーション(非リアルタイム)に対するモデルの実行を示します。
main()
{
Initialization
While (time < final time)
ModelOutputs(tid=0) -- メジャー時間ステップ
LogTXY -- 時間、状態、ルートのoutportをロギング
ModelUpdate(tid=1) -- メジャー時間ステップ
For i=1:NumTids
ModelOutputs(tid=i) -- メジャー時間ステップ
ModelUpdate(tid=i) -- メジャー時間ステップ
EndFor
Integrate -- 連続状態をもつモデルに対してマイナー時間
-- ステップで積分
ModelDerivatives
Do 0 or more:
ModelOutputs(tid=0)
ModelDerivatives
EndDo (ソルバに応じた繰り返し回数)
微係数を積分して連続状態をアップデート
EndIntegrate
EndWhile
Shutdown
}
出力関数と更新関数は、これらの関数に渡されるタスク識別子 (tid)によって分割されるので、マルチタスクの操作は、シングルタスクの実行と比較して複雑です。このため、オーバラップする割り込みを使って異なるタスク識別子をもつ関数を複数呼び出したり、リアルタイムオペレーティングシステムの使用時に複数のタスクを行うことができます。シミュレーションでは、複数のタスクは、リアルタイムシステムでプリエンプションがない場合には、コードを発生する順番に実行することによってエミュレートされます。
マルチタスクの実行は、すべてのタスクがベースレートの倍数であることを仮定しています。固定ステップマルチタスクモデルの作成時にSimulinkは、これを実行します。
マルチタスク実行ループは、argument to ModelOutputs および ModelUpdateのタスク識別子(tid)引数の利用を除いて、シングルタスクと非常に似ています。ssIsSampleHit または ssIsSpecialSampleHitマクロは、tidを使っていつブロックがヒットするかを決定します。たとえば、ModelOutputs (tid=5)は、タスク識別子5に対応するサンプル時間をもつブロックのみを実行します。
つぎのコードは、モデルが割り込みレベルで実行されている、リアルタイムシングルタスクシステムのモデルの実行を示します。
rtOneStep()
{
Check for interrupt overflow
Enable "rtOneStep" interrupt
ModelOutputs -- メジャー時間ステップ
LogTXY -- 時間、状態、ルートのoutportをロギング
ModelUpdate -- メジャー時間ステップ
Integrate -- 連続状態をもつモデルに対してマイナー時間
-- ステップで積分
ModelDerivatives
Do 0 or more
ModelOutputs
ModelDerivatives
EndDo (ソルバに応じた繰り返し回数)
微係数を積分して連続状態をアップデート
EndIntegrate
}
main()
{
Initialization (リアルタイムクロックに対して、rtOneStepを
割り込みサービスルーチンISRとしてインストールすることを含む)
While(time < final time)
バックグランドタスク
EndWhile
Mask interrupts (rtOneStepを実行不可能にする)
バックグランドタスクを終了
シャットダウン
}
リアルタイムのシングルタスクの実行は、モデルコードの実行が割り込みレベルで行われることを除いて、非リアルタイムのシングルタスクの実行と非常に似ています。
プログラムのベースサンプルレートで指定された間隔で、割り込みサービスルーチン(ISR)は、バックグランドタスクをプリエンプトしてモデルコードを実行します。ベースサンプルレートは、モデル内の最速のレートです。モデルが連続ブロックをもつ場合は、積分ステップサイズは、ベースサンプルレートを決定します。
たとえば、モデルコードが100 Hzで実行されるコントローラの場合、0.01秒毎にバックグランドタスクが割り込みされます。この割り込みの間に、コントローラは、アナログ-ディジタルコンバータ(ADC)から入力を読み込み、出力を計算し、それらの出力をディジタル-アナログコンバータ(DAC)に書き込み、状態を更新します。その後プログラムのコントロールは、バックグランドタスクに戻ります。これらのすべてのステップは、つぎの割り込みの前に発生しなければなりません。
つぎの擬似コードは、モデルがリアルタイムマルチタスクシステムでどのように実行されるかを示します(モデルは割り込みレベルで実行されます)。
rtOneStep()
{
割り込みオーバフローのチェック
Enable "rtOneStep" interrupt
ModelOutputs(tid=0) -- メジャー時間ステップ
LogTXY -- 時間、状態、ルートのoutportをロギング
ModelUpdate(tid=0) -- メジャー時間ステップ
Integrate -- 連続状態をもつモデルに対してマイナー
-- 時間ステップで積分
ModelDerivatives
Do 0 or more:
ModelOutputs(tid=0)
ModelDerivatives
EndDo (ソルバに応じた繰り返し回数)
微係数を積分して連続状態をアップデート
EndIntegrate
For i=1:NumTasks
If (hit in task i)
ModelOutputs(tid=i)
ModelUpdate(tid=i)
EndIf
EndFor
}
main()
{
Initialization (リアルタイムクロックに対してrtOneStepを割り込み
サービスルーチンISRとしてインストールすることを含む)
While(time < final time)
バックグランドタスク
EndWhile
Mask interrupts(rtOneStepの実行を不可能にする)
バックグランドタスクの終了
シャットダウン
}
リアルタイムマルチタスク環境で割り込みレベルにおいてモデルを実行することは、オーバラップした割り込みがタスクの同時実行に対して用いられることを除いて、シングルタスク環境と非常に似ています。
リアルタイムオペレーティングシステムの初期タスク利用時のシングルタスクまたはマルチタスク環境でのモデルの実行は、上記で説明した割り込みレベルの例と非常に似ています。つぎの擬似コードは、初期リアルタイムタスクを利用したシングルタスクモデルに対するものです。
tSingleRate()
{
MainLoop:
clockSemが既に与えられている場合は、オーバフローによるエラー Wait on clockSem
ModelOutputs -- メジャー時間ステップ
LogTXY -- 時間、状態、ルートのoutportをロギング
ModelUpdate --メジャー時間ステップ
Integrate -- 連続状態をもつモデルに対して、マイナー
-- 時間ステップで積分
ModelDeriviatives
Do 0 or more:
ModelOutputs
ModelDerivatives
EndDo (ソルバに応じた繰り返し回数)
微係数を積分して連続状態をアップデート
EndIntegrate
EndMainLoop
}
main()
{
Initialization
Start/spawn task "tSingleRate".
clockSemセマフォにおいて"semGive"を行うクロックを開始
"model-running" セマフォを待つ
シャットダウン
}
このシングルタスク環境で、モデルは、リアルタイムオペレーティングシステムタスクを使って実行されます。この環境では、シングルタスク(tSingleRate)を作成してモデルコードを実行します。このタスクは、クロック点が発生するときに呼び込まれます。クロック点は、モデルタスクに(tSingleRate)clockSem (クロックセマフォ)を与えます。モデルタスクは、実行する前にセマフォを待ちます。クロック点は、モデルに対して基本的なステップサイズ(ベースレート)で発生するように設定されます。
つぎの擬似コードは、初期リアルタイムタスクを使ったマルチタスクモデルに対するものです。
tSubRate(subTaskSem,i)
{
Loop:
セマフォのsubTaskSemを待つ
ModelOutputs(tid=i)
ModelUpdate(tid=i)
EndLoop
}
tBaseRate()
{
MainLoop:
clockSemが既に与えられている場合は、オーバフローによるエラー
clockSemを待つ
For i=1:NumTasks
If (hit in task i)
タスクiが現在実行中の場合は、
オーバフローエラー
タスクiに対してsubTaskSemについて"semGive"を行う.
EndIf
EndFor
ModelOutputs(tid=0) -- メジャー時間ステップ
.
LogTXY -- 時間、状態、ルートのoutportをロギング
ModelUpdate(tid=0) -- メジャー時間ステップ
Loop: -- 連続状態をもつモデルに対してマイナー時間.
-- ステップで積分
ModelDeriviatives
Do 0 or more:
ModelOutputs(tid=0)
ModelDerivatives
EndDo (ソルバに応じた繰り返し回数)
微係数を積分して連続状態をアップデート
EndLoop
EndMainLoop
}
main()
{
Initialization
Start/spawn task "tSingleRate".
clockSemセマフォにおいて "semGive"を行うクロックを開始
"model-running"セマフォを待つ
シャットダウン
}
このマルチタスク環境で、モデルはリアルタイムオペレーティングシステムタスクを使って実行されます。この環境では、複数のモデルタスク(tBaseRateおよび複数のtSubRateタスク)を作成して、モデルコードを実行することが必要です。ベースレートタスク(tBaseRate)は、サブレートタスクよりも高い優先度をもちます。tid=1に対するサブレートタスクは、tid=2に対するサブレートタスクよりも高い優先度をもちます。ベースレートタスクは、クロック点の発生時に呼び込まれます。クロック点は、tBaseRateにclockSemを与えます。tBaseRateが行う最初のことは、カレントポイントでヒットするサブタスクにセマフォを与えることです。ベースレートタスクは、高い優先度をもつので、実行を継続します。つぎに、最速のサンプルレートをもつモデル内のブロックを構成する最速のタスク (tid=0) を実行します。この実行後に、クロックセマフォの待ちを再開します。クロックティックは、モデルに対する基本ステップサイズでの実行時に発生するように設定されます。
| プログラムアーキテクチャ | プログラムのタイミング | ![]() |