Contenido principal

Detectar cambios de los valores de datos y expresiones

Los gráficos de Stateflow® pueden detectar cambios en los valores de datos y expresiones entre unidades de tiempo. Puede hacer lo siguiente:

  • Utilice operadores de detección de cambios para determinar cuándo una variable cambia a o desde un valor.

  • Utilice operadores de detección de flancos para determinar cuándo una expresión supera o cae por debajo de un umbral.

Para generar un evento local implícito cuando el gráfico establece el valor de una variable, utilice el operador change. Para obtener más información, consulte Controlar el comportamiento del gráfico con eventos implícitos.

Operadores de detección de cambios

Para detectar cambios en datos de Stateflow, utilice los operadores enumerados en esta tabla.

OperadorSintaxisDescripciónEjemplo
hasChangedtf = hasChanged(data_name)Devuelve 1 (true) si el valor de data_name al comienzo de la unidad de tiempo actual es diferente del valor de data_name al comienzo de la unidad de tiempo anterior. De lo contrario, el operador devuelve 0 (false).

Realice la transición de salida de estado si algún elemento de la matriz M ha cambiado de valor desde la última unidad de tiempo o evento de entrada.

[hasChanged(M)]

Realice la transición de salida de estado si el elemento de la fila 1 y la columna 3 de la matriz M ha cambiado de valor desde la última unidad de tiempo o evento de entrada.

En gráficos que utilizan MATLAB® como lenguaje de acción, utilice:

[hasChanged(M(1,3))]

En gráficos que utilizan C como lenguaje de acción, utilice:

[hasChanged(M[0][2])]
hasChangedFromtf = hasChangedFrom(data_name,value)Devuelve 1 (true) si el valor de data_name al comienzo de la unidad de tiempo anterior era igual al value especificado y es un valor diferente al comienzo de la unidad de tiempo actual. De lo contrario, el operador devuelve 0 (false).

Realice la transición de salida de estado si el valor anterior de la estructura struct era igual a structValue y algún campo de struct ha cambiado de valor desde la última unidad de tiempo o evento de entrada.

[hasChangedFrom(struct,structValue)]
hasChangedTotf = hasChangedTo(data_name,value)Devuelve 1 (true) si el valor de data_name al comienzo de la unidad de tiempo anterior no era igual al value especificado y es igual al value al comienzo de la unidad de tiempo actual. De lo contrario, el operador devuelve 0 (false).

Realiza la transición de salida de estado si el campo de estructura struct.field ha cambiado al valor 5 desde la última unidad de tiempo o evento de entrada.

[hasChangedTo(struct.field,5)]

Nota

Si ocurren múltiples eventos de entrada en la misma unidad de tiempo, estos operadores pueden detectar cambios en el valor de los datos entre eventos de entrada.

Ejemplo de gráfico con detección de cambios

Este modelo muestra cómo los operadores hasChanged, hasChangedFrom y hasChangedTo detectan cambios específicos en una señal de entrada. En este ejemplo, un bloque Ramp (Simulink) envía una señal de tiempo creciente y discreta a un gráfico.

El modelo utiliza un solver de paso fijo con un tamaño de paso de 1. La señal incrementa en 1 en cada unidad de tiempo. El gráfico analiza la señal de entrada u en busca de estos cambios:

  • Cualquier cambio respecto de la unidad de tiempo anterior

  • Un cambio al valor 3

  • Un cambio del valor 3

Para comprobar la señal, el gráfico llama a tres operadores de detección de cambios en una acción de transición. El gráfico genera como salida los valores devueltos como y1, y2 e y3.

