トラブルシューティング

一般的なシミュレーションの問題に対するトラブルシューティングの方法について学習します。

モデルのシミュレーションは、前述した3フェーズのプロセスの最後のフェーズです。最初に評価とコンパイルのフェーズが発生し、ソフトウェアのシミュレーションフェーズ中に使用する構造が生成されます。一部のエラー処理の方法は、これらのフェーズで発生する問題の対処に役立てることができます。

評価フェーズでのエラー

初期化されない変数

ブロックパラメーターの値はOML式によって定義されます。これらの式にはOML変数が含まれることがあります。Activateでは、評価フェーズに対して以下のスコーピング規則を使用します:一般的に、あるブロックを含むダイアグラムのコンテキスト、または初期化スクリプト内で定義された変数は、そのブロックのブロック式で使用できます。ダイアグラムコンテキストで使用する変数は、以下のスコーピング規則に沿って定義することが必要です。特に、OMLベースの作業領域で定義された変数が、モデルの作業領域にシステム的に追加されることはない点に注意してください。

評価フェーズで初期化されていない変数が見つかった場合は、適切なコンテキストまたは初期化スクリプト内でその変数を定義する必要があります。マスクされたスーパーブロック内で使用されるすべての変数は、スーパーブロック内でマスクパラメーターとして定義するか、コンテキストに沿って定義する必要があります。

モデルには関連付けられているが特定のダイアグラムには関連付けられていないシミュレーションパラメーターの定義で変数を使用する場合、これらの変数は初期化スクリプト内で定義されている必要があります。

パラメータータイプの不一致

ブロックパラメーター式は、ブロックによって課せられる制約のタイプに対して評価およびチェックされます。例えば、パラメーターが値として数値行列しか受け入れないのに、その式の評価で文字列が得られた場合は、エラーが生成されます。

コンパイルフェーズでのエラー

コンパイルフェーズの主な役割は、すべてのブロックに関連付けられるシミュレーション関数を検出し、シミュレーション時にブロックシミュレーション関数を呼び出す順序を指定するスケジューリングテーブルを構築することです。このステージで発生する一般的なエラーには、代数ループと、データ型およびサイズの不適合が含まれます。

代数ループ

代数ループは、モデル内のブロックアクティベーションをシミュレーション用にスケジュールできない場合に発生します。例えば、ブロックAは、フィードスループロパティにより、入力を生成するブロックからすでにその入力の値が使用可能になっている場合にのみ、アクティベートしてその出力を生成できます。このシナリオは、その入力を生成するブロックをスケジュールした後に、ブロックAをスケジュールする必要があることを意味しています。つまり、フィードスループロパティを含むブロックの入力ポートを通るパスがモデルに含まれ、そのパスがモデルを通ってループバックしている場合、ループ内のすべてのブロックで、その出力を計算するためにその出力自身の値が必要になり、矛盾が生じてしまいます。この場合、スケジューリングは行えず、モデルに代数ループがある状態だと言えます。一般的に、こうしたループは正しく作成されたモデルでは発生しません。正常なモデルの場合、ユーザー定義ブロック内のフィードスループロパティの設定にエラーがあることで、ループが発生している可能性があります。正しく作成されたモデル内にループが発生した場合は、LoopBreakerブロックをモデルに組み込むことでループを切断することができます。

代数ループはアクティベーション信号を伴う場合もあります。例えば、ジャンプオプションを持つ積分器の出力は、この出力がその積分器の新しい状態の定義に使用できないように、そのジャンプの原因となるイベントと同期化されます。問題は、アクティベーション時の出力はジャンプ後の値であるため、状態の新しい値に依存するということです。一般に、ユーザーの目的は、新しい状態の値を、ジャンプの後でなく、ジャンプの直前の出力の値に基づいて計算することです。1つの解決策は、LastInputブロックをモデルに追加することです。このブロックは入力信号の左限を提供するので、積分器の出力がこのブロックを通って新しい状態を定義する場合、ジャンプ時のアクティベーションがその新しい状態に必要な値を提供し、ループが切断されます。

代数ループは、スーパーブロックをアトミックにした場合に発生することもあります。この操作により人為的なフィードスループロパティが追加で導入され、これまでループのなかったモデルに代数ループが生まれることがあります。

