diff --git a/chapters/statemachines.tex b/chapters/statemachines.tex index 13e5df3ec..5f0e06a9a 100644 --- a/chapters/statemachines.tex +++ b/chapters/statemachines.tex @@ -139,7 +139,7 @@ \section{Transitions}\label{transitions} \end{operatordefinition} \begin{example} -If there is a transition with \lstinline!immediate=false! from +If there is a transition with \lstinline!immediate = false! from state \lstinline!A1! to \lstinline!A2! and the condition is \lstinline!ticksInState() >= 5!, and \lstinline!A1! became active at 10ms, and the clock period is 1ms, then \lstinline!A1! will be active at 10ms, 11ms, 12ms, 13ms, 14ms, and will be not active at 15 ms. @@ -151,7 +151,7 @@ \section{Transitions}\label{transitions} equation initialState(A0); transition(A0, A1, sample(time, Clock(1, 1000)) > 0.0095); - transition(A1, A2, ticksInState() >= 5, immediate=false); + transition(A1, A2, ticksInState() >= 5, immediate = false); \end{lstlisting} \end{example} @@ -177,7 +177,8 @@ \section{State Machine Graphics}\label{state-machine-graphics} \begin{example} \begin{lstlisting}[language=modelica] -transition(state2, state1, x < 10, immediate=true, reset=true, synchronize=false, priority=1) +transition(state2, state1, x < 10, + immediate = true, reset = true, synchronize = false, priority = 1) annotation( Line( points = {{-40,-16},{-36,-4},{-32,8},{-40,26},{-40,32},{-46,50}}, @@ -197,15 +198,15 @@ \section{State Machine Graphics}\label{state-machine-graphics} The \lstinline!Text! annotation representing the transition condition can use the notation \lstinline!%condition! to refer to the condition expression. -The extent of the Text is interpreted relative to either the first point of the \lstinline!Line!, in the case of \lstinline!immediate=false!, or the last point (\lstinline!immediate=true!). +The extent of the Text is interpreted relative to either the first point of the \lstinline!Line!, in the case of \lstinline!immediate = false!, or the last point (\lstinline!immediate = true!). -In addition to the line defined by the points of the \lstinline!Line! annotation, a perpendicular line is used to represent the transition. This line is closer to the first point if \lstinline!immediate=false! otherwise closer to the last point. +In addition to the line defined by the points of the \lstinline!Line! annotation, a perpendicular line is used to represent the transition. This line is closer to the first point if \lstinline!immediate = false! otherwise closer to the last point. If the condition text is somewhat distant from the perpendicular line, a dimmed straight line joins the transition text and the perpendicular line. (See the rightmost transition above.) -If \lstinline!reset=true!, a filled arrow head is used otherwise an open arrow head. -For \lstinline!synchronize=true!, an inverse ``fork'' symbol is used in the -beginning of the arrow. (See the rightmost transition above.) +If \lstinline!reset = true!, a filled arrow head is used otherwise an open arrow head. +For \lstinline!synchronize = true!, an inverse ``fork'' symbol is used in the beginning of the arrow. +(See the rightmost transition above.) The value of the \lstinline!priority! attribute is prefixing the condition text followed by a colon if \lstinline!priority! \textgreater{} 1. @@ -257,7 +258,7 @@ \subsection{State Activation}\label{state-activation} else false) then i else 0 - for i in 1:size(t,1)); + for i in 1 : size(t, 1)); \end{lstlisting} The start value of c is false. This definition would require that the previous value is recorded for all transitions conditions. Below is @@ -277,7 +278,7 @@ \subsection{State Activation}\label{state-activation} else false) then i else 0 - for i in 1:size(t,1)); + for i in 1 : size(t, 1)); \end{lstlisting} In a similar way, the \lstinline!Integer delayed! is calculated as the index for a @@ -292,7 +293,7 @@ \subsection{State Activation}\label{state-activation} else false) then i else 0 - for i in 1:size(t,1)); + for i in 1 : size(t, 1)); \end{lstlisting} The transition to be fired is determined as follows, taking into account @@ -315,9 +316,9 @@ \subsection{State Activation}\label{state-activation} from-transitions and to determine if the state machine is in a final state currently: \begin{lstlisting}[language=modelica] -Boolean finalStates[nStates] = { - max(if t[j].from == i then 1 else 0 for j in 1:size(t,1)) == 0 - for i in 1:nStates}; +Boolean finalStates[nStates] = + {max(if t[j].from == i then 1 else 0 for j in 1 : size(t, 1)) == 0 + for i in 1 : nStates}; Boolean stateMachineInFinalState = finalStates[activeState]; \end{lstlisting} To enable a synchronize transition, all the \lstinline!stateMachineInFinalState! conditions of all state machines within the meta state must be true. An example is given below in the semantic example model. @@ -339,13 +340,15 @@ \subsection{Reset Handling}\label{reset-handling} The state machine reset flag is propagated and maintained to each state individually: \begin{lstlisting}[language=modelica] -output Boolean activeResetStates[nStates] = {if reset then true else previous(nextResetStates[i]) for i in 1:nStates}; +output Boolean activeResetStates[nStates] = + {if reset then true else previous(nextResetStates[i]) for i in 1 : nStates}; \end{lstlisting} until a state is eventually executed, then its corresponding reset condition is set to false: \begin{lstlisting}[language=modelica] Boolean nextResetStates[nStates] = if active then - {if activeState == i then false else activeResetStates[i] for i in 1:nStates} + {if activeState == i then false else activeResetStates[i] + for i in 1 : nStates} else previous(nextResetStates) \end{lstlisting} @@ -368,31 +371,50 @@ \subsection{Semantics Summary}\label{semantics-summary} model StateMachineSemantics "Semantics of state machines" parameter Integer nStates; parameter Transition t[:] "Array of transition data sorted in priority"; - input - Boolean c[size(t,1)] "Transition conditions sorted in priority"; + input Boolean c[size(t, 1)] "Transition conditions sorted in priority"; input Boolean active "true if the state machine is active"; - input Boolean reset "true when the state -machine should be reset"; + input Boolean reset "true when the state machine should be reset"; Integer selectedState = if reset then 1 else previous(nextState); Boolean selectedReset = if reset then true else previous(nextReset); // For strong (immediate) and weak (delayed) transitions - Integer immediate = max(if (if t[i].immediate and t[i].from == selectedState - then c[i] else false) then i else 0 for i in 1:size(t,1)); - Integer delayed = max(if (if not t[i].immediate and t[i].from == nextState - then c[i] else false) then i else 0 for i in 1:size(t,1)); + Integer immediate = + max( + if (if t[i].immediate and t[i].from == selectedState + then c[i] + else false) + then i + else 0 + for i in 1 : size(t, 1)); + Integer delayed = + max( + if (if not t[i].immediate and t[i].from == nextState + then c[i] + else false) + then i + else 0 + for i in 1 : size(t, 1)); Integer fired = max(previous(delayed), immediate); - output Integer activeState = if reset then 1 elseif fired > 0 then t[fired].to else selectedState; - output Boolean activeReset = if reset then true elseif fired > 0 then t[fired].reset else selectedReset; + output Integer activeState = + if reset then 1 elseif fired > 0 then t[fired].to else selectedState; + output Boolean activeReset = + if reset then true elseif fired > 0 then t[fired].reset else selectedReset; // Update states Integer nextState = if active then activeState else previous(nextState); Boolean nextReset = if active then false else previous(nextReset); // Delayed resetting of individual states - output Boolean activeResetStates[nStates] = {if reset then true else - previous(nextResetStates[i]) for i in 1:nStates}; - Boolean nextResetStates[nStates] = if active then {if activeState == i then false - else activeResetStates[i] for i in 1:nStates} else previous(nextResetStates); - Boolean finalStates[nStates] = {max(if t[j].from == i then 1 else 0 for j in 1:size(t,1))== 0 for i in 1:nStates}; + output Boolean activeResetStates[nStates] = + {if reset then true else previous(nextResetStates[i]) + for i in 1 : nStates}; + Boolean nextResetStates[nStates] = + if active then + {if activeState == i then false else activeResetStates[i] + for i in 1 : nStates} + else + previous(nextResetStates); + Boolean finalStates[nStates] = + {max(if t[j].from == i then 1 else 0 for j in 1 : size(t, 1)) == 0 + for i in 1 : nStates}; Boolean stateMachineInFinalState = finalStates[activeState]; end StateMachineSemantics; \end{lstlisting} @@ -410,7 +432,14 @@ \subsection{Merging Variable Definitions}\label{merging-variable-definitions} In each state, the outer output variables are solved for and for each such variable a single definition is formed: \begin{lstlisting}[language=modelica,escapechar=!] -v := if activeState(state!\textsubscript{1}!) then expre!\textsubscript{1}! elseif activeState(state!\textsubscript{2}!) then expre!\textsubscript{2}! elseif $\ldots$ else last(v) +v := + if activeState(state!\textsubscript{1}!) then + expre!\textsubscript{1}! + elseif activeState(state!\textsubscript{2}!) then + expre!\textsubscript{2}! + elseif $\ldots$ + else + last(v) \end{lstlisting} \lstinline!last! is special internal semantic operator returning its @@ -489,19 +518,20 @@ \subsection{Example}\label{example} The Modelica code (without annotations) is: \begin{lstlisting}[language=modelica] block HierarchicalAndParallelStateMachine - inner Integer v(start=0); + inner Integer v(start = 0); State1 state1; State2 state2; equation initialState(state1); - transition(state1,state2,activeState(state1.stateD) and - activeState(state1.stateY), immediate=false); - transition(state2,state1,v >= 20, immediate=false); + transition(state1, state2, + activeState(state1.stateD) and activeState(state1.stateY), + immediate = false); + transition(state2, state1, v >= 20, immediate = false); public block State1 - inner Integer count(start=0); + inner Integer count(start = 0); inner outer output Integer v; block StateA @@ -531,15 +561,15 @@ \subsection{Example}\label{example} equation initialState(stateA); - transition(stateA, stateB, v >= 6, immediate=false); - transition(stateB, stateC, v == 0, immediate=false); - transition(stateC, stateA, true, immediate=false, priority=2); - transition(stateC, stateD, count >= 2, immediate=false); + transition(stateA, stateB, v >= 6, immediate = false); + transition(stateB, stateC, v == 0, immediate = false); + transition(stateC, stateA, true, immediate = false, priority = 2); + transition(stateC, stateD, count >= 2, immediate = false); public block StateX outer input Integer v; - Integer i(start=0); + Integer i(start = 0); Integer w; // = v; equation i = previous(i) + 1; @@ -548,7 +578,7 @@ \subsection{Example}\label{example} StateX stateX; block StateY - Integer j(start=0); + Integer j(start = 0); equation j = previous(j) + 1; end StateY; @@ -556,8 +586,8 @@ \subsection{Example}\label{example} equation initialState(stateX); - transition(stateX, stateY, stateX.i > 20, immediate=false, - reset=false); + transition(stateX, stateY, stateX.i > 20, + immediate = false, reset = false); end State1; block State2 @@ -583,28 +613,28 @@ \subsection{Example}\label{example} \begin{lstlisting}[language=modelica] block HierarchicalAndParallelStateMachine extends StateMachineSemantics( - nStates=2, - t={Transition(from=1, to=2, immediate=false, synchronize=true), - Transition(from=2, to=1, immediate=false)}, - c={true, v >= 20}); - Boolean init(start=true) = sample(false); + nStates = 2, + t = {Transition(from = 1, to = 2, immediate = false, synchronize = true), + Transition(from = 2, to = 1, immediate = false)}, + c = {true, v >= 20}); + Boolean init(start = true) = sample(false); block State1 Boolean active; Boolean reset; outer input Integer v_previous; inner output Integer v; - inner Integer count(start=0); + inner Integer count(start = 0); inner Integer count_previous = if reset then 0 else previous(count); block StateMachineOf_stateA extends StateMachineSemantics( - nStates=4, - t={Transition(from=1, to=2, immediate=false), - Transition(from=2, to=3, immediate=false), - Transition(from=3, to=1, immediate=false), - Transition(from=3, to=4, immediate=false)}, - c={v >= 6, v==0, true, count >= 2}); + nStates = 4, + t = {Transition(from = 1, to = 2, immediate = false), + Transition(from = 2, to = 3, immediate = false), + Transition(from = 3, to = 1, immediate = false), + Transition(from = 3, to = 4, immediate = false)}, + c = {v >= 6, v == 0, true, count >= 2}); outer input Integer v_previous; outer output Integer v; outer input Integer count_previous; @@ -630,26 +660,26 @@ \subsection{Example}\label{example} end if; end StateMachineOf_stateA; - StateMachineOf_stateA stateMachineOf_stateA(active=active, - reset=reset); + StateMachineOf_stateA stateMachineOf_stateA( + active = active, reset = reset); block StateMachineOf_stateX extends StateMachineSemantics( - nStates=2, - t={Transition(from=1, to=2, immediate=false, reset=false)}, - c={i>25}); + nStates = 2, + t = {Transition(from = 1, to = 2, immediate = false, reset = false)}, + c = {i > 25}); outer input Integer v; - Integer i(start=0); + Integer i(start = 0); Integer i_previous; - Integer j(start=0); + Integer j(start = 0); Integer j_previous; Integer w; equation inFinalState = true; // no macro states if activeState == 1 then // equations for stateX - i_previous = if activeReset or - activeResetStates[1] then 0 else previous(i); + i_previous = + if activeReset or activeResetStates[1] then 0 else previous(i); j_previous = previous(j); i = i_previous + 1; w = v; @@ -657,21 +687,23 @@ \subsection{Example}\label{example} else // if activeState == 2 then // equations for stateY i_previous = previous(i); - j_previous = if activeReset or activeResetStates[2] then 0 else previous(j); + j_previous = + if activeReset or activeResetStates[2] then 0 else previous(j); i = i_previous; w = previous(w); j = j_previous + 1; end if; end StateMachineOf_stateX; - StateMachineOf_stateX stateMachineOf_stateX(active=active, - reset=reset); - Boolean inFinalState = stateMachineOf_stateA.stateMachineInFinalState and + StateMachineOf_stateX stateMachineOf_stateX( + active = active, reset = reset); + Boolean inFinalState = + stateMachineOf_stateA.stateMachineInFinalState and stateMachineOf_stateX.stateMachineInFinalState; end State1; State1 state1; - Integer v(start=0); + Integer v(start = 0); inner Integer v_previous = if reset then 0 else previous(v); equation active = true;