Statecharts

Programming complex behavior or event-dependent processes in ArmarX is done with Statecharts. For more details refer to Statechart. More...

## Data Structures

class  DynamicRemoteState
DynamicRemoteStates can be used to connect to remote statecharts dynamically at runtime. More...

class  FinalStateBase< EventType, StateType >

class  ParameterMapping
This class maps parameters from several source dictionaries to one input dictionary. The mapping depends on an instance of ParameterMappingIceBase, in which the mapping is specified.
More...

class  RemoteState
This Statetype is used to create a state instance that represents a state that is located in another application. It is added in a parent state by calling State::addRemoteState(statename, proxyname).
If a RemoteState is entered for the first time, it creates automatically a new instance at the remotely located RemoteStateOfferer that contains the real state. The RemoteState receives upon creation of the new real-state instance an unique id of this state for further communication.
This id is automatically used in the onBreak- and onExit-functions, to communicate with the correct state.
Except the state creation-call (which should return immediately) all remote procedure calls are async calls. More...

class  RemoteStateOfferer< ContextType >
Class that holds states, which offer functionality for other states over Ice. More...

class  RemoteStateWrapper

class  State

class  StateBase

class  StatechartContext
This class contains a statechart and provides the interfaces to distributed components. More...

class  StateController

class  StateTemplate

class  StateUtility

## Modules

XMLStateComponent

## Typedefs

using CounterState = CounterStateTemplate< EvCounterNotFulfilled, EvCounterFulfilled >
CounterState is a typedef for the CounterStateTemplate, that uses the events EvCounterNotFulfilled and EvCounterFulfilled. More...

using FailureState = FinalState< Failure >

using SuccessState = FinalState< Success >

## Detailed Description

Programming complex behavior or event-dependent processes in ArmarX is done with Statecharts. For more details refer to Statechart.

    \page Statechart ArmarX Statecharts
\brief Programming complex behavior or event-dependent processes in ArmarX is done with Statecharts.
\tableofcontents

Statecharts are a variant of Finite-StateMachines to model complex behavior.
The main usecase of statecharts in ArmarX is to program new robot behaviors, but they can also be used for any other purpose that is state-dependent and/or require event-dependent processing.
To ease the process of programming robot behaviors ArmarX offers a graphical tool for creating these behaviors: The \ref armarx::StatechartEditorController.
With this editor it is possible to easily design hierarchical compositions of statecharts with a defined data flow.
For a detailed tutorial of the statechart editor refer to \ref ArmarXCore-Tutorials-sce "Statechart editor basic tutorial".

A detailed explanation of ArmarX Statecharts can be found in the publication:<br/>
M. Wächter, S. Ottenhaus, M. Kröhnert, N. Vahrenkamp and T. Asfour (2016), *The ArmarX Statechart Concept: Graphical Programming of Robot Behaviour*, Front. Robot. AI 3:33.
<a href="http://journal.frontiersin.org/article/10.3389/frobt.2016.00033/full">[DOI]</a>

\section StatechartConcept Statechart concept in ArmarX
Complex robot behaviors are usually compositions of smaller operations, each of which modifying the states of the robot and the environment.
Based on this principle, robot operations in ArmarX are arranged as hierarchical, distributed, and orthogonal statecharts based on Harel's approach 1987.
Statecharts are widely used in robotics to control the behavior on a high level.
The well-known RDE ROS employs statecharts that are similar to the ones in ArmarX in terms of data flow.
However, the two approaches differ in the way transitions are triggered.
In many aspects the statecharts of ArmarX are similar to rFSM from Orocos.
Nevertheless, the statecharts in Orocos focus on the coordination of components, while our approach concentrates on the disclosure of the internal state.

The key principles of the ArmarX statecharts are: **modularity**, **reusability**, **runtime reconfigurability**, **decentralization** and **state-disclosure**.

