Funciones auxiliares
Funciones de sistema
| Función | Descripción |
|---|---|
| time() | Devuelve el instante de evaluación del módulo en segundos UTC |
Propiedades de un canal o de un valor
| Función | Descripción |
|---|---|
| deltaT(x) | Devuelve la separación temporal, en segundos, de los dos últimos instantes de evaluación del término x |
| deltaY(x) | Devuelve la diferencia de valor de las dos últimas muestras del término x; es positiva si la señal es ascendente |
| time(x) | Devuelve el instante de la última muestra de datos modificada del término x |
| sgn(x) | Signo del valor x |
| sgn(x,eps) | Signo del valor x con tolerancia (eps) |
| abs(x) | Valor absoluto del valor escalar x, Para la longitud de un vector, véase Length(V) |
| isConnected(x) | Consultar la conexión con el smartCORE |
| isEmpty(x) | Consultar el estado de la fuente de datos |
| isTimeout(x) | Consultar una laguna de datos |
| isDefault(x) | Consultar si el canal está en el valor sustitutivo |
| isError(x) | Consultar el estado de error de un resultado |
| isINF(x) | Comprobar si un valor de coma flotante es infinito |
| isNAN(x) | Comprobar si un valor de coma flotante es NaN |
| isFinite(x) | Comprobar si un valor es utilizable |
| mkFinite(x,alt) | Sustituir un valor no utilizable |
| typeOf(x) | Consultar el tipo de datos |
| value(x, ...) | Consultar los valores de un canal sin referencia temporal |
| shiftT(x,dT) | Desplazamiento temporal de datos de canal |
Consultar la conexión con el smartCORE "isConnected" 1
La función devuelve true si el canal se ha conectado correctamente como entrada con un canal del smartCORE.
Si al arrancar el smartCORE y el módulo Math no se puede encontrar ningún canal del smartCORE, esto no solo se emite en el archivo de registro, sino que también se señala mediante este estado (false).
En este caso, el valor default se escribe como constante en la variable, de modo que puedan ejecutarse cálculos. Inicialmente es false, pero mediante la macro #property puede ajustarse con default=<variant> a cualquier valor y tipo constantes. Véase también isDefault().
La consulta devuelve el estado para el intervalo de lote en curso.
s1 = isConnected(x);
s2 = isConnected($'other.y');
El argumento de la función debe ser directamente una variable de entrada.
Consultar el estado de la fuente de datos "isEmpty" 1
La función devuelve true si, al arrancar el smartCORE y el módulo Math, todavía no se han producido datos en el canal de entrada del smartCORE. Esto puede ocurrir cuando otras fuentes de datos solo pueden producir datos tras una fase de inicialización o tras un establecimiento prolongado de una conexión de datos.
Si, con el canal vacío de forma persistente, se produce además la condición de timeout referida al instante de inicio del módulo Math y se ha establecido un valor por defecto explícito mediante la macro #property con la opción default=<val>, este se utiliza temporalmente como valor sustitutivo hasta la llegada de la primera muestra de datos. Véase también isDefault().
La consulta devuelve el estado para el intervalo de lote en curso y es independiente de los contenidos de datos y de las marcas de tiempo del canal.
s1 = isEmpty(x);
s2 = isEmpty($'other.y');
El argumento de la función debe ser directamente una variable de entrada.
Consultar una laguna de datos "isTimeout" 1
La función devuelve true si la muestra más reciente de la señal de entrada del smartCORE es más antigua que un intervalo de timeout ajustable y, por tanto, probablemente no se han producido datos nuevos en la señal de entrada del smartCORE. Esto puede tener distintas causas, como p. ej. la ausencia de un mensaje del bus CAN, la falta de señal GPS o la falta de una conexión a Internet para consultar información de control. En cuanto llegan datos nuevos, el estado vuelve a false.
Para cada canal de entrada puede asignarse un valor de timeout individual mediante la macro #property con la opción timeout=<val>. Este sobrescribe para el canal el ajuste global realizado mediante inputTimeoutS, que tiene un valor predeterminado de .
Si, con el canal vacío de forma persistente, se produce la condición de timeout referida al instante de inicio del módulo Math y se ha establecido un valor por defecto explícito mediante la macro #property con la opción default=<val>, este se utiliza temporalmente como valor sustitutivo hasta la llegada de la primera muestra de datos. Véase también isDefault().
Si ya existen muestras de datos en el canal, en el estado timeout se prolonga la validez del valor más reciente de la variable. Este queda entonces rezagado respecto al tiempo de ejecución actual del módulo Math en el intervalo de timeout configurado. Los cálculos dependientes pueden continuar entonces hasta ese instante.
Este desfase temporal solo se aprecia allí donde los datos se visualizan o se utilizan sin marca de tiempo, es decir, p. ej. en los datos en vivo de MQTT, pero no en los archivos OSF.
La consulta devuelve el estado para el intervalo de lote en curso y es independiente de los contenidos de datos y de las marcas de tiempo del canal.
s1 = isTimeout(x);
s2 = isTimeout($'other.y');
El argumento de la función debe ser directamente una variable de entrada.
Consultar si el canal está en el valor sustitutivo "isDefault" 2
La función devuelve true si el canal está establecido de forma permanente o temporal en un valor sustitutivo por defecto.
Para cada canal de entrada puede asignarse un valor por defecto constante individual mediante la macro #property con la opción default=<val>. Si no se ha establecido, se utiliza false (<bool> => 0, 0.0, "false").
El valor por defecto se utiliza como valor sustitutivo constante cuando el canal no ha podido conectarse con un canal del smartCORE.
El valor por defecto se utiliza como valor sustitutivo transitorio cuando
- el canal se ha conectado
isConnected() - y el canal todavía está vacío
isEmpty() - y el canal ha entrado en timeout
isTimeout() - y
- se ha establecido explícitamente el valor por defecto mediante la macro
#property - o el canal se ha marcado como
#timeless.
- se ha establecido explícitamente el valor por defecto mediante la macro
La consulta devuelve el estado para el intervalo de lote en curso y es independiente de los contenidos de datos y de las marcas de tiempo del canal.
s1 = isDefault(x);
s2 = isDefault($'other.y');
El argumento de la función debe ser directamente una variable de entrada.
Consultar el estado de error de un resultado "isError" 1
La función devuelve true si la evaluación de un término ha generado un error en tiempo de ejecución. El mensaje de error se guarda también en el archivo de registro al emitir la variable al smartCORE, o puede seguir utilizándose como cadena de texto en el módulo Math.
res = ...; // some expression
use = isError(res) ? 12.34 : res; // use alternate value on error
errCode = isError(res) ? int(res) : 0;
errMsg = isError(res) ? str(res) : 'ok';
Se recomienda utilizar una variable (local) para reutilizar el resultado.
Comprobar valores de coma flotante "isINF", "isNAN", "isFinite" 3
Los valores de coma flotante (<dbl>, <cxFlt>) pueden adoptar, por los datos de entrada o por los cálculos, los valores especiales infinito (INF, positivo o negativo) o no es un número (NaN, Not a Number). Estos valores se propagan a través de los cálculos posteriores e inutilizan los resultados.
El módulo Math suprime INF y NaN ya al leer de un canal del smartCORE: tales muestras de entrada se descartan y no llegan al conjunto de fórmulas. Del mismo modo, un resultado con INF o NaN nunca se escribe en un canal del smartCORE, sino que se descarta. Ambos casos se anotan en el archivo de registro.
Por tanto, INF y NaN solo pueden originarse en la práctica en el contexto del conjunto de fórmulas, p. ej. por un desbordamiento (x * 1.0e308) en un cálculo intermedio. Las funciones de comprobación sirven para detectar y sustituir de forma selectiva tales resultados intermedios antes de que el resultado se descarte.
| Función | devuelve true si ... |
|---|---|
| isINF(x) | x contiene el valor +INF o -INF |
| isNAN(x) | x contiene el valor NaN |
| isFinite(x) | x no contiene ni INF ni NaN, es decir, es utilizable |
- En el caso de un número complejo (
<cxFlt>) basta con que esté afectada la parte real o la imaginaria. - En el caso de vectores, matrices y tensores,
isINF()eisNAN()devuelventrueen cuanto un elemento está afectado.isFinite()solo devuelvetruesi todos los elementos son finitos. - Todos los demás tipos de datos (
<bool>,<uint>,<int>,<str>) no pueden adoptar niINFniNaN. Para ellos,isINF()eisNAN()devuelven siemprefalseeisFinite()siempretrue. Una cadena de texto no se evalúa:isNAN('nan')esfalse. - Un error en tiempo de ejecución en el argumento se transmite sin cambios; el resultado es entonces a su vez un error. Véase
isError().
ok = isFinite(x);
bad = isNAN(x) || isINF(x); // identisch zu !isFinite(x)
y = isFinite(x) ? x : 0.0; // siehe auch mkFinite()
Sustituir un valor no utilizable "mkFinite" 3
La función mkFinite(x, alt) devuelve el valor x si este es utilizable (isFinite(x) es true) y, en caso contrario, el valor sustitutivo alt. Es la notación compacta de isFinite(x) ? x : alt.
y = mkFinite(x, 0.0);
v = mkFinite(V, [0, 0, 0]);
- En el caso de vectores, matrices y tensores, si un único elemento no es finito se sustituye por
altel valor completo, no solo el elemento afectado. Por ello,altdebería ser un valor sustitutivo completo y conocido, de la dimensión adecuada. - El valor sustitutivo se adopta sin cambios, también en su tipo de datos. El propio valor sustitutivo no se comprueba.
- Un error en tiempo de ejecución en
xno se sustituye, sino que se transmite. Para interceptar un error sirveisError().
Consultar el tipo de datos "typeOf" 1
La función typeOf devuelve el tipo de datos del valor pasado como valor ENUM:
t = typeOf(x);
Los valores tienen la siguiente correspondencia:
| Valor | Tipo de datos |
|---|---|
| 0 | void |
| 1 | <bool> |
| 2 | <uint> |
| 3 | <int> |
| 4 | <dbl> |
| 5 | <cxFlt> |
| 6 | <str> |
| > 0x80000000 | (Reservado) |
| 0x8000B10B | BLOB - objeto binario, p. ej. de una transition() |
| 0x8000EBAD | ERROR - error en tiempo de ejecución de un término |
Consultar los valores de un canal sin referencia temporal "value" 2
Esta función permite resolver en un punto determinado del cálculo la dependencia temporal de una ruta de cálculo, de forma similar a #timeless.
Para ello, el último valor disponible antes del intervalo de lote (evaluationTimeMs) se utiliza como valor inicial para el intervalo, a continuación se copian todas las muestras con marcas de tiempo dentro del intervalo de lote y, al final, el último valor se extiende hasta el final del intervalo. Si como argumento se utiliza un canal vacío, puede indicarse explícitamente un valor sustitutivo.
La consulta devuelve valores para el intervalo de lote en curso y es independiente de los contenidos de datos y de las marcas de tiempo del canal.
v1 = value(x);
v2 = value(x, def); // use def, if isEmpty(x)
Típicamente, una referencia circular en el módulo Math conduce al cambio a un intervalo de muestreo discreto (discreteSampleTimeMs) para el canal afectado, que entonces debe estar dotado también de un valor inicial explícito (sintaxis @0):
zv@0 = 0; // startvalue for discrete calculation
zv = a * zv + (1 - a) * x; // example for circular use of 'zv'
En el contexto de controles lógicos, máquinas de estados, vigilancia de valores límite, etc., puede ser útil ejecutar los cálculos con la temporalidad correcta y, aun así, aprovechar una realimentación de un resultado de cálculo al principio del cálculo. La función value() representa precisamente el punto en el que la realimentación se rompe localmente en el sentido de #timeless.
La resolución de las dependencias temporales conduce, en el punto correspondiente, a un comportamiento que ya no es previsible ni está definido al 100 %. Pueden pasarse por alto cambios breves de señal en el término de entrada, o los cambios pueden hacerse visibles solo en un intervalo de lote posterior. ¡Los efectos de la función deben comprobarse cuidadosamente antes de un uso productivo!
Desplazamiento temporal de datos de canal "shiftT" 2
Para desplazar los datos de un canal un determinado intervalo de tiempo dT, puede utilizarse la función shiftT(). Dado que un desplazamiento y el posterior cálculo con otros datos con la temporalidad correcta conducen siempre a un almacenamiento en búfer, el desplazamiento debería limitarse a pocos segundos.
A todas las marcas de tiempo de los datos del término x se suma el intervalo de tiempo dT en segundos. Un desplazamiento con dT > 0.0 desplaza los datos hacia el futuro, dT < 0.0 hacia el pasado.
xs = shiftT(x, dT);
Con esta función pueden compensarse retardos de tiempo conocidos debidos a la transmisión de datos desde el sistema de adquisición real (convertidor AD, microcontrolador) de una señal analógica hasta la recepción y el sellado de tiempo de los datos en el smartCORE. Esto puede ser útil para compensar desfases, en particular en señales muestreadas a muy alta frecuencia.
Magnitudes características de varios valores
| Función | Descripción |
|---|---|
| abs(x1, ..., xN) | Norma l2 de los valores individuales (x1, ..., xN), |
| min(x1, ..., xN) | Mínimo de los valores individuales (x1, ..., xN) |
| max(x1, ..., xN) | Máximo de los valores individuales (x1, ..., xN) |
| mean(x1, ..., xN) | Media aritmética de los valores individuales (x1, ..., xN) |
| rms(x1, ..., xN) | Raíz cuadrada de la media aritmética de los valores individuales al cuadrado (x1, ..., xN) |
Limitación y redondeo
| Función | Descripción |
|---|---|
| range(x, ...) | Limita el valor de entrada a un rango de valores determinado. Véase la descripción siguiente. |
| ceil(x) | menor valor entero (conserva el tipo de datos) |
| ceil2i(x) | menor valor entero (tipo devuelto int) |
| floor(x) | mayor valor entero (conserva el tipo de datos) |
| floor2i(x) | mayor valor entero (tipo devuelto int) |
| trunc(x) | si , entonces mayor valor entero ; en caso contrario, menor valor entero |
| round(x) | valor entero tal que (conserva el tipo de datos) |
| round2i(x) | valor entero tal que (tipo devuelto int) |
| notZero(x, ...) | Sigue a x siempre que ; en caso contrario, si se fija , y en los demás casos Véase la descripción siguiente. |
Rango de valores "range"
La función restringe el rango de valores de una señal de entrada dada x (escalar o vector) a un intervalo y ofrece, mediante la configuración opcional, numerosas variantes.
r1 = range(x);
r2 = range(x, [min, max]); // bessere Lesbarkeit
r3 = range(x, min, max); // nicht mehr verwenden
// Optionale Konfiguration für alle Varianten
rx = range(..., { min: off|<val>
, max: off|<val>
, lower: off|<val>|erase
, upper: off|<val>|erase
, mode: <enum>
, defXY: [<dbl>, <dbl>]
, limVar: <str>
});
| Propiedad | Valor | Descripción |
|---|---|---|
| min | off/<val> | Desactivación o configuración fija de un límite inferior (escalar). Si se utiliza el parámetro de función min, esta propiedad no tiene efecto. |
| max | off/<val> | Desactivación o configuración fija de un límite superior (escalar). Si se utiliza el parámetro de función max, esta propiedad no tiene efecto. |
| lower | off/<val>/erase | Si está activada, al sobrepasar el límite inferior (x < min) se emite el valor sustitutivo o se elimina la muestra |
| upper | off/<val>/erase | Si está activada, al sobrepasar el límite superior (x > max) se emite el valor sustitutivo o se elimina la muestra |
| mode | <enum> | Si x es un vector, en función de mode - box: todas las coordenadas individualmente… - length: la longitud del vector ( >= 0.0 )... - azimuth: el ángulo del vector en el plano XY... - elevation: el ángulo del vector respecto al plano XY hacia el eje Z… ...se limitan al rango configurado |
| defXY | [<dbl>, <dbl>] | En el modo elevation, defXY es la dirección estándar cuando el vector debe girarse hacia atrás desde la vertical (def.: [1, 0, 0]). |
| limVar | <str> | limVar define opcionalmente el nombre de una variable local <bool> para señalar la limitación activa |
No cero "notZero"
La función garantiza que un valor crítico (def.: 0.0) nunca se emita. En su lugar, se excluye el rango de valores en torno a la magnitud crítica mediante una magnitud (def.: 1e-6). La aplicación de la función está optimizada, p. ej., para divisiones en las que sería posible una división por cero y debe excluirse.
xnz1 = notZero(x); // eps := 1e-6, x_crit := 0.0
xnz2 = notZero(x, eps); // x_crit := 0.0
xnz3 = notZero(x, eps, x_crit);
Un ejemplo es la conversión segura de un caudal volumétrico de combustible en y una velocidad en a un consumo en :
consumption = volFlow / notZero(speed, 0.1) * 100;
Umbral de conmutación con histéresis "threshold"
Esta función genera una señal de conmutación a partir de la comparación de una señal con un valor umbral fijo threshold. Mediante una histéresis hysteresis y tiempos de retardo delayOn, delayOff pueden suprimirse perturbaciones en la forma de onda de la señal.
La función puede utilizarse en distintas formas de aplicación:
trig1 = threshold(x);
trig2 = threshold(x, t);
trig3 = threshold(x, t, h);
// Optionale Konfiguration für alle Varianten
trigX = threshold(..., { threshold: <dbl>
, hysteresis: <dbl>
, delayOn: off|<time>
, delayOff: off|<time>
, logic: <enum>
, startup: inf|<bool>
});
| Propiedad | Valor | Significado |
|---|---|---|
| threshold | <dbl> | Umbral de disparo, def.: 0.55 Se sobrescribe con el argumento t |
| hysteresis | <dbl> | Anchura de la zona de histéresis, se suma al threshold para el segundo valor límite, def.: -0.10 Se sobrescribe con el argumento h |
| delayOn | off/<time> | tiempo de filtrado opcional en segundos para el proceso de conexión off3 o 0: sin tiempo de filtrado (def.) |
| delayOff | off/<time> | tiempo de filtrado opcional en segundos para el proceso de desconexión off3 o 0: sin tiempo de filtrado (def.) |
| logic | <enum> | - auto: la función viene determinada por el signo de la histéresis - above: disparo por encima de la zona de histéresis - below: disparo por debajo de la zona de histéresis |
| startup | inf|<bool> | Comportamiento de arranque: inf: la posición de la primera muestra respecto al umbral determina el valor de salida (def.). <bool>: se asume que este valor de salida se emitió antes de la primera muestra. |
- La función devuelve true para el instante en que la señal x sobrepasa el umbral de disparo definido y false para el instante en que la señal x cae en el restablecimiento.
Si se configuran los tiempos de retardo, la señal x debe permanecer de forma continua durante el intervalo indicado en el disparo o en el restablecimiento antes de que se realice la conmutación. La conmutación queda así retardada con respecto al momento en que se sobrepasa el valor límite correspondiente.
Si la señal de entrada está marcada como interpolable linealmente, como p. ej. la salida de integrate(), entre dos puntos de datos discurre como una rampa. La conmutación se produce entonces en el instante en que la rampa alcanza el valor límite, y los tiempos de retardo transcurren a partir de ese instante; si la rampa abandona de nuevo el disparo o el restablecimiento antes de que transcurra el retardo, no se produce la conmutación. La propia salida sigue siendo una señal de conmutación. Los valores NaN e INF se sustituyen por el último valor finito recibido; antes del primer valor finito, la función no emite nada. Un t o h no finito deja vigentes el último valor límite o la última histéresis válidos. Para x, t y h solo se aceptan escalares numéricos; ante un vector, una matriz, una cadena de texto o un valor complejo, threshold() devuelve el mensaje de error Input Value is not a numerical scalar.
En el modo de funcionamiento auto (default), el disparo se produce en función del signo de la histéresis:
| Histéresis | Disparo (true) | Restablecimiento (false) |
|---|---|---|
En los modos de funcionamiento above y below, threshold e hysteresis definen dos límites de una zona de histéresis:
| Modo de funcionamiento | Disparo (true) | Restablecimiento (false) |
|---|---|---|
| above | ||
| below |
Limitación de pendiente "rampLimit" 4
La función garantiza que los cambios en la señal de entrada x se transmitan con una pendiente de rampa limitada. Opcionalmente pueden utilizarse uno o dos parámetros adicionales para definir un gradiente máximo independiente de la dirección o bien gradientes distintos para formas de onda ascendentes y descendentes.
y1 = rampLimit(x, maxGrad);
y2 = rampLimit(x, maxPosGrad, maxNegGrad);
| Propiedad | Valor | Significado |
|---|---|---|
| x | <dbl> | Señal de entrada |
| maxGrad | <dbl> | Gradiente máximo común para formas de onda ascendentes y descendentes |
| maxPosGrad | <dbl> | Gradiente máximo para formas de onda ascendentes |
| maxNegGrad | <dbl> | Gradiente máximo para formas de onda descendentes |
La unidad de los gradientes máximos es [unidad de x] / s. La indicación es sin signo, es decir, . Un gradiente de 0.0 pone la función en bypass en la dirección correspondiente: la señal de entrada se emite directamente.
Los valores NaN e INF se sustituyen por el último valor finito recibido; antes del primer valor finito, la función no emite nada, y el primer valor finito inicia la salida. Un gradiente no finito deja vigente el último válido. Solo se aceptan escalares numéricos; ante un vector, una matriz, una cadena de texto o un valor complejo, rampLimit() devuelve el mensaje de error Input Value is not a numerical scalar.