【问题标题】:boost msm submachine current_state for accessing sub stateboost msm submachine current_state 用于访问子状态
【发布时间】:2016-07-28 09:11:47
【问题描述】:

知道如何使用 boost msm 1_60 获取 submachine 的 current_state(s) 吗?考虑下面的代码,它描述了一个外部状态机,它允许在两个不同的交通信号灯之间进行选择(例如标准的红色、黄色、绿色和另一个交替的两个黄灯):

class SMBigMom : public msmf::state_machine_def<SMBigMom>
{
public:
SMBigMom() {};

using initial_state = SMSelectorState;

class SMLightBase : public msmf::state_machine_def<SMLightBase>
{
public:
    SMLightBase() {};

    using initial_state = BaseState;
    struct transition_table : mpl::vector<> {};
};
using SMBaseBackend = msm::back::state_machine<SMLightBase>;

class SMCommonRYG : public SMLightBase
{
public:
    SMCommonRYG() = default;
    ~SMCommonRYG() {};

    using initial_state = Red; // init state

    struct transition_table : mpl::vector<
        //         Start, Event, Target, Action, Guard
        msmf::Row< Red, evNext, RedYellow, msmf::none, msmf::none >,
        msmf::Row< RedYellow, evNext, Green, msmf::none, msmf::none >,
        msmf::Row< Green, evNext, Yellow, msmf::none, msmf::none >,
        msmf::Row< Yellow, evNext, Red, msmf::none, msmf::none >
    > {};
};
using SMCommonRYGBackend = msm::back::state_machine<SMCommonRYG>;

class SMYellowAlternate : public SMLightBase
{
public:
    SMYellowAlternate() = default;
    ~SMYellowAlternate() {};

    using initial_state = Yellow; // init state

    struct transition_table : mpl::vector<
        //         Start, Event, Target, Action, Guard
        msmf::Row< Yellow, evNext, Yellow2, msmf::none, msmf::none >,
        msmf::Row< Yellow2, evNext, Yellow, msmf::none, msmf::none >
    > {};
};
using SMYellowAlternateBackend = msm::back::state_machine<SMYellowAlternate>;

struct transition_table : mpl::vector<
    msmf::Row< SMSelectorState, evSelectCommonRYG, SMCommonRYGBackend, msmf::none, msmf::none >,
    msmf::Row< SMSelectorState, evSelectYellowAlternate, SMYellowAlternateBackend, msmf::none, msmf::none >
> {};

};

using SMBackend = msm::back::state_machine<SMBigMom>;

现在,我可以通过

跳入 RYG
SMBackend oSM. oSM.process_event(evSelectCommonRYG());

但是如何获取RYG子机的当前状态呢?

oSM.current_state()[0]

仅返回 1(因为这是外部状态机 BigMom 的状态...)...

感谢您的帮助!

【问题讨论】:

    标签: state boost-msm


    【解决方案1】:

    我同时想通了,解决方案相当简单。只需使用仿函数前端,添加一个动作(ROW 中的第 4 列)函数,调用如下:

    struct submachineAction
    {
      toNext() {};
      ~toNext() {};
      template<class TFsm, class TEvent, class TStateIn, class TStateOut>
      void operator() (const TEvent& p_rEV, const TFsm& p_rFSM, TStateIn&   p_rStateIn, TStateOut& p_rStateOut)
      { 
        std::cout << "Substate: " << p_rFSM.current_state()[0] << std::endl;
      }
    };
    

    如果您有几台“主”机器在运行并且需要知道哪一台称为 submachineAction,您可以定义一个基础前端类,例如,使用附加标识符(字符串、int,您可以命名)并派生该类的子机。然后,按照这个线程,你可以设置标识符,可以通过上面仿函数中的p_rFSM访问:How to Pass data to the current boost meta state machine(MSM) substate

    希望这可以帮助其他人。

    【讨论】: