Note: This tutorial assumes that you have completed the previous tutorials: decision_making/Tutorials/FSM. |
Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags. |
FSM C++ Reference
Description: Finite State Machine C++ ReferenceKeywords: decision_making
Tutorial Level: BEGINNER
Next Tutorial: decision_making/Tutorials/HSM
Contents
Introduction
This page includes a Reference manual to FSM C++ syntax. If you wish to get an overview of several FSM examples go to one of the links below
Textbook Examples
Dual Task FSM decision_making/Tutorials/DualTask FSM
Turnstile FSM decision_making_examples/Tutorials/Turnstile
Roomba FSM decision_making_examples/Tutorials/Roomba
Wandering Robot FSM decision_making_examples/Tutorials/FSM_Wandering
Event Raise HSM decision_making/Tutorials/Eventraise HSM
Increment TAO decision_making/Tutorials/Increment TAO
Example TAO decision_making/Tutorials/Example TAO
FSM Machine definition
FSM's are defined in a CPP file, and declared in the header file.
FSM
FSM(FSM_NAME){ ... }
- FSM machine definition
FSM_HEADER
FSM_HEADER(FSM_NAME);
- FSM machine declaration in header (.h) files.
FSM State definition
FSM_STATES
FSM_STATES{ STATE_1, STATE_2, ... }
- List of states. Must be located before FSM_START
FSM_START
FSM_START(STATE_NAME);
- Select start state. Must be located before FSM_BGN
FSM_BGN - FSM_END
FSM_BGN{ STATES }FSM_END
- FSM logic description
FSM_STATE
FSM_STATE(STATE_NAME){ ON_ENTRY_ACTION TRANSITONS }
Description of one state. Must be located inside of FSM_BGN-FSM_END block. All CALLs defined in ON_ENRTY_ACTION section run in parallel.
FSM transitions
FSM_TRANSITIONS
FSM_TRANSITIONS{ REACTIONS }
- List of FSM transitions and other events reactions. Must be located inside of STATE block
FSM Events and Conditions
EventQueue is a events distribution system.
- It's used for sharing events inside of FSM/HSM/BT machines.
- It's possible to insert external events to the system (from ROS or other custom source).
- It's thread safe.
Each Event is a path containing:
- all context names
- when this event was created
- an event short name at the end.
Example: /Con/tex/Na/me/EventName. When you compare two events you can use Regular Expressions as the name of one event by writing @ on the begging of the name. Example: @/Con/.*/Event[NT]...e
Events usage : (STOP event for example)
- Outside of FSM:
- Event e("/STOP")
- global / without context
- related to call_context
events->raiseEvent(e);
- raise event
- FSM_RAISE(/STOP)
- raise global event
- raise related to FSM context (without name of state) event
- raise related to FSM STATE context event
FSM_ON_EVENT(STOP, DO_SOMETHING)
check for event and do something if event is gotten.
FSM_ON_CONDITION(event==FSM_EVENT(STOP), DO_SOMETHING)
check condition. if satisfied do something
- clear current events queue
- Event e("/STOP")
Interface:
- Event waitEvent()
- blocked function up to new event arrived.
Event tryGetEvent(bool& success)
- unblocked function for get new event if exists
- clear queue
- close event system. release all waited processes.
- check if event system is closed.
Common extensions :
RosEventQueue is a connection of Ros (/decision_making/NODE_NAME/events topic) and internal EventQueue. Must be created after ros::init and ros_decision_making_init.
FSM_ON_EVENT
FSM_ON_EVENT(EVENT,REACTION)
- Reaction on event. Must be located inside FSM_TRANSITONS block. Rection is a c++ code or FSM_NEXT , FSM_RAISE macros.
FSM_ON_CONDITION
FSM_ON_CONDITION(BOOL_CONDITION,REACTION)
Reaction on condition satisfaction. Must be located inside FSM_TRANSITIONS block. Reaction is a c++ code or FSM_NEXT , FSM_RAISE macros.
FSM_NEXT
FSM_NEXT(STATE)
- Select next active state. This is reaction for FSM_ON_EVENT or FSM_ON_CONDITION
FSM_RAISE
FSM_RAISE(EVENT)
Raise event to events publication system. This macro can be reaction for FSM_ON_EVENT or FSM_ON_CONDITION and can be on_entry_action inside FSM_STATE block
FSM_EVENTS_DROP
FSM_EVENTS_DROP;
- Clear events queue for current state. It's optional command. Must be located before FSM_TRANSITIONS.
FSM_EVENT
FSM_EVENT(EVENT)
Create decision_making::Event object with current CallContext. Can be usefull with FSM_ON_CONDITION with local special variable event
Example:
- FSM_ON_CONDITION(event!=FSM_EVENT("/STOP"),FSM_NEXT(PROGRESS));
FSM Actions
FSM_CALL_TASK
FSM_CALL_TASK(TASK_NAME)
call remote or local task or external robot_task client (actionlib http://wiki.ros.org/actionlib) or registred local function.
FSM_CALL_FSM
FSM_CALL_FSM(FSM_NAME)
- call other FSM
FSM_CALL_BT
FSM_CALL_BT(BT_NAME)
call BehaviorTree
FSM_ON_STATE_EXIT
FSM_ON_STATE_EXIT_BGN{ ... }FSM_ON_STATE_EXIT_END
- Reaction on exit from current state. Must be located in FSM_STATE block before FSM_TRANSITIONS. Contains c++ code, FSM_CALL_* and FSM_RAISE macros. State transition will be blocked up to all calls in the block is finished.
FSM_STOP
FSM_STOP(EVENT,RESULT)
Stop FSM, raise event EVENT to global events system and return RESULT as result of FSM function.
Call FSM
FSM is a function with signature:
TaskResult FsmNAME(const CallContext* ctx,EventQueue* events);
This function is blocked up to FSM is finished (preempted, stopped by FSM_STOP or EventQueue is closed). So, just call this function.
- Parameters:
const CallContext* ctx : pointer to current context. Can be NULL. EventQueue* events : pointer to events system. Can not be NULL.
CallContext
This is a class for shearing parameters and context information through calls of FSM/HSM/BT machines.
Interface:
- void push(string name)
- add new context name
- remove last context name
- create parameter object of type A (template)
- check if parameters created
A& parameters()const
- get parameters. if not defined throw exception.
A& parameters()
- get parameters. if not defined create default instance.
Tasks
Task is an atomic preemptable action. decision making supports two types of Tasks
- ROS remote task
- Local task
ROS remote task
Special Activelib client. For create this kind of task, you need extend RobotTask class from robot_task package.
Local task
It's a callback function:
TaskResult FUNCTION_NAME( string task_name, const CallContext& context, EventQueue& events)
You need to registrate local task before usage (otherwise, the system assumes that the task is remote).
LocalTasks::registrate(''TASK_NAME'', ''CALLBACK'')