Utility Functions
System Functions
| Function | Description |
|---|---|
| time() | Returns the evaluation time of the module in UTC seconds |
Properties of a Channel or Value
| Function | Description |
|---|---|
| deltaT(x) | Returns the time interval between the last two evaluation times of term x in seconds |
| deltaY(x) | Returns the difference in values between the last two samples of term x; is positive for a rising signal curve |
| time(x) | Returns the time of the last modified data sample of the term x |
| sgn(x) | Sign of the value x |
| sgn(x,eps) | Sign of the value x with tolerance (eps) |
| abs(x) | Absolute value of the scalar x, For the length of a vector, see Length(V) |
| isConnected(x) | Check SmartCORE connection |
| isEmpty(x) | Check data source status |
| isTimeout(x) | Check for data gap |
| isDefault(x) | Query channel for default value |
| isError(x) | Query error status of a result |
| isINF(x) | Check floating-point value for infinity |
| isNAN(x) | Check floating-point value for NaN |
| isFinite(x) | Check whether a value is usable |
| mkFinite(x,alt) | Replace an unusable value |
| typeOf(x) | Query data type |
| value(x, ...) | Query channel values without time stamp |
| shiftT(x,dT) | Time shift of channel data |
Query SmartCORE connection "isConnected" 1
The function returns true if the channel has been successfully connected as an input to a smartCORE channel.
If no smartCORE channel can be found when the smartCORE and Math modules start up, this is not only logged in the log file but also signaled via this status (false).
In this case, the default value is written to the variable as a constant so that calculations can be performed. This is initially false, but can be set to any constant value and type using the #property macro via default=<variant>. See also isDefault().
The query returns the status for the current batch interval.
s1 = isConnected(x);
s2 = isConnected($'other.y');
The function’s argument must be an input variable.
Query the status of the data source "isEmpty" 1
The function returns true if no data has yet been produced in the smartCORE input channel when the smartCORE and Math Module start. This can happen if other data sources can only produce data after an initialization phase or a prolonged establishment of a data connection.
If the channel remains empty and the timeout condition related to the Math module’s start time is met, and an explicit default value has been set via the #property macro with the option default=<val>, this value is temporarily used as a substitute until the first data sample arrives. See also isDefault().
The query returns the status for the current batch interval and is independent of the channel’s data content and timestamps.
s1 = isEmpty(x);
s2 = isEmpty($'other.y');
The function’s argument must be an immediate input variable.
Query data gap "isTimeout" 1
The function returns true if the most recent sample in the smartCORE input signal is older than a configurable timeout interval and thus likely no new data has been produced on the smartCORE input signal. This can have various causes, such as the absence of a CAN bus message, a missing GPS signal, or a missing internet connection for querying control information. As soon as new data arrives, the status reverts to false.
For each input channel, an individual timeout value can be assigned using the #property macro with the option timeout=<val>. This overrides the global setting for the channel via inputTimeoutS, which is preset to .
If the timeout condition occurs relative to the start time of the Math module while the channel remains empty, and an explicit default value is set via the #property macro with the option default=<val>, this value is temporarily used as a substitute until the first data sample arrives. See also isDefault().
If data samples are already present in the channel, the timeout status extends the validity of the variable’s most recent value. It then lags behind the current execution time of the Math module by the set timeout interval. Dependent calculations can then continue until this point.
This time offset is only visible where data is visualized or used without timestamps, e.g., in the MQTT live data, but not in the OSF files.
The query returns the status for the current batch interval and is independent of the channel’s data content and timestamps.
s1 = isTimeout(x);
s2 = isTimeout($'other.y');
The function’s argument must be an input variable.
Query channel for default value "isDefault" 2
The function returns true if the channel is permanently or temporarily set to a default replacement value.
For each input channel, an individual, constant default value can be assigned using the #property macro with the option default=<val>. If this is not set, false (<bool> => 0, 0.0, "false") is used.
The default value is used as a constant substitute if the channel could not be connected to a smartCORE channel.
The default value is used as a temporary substitute if
- the channel has been connected
isConnected() - and the channel is still empty
isEmpty() - and the channel has timed out
isTimeout() - and
- the default value was explicitly set via the
#propertymacro - or the channel was marked as
#timeless.
- the default value was explicitly set via the
The query returns the status for the current batch interval and is independent of the channel’s data content and timestamps.
s1 = isDefault(x);
s2 = isDefault($'other.y');
The function’s argument must be an immediate input variable.
Query the error status of a result "isError" 1
The function returns true if the evaluation of a term has generated a runtime error. When the variable is output to the smartCORE, the error message is also stored in the log file or can be reused as a string in the Math module.
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';
Using a (local) variable to reuse the result is recommended.
Check floating-point values "isINF", "isNAN", "isFinite" 3
Floating-point values (<dbl>, <cxFlt>) can take on the special values infinity (INF, positive or negative) or not a number (NaN) through input data or calculations. These values propagate through subsequent calculations and make the results unusable.
The Math module already suppresses INF and NaN when reading from a smartCORE channel: such input samples are discarded and never reach the formula set. Likewise, a result containing INF or NaN is never written to a smartCORE channel but discarded. Both cases are recorded in the log file.
INF and NaN can therefore practically only arise within the formula set, e.g. through an overflow (x * 1.0e308) in an intermediate calculation. The check functions serve to detect and replace such intermediate results deliberately before the result is discarded.
| Function | returns true if ... |
|---|---|
| isINF(x) | x contains the value +INF or -INF |
| isNAN(x) | x contains the value NaN |
| isFinite(x) | x contains neither INF nor NaN, i.e. is usable |
- For a complex number (
<cxFlt>), it is sufficient if the real or the imaginary part is affected. - For vectors, matrices and tensors,
isINF()andisNAN()returntrueas soon as one element is affected.isFinite()returnstrueonly if all elements are finite. - All other data types (
<bool>,<uint>,<int>,<str>) cannot take onINForNaN. For them,isINF()andisNAN()always returnfalseandisFinite()always returnstrue. A string is not parsed:isNAN('nan')isfalse. - A runtime error in the argument is passed on unchanged; the result is then an error itself. See
isError().
ok = isFinite(x);
bad = isNAN(x) || isINF(x); // same as !isFinite(x)
y = isFinite(x) ? x : 0.0; // see also mkFinite()
Replace an unusable value "mkFinite" 3
The function mkFinite(x, alt) returns the value x if it is usable (isFinite(x) is true), otherwise the substitute value alt. It is the compact form of isFinite(x) ? x : alt.
y = mkFinite(x, 0.0);
v = mkFinite(V, [0, 0, 0]);
- For vectors, matrices and tensors, a single non-finite element replaces the entire value with
alt, not just the affected element.altshould therefore be a complete, known substitute value of matching dimension. - The substitute value is taken over unchanged, including its data type. It is not checked itself.
- A runtime error in
xis not replaced but passed on. UseisError()to catch an error.
Query data type "typeOf" 1
The typeOf function returns the data type of the passed value as an ENUM value:
t = typeOf(x);
The values have the following correspondences:
| Value | Data Type |
|---|---|
| 0 | void |
| 1 | <bool> |
| 2 | <uint> |
| 3 | <int> |
| 4 | <dbl> |
| 5 | <cxFlt> |
| 6 | <str> |
| > 0x80000000 | (Reserved) |
| 0x8000B10B | BLOB - Binary object, e.g., of a transition() |
| 0x8000EBAD | ERROR - Runtime error of a term |
Querying channel values timelessly "value" 2
This function allows you to resolve the time dependency of a computation path at a specific point in the computation, similar to #timeless.
To do this, the last value available before the batch interval (evaluationTimeMs) is used as the starting value for the interval, then all samples with timestamps within the batch interval are copied, and finally the last value is extended to the end of the interval. If an empty channel is used as an argument, a replacement value can be explicitly specified.
The query returns values for the current batch interval and is independent of the channel’s data content and timestamps.
v1 = value(x);
v2 = value(x, def); // use def, if isEmpty(x)
Typically, a circular reference in the Math Module results in a switch to a discrete sampling interval (discreteSampleTimeMs) for the affected channel, which must then also be provided with an explicit start value (@0 syntax):
zv@0 = 0; // start value for discrete calculation
zv = a * zv + (1 - a) * x; // example of circular use of 'zv'
In the context of logic controllers, state machines, limit value monitoring, etc., it can be useful to execute calculations in real time while still utilizing the feedback of a calculation result back to the beginning of the calculation. The value() function represents exactly the point at which the feedback is broken locally in the sense of #timeless.
Resolving time dependencies leads to behavior at the corresponding point that is no longer 100% predictable or defined. Short-term signal changes on the input term may be overlooked, or changes may only become visible in a later batch interval. The effects of the function must be carefully tested before productive use!
Temporal shift of channel data "shiftT" 2
To shift the data of a channel by a specific time interval dT, the shiftT() function can be used. Since shifting the data and subsequently synchronizing it with other data always results in buffering, the shift should be limited to a few seconds.
The time interval dT in seconds is added to all timestamps of the x-term data. A shift with dT > 0.0 shifts the data into the future, dT < 0.0 into the past.
xs = shiftT(x, dT);
This function can be used to compensate for known time delays caused by data transmission from the actual acquisition system (AD converter, microcontroller) of an analog signal to the reception and timestamping of the data in smartCORE. This can be useful for compensating for phase shifts, particularly with signals sampled at very high frequencies.
Properties of Multiple Values
| Function | Description |
|---|---|
| abs(x1, ..., xN) | L2 norm of the individual values (x1, ..., xN), |
| min(x1, ..., xN) | Minimum of the individual values (x1, ..., xN) |
| max(x1, ..., xN) | Maximum of the individual values (x1, ..., xN) |
| mean(x1, ..., xN) | Arithmetic mean of the individual values (x1, ..., xN) |
| rms(x1, ..., xN) | Square root of the arithmetic mean of the squared individual values (x1, ..., xN) |
Limiting and Rounding
| Function | Description |
|---|---|
| range(x, ...) | Limits the input value to a specific range. See the description below. |
| ceil(x) | Smallest integer value (preserves data type) |
| ceil2i(x) | Smallest integer value (return type int) |
| floor(x) | Largest integer value (preserves data type) |
| floor2i(x) | largest integer value (return type int) |
| trunc(x) | if then largest integer value , otherwise smallest integer value |
| round(x) | integer value such that (preserves data type) |
| round2i(x) | integer value such that |