有限状态机TinyFSM使用指南

本文档介绍了TinyFSM库的使用方法,它是一个C++11实现的轻量级有限状态机库。文章通过Elevator(电梯)项目的例子,详细阐述了如何声明事件类、状态机类、状态类,以及如何实现状态迁移和事件响应。重点强调了避免循环依赖以保持状态机的可控性,并展示了如何自定义初始化和事件分发。此外,还提到了初始化状态设置和状态转移日志的输出。

有限状态机TinyFSM使用指南

贺志国
2022-7-14

项目网址:https://github.com/digint/tinyfsm

一、类图

                                       .......
+--------------------------------------:  T  :
| tinyfsm::FsmList                     :.....:
+-----------------------------------------|
| [+] set_initial_state()     <<static>>  |
| [+] reset()                 <<static>>  |
| [+] enter()                 <<static>>  |
| [+] start()                 <<static>>  |
| [+] dispatch(Event)         <<static>>  |
+-----------------------------------------+


                                       .......
+--------------------------------------:  T  :
| tinyfsm::Fsm                         :.....:
+-----------------------------------------|
| [+] state<S>()              <<static>>  |
| [+] set_initial_state()     <<static>>  |
| [+] reset()                 <<static>>  |
| [+] enter()                 <<static>>  |
| [+] start()                 <<static>>  |
| [+] dispatch(Event)         <<static>>  |
| [#] transit<S>()                        |
| [#] transit<S>(Action)                  |
| [#] transit<S>(Action, Condition)       |
+-----------------------------------------+
                     #
                     |
                     |
          +---------------------+
          | MyFSM               |
          +---------------------+
          | [+] entry()         |
          | [+] exit()          |
          | [+] react(EventX)   |
          | [+] react(EventY)   |
          | ...                 |
          +---------------------+
                     #
                     |
       +-------------+-------------+
       |             |             |
  +---------+   +---------+   +---------+
  | State_A |   | State_B |   | ...     |
  +---------+   +---------+   +---------+


[#]  protected
[+]  public
[-]  private

二、使用说明

TinyFSM是一个基于模板撰写的头文件库, 要求编译器支持C++11标准(GCC的编译选项为-std=c++11,Ubuntu 16.04以上操作系统自带的GCC默认支持)。使用时,只需将头文件tinyfsm.hpp复制到项目合适的位置,然后使用如下语句包含该头文件即可使用。

#include <tinyfsm.hpp>

TinyFSM不依赖于RTTI(“Runtime Type Information”的缩写,表示运行时类型信息)、异常或者任何外部库。如果编译时C++标准库(即STL库)都不想使用,请在编译时添加-DTINYFSM_NOSTDLIB选项,在链接时添加-nostdlib选项。

下面以Elevator(电梯)项目为例,对使用TinyFSM实现状态机进行详细地阐述。Elevator是一个同时使用两个有限状态机的较复杂示例。

2.1 需求分析

一般而言,一部电梯拥有:

  1. “Call”(呼叫)按钮,即每层楼召唤电梯(上升或下降)的按钮;

  2. “Floor Sensor”(楼层传感器)按钮,即”1“、”2“、”3“等楼层按钮;

  3. “Alarm”(报警)按钮。

说明:当然还有“Open Door(开门)”和“Close Door(关门)”按钮,该项目未提及,大家可以尝试自行添加。

同时,一部电梯包含轿厢(Cabin)和马达(Motor)两大部件。

其中,Cabin的状态包括(后文直接使用Elevator代替Cabin):

  1. 状态: Idle(空闲)
  2. 状态: Moving(移动)
  3. 状态: Panic(恐慌,即故障状态)

Motor的状态包括:

  1. 状态: Stopped(停止)
  2. 状态: Up(上升)
  3. 状态: Down(下降)

特别强调一个良好的状态机必须避免循环依赖。以Elevator项目为例:Elevator可以向Motor发送事件,但Motor永远不会向Elevator发送事件。这样就只存在单向事件传输,否则就是循环依赖。一旦出现循环依赖,系统将变得不可控!

2.2 状态迁移图
  1. Elevator的状态迁移图如下(椭圆表示状态,箭头表示事件):
    在这里插入图片描述

  2. Motor的状态迁移图如下(椭圆表示状态,箭头表示事件):

  3. 在这里插入图片描述

2.3 代码分析
2.3.1 声明事件类

声明状态机需要监听的事件类。事件类从tinyfsm::Event类派生得到,示例代码如下:

    struct FloorEvent : tinyfsm::Event
    {
   
   
      int floor;
    };
    
    struct
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值