如何在Boost 1.64.0 MSM中定义分层状态机子状态S11到S21的转换?
实现Boost MSM 1.64.0中S11到S21的分层状态转换
嘿,针对你这个分层状态机的跨子状态转换需求,我来一步步给你讲清楚怎么实现——Boost MSM对分层状态的转换处理其实很直观,只要理清状态层级关系,按规则定义转换就行。
首先先明确你的状态层级结构:
- 顶层状态
S- 子状态
S1→ 包含子状态S11 - 子状态
S2→ 包含子状态S21
- 子状态
接下来分步骤实现:
1. 定义触发转换的事件
首先得有一个事件来触发这次跨状态转换,比如:
// 定义触发S11→S21的事件 struct EvSwitchToS21 {};
2. 给子状态S11添加转换规则
因为S11是S1的子状态,你直接在S11的转换表中定义到S21的转换即可——Boost MSM会自动帮你处理**退出源路径(S11→S1)和进入目标路径(S2→S21)**的整个流程,不需要手动处理每一层的退出/进入。
完整状态机代码示例
#include <iostream> #include <boost/msm/front/state_machine_def.hpp> #include <boost/msm/back/state_machine.hpp> #include <boost/mpl/vector.hpp> using namespace boost::msm; using namespace boost::msm::front; using namespace boost::mpl; // 触发转换的事件 struct EvSwitchToS21 {}; // 子状态S11 struct S11 : state<> { // S11的转换表:响应EvSwitchToS21事件,跳转到S21 typedef vector< transition<EvSwitchToS21, S21> > reactions; // 可选:退出S11时的动作 template <class Event, class Fsm> void on_exit(const Event&, Fsm&) { std::cout << "Exiting S11" << std::endl; } }; // 子状态S1(包含S11) struct S1 : state<> { // S1的初始状态是S11 typedef initial_state<S11> initial_state; // 可选:退出S1时的动作 template <class Event, class Fsm> void on_exit(const Event&, Fsm&) { std::cout << "Exiting S1" << std::endl; } }; // 子状态S21 struct S21 : state<> { // 可选:进入S21时的动作 template <class Event, class Fsm> void on_entry(const Event&, Fsm&) { std::cout << "Entered S21" << std::endl; } }; // 子状态S2(包含S21) struct S2 : state<> { // S2的初始状态是S21 typedef initial_state<S21> initial_state; // 可选:进入S2时的动作 template <class Event, class Fsm> void on_entry(const Event&, Fsm&) { std::cout << "Entered S2" << std::endl; } }; // 顶层状态S(包含S1和S2) struct S : state<> { // S的初始状态是S1 typedef initial_state<S1> initial_state; }; // 状态机定义 struct MyHierarchicalFsm : state_machine_def<MyHierarchicalFsm> { // 状态机的顶层状态是S typedef S initial_state; }; // 实例化状态机 typedef back::state_machine<MyHierarchicalFsm> FsmInstance; int main() { FsmInstance fsm; fsm.start(); // 启动后自动进入 S → S1 → S11 std::cout << "--- Triggering transition to S21 ---" << std::endl; fsm.process_event(EvSwitchToS21()); // 触发转换 return 0; }
3. 关键细节说明
- 自动处理层级流转:当你发送
EvSwitchToS21事件后,MSM会自动执行:S11::on_exit→S1::on_exit→S2::on_entry→S21::on_entry,完全不需要手动干预层级状态的进出。 - 添加自定义动作/守卫:如果需要在转换过程中执行逻辑,或者加转换条件,可以给转换添加动作或守卫:
// 自定义转换动作 struct SwitchAction { template <class Event, class Fsm, class Source, class Target> void operator()(const Event&, Fsm&, Source&, Target&) { std::cout << "Performing transition from S11 to S21" << std::endl; } }; // 自定义转换守卫(满足条件才允许转换) struct SwitchGuard { template <class Event, class Fsm, class Source, class Target> bool operator()(const Event&, Fsm&, Source&, Target&) { // 这里写你的判断逻辑,返回true则允许转换 return true; } }; // 修改S11的转换表 typedef vector< transition<EvSwitchToS21, S21, SwitchGuard, SwitchAction> > reactions;
运行上面的示例代码,你会看到控制台输出的状态流转日志,就能确认转换是否正常工作啦。
内容的提问来源于stack exchange,提问作者szh
相关产品推荐
相关产品推荐

