States
Overview
States are defined using hsmcpp::StateID_t type. Recommended way is to put definitions into a namespace:
namespace MyStates {
constexpr hsmcpp::StateID_t StateA = 0;
constexpr hsmcpp::StateID_t StateB = 1;
constexpr hsmcpp::StateID_t StateC = 2;
}
State callbacks are optional and include:
entering
called right before changing a state
transition is canceled if callback returns FALSE
state changed
called when HSM already changed its current state
exiting
called for previous state before starting to transition to a new state
transition is canceled if callback returns FALSE
Usage
Adding a new state is done using HierarchicalStateMachine::registerState() API. Assuming we create HSM as a separate object, here are possible ways to register a state:
hsmcpp::HierarchicalStateMachine hsm;
HandlerClass hsmHandler;
hsm.registerState(MyStates::StateA);
hsm.registerState<HandlerClass>(MyStates::StateA, &hsmHandler, &HandlerClass::on_state_changed_a);
hsm.registerState<HandlerClass>(MyStates::StateA,
&hsmHandler,
&HandlerClass::on_state_changed_a,
&HandlerClass::on_entering_a);
hsm.registerState<HandlerClass>(MyStates::StateA,
&hsmHandler,
&HandlerClass::on_state_changed_a,
&HandlerClass::on_entering_a,
&HandlerClass::on_exiting_a);
hsm.registerState<HandlerClass>(MyStates::StateA,
&hsmHandler,
&HandlerClass::on_state_changed_a,
nullptr,
&HandlerClass::on_exiting_a);
Note that specifying template parameter for registerState() function is optional, if you explicitly need to pass nullptr (as in the last example) you will need to provide it.
State actions
Besides implementing logic inside HSM callbacks it’s possible to define some operations as state actions. These actions are built-in commands that are executed automatically based on HSM activity.
Actions could be added using HierarchicalStateMachine::registerStateAction() API.
hsm.registerStateAction(MyStates::StateA,
hsmcpp::StateActionTrigger::ON_STATE_ENTRY,
hsmcpp::StateAction::START_TIMER,
MyTimers::Timer1, 1000, false);
At the moment two triggers are supported (see StateActionTrigger enum):
enum class StateActionTrigger {
ON_STATE_ENTRY,
ON_STATE_EXIT
};
Trigger |
Description |
---|---|
StateActionTrigger.ON_STATE_ENTRY |
will execute action when entering a state; |
StateActionTrigger:ON_STATE_EXIT |
will execute action when exiting a state. |
Note
actions will be executed only if ongoing transition wasn’t blocked by entry/exit callbacks.
Supported actions are defined in StateAction enum:
Action |
Arguments |
Description |
---|---|---|
StateAction::START_TIMER |
|
|
StateAction::STOP_TIMER |
|
|
StateAction::RESTART_TIMER |
|
Note trying to restart expired singleshot timer will do nothing since this timer is considered as “not running”. Use “start timer” action instead. |
StateAction::TRANSITION |
|
|
See Timers for details regarding their usage.