Durante la simulación, el bloque Scope (Simulink) muestra las señales de entrada y salida del gráfico.

  • El valor de u aumenta en 1 en cada unidad de tiempo.

  • El valor de y1 cambia de 0 a 1 en la unidad de tiempo t = 1. El valor de y1 sigue siendo 1 porque u continúa cambiando en cada unidad de tiempo posterior.

  • El valor de y2 cambia de 0 a 1 en la unidad de tiempo t = 4 cuando el valor de u cambia de 3 a 4. El valor de y2 vuelve a 0 después de una unidad de tiempo.

  • El valor de y3 cambia de 0 a 1 en la unidad de tiempo t = 3 cuando el valor de u cambia de 2 a 3. El valor de y3 vuelve a 0 después de una unidad de tiempo.

Limitaciones de la detección de cambios

El tipo de gráfico de Stateflow determina el ámbito de los datos admitidos para la detección de cambios:

  • Gráficos de Stateflow independientes en MATLAB: solo Local

  • Gráficos de Simulink® que utilizan MATLAB como lenguaje de acción: solo Input

  • Gráficos de Simulink que utilizan C como lenguaje de acción: Input, Output, Local o Data Store Memory

El argumento data_name puede ser:

  • Una variable escalar.

  • Una matriz o un elemento de una matriz.

    • Si data_name es una matriz, el operador devuelve true cuando detecta un cambio en cualquier elemento de data_name.

    • Indexe los elementos de una matriz usando números o expresiones que se evalúen como un entero constante. Para obtener más información, consulte Operaciones para vectores y matrices en Stateflow.

  • Una estructura o un campo en una estructura.

    • Si data_name es una estructura, el operador de detección de cambios devuelve true cuando detecta un cambio en cualquier campo de data_name.

    • Indexe campos en una estructura usando la notación de puntos. Para obtener más información, consulte Index and Assign Values to Stateflow Structures.

  • Cualquier combinación válida de campos de estructura o elementos de matriz.

El argumento data_name no puede ser una expresión no trivial o una variable de código personalizada.

Nota

Los gráficos independientes en MATLAB no admiten la detección de cambios en un elemento de una matriz o un campo en una estructura.

Para los operadores hasChangedFrom y hasChangedTo, el argumento value puede ser cualquier expresión que se resuelva en un valor comparable con data_name.

  • Si data_name es un escalar, value debe resolverse en un valor escalar.

  • Si data_name es una matriz, value debe resolverse en un valor de matriz con las mismas dimensiones que data_name.

    Como alternativa, en un gráfico que utilice C como lenguaje de acción, value puede resolverse en un valor escalar. El gráfico utiliza la expansión escalar para comparar data_name con una matriz cuyos elementos son todos iguales al valor especificado por value. Para obtener más información, consulte Asignar valores a todos los elementos de una matriz.

  • Si data_name es una estructura, value debe resolverse en un valor de estructura cuya especificación de campos coincida exactamente con data_name.

Si habilita el orden de arreglos por fila principal, los gráficos que utilicen operadores de detección de cambios sobre valores no escalares no admitirán la generación de código. Para generar código, habilite el orden de arreglos por columna principal. Para obtener más información, consulte Select Array Layout for Matrices in Generated Code.

Operadores de detección de flancos

Para determinar cuándo una expresión supera o cae por debajo de un umbral, utilice los operadores enumerados en esta tabla.

OperadorSintaxisDescripciónEjemplo
crossingtf = crossing(expression)

Devuelve 1 (true) si:

  • El valor anterior de expression era positivo y su valor actual es cero o negativo.

  • El valor anterior de expression era cero y su valor actual es distinto de cero.

  • El valor anterior de expression era negativo y su valor actual es cero o positivo.

De lo contrario, el operador devuelve 0 (false).

Este operador imita el comportamiento de un bloque Trigger (Simulink) con Trigger Type establecido en either.

Realice una transición de salida de estado si el valor de los datos de entrada signal supera un umbral de 2.5.

[crossing(signal-2.5)]

El flanco se detecta cuando el valor de la expresión signal-2.5 cambia de positivo a negativo, de negativo a positivo, de cero a distinto de cero o de distinto de cero a cero.

fallingtf = falling(expression)

