ustinyfsm
This commit is contained in:
@@ -150,33 +150,19 @@ class PowerManger : public AppCastingMOOSApp
|
||||
unsigned int m_ticker;
|
||||
|
||||
public:
|
||||
//===========================状态机实现==============================================
|
||||
void printState(FSM_State st, string desp);
|
||||
//===========================状态机实现(tinyfsm)=======================================
|
||||
void printState(const char* st, string desp);
|
||||
bool FSM_RUN_IS_OK = true;
|
||||
|
||||
StateData m_stateData;
|
||||
FSM_State m_pmState; //当前状态
|
||||
string m_pmEvent;
|
||||
FSM m_fsm;
|
||||
|
||||
//初始化状态
|
||||
FSM_State m_Inite_s1;
|
||||
static int handleInite_s1(FSM_State &fsm, void* pData);
|
||||
// 状态机事件分发
|
||||
void dispatchFsmEvent();
|
||||
|
||||
//待机状态
|
||||
FSM_State m_Standby_s2;
|
||||
static int handleStandby_s2(FSM_State &fsm, void* pData);
|
||||
|
||||
//岸基备航
|
||||
// FSM_State m_ShoreReady_s3;
|
||||
|
||||
//水中备航
|
||||
|
||||
//自动工况
|
||||
|
||||
//故障处理
|
||||
FSM_State m_Fault_s99;
|
||||
static int handleFault_s99(FSM_State &fsm, void* pData);
|
||||
// 状态处理函数
|
||||
void handleInitState();
|
||||
void handleStandbyState();
|
||||
void handleFaultState();
|
||||
//======================================================================================
|
||||
int checkError();
|
||||
bool shutdown();
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#include "fsm_tinyfsm.h"
|
||||
#include "PowerManger.h"
|
||||
|
||||
// 初始化状态实现
|
||||
void InitState::entry() {
|
||||
// 初始化状态进入动作
|
||||
PowerManger::printState("InitState", "Enter initialization state");
|
||||
}
|
||||
|
||||
void InitState::react(InitEvent const & e) {
|
||||
// 初始化状态处理逻辑
|
||||
if (e.data->isInitialized) {
|
||||
transit<StandbyState>();
|
||||
}
|
||||
}
|
||||
|
||||
// 待机状态实现
|
||||
void StandbyState::entry() {
|
||||
// 待机状态进入动作
|
||||
PowerManger::printState("StandbyState", "Enter standby state");
|
||||
}
|
||||
|
||||
void StandbyState::react(StandbyEvent const & e) {
|
||||
// 待机状态处理逻辑
|
||||
if (e.data->hasFault) {
|
||||
transit<FaultState>();
|
||||
}
|
||||
// 其他待机状态处理...
|
||||
}
|
||||
|
||||
// 故障状态实现
|
||||
void FaultState::entry() {
|
||||
// 故障状态进入动作
|
||||
PowerManger::printState("FaultState", "Enter fault handling state");
|
||||
}
|
||||
|
||||
void FaultState::react(FaultEvent const & e) {
|
||||
// 故障状态处理逻辑
|
||||
if (!e.data->hasFault) {
|
||||
transit<StandbyState>();
|
||||
}
|
||||
// 其他故障处理逻辑...
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#ifndef FSM_TINYFSM_H
|
||||
#define FSM_TINYFSM_H
|
||||
|
||||
#include "tinyfsm.hpp"
|
||||
#include "pmSysvariable.h"
|
||||
|
||||
// 定义状态机事件
|
||||
struct PowerEvent : tinyfsm::Event {
|
||||
StateData* data;
|
||||
explicit PowerEvent(StateData* d) : data(d) {}
|
||||
};
|
||||
|
||||
struct InitEvent : PowerEvent {
|
||||
using PowerEvent::PowerEvent;
|
||||
};
|
||||
|
||||
struct StandbyEvent : PowerEvent {
|
||||
using PowerEvent::PowerEvent;
|
||||
};
|
||||
|
||||
struct FaultEvent : PowerEvent {
|
||||
using PowerEvent::PowerEvent;
|
||||
};
|
||||
|
||||
// 定义状态机
|
||||
class PowerFsm : public tinyfsm::Fsm<PowerFsm> {
|
||||
public:
|
||||
// 响应所有事件类型的默认处理
|
||||
void react(tinyfsm::Event const &) { }
|
||||
|
||||
// 响应特定事件类型的处理
|
||||
virtual void react(InitEvent const &) { }
|
||||
virtual void react(StandbyEvent const &) { }
|
||||
virtual void react(FaultEvent const &) { }
|
||||
|
||||
// 进入/退出动作
|
||||
virtual void entry(void) { }
|
||||
void exit(void) { }
|
||||
};
|
||||
|
||||
// 定义状态
|
||||
class InitState : public PowerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void react(InitEvent const &) override;
|
||||
};
|
||||
|
||||
class StandbyState : public PowerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void react(StandbyEvent const &) override;
|
||||
};
|
||||
|
||||
class FaultState : public PowerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void react(FaultEvent const &) override;
|
||||
};
|
||||
|
||||
// 声明状态机列表
|
||||
using PowerFsmList = tinyfsm::FsmList<PowerFsm>;
|
||||
|
||||
// 声明状态列表
|
||||
using PowerStateList = tinyfsm::StateList<InitState, StandbyState, FaultState>;
|
||||
|
||||
// 设置初始状态
|
||||
FSM_INITIAL_STATE(PowerFsm, InitState)
|
||||
|
||||
#endif // FSM_TINYFSM_H
|
||||
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* TinyFSM - Tiny Finite State Machine Processor
|
||||
*
|
||||
* Copyright (c) 2012-2022 Axel Burri
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Version: 0.3.3
|
||||
*
|
||||
* API documentation: see "../doc/50-API.md"
|
||||
*
|
||||
* The official TinyFSM website is located at:
|
||||
* https://digint.ch/tinyfsm/
|
||||
*
|
||||
* Author:
|
||||
* Axel Burri <axel@tty0.ch>
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TINYFSM_HPP_INCLUDED
|
||||
#define TINYFSM_HPP_INCLUDED
|
||||
|
||||
#ifndef TINYFSM_NOSTDLIB
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
// #include <iostream>
|
||||
// #define DBG(str) do { std::cerr << str << std::endl; } while( false )
|
||||
// DBG("*** dbg_example *** " << __PRETTY_FUNCTION__);
|
||||
|
||||
namespace tinyfsm
|
||||
{
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
struct Event { };
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#ifdef TINYFSM_NOSTDLIB
|
||||
// remove dependency on standard library (silent fail!).
|
||||
// useful in conjunction with -nostdlib option, e.g. if your compiler
|
||||
// does not provide a standard library.
|
||||
// NOTE: this silently disables all static_assert() calls below!
|
||||
template<typename F, typename S>
|
||||
struct is_same_fsm { static constexpr bool value = true; };
|
||||
#else
|
||||
// check if both fsm and state class share same fsmtype
|
||||
template<typename F, typename S>
|
||||
struct is_same_fsm : std::is_same< typename F::fsmtype, typename S::fsmtype > { };
|
||||
#endif
|
||||
|
||||
template<typename S>
|
||||
struct _state_instance
|
||||
{
|
||||
using value_type = S;
|
||||
using type = _state_instance<S>;
|
||||
static S value;
|
||||
};
|
||||
|
||||
template<typename S>
|
||||
typename _state_instance<S>::value_type _state_instance<S>::value;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
template<typename F>
|
||||
class Fsm
|
||||
{
|
||||
public:
|
||||
|
||||
using fsmtype = Fsm<F>;
|
||||
using state_ptr_t = F *;
|
||||
|
||||
static state_ptr_t current_state_ptr;
|
||||
|
||||
// public, leaving ability to access state instance (e.g. on reset)
|
||||
template<typename S>
|
||||
static constexpr S & state(void) {
|
||||
static_assert(is_same_fsm<F, S>::value, "accessing state of different state machine");
|
||||
return _state_instance<S>::value;
|
||||
}
|
||||
|
||||
template<typename S>
|
||||
static constexpr bool is_in_state(void) {
|
||||
static_assert(is_same_fsm<F, S>::value, "accessing state of different state machine");
|
||||
return current_state_ptr == &_state_instance<S>::value;
|
||||
}
|
||||
|
||||
/// state machine functions
|
||||
public:
|
||||
|
||||
// explicitely specialized in FSM_INITIAL_STATE macro
|
||||
static void set_initial_state();
|
||||
|
||||
static void reset() { };
|
||||
|
||||
static void enter() {
|
||||
current_state_ptr->entry();
|
||||
}
|
||||
|
||||
static void start() {
|
||||
set_initial_state();
|
||||
enter();
|
||||
}
|
||||
|
||||
template<typename E>
|
||||
static void dispatch(E const & event) {
|
||||
current_state_ptr->react(event);
|
||||
}
|
||||
|
||||
|
||||
/// state transition functions
|
||||
protected:
|
||||
|
||||
template<typename S>
|
||||
void transit(void) {
|
||||
static_assert(is_same_fsm<F, S>::value, "transit to different state machine");
|
||||
current_state_ptr->exit();
|
||||
current_state_ptr = &_state_instance<S>::value;
|
||||
current_state_ptr->entry();
|
||||
}
|
||||
|
||||
template<typename S, typename ActionFunction>
|
||||
void transit(ActionFunction action_function) {
|
||||
static_assert(is_same_fsm<F, S>::value, "transit to different state machine");
|
||||
current_state_ptr->exit();
|
||||
// NOTE: do not send events in action_function definisions.
|
||||
action_function();
|
||||
current_state_ptr = &_state_instance<S>::value;
|
||||
current_state_ptr->entry();
|
||||
}
|
||||
|
||||
template<typename S, typename ActionFunction, typename ConditionFunction>
|
||||
void transit(ActionFunction action_function, ConditionFunction condition_function) {
|
||||
if(condition_function()) {
|
||||
transit<S>(action_function);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename F>
|
||||
typename Fsm<F>::state_ptr_t Fsm<F>::current_state_ptr;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
template<typename... FF>
|
||||
struct FsmList;
|
||||
|
||||
template<> struct FsmList<> {
|
||||
static void set_initial_state() { }
|
||||
static void reset() { }
|
||||
static void enter() { }
|
||||
template<typename E>
|
||||
static void dispatch(E const &) { }
|
||||
};
|
||||
|
||||
template<typename F, typename... FF>
|
||||
struct FsmList<F, FF...>
|
||||
{
|
||||
using fsmtype = Fsm<F>;
|
||||
|
||||
static void set_initial_state() {
|
||||
fsmtype::set_initial_state();
|
||||
FsmList<FF...>::set_initial_state();
|
||||
}
|
||||
|
||||
static void reset() {
|
||||
F::reset();
|
||||
FsmList<FF...>::reset();
|
||||
}
|
||||
|
||||
static void enter() {
|
||||
fsmtype::enter();
|
||||
FsmList<FF...>::enter();
|
||||
}
|
||||
|
||||
static void start() {
|
||||
set_initial_state();
|
||||
enter();
|
||||
}
|
||||
|
||||
template<typename E>
|
||||
static void dispatch(E const & event) {
|
||||
fsmtype::template dispatch<E>(event);
|
||||
FsmList<FF...>::template dispatch<E>(event);
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
template<typename... SS> struct StateList;
|
||||
template<> struct StateList<> {
|
||||
static void reset() { }
|
||||
};
|
||||
template<typename S, typename... SS>
|
||||
struct StateList<S, SS...>
|
||||
{
|
||||
static void reset() {
|
||||
_state_instance<S>::value = S();
|
||||
StateList<SS...>::reset();
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
template<typename F>
|
||||
struct MooreMachine : tinyfsm::Fsm<F>
|
||||
{
|
||||
virtual void entry(void) { }; /* entry actions in some states */
|
||||
void exit(void) { }; /* no exit actions */
|
||||
};
|
||||
|
||||
template<typename F>
|
||||
struct MealyMachine : tinyfsm::Fsm<F>
|
||||
{
|
||||
// input actions are modeled in react():
|
||||
// - conditional dependent of event type or payload
|
||||
// - transit<>(ActionFunction)
|
||||
void entry(void) { }; /* no entry actions */
|
||||
void exit(void) { }; /* no exit actions */
|
||||
};
|
||||
|
||||
} /* namespace tinyfsm */
|
||||
|
||||
|
||||
#define FSM_INITIAL_STATE(_FSM, _STATE) \
|
||||
namespace tinyfsm { \
|
||||
template<> void Fsm< _FSM >::set_initial_state(void) { \
|
||||
current_state_ptr = &_state_instance< _STATE >::value; \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* TINYFSM_HPP_INCLUDED */
|
||||
Reference in New Issue
Block a user