コネクティブ ジャンクションを使用した複数パスの表現
遷移セグメントのラベル形式
ジャンクションに入力される遷移セグメントのラベル形式は、以下の例に示すように、ステートに入力される遷移の場合と同じです。チャートでは、出力遷移の暗黙的な順序付けが使用されます (暗黙的な順序付けを参照)。
以下の例では、遷移の実行は次のように発生します。
イベントが発生すると、ステート
S1
は一致するイベントが指定された出力遷移をチェックします。一致するイベントを含む遷移が検出された場合は、その遷移の条件 (大かっこで囲まれた部分) が評価されます。
condition_1
が真として評価された場合は、条件アクションcondition_action
(大かっこで囲まれた部分) が実行されます。ジャンクションからの出力遷移は、有効な遷移に対してチェックされます。
condition_2
は真であるため、有効なステート間の遷移 (S1
からS2
) が存在します。ステート
S1
の exit アクションが実行されて完了します。ステート
S1
が非アクティブとしてマークされます。遷移アクション
transition_action
が実行されて完了します。ステート間の遷移 (
S1
からS2
) 全体が発生します。ステート
S2
がアクティブとしてマークされます。ステート
S2
の entry アクションが実行されて完了します。
if-then-else 判断の構成
以下の例は、if-then-else
判断の構成の動作を示しています。チャートでは、出力遷移の暗黙的な順序付けが使用されます (暗黙的な順序付けを参照)。
最初は、チャートはスリープ状態です。ステート A
がアクティブです。条件 [C_two]
は真です。イベント E_one
が発生して、チャートを起動します。このイベントは、チャートのルートからチャートの階層の下方向に処理されます。
チャートのルートは、
E_one
の結果、有効な遷移が存在するかどうかをチェックします。ステート
A
からコネクティブ ジャンクションへの有効な遷移セグメントが存在します。暗黙的な順序付けが適用されるため、コネクティブ ジャンクションの 12 時の位置から始まる遷移セグメントの妥当性が評価されます。条件 [C_one
] というラベルが追加された最初の遷移セグメントは無効です。条件 [C_two
] というラベルが追加された次の遷移セグメントは有効です。ステートA
からC
への遷移全体は有効です。ステート
A
の exit アクション (exitA()
) が実行されて完了します。ステート
A
が非アクティブとしてマークされます。ステート
C
がアクティブとしてマークされます。ステート
C
の entry アクション (entC()
) が実行されて完了します。チャートはスリープ状態に戻ります。
このシーケンスは、イベント E_one
に関連する Stateflow® チャートの実行を完了します。
自己ループ遷移
以下の例は、コネクティブ ジャンクションによる自己ループ遷移の動作を示しています。チャートでは、出力遷移の暗黙的な順序付けが使用されます (暗黙的な順序付けを参照)。
最初は、チャートはスリープ状態です。ステート A
がアクティブです。条件 [C_one]
は偽です。イベント E_one
が発生して、チャートを起動します。このイベントは、チャートのルートからチャートの階層の下方向に処理されます。
チャートのルートは、
E_one
の結果、有効な遷移が存在するかどうかをチェックします。ステートA
からコネクティブ ジャンクションへの有効な遷移セグメントが存在します。暗黙的な順序が適用されるため、条件のラベルが追加された遷移セグメントの妥当性が検証されます。条件 [C_one
] は無効であるため、ステートA
からステートB
への遷移全体が無効です。コネクティブ ジャンクションからステートA
に戻る遷移セグメントは有効です。ステート
A
の exit アクション (exitA()
) が実行されて完了します。ステート
A
が非アクティブとしてマークされます。遷移アクション
A_two
が実行されて完了します。ステート
A
がアクティブとしてマークされます。ステート
A
の entry アクション (entA()
) が実行されて完了します。チャートはスリープ状態に戻ります。
このシーケンスは、イベント E_one
に関連する Stateflow チャートの実行を完了します。
for ループの構成
以下の例は、コネクティブ ジャンクションによる for
ループの動作を示しています。チャートでは、出力遷移の暗黙的な順序付けが使用されます (暗黙的な順序付けを参照)。
最初は、チャートはスリープ状態です。ステート A
がアクティブです。イベント E_one
が発生して、チャートを起動します。このイベントは、チャートのルートからチャートの階層の下方向に処理されます。
チャートのルートは、
E_one
の結果、有効な遷移が存在するかどうかをチェックします。ステートA
からコネクティブ ジャンクションへの有効な遷移セグメントが存在します。遷移セグメントの条件アクションi = 0
が実行されて完了します。コネクティブ ジャンクションから出力される 2 つの遷移セグメントのうち、コネクティブ ジャンクションへの自己ループである遷移セグメントの妥当性が次に評価されます。このセグメントに条件が指定されているのに対して、もう一方のセグメントにはラベルが追加されていないため、このセグメントが優先的に評価されます。この評価の動作は、チャート内の出力遷移の暗黙的な順序付けを反映します。条件
[i < 10]
が真として評価されます。条件が偽になるまで、条件アクションi++
とfunc1
への呼び出しが実行されて完了します。コネクティブ ジャンクションは最終的な遷移先ではないため、遷移先はまだ不明です。ステート
B
への無条件セグメントが有効になっています。ステートA
からB
への遷移全体は有効です。ステート
A
の exit アクション (exitA()
) が実行されて完了します。ステート
A
が非アクティブとしてマークされます。ステート
B
がアクティブとしてマークされます。ステート
B
の entry アクション (entB()
) が実行されて完了します。チャートはスリープ状態に戻ります。
このシーケンスは、イベント E_one
に関連するこのチャートの実行を完了します。
フロー チャート表記法
以下の例では、フロー チャート表記法を使用した Stateflow チャートの動作を説明します。チャートでは、出力遷移の暗黙的な順序付けが使用されます (暗黙的な順序付けを参照)。
最初は、チャートはスリープ状態です。ステート A.A1
がアクティブです。条件 [C_one()]
は最初から真です。イベント E_one
が発生して、チャートを起動します。このイベントは、チャートのルートからチャートの階層の下方向に処理されます。
チャートのルートは、
E_one
の結果、有効な遷移が存在するかどうかをチェックします。有効な遷移は存在しません。ステート
A
は自身の有効な遷移をチェックして、コネクティブ ジャンクションへの有効な内部遷移が存在することを検出します。次に選択可能な遷移セグメントが評価されます。出力する遷移は 1 つのみであり、この遷移には条件アクションが定義されています。条件アクションが実行されて完了します。
次に選択可能なセグメントが評価されます。2 つの出力遷移が存在しており、一方は条件付き自己ループ遷移セグメント、もう一方は無条件遷移セグメントです。暗黙的な順序付けが適用されるため、ステート付き遷移セグメントの処理が優先されます。条件
[C_one()]
がテストされて真であると確定されるため、自己ループ遷移が実行されます。最終遷移先には到達していないため、この自己ループは[C_one()]
が偽になるまで継続します。5 回の反復後、
[C_one()]
は偽になると仮定します。次に選択可能な遷移セグメント (次のコネクティブ ジャンクションへの遷移) が評価されます。これは、条件アクションを含む無条件遷移セグメントです。遷移セグメントが処理されて、条件アクション
{d=my_func()}
が実行されて完了します。d
の戻り値は 84 です。次に選択可能な遷移セグメントが評価されます。3 つの出力遷移セグメントが存在します。2 つは条件付きで 1 つは無条件です。暗黙的な順序付けが適用されるため、2 つの条件付き出力遷移セグメントの配置に基づいて、条件
[d < 100]
というラベルが追加されたセグメントが最初に評価されます。d
の戻り値は 84 であることから、条件[d < 100]
が真であり、この遷移 (遷移先ステートA.A1
への遷移) は有効になります。ステート
A.A1
の exit アクション (exitA1()
) が実行されて完了します。ステート
A.A1
が非アクティブとしてマークされます。ステート
A.A1
がアクティブとしてマークされます。ステート
A.A1
の entry アクション (entA1()
) が実行されて完了します。チャートはスリープ状態に戻ります。
このシーケンスは、イベント E_one
に関連する Stateflow チャートの実行を完了します。
共通の遷移元から複数の遷移先への遷移
以下の例は、コネクティブ ジャンクションを経由した共通の遷移元から複数の条件付き遷移先への遷移の動作を示しています。チャートでは、出力遷移の暗黙的な順序付けが使用されます (暗黙的な順序付けを参照)。
最初は、チャートはスリープ状態です。ステート A
がアクティブです。イベント E_two
が発生して、チャートを起動します。このイベントは、チャートのルートからチャートの階層の下方向に処理されます。
チャートのルートは、
E_two
の結果、有効な遷移が存在するかどうかをチェックします。ステートA
からコネクティブ ジャンクションへの有効な遷移セグメントが存在します。暗黙的な順序付けが適用されるため、遷移セグメントに同等のラベルが追加されていると仮定すると、評価はコネクティブ ジャンクションの 12 時の位置から始まって、時計回りに処理されます。イベントE_one
というラベルが追加された最初の遷移セグメントは無効です。イベントE_two
というラベルが追加された次の遷移セグメントは有効です。ステートA
からC
への遷移全体は有効です。ステート
A
の exit アクション (exitA()
) が実行されて完了します。ステート
A
が非アクティブとしてマークされます。ステート
C
がアクティブとしてマークされます。ステート
C
の entry アクション (entC()
) が実行されて完了します。チャートはスリープ状態に戻ります。
このシーケンスは、イベント E_two
に関連する Stateflow チャートの実行を完了します。
等しく有効な遷移パスの解決
競合した遷移とは
競合した遷移とは、シミュレーション時に Stateflow チャート内の同じソースから派生する均等に有効な 2 つのパスを指します。競合が発生している場合、チャートは、均等に有効な遷移をチャート内の順序付けモードに基づいて評価します。つまり、明示的にまたは暗黙的にです。
競合した遷移の例
次のチャートには、等しく有効な遷移パスが 2 つあります。
暗黙的な順序の競合解決
暗黙的な順序の場合、チャートは、ラベル優先順位が等しい複数の出力遷移を、ステートの上の 12 時の位置から時計回りの順序で評価します。このケースでは、ステート A
からステート B
への遷移が発生します。
明示的な順序の競合解決
明示的な順序の場合、チャートは、明示的に指定した順序で出力遷移を評価することで、競合を解決します。たとえば、ステート A
からステート C
への遷移を右クリックし、コンテキスト メニューから [実行順序] 、 [1] を選択すると、チャートによってまずこの遷移が評価されます。このケースでは、ステート A
からステート C
への遷移が発生します。
遷移の競合が発生する仕組み
ステート A
へのデフォルト遷移は、データ a
は 1 に等しく、データ b
は 10に等しく割り当てます。ステート A
の during
アクションは各タイム ステップ中に、a
を増加させ、 b
を減少させます。ステート A
からステート B
への遷移は、条件 [a > 4]
が真の場合に有効になります。ステート A
からステート C
への遷移は、条件 [b < 7]
が真の場合に有効になります。シミュレーション中に、ステート A
がアクティブになり、両方の条件が真であるタイム ステップが存在します。これが遷移の競合です。
複数の遷移元から共通の遷移先への遷移
以下の例は、コネクティブ ジャンクションを経由した複数の遷移元から単一の遷移先への遷移の動作を示しています。
最初は、チャートはスリープ状態です。ステート A
がアクティブです。イベント E_one
が発生して、チャートを起動します。このイベントは、チャートのルートからチャートの階層の下方向に処理されます。
チャートのルートは、
E_one
の結果、有効な遷移が存在するかどうかをチェックします。ステートA
からコネクティブ ジャンクション、コネクティブ ジャンクションからステートC
への有効な遷移セグメントが存在します。ステート
A
の exit アクション (exitA()
) が実行されて完了します。ステート
A
が非アクティブとしてマークされます。ステート
C
がアクティブとしてマークされます。ステート
C
の entry アクション (entC()
) が実行されて完了します。チャートはスリープ状態に戻ります。
このシーケンスは、イベント E_one
に関連する Stateflow チャートの実行を完了します。
共通のイベントに基づく遷移元から遷移先への遷移
以下の例は、コネクティブ ジャンクションを経由した同じイベントに基づく複数の遷移元から単一の遷移先への遷移の動作を示しています。
最初は、チャートはスリープ状態です。ステート B
がアクティブです。イベント E_one
が発生して、チャートを起動します。このイベントは、チャートのルートからチャートの階層の下方向に処理されます。
チャートのルートは、
E_one
の結果、有効な遷移が存在するかどうかをチェックします。ステートB
からコネクティブ ジャンクション、コネクティブ ジャンクションからステート C への有効な遷移セグメントが存在します。ステート
B
の exit アクション (exitB()
) が実行されて完了します。ステート
B
が非アクティブとしてマークされます。ステート
C
がアクティブとしてマークされます。ステート
C
の entry アクション (entC()
) が実行されて完了します。チャートはスリープ状態に戻ります。
このシーケンスは、イベント E_one
に関連する Stateflow チャートの実行を完了します。
フロー チャートのバックトラック
以下の例では、フロー チャートでのバックトラッキング動作を強制するコネクティブ ジャンクションを経由した遷移の動作を説明します。
最初はステート A
はアクティブであり、条件 c1
、c2
、および c3
は真、条件 c4
は偽です。
チャートのルートは、ステート
A
から有効な遷移が存在しないかどうかをチェックします。ステート
A
からコネクティブ ジャンクションに、条件c1
としてマークされた有効な遷移セグメントが存在します。条件
c1
は真であるため、アクションa1
が実行されます。条件
c3
は真であるため、アクションa3
が実行されます。条件
c4
は真でないため、制御フローはステートA
に戻ります。チャートのルートは、ステート
A
から他に有効な遷移が存在しないかどうかをチェックします。ステート
A
からコネクティブ ジャンクションに、条件c2
としてマークされた有効な遷移セグメントが存在します。条件
c2
は真であるため、アクションa2
が実行されます。条件
c3
は真であるため、アクションa3
が実行されます。条件
c4
は真でないため、制御フローはステートA
に戻ります。チャートはスリープします。
前述の例は、a1
と a2
の両方のアクションを実行したときの予期される動作を示します。もう 1 つの予期しない動作は、a3
アクションを 2 回実行した場合です。この問題を解決するには、無条件遷移を終端ジャンクションに追加することを検討してください。
終端ジャンクションを使用すると、c3
または c4
のどちらかが真でない場合にフローを終了できます。これにより、ステート A は不要なアクションを伴わずにアクティブなままです。
意図しないバックトラッキングのその他の例
フロー チャートでの意図しないバックトラッキングのその他の例については、このモデルを開いて確認してください。