Devuelve 1 (true) si:

  • El valor anterior de expression era positivo y su valor actual es cero o negativo.

  • El valor anterior de expression era cero y su valor actual es negativo.

De lo contrario, el operador devuelve 0 (false).

Este operador imita el comportamiento de un bloque Trigger (Simulink) con Trigger Type establecido en falling.

Realice una transición de salida de estado si el valor de los datos de entrada signal cae por debajo de un umbral de 2.5.

[falling(signal-2.5)]

El flanco descendente se detecta cuando el valor de la expresión signal-2.5 cambia de positivo a negativo, de positivo a cero o de cero a negativo.

risingtf = rising(expression)

Devuelve 1 (true) si:

  • El valor anterior de expression era negativo y su valor actual es cero o positivo.

  • El valor anterior de expression era cero y su valor actual es positivo.

De lo contrario, el operador devuelve 0 (false).

Este operador imita el comportamiento de un bloque Trigger (Simulink) con Trigger Type establecido en rising.

Realiza una transición de salida de estado si el valor de los datos de entrada signal supera un umbral de 2,5.

[rising(signal-2.5)]

El flanco ascendente se detecta cuando el valor de la expresión signal-2.5 cambia de negativo a positivo, de negativo a cero o de cero a positivo.

Nota

Al igual que el bloque Trigger, estos operadores detectan un solo flanco cuando el valor del argumento expression cambia de positivo a cero y luego a negativo, o de negativo a cero y luego a positivo en tres unidades de tiempo consecutivas. El flanco se produce cuando el valor de la expresión se convierte en cero.

Ejemplo de gráfico con detección de flancos

Este modelo muestra cómo los operadores crossing, falling y rising detectan flancos en una señal de entrada. En este ejemplo, un bloque Pulse Generator (Simulink) envía una onda cuadrada a un gráfico.

El modelo utiliza un solver de paso fijo con un tamaño de paso de 1. El valor de la señal de entrada u alterna entre 0 y 5 cada dos unidades de tiempo. El gráfico analiza la señal de entrada u en busca de estos flancos:

  • Un flanco descendente o ascendente que cruce el umbral de 2.5

  • Un flanco que supere el umbral de 2.5

  • Un flanco por debajo del umbral de 2.5

Para comprobar la señal, el gráfico llama a tres operadores de detección de flancos en una acción de transición. El gráfico genera como salida los valores devueltos como y1, y2 e y3.

Durante la simulación, el bloque Scope (Simulink) muestra las señales de entrada y salida del gráfico.

  • El valor de u alterna entre 0 y 5 en cada unidad de tiempo.

  • El valor de y1 cambia de 0 a 1 en las unidades de tiempo t = 1, 3, 5 y 7, cuando el valor de la expresión u-2.5 cambia de signo. El valor de y1 vuelve a 0 después de una unidad de tiempo.

  • El valor de y2 cambia de 0 a 1 en las unidades de tiempo t = 1 y 5, cuando el valor de la expresión u-2.5 cambia de negativo a positivo. El valor de y2 vuelve a 0 después de una unidad de tiempo.

  • El valor de y3 cambia de 0 a 1 en las unidades de tiempo t = 3 y 7, cuando el valor de la expresión u-2.5 cambia de positivo a negativo. El valor de y3 vuelve a 0 después de una unidad de tiempo.

Limitaciones de la detección de flancos

La detección de flancos solo se admite en gráficos de Stateflow en modelos de Simulink.

El argumento expression:

  • Debe ser una expresión de valor escalar

  • Puede combinar datos de entrada de gráficos, constantes, parámetros no ajustables, datos locales de tiempo continuo y datos de estado de los estados basados en Simulink

  • Puede incluir la suma, la resta y la multiplicación de variables escalares, elementos de una matriz, campos de una estructura o cualquier combinación válida de campos de estructura y elementos de matriz

Indexe los elementos de una matriz usando números o expresiones que se evalúen como un entero constante.