- *Modularity* is an inherent characteristic of our statecharts due to the definition of states as individual objects with specified input and output.
- *Reusability* is ensured since states are composites, i.e. every state can be used as a substate in any other state. Furthermore, states offer a generic interface for communication.
- *Runtime reconfigurability* means that a statechart can be defined in configuration files that allows changing its structure at runtime completely.
- *Decentralization* means that a statechart does not need to entirely reside in one process, but can be distributed over several components.
This allows load balancing and increases robustness.
A crashed distributed state component would not crash the whole statechart, but would just create an event for higher layers, indicating that this specific component has failed.
- *State-disclosure* means that the current state and all its parameters can be inspected and logged at runtime.

\section Structure Structure of a statechart
A statechart in ArmarX is a normal state itself. It contains
- the statename, unique in its hierarchy level
- an id, that is unique in its process
- *onEnter()*, *onBreak()* and *onExit()*-functions (synchronous) and *run()* (asynchronous), that provide the functionality of the state (*optional*)
- **Substates** (instances of states) (*optional*)
- **Transitions** (table of conditional links between states) (*optional*)
- **Input parameters**, which are set by the system or parentstates before the state is entered (*read-only* set of parameters that this state requires) (*optional*)
- **Local parameters**, which can be read and written by the user to pass self-calulated data down to substates (*optional*)
- **Output parameters**, which should contain the result of the state and are to be set by the statechart-designer (set of result parameters, that this state offers)(*optional*)

So a statechart in ArmarX consists of a toplevel state, that is the statechart itself. This state has a set of substates, which can have substates as well and so on.<br/>
Since a statechart is a state itself, it can be used by other state as well. The other state just needs to know what input and output parameters the statechart expects/offers and has to provide the inputparameters.

\section DesigningAStatechart Creation of statecharts
ArmarX provides means for designing statecharts textually and \ref armarx::StatechartEditorGuiPlugin "graphically" with the possibility to include user-defined code for custom operations.

\subsection ProgrammingStateharts Textually programming a statechart
This type of designing a statechart is the deprecated way.
It is still possible, but it is takes much longer and more complex to understand.
The implementation is based on inheritance from base classes, i.e. a state needs to be derived from StateTemplate <myStateType>, where myStateType is the new State-class itself.<br/>
To add functionality to a new, derived state, one has to implement the functions StateBase::defineState(), StateBase::defineParameters(), StateBase::defineSubstates(), StateBase::onEnter(), StateBase::onExit(), StateBase::onBreak(), StateBase::run(). But it is not required to implement all these functions, just these that are needed for the purpose of the state.

So, a basic statechart looks like this:
\include StatechartExample.dox

\image html ArmarX-Statechart-SimpleExample.png "Visualization of the statechart example"

More and complete examples can be found in \${ArmarXCore_DIR}/../source/ArmarXCore/applications/StateChartExamples.
Examples:
- InstallConditionExample
- RemoteAccessableStateExample
- StatechartPerformanceTest
- StateParameterExample
- TimeoutExample

\section Eventprocessing
Events are the triggers for transitions. Events are triggered on fulfillment of conditions, which the same state installed before.
And since states should be modular and reuseable they
dont know anything about other states on the same hierarchy level or higher. Therefore events are sent to the statechart
and then processed by the state, where the transition is located. Events are <b>not</b> processed by the
state, that the transition is affecting.<br/>
Events always have a specific receiver state, for which the event was meant, so that it is easier to identify
if an unexpected was received and which state it should originally reach.<br/>
If there is a state S with two substates A and B and a transition from A to B like this:
\verbatim
S
/ \
A-->B

An event that triggers the transition from A to B must have the eventReceiver set to A and be send to state S. State S then calls the onExit()-function of state A, applies the parameter-mapping, then calls onEnter() of state B. But usually the statechart-implementing-user does not need to know all these eventprocessing details. The installed events (e.g. with installCondition, sendEvent) are automatically sent to the correct state.

# Controlling the Dataflow

