State Machines
State machines are a formalism for event driven systems that move from one discrete state to another in response to discrete events. PLECS lets you graphically create and edit state machines using common concepts such as boxes for states and curved arrows for transitions, and simulate them together with a surrounding system. You can feed continuous or discrete signals into a state machine e.g. to react to external events and output discrete signals from a state machine e.g. as control signals. Actions are specified in the C programming language and can be associated with states and transitions. Thanks to their built-in timer events, state machines are equally useful for implementing supervisory controls and complex modulators.
This chapter is subdivided into three sections. The first section describes how you interact with the graphical editor to create and modify state machines. The second section describes the semantics of a state diagram and how they influence the execution of the state machine. The third section contains examples that highlight different features of the state machine.
Working with State Machines
To create a new state machine, copy the State Machine block from the library browser into your model. A double-click on the block opens a new window with the state machine editor.
Fig. 106 State machine editor window
Note
The State Machine uses a distinct editor. You cannot copy block diagram components to a state chart or state machine elements to a block diagram schematic.
Working with States
A state is represented by a box with rounded corners. The name of the state is displayed at the top of the box in a title bar with a gray background.
Fig. 107 An empty state
To create a new state, click on the
button in the tool bar. Move the mouse anywhere on the chart and click the left mouse button to place the new state. To cancel the operation, press the Escape key, click the right mouse button, or click anywhere outside the editor window.
To duplicate an existing state, hold down the Ctrl (on macOS: Cmd) key, then click on the title bar of the state and drag the mouse to a new location in the same or a different editor window.
To change the size of a state, move the mouse over one of the four corners so that the pointer shape becomes a diagonal arrow. Hold down the mouse button, drag the mouse until the dashed box has the desired size and release the mouse button.
To change the name of a state, double-click on the name and edit it on the chart. Valid state names must start with a letter and can contain only letters and numbers. Whitespace, dashes or underscores are not allowed.
To edit the actions associated with the state, double-click on a free area within the state. This will open a tabbed code editor, in which you can edit the Enter, During and Exit actions for the state. If there is enough space, the action code is also displayed on the state. By double-clicking on the code, you can edit it directly on the chart.
Hierarchical States
A state can contain other states. The containing state is called a super-state or compound state, the contained state, a sub-state. A state that does not contain other states is called a leaf state. Compound states do not have a During action.
To create hierarchical states, resize a state so that it is large enough to fully surround another state, then move the other state into the first state.
Fig. 108 A super-state containing a sub-state
Note
Overlapping states are forbidden and will produce an error message at simulation start.
Working with Transitions
Transitions are represented by curved arrows from one state to another (or also the same) state. To create a new transition, move the mouse over one of the edges so that the pointer shape changes to crosshairs. Hold down the mouse button, drag the mouse to another edge until the pointer shape changes to double crosshairs and release the mouse button. If you release the mouse button before the pointer shape has changed to double crosshairs, the operation is cancelled.
To change the start point or end point of an existing transition, move the mouse pointer over either end until the pointer shape changes to an open hand, then hold down the mouse button and drag the mouse to the new location until the pointer shape changes to a double crosshair. If you release the mouse button before the pointer shape has changed to double crosshairs, the operation is cancelled and the transition remains unchanged.
Depending on its shape, a transition may have one or more control handles that become visible when you hover the mouse over the transition. To change the shape of the transition, hold down the mouse button over a control handle and drag it to the desired location.
A double-click on a transition opens the Transition Editor. It allows you to edit the Priority, Trigger, Condition and Action of the transition. The priority is also displayed at the origin of the transition arrow, and a double-click lets you edit it directly on the chart. Trigger, condition and action combined form the transition label in the form Trigger [Condition] / Action, which is shown next to the transition arrow. To change the location of the label along the transition, hold down the mouse button over the label and drag it to the desired location. By double-clicking on the label you can edit it directly on the chart.
Fig. 109 A transition with labels and control handle
Default Transitions
A default transition is represented by a curved arrow originating from a black dot. It is required on the top level of a state machine to define which state shall become active at the beginning of a simulation. If a compound state is the direct target of any transitions, it also requires an internal default transition to define which of its sub-states shall become active when an incoming transition is activated.
To create a new default transition, click on the
button in the tool bar. Move the mouse anywhere on the chart and click the left mouse button to place the origin of the default transition (marked with a dot). Then, move the mouse to draw the transition to an edge of the desired target state and click the left mouse button again. To cancel the operation, press the Escape key, click the right mouse button, or click anywhere on the chart that is not the edge of a state.
Working with Junctions
Junctions are branching points that join or fork transitions. They are represented by circles. Junctions are useful e.g. if the state that shall become active at the beginning of a simulation depends on one or more conditions. To create a new junction, click on the
button in the tool bar.
Fig. 110 A junction forking a default transition
Working with Annotations
Annotations are text blocks that you can place freely on a chart for documentation purposes. They have no influence on the execution of the state machine. To create a new annotation, double-click on an empty space in the chart and start typing. To move an annotation, hold down the mouse button over the annotation and drag it to the desired location. To edit an annotation, double-click on it. Choose Text alignment from the Format menu to change the text alignment of the annotation.
State Machine Configuration
To open the configuration editor, click on the
button in the tool bar.
Fig. 111 State machine configuration editor
Input Signals
On the Inputs tab you define input signals that are fed from the surrounding system into the state machine. Input signals are specified by an Input variable and a Type.
The Input variable specifies the name with which you refer to the input signal in actions or expressions. It is also displayed next to the corresponding input terminal of the State Machine block. The variable name must be unique and a valid C identifier, i.e. it must start with a letter and consist of only letters, numbers and underscores.
The Type specifies whether the signal is a continuous signal or a trigger signal. For continuous and trigger signals, the actual signal value is assigned to the input variable in every time step. For trigger signals, additionally an event with the same name will be created when the input signal changes in the prescribed way. A rising trigger event is created in the instant when the input signal changes from zero to non-zero, a falling trigger event is created in the instant when the input signal changes from non-zero to zero. For trigger signals, a trigger symbol is also displayed next to the corresponding input terminal of the State Machine block.
Note
Signal changes from one non-zero value to another non-zero value, e.g. from a negative value to a positive value, do not cause an event to be created.
Input signals appear on the State Machine block in the order in which they appear in the list. Use the four buttons to the left of the list to add or remove inputs or to change their order.
Output Signals
On the Outputs tab you define output signals that are fed from the state machine to the surrounding system. Output signals are defined by an Output variable that specifies the name with which you refer to the output signal in actions. It is also displayed next to the corresponding output terminal on the State Machine block. The variable name must be unique and a valid C identifier, i.e. it must start with a letter and consist of only letters, numbers and underscores.
Output signals appear on the State Machine block in the order in which they appear in the list. Use the four buttons to the left of the list to add or remove outputs or to change their order.
Constants and Variables
On these tabs you define global variables that you can use in actions or expressions. They must have a unique and valid C identifier, i.e. they must start with a letter and consist of only letters, numbers and underscores.
Constants remain constant during a simulation. The value is determined by the Value expression, which can be any valid MATLAB or Octave expression that evaluates to a scalar number.
Variables can be modified by actions. They are in fact additional discrete state variables in addition to the active state of the state machine. Their initial value is determined by the Initial value expression, which can be any valid MATLAB or Octave expression that evaluates to a scalar number.
C Declarations
The C declarations tab is used for global declarations and definitions. It is also the place to include standard library headers and to define macros and static helper functions that you want to use in actions and expressions.
In addition to the user defined variables and functions, the following pre-defined macros can be used in actions:
Macro |
Type |
Access |
Description |
|---|---|---|---|
|
double |
R |
Returns the current simulation time. |
|
void |
W |
Use this macro to report errors that occur in your code. The simulation will be terminated after the current simulation step. In general, this macro should be followed by a |
|
void |
W |
Use this macro to report warnings. The warning status is reset after the execution of the current simulation step, so you do not need to reset it manually. The pointer |
Note
User defined variable or function names must not start with fsm_ or FSM_ because these prefixes are reserved for internal symbols in the generated code.
Hierarchical Transition Order
This option is only relevant for hierarchical state machines (see Hierarchical States and Execution of Hierarchical State Machines). When both a super-state and its sub-states have outgoing transitions that are eligible to be taken at the same time, this option determines whether transitions from the super-state take precedence over transitions from the sub-states or vice versa.
Sample Time
This parameter determines how the state machine is executed. The table below lists the valid parameter values for the different sample time types. For a detailed description of the sample time types see Sample Times.
Type |
Value |
|
|---|---|---|
Continuous |
|
|
Discrete-Periodic |
|
|
Inherited |
|
With a Continuous sample time, the state machine is executed at every simulation step. With a Discrete-Periodic sample time, the state machine is executed only at the regularly spaced simulation steps prescribed by the sample time values. With an Inherited sample time, the actual sample time depends on the blocks that are connected to the State Machine block.
Animation
This option is useful for debugging your state machine. When the option is checked, the simulation is paused whenever a transition fires, and the transition path including the source and target state is highlighted. The simulation can be continued by selecting Continue from the Simulation menu or by pressing the Space key.
State Machine Execution
A state machine is executed at each simulation step that the solver makes if it has a continuous sample time or at the specified time steps if it has a discrete sample time (see also Sample Time). During each execution, the following steps are performed:
The triggers and conditions of all transitions leaving the currently active state are evaluated.
If a transition “fires”, i.e. if both trigger and condition are true, the State Machine executes the Exit action of the current state followed by the transition action and the Enter action of the target state.
If no transition fires, the During action of the current state is executed.
During each execution, at most one state change can occur, i.e. at most one transition can be taken. Note that a transition may include one or more junctions (see Compound Transitions).
Transition Evaluation
A transition from an active state can be taken when the specified trigger event occurs, provided that the condition is true at the same time. Both trigger and condition are optional. If a transition does not specify a trigger, any event (including the mere execution of the state machine) will qualify so that the transition can be taken if the condition is true. If a transition does not specify a condition, it can be taken when the trigger event occurs.
Transition Priorities
It is possible that multiple transitions from the current state are eligible to be taken at the same time. In this case, the transition with the lower priority number is given precedence.
Compound Transitions
A compound transition is a complete path from one leaf state to another (or the same) leaf state consisting of two or more transitions joined by one or more junctions. A compound transition can only be taken when all trigger events specified by the individual transitions occur and all conditions specified by the individual transitions are true. If a compound transition is taken, the actions of all individual transitions are executed in the order of the transitions on the path.
Trigger Types
PLECS distinguishes between explicit, implicit and time-based triggers.
Explicit Trigger
An explicit trigger is an input signal that is configured as a trigger signal. It is active whenever the input signal changes in the specified way. In the example shown in Fig. 112, the event E is active whenever the signal connected to the input terminal E changes from zero to a non-zero value or from a non-zero value to zero. If State1 is active at this time, the transition fires.
Fig. 112 State machine with explicit trigger
Note
It is expected that the input signal for an explicit trigger changes only at discrete instants. The signal source is responsible for registering an appropriate zero-crossing function to enable a variable-step solver to make a simulation step at the instant at which the signal reaches or leaves zero.
Implicit Trigger
An implicit trigger is a relational expression. It is active when the expression becomes true, i.e. if it evaluated to false in the previous time step and evaluates to true in the current time step. If the state machine uses a continuous sample time, an implicit trigger will also register a zero-crossing function to enable the solver to make a simulation step at precisely the instant at which the expression becomes true.
Notice the fundamental difference between an implicit trigger x > 0 and a condition [x > 0] illustrated in Fig. 113.
Fig. 113 Implicit trigger (left) versus condition (right)
In the left chart, if State1 is active, the transition will be taken only when x becomes greater than \(0\). However, if x is already greater than 0 when State1 becomes active, nothing will happen until x becomes less than or equal to \(0\) and afterwards greater than \(0\) again. If x is a continuous signal and the state machine uses a continuous sample time, the state machine will be executed precisely at the instant at which x crosses \(0\).
In the right chart, if State1 is active, the transition will be taken at any execution of the state machine if x happens to be greater than \(0\). If x is already greater than \(0\) when State1 becomes active, the transition will be taken during the next execution of the state machine. However, the execution of the state machine does not necessarily coincide with the instant at which x crosses \(0\).
Time-Based Trigger
A time-based trigger is an expression of the form AFTER(delay), where delay is an expression that evaluates to a number. If the state machine uses a continuous sample time, the trigger event will be created exactly delay seconds after the source state of the transition was entered. If the state machine uses a discrete sample time, the trigger event will be created at the first execution time following the delay period.
Trigger Lifetime
A trigger event is only valid in the simulation step in which it is created. If no transition responds to the event in this time step, the event is ignored; it is not deferred to a subsequent execution of the state machine.
Execution of Hierarchical State Machines
In a hierarchical state machine it is not immediately obvious which transitions are eligible to be taken, and which actions are executed when a transition is taken.
Transition Evaluation
Only leaf states, i.e. states that do not contain other states, can be the active state. But compound states that directly or indirectly contain the active state are also implicitly active. When the state machine searches for a transition to be taken, it not only evaluates the transitions leaving the active leaf state but also those that leave the implicitly active compound states.
In the case where both a transition from a super-state and a transition from a sub-state are eligible to be taken, the option Hierarchical Transition Order in the State Machine Configuration dialog determines whether the transition leaving the super-state is given precedence over the transition leaving the sub-state (top to bottom) or vice versa (bottom to top). Note that in this context leaf states are considered to be at the bottom of a state hierarchy.
Execution Sequence
The two states that are directly connected by a transition are designated the main source and the main target of the transition. Notice that source state and target state may both be compound states. The lowest compound state that contains both source state and target state is designated the lowest common ancestor (LCA) state. When the transition is taken, the following actions are executed in this order:
The Exit actions of all states from the active leaf state (which may be the main source state or a sub-state of it) up to (but not including) the LCA state are executed from bottom to top.
The transition action is executed.
The Enter actions of the state hierarchy inside the LCA state to the main target state are executed from top to bottom.
If the main target is a compound state, the action of its local default transition is executed followed by the Enter action of the default transition’s target state. If necessary, this process is repeated recursively until a leaf state is reached.
This process is illustrated in Fig. 114. Consider that S11 is the currently active state, so both S1 and S are also implicitly active.
Fig. 114 Execution sequence in a hierarchical state machine
Transition T1 has S1 and S2 as its main source and target. Their LCA state is S. S2 is a compound state, and therefore after it has been entered, its internal default transition causes S21 to be entered. Consequently, taking T1 causes the following sequence of actions to be executed: S11_exit(); S1_exit(); T1_action(); S2_enter(); D_action(); S21_enter();.
Transition T2 has S11 and S21 as its main source and target. Their LCA state is again S. Taking T2 causes the following sequence of actions to be executed: S11_exit(); S1_exit(); T2_action(); S2_enter(); S21_enter();.
State Machine Examples
Oven Control
This example demonstrates a simple oven control. While the oven is in operation, a hysteresis type control shall keep the oven temperature within a certain tolerance band around a set point by switching the heating on and off. As a safety measure, we also want to ensure that the heating is always switched off when the oven door is open.
Example Model
See the example model “Oven Control”.
Find it in PLECS under Help > PLECS Documentation > List of Example Models.
Fig. 115 Example of a simple oven control
The oven is modeled with a heat source, a thermal capacitance and resistance and a thermometer. The oven control is implemented with a state machine. Its inputs are the actual and the desired temperature and the status of the oven door, which is defined as 0 when the door is open and 1 when the door is closed. The state machine output is the command for the oven heating. The state machine uses a constant variable DeltaT that determines the limits of the tolerance band around the desired temperature.
The top-level states DoorOpen and DoorClosed reflect the actual state of the oven door. The default transition, which is taken at the first execution of the state machine, is branched with a Junction. If the door is initially open, the (i.e. Door==0), DoorOpen state will be entered, else the DoorClosed state. Notice that the unconditional “else” branch leaving the Junction has a lower precedence than the conditional branch. Afterwards, the state machine will transition from DoorOpen to DoorClosed when Door becomes non-zero and vice versa when the input variable Door becomes zero.
DoorClosed is a compound state. Therefore, when it is the target of a transition, its internal default transition will be executed, which is also branched with a Junction. If the actual temperature is below the set point when the default transition executes, the Heating state will be entered, else the NoHeating state. Afterwards, the state machine will transition from Heating to NoHeating when the actual temperature becomes greater than the upper limit and from NoHeating to Heating, when the actual temperature becomes less than the lower limit.
The output variable Heating is set to 1 when the Heating state is entered, and to 0 when the state is left. Notice that it does not matter whether the state is left because the transition ActT>SetT+DeltaT is taken when the temperature exceeds the upper limit, or because the transition !Door is taken when the oven door is opened. In either case, the Exit action of Heating is executed and the heating is turned off.
For this state machine to work properly, the Hierarchical Transition Order must be set to top to bottom (which is the default). This is important because a door opening event might coincide with the event that the actual temperature exceeds the upper or lower limit. The higher-level door opening event must take precedence over the lower-level temperature events so that the state machine will unconditionally transition to the DoorOpen state.
Demo Models
Demo Model
The demo model “Current Controlled Z-Source Inverter” features a modulator implemented with the state machine block.
Find it in PLECS under Window > Demo Models > Power Supplies.
Demo Model
The demo model “Buck Converter with Cascaded Controls” features a state machine based current controller.
Find it in PLECS under Window > Demo Models > Power Supplies.
Demo Model
The demo model “Windpower System with Permanent Magnet Synchronous Generator” features a maximum power point tracker implemented with the state machine block.
Find it in PLECS under Window > Demo Models > Power Generation.