La detección de flancos para los datos locales de tiempo continuo y los datos de estado de los estados basados en Simulink solo se admite en condiciones de transición.

En los subgráficos atómicos, asigne todos los datos de entrada que utilice en las expresiones de detección de flancos a los datos de entrada o a los parámetros no ajustables del gráfico principal. La asignación de estos datos de entrada a los datos de salida, los datos locales o los parámetros ajustables puede dar lugar a un comportamiento indefinido.

Los gráficos de Stateflow que utilizan operadores de detección de flancos no admiten puntos operativos.

Si habilita el orden de arreglos por fila principal, los gráficos que utilicen operadores de detección de flancos sobre valores no escalares no admitirán la generación de código. Para generar código, habilite el orden de arreglos por columna principal. Para obtener más información, consulte Select Array Layout for Matrices in Generated Code.

Implementación de detección de cambios y flancos

Un gráfico detecta cambios en los datos y expresiones del gráfico evaluando los valores en los límites de la unidad de tiempo. El gráfico compara el valor al comienzo del paso de ejecución anterior con el valor al comienzo del paso de ejecución actual.

Por ejemplo, cuando se invoca el operador hasChanged con un argumento de x, el gráfico de Stateflow almacena dos veces en buffer los valores de x en variables locales.

Buffer localDescripción
x_prev

Valor de los datos x al comienzo de la última unidad de tiempo

x_start

Valor de los datos x al comienzo de la unidad de tiempo actual

Para detectar cambios, el gráfico almacena valores de datos dos veces en buffer después de que un evento activa el gráfico pero antes de que el gráfico comience la ejecución. Si los valores de xprev y xstart coinciden, el operador de detección de cambios devuelve false para indicar que no se ha producido ningún cambio; por el contrario, devuelve true para indicar un cambio. Este diagrama coloca estas tareas en el contexto del ciclo del gráfico.

Flowchart detailing double-buffering of data values for change detection.

Los operadores de detección de flancos se comportan de manera similar, salvo que comparan el valor de una expresión al comienzo de la última unidad de tiempo (xprev) con su valor actual (x). La diferencia de implementación permite que los gráficos de tiempo continuo detecten flancos en datos locales durante unidades de tiempo de menor duración.

Cambios de valor transitorios en datos locales

Los operadores de detección de cambios intentan filtrar los cambios transitorios en variables de gráfico locales evaluando sus valores solo en los límites de la unidad de tiempo. El gráfico evalúa la variable local especificada solo una vez al final del paso de ejecución. El valor devuelto de los operadores de detección de cambios permanece constante incluso si el valor de la variable local fluctúa dentro de una unidad de tiempo dada. Por ejemplo, supongamos que en la unidad de tiempo actual, la variable local temp cambia de su valor en la unidad de tiempo anterior, pero luego vuelve al valor original. El operador hasChanged(temp) devuelve false para la siguiente unidad de tiempo, lo que indica que no se ha producido ningún cambio.

Por el contrario, los operadores de detección de flancos pueden detectar flancos en datos locales de tiempo continuo durante unidades de tiempo de menor duración. Por ejemplo, supongamos que p es una variable local de tiempo continuo con una derivada negativa. Luego, el operador falling(p) devuelve true durante la unidad de tiempo de menor duración cuando p cambia de signo de positivo a negativo.

Detectar cambios de valor entre eventos de entrada o iteraciones de superpaso

Cuando se producen varios eventos de entrada en la misma unidad de tiempo o cuando se habilita la semántica de superpaso, el gráfico actualiza los buffers xprev y xstart cada vez que se ejecuta. El gráfico detecta cambios de valor entre los eventos de entrada y las iteraciones de superpaso incluso si los cambios se producen más de una vez en una unidad de tiempo dada. Para obtener más información, consulte Use Events to Execute Charts y Super Step Semantics.

Consulte también

| | | | | |

Temas