問題タブ [boost-msm]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
uml - ステート マシンは値 (フロア番号など) を含むイベントをどのように処理しますか?
私はhttp://boost-experimental.github.io/msm-lite/tutorial/index.htmlで遊んでいます(msm-lite のタグはありませんが、同様の質問が適用されるため、タグは boost-msm 用です)。多くの可能な入力を持つステートマシンの設計に関する質問。
エレベーターをモデリングしていると想像してください。移動中、停止中、door_open、door_closed などの明白な状態のほかに、ボタンが押された (つまり、-2 から 39 までの数値) をモデル化する方法を考えています。
c++ - シグナル ハンドラーを使用してイベントをトリガーするときに、boost.msm の状態を適切に変更するにはどうすればよいですか?
シグナル ハンドラを使用してイベントをトリガーすると、 ( boost.msm
) ステート マシンが「ロールバック」しているように見えます。ただし、直接呼び出しを使用してイベントをトリガーすると、ステート マシンは正しく動作します。
boost のドキュメントを参照して Web を検索したところ、すべての例でイベント トリガーに直接呼び出しが使用されているようです。SOも検索しましたが、このトピックに対処するものは見つかりませんでした。
開発チームが現在使用している既存の「自作」ステート マシン ライブラリを置き換えるのに役立つかどうかを確認するために、ブースト メタ ステート マシン ライブラリを学習中です。
これを機能させるには、シグナル ハンドラー (からのシグナルの処理) からステート マシン イベントをトリガーできる必要がありますboost.signals2
。
テストを実行するために単純だが不自然な例を作成し、最初のイベントがトリガーされた後、ステート マシンが (シグナル ハンドラー内で) 状態を正しく (ただし一時的に) 変更したものの、明らかに「ロールした」ことを確認して困惑しました。メインに戻った後。
(process_event への直接呼び出しを使用して) シグナル ハンドラーをバイパスすると、すべてが正しく機能しました。
確かに考案されたテスト ステート マシンは、これを行うように設計されています。
シグナル ハンドラーを使用してこのデザイン (または同様のもの) を機能させ、ステート マシン イベントを正しくトリガーする方法を知りたいです。私は操作する信号しか受信しないため、直接呼び出しを使用することはできません。
以下のテストコードを含めました。main 関数の前半はシグナル ハンドラのトリガーを実行し、main の後半は直接呼び出しのトリガーを実行することに注意してください ( を使用してコンパイルg++ main.cpp -omain' or 'clang++ main.cpp -omain
)。
出力は次のとおりです。
参照しやすいように、出力ファイルを後処理して行番号を追加しました。
出力の 01 行目は、ステート マシンが最初の疑似状態から state_a に正しく遷移したことを示しています。
出力の 14 行目は、on_sa_event 関数内でステート マシンが state_a から state_b に正しく遷移したことを示しています。
ただし、17 行目は、メインからテストしたときにステート マシンが state_a に戻ったことを示しています (!)
ステート マシンは、シグナル ハンドラー テストの残りの遷移 (18 行目から 41 行目) の間、state_a のままであり、いくつかの「No Transition」エラー メッセージが表示されます。
直接呼び出しの演習 (出力行 42 ~ 65) の場合、ステート マシンはすべての状態を正しく遷移し、トリガー関数内とメインのとき (トリガー関数呼び出し後) の「現在の状態」に違いはありません。
環境:OS:「Ubuntu 16.04 LTS」
g++ バージョン: (Ubuntu 5.3.1-14ubuntu2) 5.3.1 20160413
ブースト バージョン: boost_1_60_0
c++ - ステート マシンを動的に作成する方法
たとえば、マシンを説明するテンプレート XML ファイルを読み取るなど、boost msm を動的に使用して FSM を作成する方法はまだわかりません。問題に対処する方法はありますか?ブースト msm 1.61 でファンクター アプローチを使用したいと考えています。
一般的な方法でフロントエンドの基本クラスを作成できるように、少し進歩しました。
ただし、ステート マシン自体はバックエンドによって操作されており、実行時に後者を選択する方法はこれまでのところわかりません (たとえば、
)。
state - サブ状態にアクセスするためのブースト msm サブマシン current_state
ブースト msm 1_60 を使用して、サブマシンの current_state を取得する方法はありますか? 次のコードを考えてみましょう。このコードは、2 つの異なる信号機 (たとえば、標準の赤、黄、緑の 1 つと、交互に 2 つの黄色の信号を持つ別のもの) の間で選択できる外側のステート マシンを記述しています。
};
これで、次の方法で RYG にスキップできます
しかし、RYG サブマシンの現在の状態を取得するにはどうすればよいでしょうか?
1 のみを返します (これは外部ステート マシン BigMom の状態であるため...)...
手伝ってくれてありがとう!
c++ - ブースト MSM を備えた階層型ステート マシン
ブースト MSM の経験がある方に質問です。ブースト MSM を実装した非常に大きなステート マシンがあり、ついに今日、ベクトルの制限である 50 を使い果たしました (ステート マシンに入るイベントが多すぎて、避けられません)。上位のベクター ヘッダー (vector60、vector70 など) を作成しましたが、ステート マシン全体を圧縮したいと考えていました。
質問は、MSM が階層状態マシンをサポートするかどうかです。たとえば (間違っている場合は訂正してください)、階層状態マシンでは、イベントが特定の状態で処理されない場合、そのイベントは現在の状態の親状態などに転送されます。
遷移テーブルのサイズを縮小する一環として、共通のハンドラーを持つイベントが処理される親ステートを作成して、遷移テーブルのサイズを縮小したいと考えていました。
アドバイス/コメントをいただければ幸いです。
ありがとう
c++11 - ブースト メタ ステート マシンの無限ループ セグメント障害
Boost State Machine を使用しようとしていますが、マシンを無限ループで実行しているときにセグメンテーション フォールトが発生しました。基本的に、以下に示すブースト ステート マシン ファンクターの例に同じ例があります。
唯一の違いは、State4 に入るとすぐに "event1" が発生するようになり、ループが作成されることです。これは数千回の反復で機能しますが、その後はセグメント フォールトになります。ある種の UML ルールに違反していて、スタックがオーバーフローしていませんか? 私は基本的に 1 つのブロッキング イベントしか持たず、他のすべての状態を自動的にトリガーして、最終的に State4 にします (実際には、ネットワークからのメッセージを待機しているブロッキング コールになります)。スタックを爆破しないように、Meta State Machine を使用してこれを適切に実装するにはどうすればよいですか?
更新
ここに問題を引き起こしているソースコードを含めました:
http://pastebin.com/fu6rzF0Q
これは基本的に、次の変更を除いて、ファンクター フロント エンドの例です。
「ふりをする」ブロッキング呼び出し機能を追加:
また、遷移表の最後の行も更新しました。
State4 から State1 に移行するためにトリガーする必要があるイベントがなくなったことに注意してください。このコードにより、間違いなくセグ フォールトが発生し、数千行に及ぶスタック トレースが生成されます。
また、待機時間に関係なく、最終的には常にセグフォルトになることにも注意してください。スリープを 1 ~ 100 に変更して遊んでみましたが、最終的には死んでしまいます。単一のループが完了したら、スタックを展開する何らかの方法が必要だと思います。
UPDATE 2 したがって、無限ループでイベントをトリガーすると、エラーが発生しないことがわかりました。これが私がしたことです:
最初に、遷移テーブルを元の例に戻します。
次に、メインプログラムを次のように変更しました。
そして今、私は全速力で (スリープなしで) 実行しており、セグ フォールトも発生していません。これに基づいて、ステート マシンを起動し、内部イベントを実行して処理する方法はないようですが、正しいですか? 私は常に、少なくとも偶数でトリガーされるプロセスを外側に持つ必要がありますか?
更新 3
最終的に私の目標は、次の図のようなものを実装することです。
私の意図は、ステート マシンを開始することであり、それ以上の介入なしに着信メッセージを待つだけです。