The specification of the dataflow between states is an important part in the design of the ArmarX statecharts. It is possible to specify which parameters are transferred when an active state is changed. Every state has an input-, local- and an output-parametermap. These maps are string->Variant maps, that means a string is associated with a variable type, that can contain an int, a float, a string etc.
The input-parametermap is filled before the onEnter()-function is called. This happens automatically during the transition.
The transition-class has a member where the user can specify how the source-parameters should be mapped onto the input-parametermap of the next state (see ParameterMapping) or via the transition dialog in the Statechart Editor. As sources for the input parameters the following sources are available:

• the output-parameterset of the previous state
• the event-parametermap
• the input- and local-parametermap of the parentstate
• the default values (used no mapping is specified)

# Statechart Profiles

ArmarX Statecharts offer the possibility to provide different parameter sets for different robots or different setups. These profiles are defined in a hierarchical way, which means that values of lower priority profiles (lowest is Root) are overwritten by values of a profile with a higher priority.

## State Parameter Default Values

A profile encapsulates default parameter values for a well-defined use case configuration of a statechart while maintaining the same functionality for all statecharts of the hierarchy. For example, a statechart that is used on a simulated robot might need different default parameter values than the same statechart that is deployed on a real robot. This notion helps with preventing duplicates of functionally equal statecharts while still allowing individual configurations for different use cases. The profiles are ordered in a hierarchy to enable inheritance of parameter values.

## Statechart Group Default Configuration

Additionally, the profiles offer to specify configuration values for the whole statechart group like proxy names, e.g. the KinematicUnit. These differ usually from robot to robot, e.g. Armar3KinematicUnit, and need to be specified for each robot seperately. These configuration values can be specified in the Statechart Editor within in the statechart group properties.

SCE-Configurations

## Profile Hierarchy

Usually there is a hierarchy for each type of a robot, e.g. for Armar3 we use the following profile hierarchy:

Statechart Profile Hierarchy Example

Any profile here can be specified to be used, even intermediate profiles. If Armar3Real is selected in the statechart configuration and for one parameter there is no value given for Armar3Real, the hierarchy is traversed until a parameter is found. If no profile is specified, the Root profile is used.

# Working with statecharts

Note
Most parts of this section is only relevant if you are writing statecharts manually in the source code. The usual way to create statecharts is to use the StatechartEditor, of which the usage is described in this tutorial.

## Calling of external Components

It is possible to call external components inside the statecharts. Since statecharts on their own are not particularly useful for robotics, they need to communicate with the other components, i.e. the robot components. To this end, each state has a pointer to its StatechartContext, which contains Ice proxies to other components. In case of an XML state created with the StatechartEditor these contexts can be generated from the GUI automatically.

## How to install conditions

State usually react on events and trigger transitions into other states based on these events. These events can be fired if an condition is fulfilled. To specify such a condition and connect it to an event you need to use the installCondition function inside your onEnter or onRun function and construct a condition as described here.

## How to offer functionality with a statechart over Ice

In a normal application the maincomponent derives from component. To offer functionality over Ice for other components/statecharts the main component needs to be derived from the class RemoteStateOfferer.
Additionally the pure virtual function RemoteStateOfferer::onInitRemoteStateOfferer() needs to be implemented in this class. In onInitRemoteStateOfferer() the states, that should be accessable remotely, are to be added with State::addState<StateType>(statename).

## How to control a statechart

Online statecharts can be controlled from the StatechartViewer.

## ◆ CounterState

 using CounterState = CounterStateTemplate

#include <ArmarXCore/statechart/standardstates/CounterState.h>

CounterState is a typedef for the CounterStateTemplate, that uses the events EvCounterNotFulfilled and EvCounterFulfilled.

CounterStateTemplate

Definition at line 97 of file CounterState.h.

## ◆ FailureState

#include <ArmarXCore/statechart/standardstates/FinalState.h>

State that automatically signals "Failure" to the parent state. See class FinalStateBase for more information.

Definition at line 184 of file FinalState.h.

## ◆ SuccessState

#include <ArmarXCore/statechart/standardstates/FinalState.h>

State that automatically signals "Success" to the parent state. See class FinalStateBase for more information.

Definition at line 173 of file FinalState.h.