diff --git a/src/pPowerManger/PowerManger.h b/src/pPowerManger/PowerManger.h index b56b07b..52b9441 100644 --- a/src/pPowerManger/PowerManger.h +++ b/src/pPowerManger/PowerManger.h @@ -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); - - //待机状态 - 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 dispatchFsmEvent(); + + // 状态处理函数 + void handleInitState(); + void handleStandbyState(); + void handleFaultState(); //====================================================================================== int checkError(); bool shutdown(); diff --git a/src/pPowerManger/fsm_tinyfsm.cpp b/src/pPowerManger/fsm_tinyfsm.cpp new file mode 100644 index 0000000..c0b77ab --- /dev/null +++ b/src/pPowerManger/fsm_tinyfsm.cpp @@ -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(); + } +} + +// 待机状态实现 +void StandbyState::entry() { + // 待机状态进入动作 + PowerManger::printState("StandbyState", "Enter standby state"); +} + +void StandbyState::react(StandbyEvent const & e) { + // 待机状态处理逻辑 + if (e.data->hasFault) { + transit(); + } + // 其他待机状态处理... +} + +// 故障状态实现 +void FaultState::entry() { + // 故障状态进入动作 + PowerManger::printState("FaultState", "Enter fault handling state"); +} + +void FaultState::react(FaultEvent const & e) { + // 故障状态处理逻辑 + if (!e.data->hasFault) { + transit(); + } + // 其他故障处理逻辑... +} diff --git a/src/pPowerManger/fsm_tinyfsm.h b/src/pPowerManger/fsm_tinyfsm.h new file mode 100644 index 0000000..219fb5c --- /dev/null +++ b/src/pPowerManger/fsm_tinyfsm.h @@ -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 { +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; + +// 声明状态列表 +using PowerStateList = tinyfsm::StateList; + +// 设置初始状态 +FSM_INITIAL_STATE(PowerFsm, InitState) + +#endif // FSM_TINYFSM_H diff --git a/src/pPowerManger/tinyfsm.hpp b/src/pPowerManger/tinyfsm.hpp new file mode 100644 index 0000000..5a11f8a --- /dev/null +++ b/src/pPowerManger/tinyfsm.hpp @@ -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 + * --------------------------------------------------------------------- + */ + +#ifndef TINYFSM_HPP_INCLUDED +#define TINYFSM_HPP_INCLUDED + +#ifndef TINYFSM_NOSTDLIB +#include +#endif + +// #include +// #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 + struct is_same_fsm { static constexpr bool value = true; }; +#else + // check if both fsm and state class share same fsmtype + template + struct is_same_fsm : std::is_same< typename F::fsmtype, typename S::fsmtype > { }; +#endif + + template + struct _state_instance + { + using value_type = S; + using type = _state_instance; + static S value; + }; + + template + typename _state_instance::value_type _state_instance::value; + + // -------------------------------------------------------------------------- + + template + class Fsm + { + public: + + using fsmtype = Fsm; + using state_ptr_t = F *; + + static state_ptr_t current_state_ptr; + + // public, leaving ability to access state instance (e.g. on reset) + template + static constexpr S & state(void) { + static_assert(is_same_fsm::value, "accessing state of different state machine"); + return _state_instance::value; + } + + template + static constexpr bool is_in_state(void) { + static_assert(is_same_fsm::value, "accessing state of different state machine"); + return current_state_ptr == &_state_instance::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 + static void dispatch(E const & event) { + current_state_ptr->react(event); + } + + + /// state transition functions + protected: + + template + void transit(void) { + static_assert(is_same_fsm::value, "transit to different state machine"); + current_state_ptr->exit(); + current_state_ptr = &_state_instance::value; + current_state_ptr->entry(); + } + + template + void transit(ActionFunction action_function) { + static_assert(is_same_fsm::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::value; + current_state_ptr->entry(); + } + + template + void transit(ActionFunction action_function, ConditionFunction condition_function) { + if(condition_function()) { + transit(action_function); + } + } + }; + + template + typename Fsm::state_ptr_t Fsm::current_state_ptr; + + // -------------------------------------------------------------------------- + + template + struct FsmList; + + template<> struct FsmList<> { + static void set_initial_state() { } + static void reset() { } + static void enter() { } + template + static void dispatch(E const &) { } + }; + + template + struct FsmList + { + using fsmtype = Fsm; + + static void set_initial_state() { + fsmtype::set_initial_state(); + FsmList::set_initial_state(); + } + + static void reset() { + F::reset(); + FsmList::reset(); + } + + static void enter() { + fsmtype::enter(); + FsmList::enter(); + } + + static void start() { + set_initial_state(); + enter(); + } + + template + static void dispatch(E const & event) { + fsmtype::template dispatch(event); + FsmList::template dispatch(event); + } + }; + + // -------------------------------------------------------------------------- + + template struct StateList; + template<> struct StateList<> { + static void reset() { } + }; + template + struct StateList + { + static void reset() { + _state_instance::value = S(); + StateList::reset(); + } + }; + + // -------------------------------------------------------------------------- + + template + struct MooreMachine : tinyfsm::Fsm + { + virtual void entry(void) { }; /* entry actions in some states */ + void exit(void) { }; /* no exit actions */ + }; + + template + struct MealyMachine : tinyfsm::Fsm + { + // 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 */