ポートのデータ型およびサイズの不適合

コンパイルフェーズによって、ブロックの通常のポート間を接続する信号のデータ型とサイズが決まります。本ソフトウェア内の大部分のブロックは多様なデータ型とサイズの信号を受け入れますが、そこには特定の制約が課される場合もあります。接続では追加の制約が発生しますが、特に、接続されるポートのデータ型とサイズが同じである必要があります。ただし例外として、実数の出力ポートは複素数ポートに接続できます。コンパイルの役割は、制約条件を満たすために、すべての接続信号のデータ型とサイズを検出することです。

場合によっては、信号のデータ型とサイズに課せられた制約が一致せず、コンパイラーによってデータ型とサイズを決定するために実装された不動点反復法が、以下の理由で失敗することもあります。

行ベクトルまたは列ベクトルの差異

ソフトウェア内の信号は2次元の行列になっています。スカラー信号は1x1行列です。厳密に言うと、ベクトル信号のデータ型は存在しません。ただし、ベクトルは列ベクトルのようにnx1行列とみなされることがよくあります。列ベクトルの代わりに行ベクトルを使用すると、一部のブロックではサイズの不一致エラーが発生します。

データ型の伝播

大部分のブロックでは、入力と出力が同じデータ型である必要があります。例えば、SumブロックはすべてのActivateデータ型(実数、複素数、さまざまな整数)を受け入れますが、すべての入力とその出力は同じデータ型である必要があります。このため、データ型がモデル全体に伝播されることがよくあります。モデル内で異なるデータ型の信号が必要とされる場合は、あるデータ型を別のデータ型に明示的に変更するために、DatatypeConversionブロックを追加する必要があるかもしれません。

データ型とサイズの制約を新しいブロックに課す

新しいブロック、カスタムブロック、またはライブラリブロックを作成する場合には、可能な限り、様々なデータ型とサイズの入力および出力を可能にすることが有用です。ポートのデータ型とサイズに対する一般的な制約の指定には、高度なメカニズムが機能しますが、ほとんどの場合、不明なサイズとデータ型の指定に負の数を使用することで制約を課すことができます。例えば、入力のサイズを[-1,1]と定義した場合、その入力には任意の数の行を持つことができますが、列は1つしか持つことができません。同じブロックにサイズが[-2,-1]である別の入力が存在する場合、この入力は、最初の入力の行数と同じ数の列と、任意の数の行を持ちます。つまり、ポートサイズの定義に使用する負の数はフリーの値を意味していますが、同じブロックの別のポートサイズの定義で同じ負の数が使用されている場合は、2つのサイズは同じ値であることになります。同じことがデータ型にも当てはまります。

シミュレーションパフォーマンス

一般的に、シミュレーションパフォーマンスはモデルの複雑さとシミュレーションに求められる精度に依存しています。ただし、モデルに小規模な修正を行うことで、シミュレーション時間が大きく削減されることもあります。

OMLカスタムブロックの使用

OMLカスタムブロックにより、OMLによってブロックシミュレーションの動作を定義するオプションが提供されています。OMLプログラムは開発やデバッグが容易なだけでなく、OMLライブラリにあるすべての関数にアクセスできます。しかしOMLはインタープリター言語なので、Cなどのコンパイル言語と比べるとパフォーマンスが大幅に落ちます。この結果、OMLカスタムブロックを連続的にアクティベートすると、シミュレーションパフォーマンスが大幅に低下する可能性があります。

シミュレーション時間に問題がある場合は、OMLブロックをActivate基本ブロック(特に、MathブロックおよびMatrix Expressionブロック、またはCカスタムブロック)に置き換える必要があります。OMLカスタムブロックは離散時にのみアクティベートされますが、通常はこれによって連続時間のダイナミクスを含むモデルのパフォーマンスが大幅に低下することはありません。

ゼロクロッシング

可変ステップソルバーはシミュレーション中にステップサイズを修正します。設定された誤差のしきい値を満たすために、ソルバーは必要に応じてステップを小さくしますが、可能であればもっと大きなステップに戻し、シミュレーション時間を削減します。可変ステップソルバーを使用するときの基本的な前提は、解析される動的システムがスムーズで、一般的には2回以上微分可能であるということです。

