Closed10

c++の状態遷移ライブラリ調査

ピン留めされたアイテム
EhNitEhNit

○調査内容
・言語:c++
→今回はrosる予定のためc++で組むしかないので縛る

・目指すもの
ImtStateMachine
を使ってみたところ結構いい感じ
こんな感じのc++用のライブラリがないかどうか
c++素人に移植は無理だった(テンプレートまわりのエラーが取れない)

可能な限りpure c++としたい

EhNitEhNit

boost-ext / sml
boost非公式な集団らしい、よくわからないが更新は活発そう

良い点
1ファイルを取得するだけで良い
readmeが理解可能

困った点
transition_tableの書き方がわからない
リポジトリまるごとクローンしてビルドすればもう少しわかりやすいのだろうが
cmake素人は尻込みする
ひとまず他のリポジトリを見ることにする

EhNitEhNit

plantuml integrationがあるっぽい
しかし記法が理解できなさすぎる
c++素人には早い

EhNitEhNit

digint / tinyfsm
「c++ state machine library 」でgoogleから検索すると上に出てくる
スター力が高い

良い点
1ファイルを取得するだけで良い
exampleを読む限りこれはかける気がする

困った点
tinyだからかpopとかは対応していないように見える
ギリギリ使いたい気もするためひとまず他のリポジトリを見ることにする
自分で作るよりは良いのか?

EhNitEhNit

andrew-gresyk / HFSM2
Hierarchicalが何を指しているのかが謎
Flat版もある(差はわからない)

良い点
比較的ドキュメントがまとまっているように見える

若干重い気もするが
なんとなくこれがいい気がするので少し使ってみる

EhNitEhNit

なるほどnamespaceに閉じ込める方法がわからん
参照を簡単にするための仕組みでハマっているような気がする
ひとまず保留して別のものを使うことにする

/**
 * @file statemachine.hpp
 * @brief
 */
#ifndef STATEMACHINE
#define STATEMACHINE

#include <assert.h>
// Configure optional HFSM2 functionality using #defines
// (in this case we're using Plans to make transition cycle more straightforward):
#define HFSM2_ENABLE_PLANS

// Include HFSM2 header:
#include "hfsm2/machine.hpp"

////////////////////////////////////////////////////////////////////////////////
// Define interface class between the state machine and its host
// (also ok to use the host object itself):
struct Context
{
  bool powerOn;
};

// (Optional) Define type config:
using Config = hfsm2::Config::ContextT<Context>;

// (Optional, recommended) Definehfsm2::Machine for convenience:
using M = hfsm2::MachineT<Config>;

//------------------------------------------------------------------------------

// Declare state machine structure.
// States need to be forward declared, e.g. with a magic macro:
#define S(s) struct s

using FSM = M::PeerRoot<S(Start),              // initial top-level state
                        M::Composite<S(Do),    // sub-machine region with a head state (On) and and 3 sub-states
                                     S(Sub1),  // initial sub-state of the region
                                     S(Sub2), S(Sub3)>,
                        S(End)>;

#undef S

// namespace test
// {
// class statemachine
// {
//------------------------------------------------------------------------------

// While HFSM2 transitions aren't event-based,
// events can be used to have FSM react to external stimuli:
struct Event
{
};

//------------------------------------------------------------------------------

// Define states and override required state methods:
struct Start : FSM::State
{
  void entryGuard(FullControl& control) noexcept
  {                                 // called before state activation, use to re-route transitions
    if (control.context().powerOn)  // access shared data
      control.changeTo<Do>();       // initiate a transition into 'On' region
  }
};

struct Do : FSM::State
{
  void enter(PlanControl& control) noexcept
  {                              // called on state activation
    auto plan = control.plan();  // access the plan for the region

    plan.change<Sub1, Sub2>();  // sequence plan steps, executed when the previous state succeeds
    plan.change<Sub2, Sub3>();
  }

  void exit(PlanControl& /*control*/) noexcept
  {
  }  // called on state deactivation

  void planSucceeded(FullControl& control) noexcept
  {  // called on the successful completion of all plan steps
    control.changeTo<End>();
  }

  void planFailed(FullControl& /*control*/) noexcept
  {
  }  // called if any of the plan steps fails
};
struct Sub1 : FSM::State
{
  void update(FullControl& control) noexcept
  {                     // called on periodic state machine updates
    control.succeed();  // notify successful completion of the plan step
  }                     // plan will advance to the 'Yellow' state
};

struct Sub2 : FSM::State
{
  void update(FullControl& control) noexcept
  {
    control.succeed();  // plan will advance to the 'Green' state on the first entry
                        // and 'Red' state on the second one
  }
};

struct Sub3 : FSM::State
{
  void react(const Event&, FullControl& control) noexcept
  {                     // called on external events
    control.succeed();  // advance to the next plan step
  }
};
struct End : FSM::State
{
};

// public:
void set()
{
  Context context;
  context.powerOn = true;
  FSM::Instance fsm{ context };
}
// };
// }  // namespace test
#endif

masafumi shiradomasafumi shirado

いまC++のFSMを検討している自分のメモがてら

作者のツイッターより

FFSM2 is a Flat version of http://hfsm.dev, developed in parallel, trading the support for the hierarchical structure for faster build times and lower memory footprint.

HFSM2と比較すると、階層構造のサポートと引き換えに、ビルド時間の短縮とメモリフットプリントの削減、とのこと。

https://twitter.com/andrew_gresyk/status/1309369472914989056

EhNitEhNit

Boost逆引きリファレンス / 有限状態マシン
boostにあるでねか

Boost.MSMと包含を利用してprivate空間にアクセス可能なクラス内有限状態マシンを実装する
こういうことがしたかった(ここまで全力で隠蔽する必要はないがさしたるコストでもないか?)

http://pg-kura.hatenablog.com/entry/20101231/1293807175
これを読むとstatechartが良いのか

というあたりを読むといろいろと問題があるようで
インスパイアされていい感じにしたらしいやつがこれ
zmij / afsm

相変わらず::が多い。これがc++の洗礼か

このスクラップは2021/03/04にクローズされました