有限状态机 tinyfsm
马达 motor.hpp 定义,马达有上、下、停三种事件
#include "tinyfsm.hpp"
//电机马达事件定义
struct MotorUp :tinyfsm::Event{};
struct MotorDown :tinyfsm::Event{};
struct MotorStop : tinyfsm::Event{};
//马达状态机基类定义
class Motor : public tinyfsm::Fsm<Motor>
{
public:
void react(tinyfsm::Event const &){};
void react(MotorUp const &);
void react(MotorDown const &);
void react(MotorStop const &);
virtual void entry(void) = 0; //纯虚函数,需要被强制实现.
void exit(void) {};
protected:
static int direction;
public:
static int getDirection(){
return direction;
}
};
Motor.cpp 对应 马达有三个不同的状态 上、停、下状态。
#include "tinyfsm.hpp"
#include "motor.hpp"
#include <iostream>
using namespace std;
//电动马达状态机
class Stoped : public Motor {
void entry() override {
cout << "Motor: stoped." << endl;
direction = 0;
}
};
class Up : public Motor {
void entry() override {
cout << "Motor: moving up." << endl;
direction = 1;
}
};
class Down : public Motor {
void entry() override {
cout << "Motor: moving down." << endl;
direction = -1;
}
};
马达react 响应 上、下、停 事件
//基类马达状态机的虚函数实现
void Motor::react(const MotorUp &) {
transit<Up>(); //切换到上升状态
}
void Motor::react(const MotorDown &) {
transit<Down>(); //切换到下降状态
}
void Motor::react(const MotorStop &) {
transit<Stoped>(); //切换到停止状态.
}
int Motor::direction{0}; // 花括号,’{}’声明,又称为初始化列表
//状态机定义
FSM_INITIAL_STATE(Motor, Stoped)
人操作电梯,由传感器来控制马达,那么定义电梯的状态机如下, elevator.hpp
#include "tinyfsm.hpp"
//事件定义. 楼层事件基类
struct FloorEvent : tinyfsm::Event{
int floor;
};
//
struct Call : FloorEvent {}; //楼层呼叫
struct FloorSenor : FloorEvent{}; //楼层传感器
struct Alarm : tinyfsm::Event{}; //警报事件
//定义电梯状态机基类
class Elevator : public tinyfsm::Fsm<Elevator>
{
public:
void react(tinyfsm::Event const &){};
virtual void react(Call const &);
virtual void react(FloorSenor const &);
virtual void react(Alarm const &);
virtual void entry(void){}; /* entry actions in some states */
void exit(void) {}; /* no exit actions at all */
protected:
static constexpr int initial_floor = 0;
static int current_floor;
static int dest_floor;
};
给电梯定义状态机,空闲状态机,恐慌状态机,移动状态机
#include "elevator.hpp"
#include <iostream>
#include "fsmlist.hpp"
using namespace std;
//空闲类
class Idle;
//呼叫主体
static void CallMaintenance()
{
cout << "*** 打电话给维护员 ***" << endl;
}
//呼叫消防
static void CallFireFlighters()
{
cout << "*** 打电话给消防员 ***" << endl;
}
//恐慌状态机
class Panic : public Elevator{
void entry() override {
cout << "Panic Motorstop 事件.";
send_event(MotorStop()); //发送马达暂停事件
}
};
//移动状态机
class Moving : public Elevator
{
void react(FloorSenor const & e) override {
cout << "Moving Floor Floor.sensor: " << e.floor << ")" << endl;
int floor_expected = current_floor + Motor::getDirection();
if(floor_expected != e.floor)
{
cout << "Floor sensor defect (expected " << floor_expected << ", got " << e.floor << ")" << endl;
transit<Panic>(CallMaintenance);
}else{
cout << "Reached floor " << e.floor << endl;
current_floor = e.floor;
if(e.floor == dest_floor)
{
transit<Idle>();
}
}
}
};
//空闲状态机
class Idle :public Elevator{
public:
void entry() override {
cout << "进入空闲状态. --> 发送电梯停止事件." << endl;
send_event(MotorStop());
}
void react(Call const & e) override {
dest_floor = e.floor;
cout << "空闲状态Call --> dest_floor:" << dest_floor << " current_floor:" << current_floor << endl;
if(dest_floor == current_floor)
{
return;
}
auto action =[] {
if(dest_floor > current_floor){
send_event(MotorUp());
}else if(dest_floor < current_floor) {
send_event(MotorDown());
}
};
transit<Moving>(action);
}
};