You can detect changes in Stateflow^{®} data from one time step to the next time step. All charts can detect changes on chart input data. C charts can also detect changes in chart output data, local chart variables, machine-parented variables, and data store memory data.
For each of these types of data, you can use operators that detect the following changes.
Type of Change | Operator |
---|---|
Data changes value from the beginning of the last time step to the beginning of the current time step. | See hasChanged Operator. |
Data changes from a specified value at the beginning of the last time step to a different value at the beginning of the current time step. | |
Data changes to a specified value at the beginning of the current time step from a different value at the beginning of the last time step. |
Change detection operators return 1 if the data value changes or 0 if there is no change. See Change Detection Operators.
Stateflow software ships with a model sf_tetris2
that
shows how you can detect asynchronous changes in inputs — in
this case, user keystrokes — to manipulate a Tetris shape as
it moves through the playing field. The chart TetrisLogic implements
this logic:
TetrisLogic contains a subchart called Moving that calls the
operator hasChanged
to determine when users press
any of the Tetris control keys, and then moves the shape accordingly.
Here is a look inside the subchart:
To run the model, follow these steps:
Open the model by typing sf_tetris2
at
the MATLAB^{®} prompt.
Start simulation.
A chart detects changes in chart data by evaluating values at time step boundaries. That is, the chart compares the value at the beginning of the previous execution step with the value at the beginning of the current execution step. To detect changes, the chart automatically double-buffers these values in local variables, as follows:
Local Buffer: | Stores: |
---|---|
var_name | Value of data at the beginning of the last time step |
var_name | Value of data at the beginning of the current time step |
Note: Double-buffering occurs once per time step except if multiple input events occur in the same time step. Then, double-buffering occurs once per input event (see Handle Changes When Multiple Input Events Occur). |
When you invoke change detection operations in an action, Stateflow software performs the following operations:
Double-buffers data values after a Simulink^{®} event triggers the chart, but before the chart begins execution.
Compares values in _prev
and _start
buffers.
If the values match, the change detection operator returns 0 (no change);
otherwise, it returns 1 (change).
The following diagram places these tasks in the context of the chart life cycle:
The fact that buffering occurs before chart execution has implications for change detection in the following scenarios:
Stateflow software attempts to filter out transient changes in local chart variables by evaluating their values only at time boundaries (see How Change Detection Works). This behavior means that the software evaluates the specified local variable only once at the end of the execution step and, therefore, returns a consistent result. That is, the return value remains constant even if the value of the local variable fluctuates within a given time step.
For example, suppose that in the current time step a local variable temp
changes
from its value at the previous time step, but then reverts to the
original value. In this case, the operator hasChanged(temp)
returns
0 for the next time step, indicating that no change occurred. For
more information, see Change Detection Operators.
When multiple input events occur in the same time step, Stateflow software
updates the _prev
and _start
buffers
once per event. In this way, a chart detects changes between input
events, even if the changes occur more than once in a given time step.
All charts can use change detection operators to check for changes in chart inputs. C charts can also use change detection operators on outputs, local variables, and in Stateflow data that is bound to Simulink data store memory.
You can invoke change detection operators wherever you call built-in functions in a chart — in state actions, transition actions, condition actions, and conditions. There are three change detection operators:
The hasChanged
operator detects any change
in Stateflow data since the last time step, using the following
heuristic:
$$\text{hasChanged}(x)=\{\begin{array}{ll}1\hfill & \text{if}{x}_{\text{prev}}\ne {x}_{\text{start}}\hfill \\ 0\hfill & \text{otherwise,}\hfill \end{array}$$
where x_{start}
represents
the value at the beginning of the current time step and x_{prev}
represents
the value at the beginning of the previous time step.
Syntax
hasChanged ( u )
C charts can also use:
hasChanged ( m [ expr ] ) hasChanged ( s [ expr ] )
where u
is a scalar or matrix variable, m
is
a matrix, and s
is a structure.
The arguments u
, m
,
and s
must be one of the following
data types:
Input in a MATLAB chart
Input, output, or local variable in a C chart
Note:
If you enable the chart option Initialize Outputs
Every Time Chart Wakes Up, do not use an output as the
argument of the |
Stateflow data in a C chart that is bound to Simulink data store memory
The arguments cannot be expressions or custom code variables.
Description. hasChanged (
returns u
)1
if u
changes
value since the last time step. If u
is
a matrix, hasChanged
returns 1
if any element
of u
changes value since the
last time step.
hasChanged (
returns m
[ expr
]
)1
if the value at location expr
of
matrix m
changes value since
the last time step. expr
can
be an arbitrary expression that evaluates to a scalar value.
hasChanged (
returns s
[ expr
]
)1
if the value at location expr
of
structure s
has changed since
the last time step. s
must be
a fully qualified name, such as u.foo.bar
, which
resolves to a structure. expr
can
be an arbitrary expression that evaluates to a scalar value.
All forms of hasChanged
return zero if a
chart writes to the data, but does not change its value.
The hasChangedFrom
operator detects when Stateflow data
changes from a specified value since the last
time step, using the following heuristic:
$$\text{hasChangedFrom}(x,{x}_{0})=\{\begin{array}{ll}1\hfill & \text{if}{x}_{\text{prev}}\ne {x}_{\text{start}}\text{and}{x}_{\text{prev}}={x}_{0}\hfill \\ 0\hfill & \text{otherwise,}\hfill \end{array}$$
where x_{start}
represents
the value at the beginning of the current time step and x_{prev}
represents
the value at the beginning of the previous time step.
Syntax
hasChangedFrom ( u , v )
C charts can also use:
hasChangedFrom ( m [ expr ], v ) hasChangedFrom ( s [ expr ], v )
where u
is a scalar or
matrix variable, m
is a matrix,
and s
is a structure.
The arguments u
, m
,
and s
must be one of the following
data types:
Input in a MATLAB chart
Input, output, or local variable in a C chart
Note:
If you enable the chart option Initialize Outputs
Every Time Chart Wakes Up, do not use an output as the
argument of the |
Stateflow data in a C chart that is bound to Simulink data store memory
Note:
The first arguments |
Description. hasChangedFrom (
returns
1 if u
, v
)u
changes from the value
specified by v
since the last
time step. If u
is a matrix
variable whose elements all equal the value specified by v
, hasChangedFrom
returns
1 if one or more elements of the matrix changes to a different value
in the current time step.
hasChangedFrom (
returns m
[ expr
], v)1
if
the value at location expr
of
matrix m
changes from the value
specified by v
since the last
time step. expr
can be an arbitrary
expression that evaluates to a scalar value.
hasChangedFrom (
returns s
[ expr
], v)1
if
the value at location expr
of
structure s
changes from the
value specified by v
since the
last time step. s
must be a
fully qualified name, such as u.foo.bar
, which
resolves to a structure. expr
can
be an arbitrary expression that evaluates to a scalar value.
The hasChangedTo
operator detects when Stateflow data
changes to a specified value since the last time step, using the following
heuristic:
$$\text{hasChangedTo}(x,{x}_{0})=\{\begin{array}{ll}1\hfill & \text{if}{x}_{\text{prev}}\ne {x}_{\text{start}}\text{and}{x}_{\text{start}}={x}_{0}\hfill \\ 0\hfill & \text{otherwise,}\hfill \end{array}$$
where x_{start}
represents
the value at the beginning of the current time step and x_{prev}
represents
the value at the beginning of the previous time step.
Syntax
hasChangedTo ( u , v )
C charts can also use:
hasChangedTo ( m [ expr ], v ) hasChangedTo ( s [ expr ], v )
where u
is a scalar or
matrix variable, m
is a matrix,
and s
is a structure.
Note: Charts that use MATLAB as the action language can only use scalar variables. |
The arguments u
, m
,
and s
must be one of the following
data types:
Input in a MATLAB chart
Input, output, or local variable in a C chart
Note:
If you enable the chart option Initialize Outputs
Every Time Chart Wakes Up, do not use an output as the
argument of the |
Stateflow data in a C chart that is bound to Simulink data store memory
Note:
The first arguments |
Description. hasChangedTo (
returns
1 if u
, v
)u
changes to the value
specified by v
in the current
time step. If u
is a matrix
variable, hasChangedTo
returns 1 if any its of
its elements changes value so that all elements of the matrix equal
the value specified by v
in
the current time step.
hasChangedTo (
returns m
[ expr
], v)1
if
the value at location expr
of
matrix m
changes to the value
specified by v
in the current
time step. expr
can be an arbitrary
expression that evaluates to a scalar value.
hasChangedTo (
returns s
[ expr
], v)1
if
the value at location expr
of
structure s
changes to the value
specified by v
in the current
time step. s must be a fully qualified name, such
as u.foo.bar
, which resolves to a structure. expr
can
be an arbitrary expression that evaluates to a scalar value.
The following model shows
how to use the hasChanged
, hasChangedFrom
,
and hasChangedTo
operators to detect specific changes
in an input signal. In this example, a Ramp block sends a discrete,
increasing time signal to a chart:
The model uses a fixed-step solver with a step size of 1. The signal increments by 1 at each time step. The chart analyzes the input signal for the following changes at each time step:
Any change from the previous time step
Change to the value 3
Change from the value 3
To check the signal, the chart calls three
change detection operators in a transition action, and outputs the
return values as y1
, y2
, and y3
,
as follows:
During simulation, the outputs y1
, y2
,
and y3
are shown in this scope.
The ramp input
signal u
is represented in green, and the y1
, y2
,
and y3
values are represented as yellow, blue,
and red respectively. y1
transitions at T1, and
stays at a value of 1 because u
continues to increase
each time step. y3
transitions at T3 when the value
of u
has reached 3, but then transitions back to
0 at T4 when u
increases from 3 to 4. y2
transitions
to 1 at T4 when u
changes from 3 to 4, and then
transitions back to 0 at T5 when u
increases from
4 to 5.