シミュレーション対象のモデルがスムーズでない場合(一般的にはハイブリッドシステムの場合に該当する)、時間間隔を明確な間隔に分割し、各間隔において、スムーズな動的システムが数値ソルバーに提示されるようにする必要があります。そうでない場合、ソルバーはスムーズでないポイントを越えるために、ステップサイズを大幅に縮小させる必要があり、失敗する恐れもあります。

本ソフトウェアには、クリティカルイベントと非クリティカルイベントの識別に基づいて、この戦略を実装するための高度なメカニズムが含まれています。クリティカルイベントは、シミュレーション時の最大ステップサイズとコールドリスタートアクションを指定するために使用されます。

本ソフトウェアのコンパイラーおよびシミュレーターはほとんどのクリティカルイベントを特定および管理しますが、ブロック内部にスムーズでない原因が存在する場合には、ブロック自身がその原因を公開する必要があります。これは特に、ゼロクロッシングサーフェスを宣言することで実行されます。インストールされたライブラリにあるスムーズでないブロックのほとんどは、ゼロクロッシングを宣言しますが、ゼロクロッシングをオフにするオプションも用意されています。ゼロクロッシングメカニズムの使用によって、ソルバーの失敗原因となる範囲外の信号が作成されるような状況で、特定のシミュレーションが実行される可能性もあります。このような状況では、ブロックのゼロクロッシングオプションをオフにする必要があります。それ以外の場合は、良好なシミュレーションパフォーマンスを達成するために、すべてのブロックに対してゼロクロッシングオプションをオンにする必要があります。

同じ理由で、スムーズでないダイナミクスを含むすべてのユーザー定義のブロックでは(カスタムブロックであってもそうでなくても)、連続時間アクティベートされる場合には、ゼロクロッシングサーフェスを実装する必要があります。

ソルバーの選択

本ソフトウェアでは、多くの数値ソルバーが提供されています。モデルによってはソルバーを変更した方がよい場合があります。。適切なソルバーを選択するための単純な規則はありませんが、一般的には、固定ステップソルバーを使用する特別な理由がない限り、可変ステップソルバーを使用してください。誤差しきい値を緩めても、可変ステップソルバーが失敗したり遅すぎたりする場合は、一般的にはモデルにスムーズでない部分が隠れて存在していると考えられるので、固定ステップソルバーを使用してください。ステップサイズの選択は適切に行う必要があります。固定ステップソルバーにはエラー制御メカニズムが存在しないことに注意してください。

スライディングモード

ハイブリッドシステムでは、シミュレーション中に動的挙動を切り替えられます。いくつかのケースでは、サーフェスに収束するソリューションによって、次への切り替えの時間差がゼロになっていく場合もあります(ゼロ挙動)。このスライディングサーフェスに制約される動作を得るため、システムの動的挙動を再定式化することができます。こうしたダイナミクスはスライディングモードにあると言えます。しかし、こうした変換は、Activateなどの一般目的のソルバーでは実行できません。ゼロクロッシングを用いてスライディングサーフェスが正しく宣言されている場合、可変ステップソルバーが使用されていると想定され、切り替えのたびにソルバーが停止と再起動を行い、シミュレーションがある時点でフリーズしてしまいます。

スライディングサーフェスがゼロクロッシングを用いて実装されていない場合には、シミュレーションが低速で進行し、ソリューションは高周波のチャタリングを示します。これによって、スライディングモードのオリジナルモデルに、許容できる近似ソリューションが提供されることもあります。この場合には、固定ステップソルバーを代替策として使用できます。しかし、ほとんどの場合、スライディングモードがモデル内に実際に存在しており、それがモデリングエラーの結果ではない場合には、モデルに対する修正を検討する必要があります。そこには、動的挙動、ヒステリシス、または陽的な時間遅延を追加導入して、チャタリングを削減することも含まれます。一般的に、こうした動作は、スライディングモードが遭遇する制御モデルの実際のダイナミクスをより適切に表しています。

ScopeブロックとDisplayブロック

