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++ Reference

Keywords: decision_making

Tutorial Level: BEGINNER

Next Tutorial: decision_making/Tutorials/HSM

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

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
      Event e("STOP",call_context)
      • related to call_context

      events->raiseEvent(e);

      • raise event
    Inside of FSM:
    • FSM_RAISE(/STOP)
      • raise global event
      FSM_RAISE(STOP)
      • raise related to FSM context (without name of state) event
      FSM_RAISE(STATE_NAME/STOP)
      • 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

      FSM_EVENTS_DROP
      • clear current events queue

Interface:

  • Event waitEvent()
    • blocked function up to new event arrived.

    Event tryGetEvent(bool& success)

    • unblocked function for get new event if exists
    void drop_all()
    • clear queue
    void close()
    • close event system. release all waited processes.
    bool isTerminated()const
    • 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)

FSM_CALL_FSM

FSM_CALL_FSM(FSM_NAME)

  • call other FSM

FSM_CALL_BT

FSM_CALL_BT(BT_NAME)

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
    void pop()
    • remove last context name
    void createParameters(A* a= new A())
    • create parameter object of type A (template)
    bool isParametersDefined()const
    • 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

  1. ROS remote task
  2. 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'')

Wiki: decision_making/Tutorials/FSM(C++) (last edited 2013-12-17 07:09:37 by Ari Yakir)