You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:40:11