9.2 Expressions

ASAM OpenSCENARIO supports mathematical operations for evaluating expressions. Every attribute of a language element may contain either the actual attribute as a literal (constant value), a reference to a parameter, or an expression.

Expressions are notated with the following syntax:

${Expr}

ASAM OpenSCENARIO expressions are built on literals and parameters. Because of that circumstance, the expressions are typed as well.

Expressions are designed to define relatively simple operations in scenario files. Checks and more sophisticated, complex calculations should not be expressed in a scenario file.

9.2.1 Operators

Operators are used to define mathematical operations between expressions. The precedence of the operator is defined by general mathematical rules. Nested expressions with brackets are supported. Operators are exclusively supported for numerical (int, unsignedInt, unsignedShort, and double) and boolean data types. They are not defined for string, dateTime, or other data types.

All arithmetic operators ordered by their precedence are listed as follows:

Supported arithmetic operators (ordered by operator precedence):
  • Operators with highest precedence

    • Unary Minus (-): numeric → numeric

    • Round operator (round): doubleint

    • Floor operator (floor): doubleint

    • Ceil operator (ceil): doubleint

    • Square root operator (sqrt): doubledouble

    • Sine operator (sin): doubledouble

    • Cosine operator (cos): doubledouble

    • Tangent operator (tan): doubledouble

    • Inverse sine operator (asin): doubledouble

    • Inverse cosine operator (acos): doubledouble

    • Inverse tangent operator (atan): doubledouble

    • Sign operator (sign): numeric → numeric

    • Absolute value operator (abs): numeric → numeric

    • Maximum value operator (max): numeric, numeric → numeric

    • Minimum value operator (min): numeric, numeric → numeric

  • Operators with middle precedence

    • Power operator (pow): double, doubledouble

    • Multiply operator (*): numeric, numeric → numeric

    • Division operator (/): double, doubledouble

    • Remainder operator(%): numeric, numeric → numeric

  • Operators with lowest precedence

    • Plus operator (+): numeric, numeric → numeric

    • Minus operator (-): numeric, numeric → numeric

The operators -, +, %, *, sign, abs, max, and min are defined for all numeric data types. Furthermore, the result of such an operator has the same data type as its arguments and all of its arguments have the same type.

For the definition of the arithmetic operators [13] shall be used. It is noteworthy that % is the remainder operator, not the modulo operator. For integers greater than zero, both operators give equal results. Furthermore, the arguments of the operators round, floor, ceil, and pow are given behind the operator name and need to be surrounded by parentheses.

The sign operator returns either -1, 0, or 1, according to whether its argument is negative, zero, or positive:

sign(x) = -1, if x < 0
sign(x) =  0, if x = 0
sign(x) =  1, if x > 0
This can be implemented as: sign(x) = (x > 0) - (x < 0)

Additionally, ASAM OpenSCENARIO has three Boolean operators:

Supported Boolean operators (ordered by operator precedence):
  • Negation operator (not)

  • Conjunction operator (and)

  • Disjunction operator (or)

Example expressions:
  • Arithmetic expressions:

    ${pow(2, 8) - 1}
    ${-round(2.6)}
    ${1 + sqrt(9) * 2.2}

    is equivalent to

    ${1 + (sqrt(9) * 2.2)}
  • Boolean expressions:

    ${not $A and $B}

    is equivalent to

    ${(not $A) and $B}
    ${$A or $B and not $C}

    is equivalent to

    ${$A or ($B and (not $C))}`

9.2.2 Types

ASAM OpenSCENARIO allows Boolean literals to be given as 0, 1, true, and false. However, it results in a type error if an arithmetic function is used in an expression where a Boolean value is expected.

For arithmetic expressions, ASAM OpenSCENARIO does not support explicit type casting. Instead, the standard allows for type conversion from double to int via the operators round, floor, and ceil.

Moreover, implicit type conversion is applied where information loss is not an issue. The implicit type conversion follows the following rules:

  • Integer values (signed and unsigned) may be implicitly converted to double values.

  • Integer literals can be implicitly converted to any integer data type.

For the user this means that integer literals, such as 0, 1, and 2 are automatically correctly used as int, unsignedInt, unsignedShort, and double as needed. Furthermore, for unsignedInt and unsignedShort only the operators +, *, %, and - may be used, where - should be used carefully to avoid underflow errors. Additionally, parameters of the types unsignedInt, unsignedShort, and int shall not be mixed.

The rest of this subsection details the type inference. The expected type is defined to be the type that an expression or a value is expected to have. For example, WorldPosition has attributes x, y, and z to describe coordinate positions. All of these attributes have double as data type. A type mismatch occurs if the expected type and the actual type differ. A type error occurs if a type mismatch cannot be resolved by an implicit conversion.

9.2.2.1 Example of type mismatches

For example, in

<WorldPosition x="${pow(2, 8) - 1}" y="${-round(2.6)}" />

the expected type of both expressions is double.

When analyzing the type of the first expression and its subexpression, several type mismatches are found. To find the mismatches, we propagate the expected type backwards through the expression. The expected type of the whole expression is double. The actual types of the arguments of the subtraction are double for pow(2, 8) and int for 1. Because the types of the arguments of the subtraction are required to be equal to the type of the result (which is expected to be a double), we have a type mismatch. The integer literal 1 can be implicitly converted to double, which resolves the mismatch. The operator pow expects two double arguments, which results in another type mismatch. The given arguments 2 and 8 can be implicitly converted to double.

Analyzing the second expression shows that the result of round has int as actual type, while the expected type is double. This is a type mismatch, which can be resolved by implicitly converting the result of round to double. There are no more mismatches.

Because all type mismatches in both expressions can be resolved, we conclude that neither of the two expressions cause a type error.

9.2.3 General restrictions

Because ASAM OpenSCENARIO does not use NaN or infinity, all operations where [13] defines the result to be either NaN or infinity shall instead result in an error.

Furthermore, an implementation must raise an appropriate error if:

  • The application detects arithmetic errors (division by zero, sqrt of a negative value, …​).

  • An unresolvable type mismatch occurs.

  • An arithmetic overflow or underflow occurs.

The following example illustrates this:

<Dimensions width="${$defaultWidth + 12.3}" length="4.2" height="1.6"/>