ScopeブロックとDisplayブロックを過度に使用すると、シミュレーション速度が低下します。これらのブロックをデバッグ目的でモデル内に多数配置することはできますが、特定のシミュレーションの実行に本当に必要なものはわずかです。シミュレーション時間を短縮するには、これらのブロックのいくつかのステータスをオフにします。ステータスをオフにするとそのブロックがシミュレーション構造から削除され、シミュレーションのパフォーマンスは、それをブロックから完全に削除した場合とまったく同じレベルになります。

リアルタイムスケーリング

リアルタイムスケーリングのモデルパラメーターは、リアルタイムでの実行を可能にするために、シミュレーションの速度を低下させます。このパラメーターが正しく設定されないと、シミュレーションは低速になり過ぎてしまいます。パラメーター値をゼロに設定すると、シミュレーションは可能な限り高速で実行されます。

プロファイリング
モデルのシミュレーションパラメータを定義するときにデバッグファイルの作成のオプションを選択すると、シミュレーションの解析で効果的なプロファイリング情報を収めた.csvファイル(<modelname>_profile.csv)も生成されます。
プロファイリングファイルとデバッグファイルを作成するには、シミュレートツールグループでシミュレーションパラメータを選択します。
デバッグタブでデバッグファイルの作成を選択し、デバッグファイルの名前と保存先を入力してOKをクリックします。


シミュレーションを実行すると、デバッグファイルのほかにプロファイリングファイル<modelname>_profile.csvが生成され、モデルの一時ディレクトリ(tempdir)に保存されます。
NoteColonSymbol tempdirは、シミュレーションの実行時にOMLコマンドウィンドウに表示されます。このディレクトリの位置は、コマンドGetCurrentModelTempDirで照会できます。

プロファイリングファイルには、各ブロックの実行時間、およびシミュレーションでブロックが呼び出された回数とそのときの状態(フラグ)が記録されています。この情報はブロックごとに列形式で表示され、フラグごとのブロックの呼び出し回数が示されます。各フラグは次のように定義されています。

発行するフラグ番号 フラグの定義
Flag 0 VssFlag_Derivatives
Flag 1 VssFlag_OutputUpdate
Flag 2 VssFlag_StateUpdate
Flag 3 VssFlag_EventScheduling
Flag 4 VssFlag_Initialize
Flag 5 VssFlag_Terminate
Flag 6 VssFlag_Reinitialize
Flag 7 VssFlag_ReinitializeImplicit
Flag 8 VssFlag_Projection
Flag 9 VssFlag_ZeroCrossings
Flag 10 VssFlag_Jacobians
Flag 11 VssFlag_GotoPause
Flag 12 VssFlag_ReturnFromPause

シミュレーションの失敗

ブロックの特異性

ブロックシミュレーション関数が範囲外の入力(ゼロによる除算など)を使用して計算を実行すると、エラーが生成されます。許容される演算はサポートされるデータ型によって決まります。例えば、Logブロックでは、出力は実数となるように定義されているので、負の実数の入力は受け入れられません。ただしLogブロックでは、複素データ型の負の値の入力は受け入れられます。

NoteColonSymbol 特異性の問題は、すべてのブロックの出力がデフォルトでゼロに設定されている場合に、シミュレーションの開始時に発生する可能性があります。
シミュレーションのフリーズ

スライディングモードが存在するとシミュレーション速度が低下する可能性がありますが、場合によってはシミュレーションが停止したり、エラーが生成されたりすることもあります。詳細は、スライディングモードの項をご参照ください。

非収束

モデルに不安定なモードが存在する場合に、ソルバーが収束しないことはよくあります。発散は非常に急速に発生する場合もありますが、通常は、Scopeブロックをモデルに追加して状態の値を可視化することで確認できます。非収束の理由としてもう1つ考えられるのは、スムーズでない部分が隠れて存在していることです。

エラーメッセージ

サポートされていないVisual C++ターゲットオプション
FMIのインポート / エクスポートやModelicaモデルのシミュレーションなどの一部の使用状況では、本ソフトウェアは、システムにインストールされたC++コンパイラーを検出できない場合はエラーを発行します。このエラーを修正するには、サポートされているMicrosoft Visual Studio C++コンパイラーをインストールしてください。システムにインストールされているコンパイラーを表示するには、OMLコマンドウィンドウでvssGetCompilerName()と入力します。