Conditions, argument values and call arguments are expressions, parsed and type-checked by the compiler: there is no textual substitution. The same expression language serves the derived measures and alarms of the catalogues; procedures use a subset of it, without temporal functions.
Input types#
| Type | Written | Value given at launch |
|---|---|---|
| Boolean | bool | true, false |
| Integer | i8, i16, i32, i64, u8, u16, u32, u64, optionally with a unit | a whole number in range: 3, 12 s |
| Float | f32, f64, optionally with a unit (f32 V) | 28 V, 28000 mV, 27.5 without unit |
| Bytes | bytes | hexadecimal: 0a1b, 0x0a1b |
| Enum | the name of an enum of a platform of the roles (tcu_id) | a value of the enum: TCU2 |
| File identifier | file_id of <file type> (file_id of lttm) | the on-board identifier: 12 |
| File content | file | the SHA-256 of a content stored with stellar put |
input tcu: tcu_id
input bus_voltage: f32 V
input lttm: file_id of lttm
input patch: fileRules checked by the compiler:
- Only numeric types carry a unit (
procedure::invalid-type); the unit must be known (procedure::invalid-unit). - An enum is looked up in the catalogues of the roles of the step or procedure. A name defined
differently by two of these platforms is ambiguous and refused (
procedure::ambiguous-enum); an unknown type is reported with the closest candidates (procedure::unknown-type). - A
file_idneeds its file type, declared by thefilescomponent of a platform of the roles (procedure::unknown-file-type). - The answer of
ask … as <type> into <name>uses the same types.
At launch, a quantity is converted into the unit of its input, or refused when the units are
incompatible (run::invalid-input): bus_voltage: 28000 mV is 28 V, bus_voltage: 28 A is
refused, and so is bus_voltage: 28 for an input with a unit.
Literals#
| Literal | Examples |
|---|---|
| Number | 3, 27.5, 2.5e-3 |
| Quantity: a number followed by a unit | 28 V, 800 degC, 10 V/s, 2.5e-3 kV, 500 ms |
| Boolean | true, false |
| Enum value | STANDBY, TCU2, PROCESSED, bare |
A unit follows its number, separated by a space or not (5s, 5 s). Units compose with /,
* and ^: V/s. Units of the same dimension convert into each other (mV, V,
kV; ms, s, min, h, d).
References#
A reference is a path:
- a measure or derived measure of a role:
sat.tcu[tcu].mode,psu.voltage,sat.files[lttm].transfer,sat.link[nominal].lockout; - an input or a typed answer:
bus_voltage,measured; - a bare enum value, on one side of
isor as an enum argument:STANDBY.
A role alone is not a value (expr::type-mismatch), and neither are file_id and file
inputs: those index files or are the source of an upload.
Parameters: param#
param <role>.<component>[<instance>].<parameter> [in <mode>]send set_anode_voltage to sat.tcu[tcu] with voltage = param sat.tcu[tcu].anode_voltage in Nominal
check sat.tcu[TCU1].anode_voltage is param sat.tcu[TCU1].anode_voltage +/- 2 Vparam reads a parameter of the target of a role, as the topology
gives it for that target, in the environment of the run:
- without
in, in the current mode of the target, read fromstellar_modeswhen the statement is evaluated (the default mode of the topology when it was never set); - with
in <mode>, in that mode.
The value has the type and unit of the parameter; it serves as an argument of a telecommand or in
a condition, like a measure. The path is written like that of a measure; the component is left
out on a platform of one component, and the instance is a value of the enum or an input of that
type. Parameters have their own namespace: param sat.tcu[TCU1].anode_voltage is the parameter,
sat.tcu[TCU1].anode_voltage the measure.
- The mode must be declared in the topology (
procedure::unknown-mode), and the path must name a parameter (procedure::unknown-parameter;procedure::unexpected-instancefor an index on the parameter itself). param … in <mode>on a known instance is checked when the run request is resolved: the target must have a value in that mode (run::parameter-undefined). Otherwise, a parameter without a value for the target fails the statement at run time.paramexists in procedures only; in a catalogue expression it is refused (expr::parameter-not-here).
Operators#
From the lowest precedence to the highest:
| Operators | Meaning | Operands |
|---|---|---|
or | Either | Booleans |
and | Both | Booleans |
not | Negation | Boolean |
is, is not, is … +/- …, <, <=, >, >= | Comparison | See below |
+, - | Sum, difference | Numbers of compatible units |
*, / | Product, quotient | Numbers; units multiply and divide |
- (unary) | Opposite | Number |
Parentheses group: (a or b) and c. A comparison takes one comparison operator: write
a > 1 V and a < 5 V, not 1 V < a < 5 V.
Equality: is and is not#
is compares numbers, booleans and enum values; is not negates it.
check sat.tcu[tcu].mode is mode
expect sat.tcu[tcu].responding is true within 5 s
check sat.tcu[tcu].mode is not SAFE_MODE- The two sides must have the same type: two numbers of compatible units, two booleans, or two
values of the same enum (
expr::type-mismatch). - An enum value is written bare; it is checked against the enum of the other side
(
expr::unknown-enum-value).
Tolerance: +/-#
check psu.voltage is 28 V +/- 0.5 V
check psu.voltage is measured +/- 0.5 Va is b +/- t holds when a is within t of b. It applies to numbers only, and the
tolerance has a compatible unit.
Ordering: <, <=, >, >=#
check psu.current < 2 A
wait until sat.tcu[tcu].anode_voltage >= 99 V within 30 sBoth sides are numbers of compatible units.
Units#
The compiler checks units everywhere:
- adding, subtracting or comparing values of incompatible units is an error
(
expr::unit-mismatch): degrees Celsius and volts never mix; - a number without unit compared with a value that has one is an error
(
expr::missing-unit): write5 V, not5; - values of compatible units are converted:
psu.voltage > 27000 mVis valid.
Functions#
Conditions may use the pure mathematical functions abs, floor, ceil, round, sqrt,
exp, ln, log10, sin, cos, tan, asin, acos, atan, atan2, hypot and
clamp.
check abs(psu.current) < 2 AThe temporal functions (age, stable, rate, avg…) are refused in procedures
(expr::temporal-not-allowed): declare them as derived measures
in the catalogue, and read the derived measure in the procedure.
Conditions#
The conditions of expect, check and wait until are boolean (expr::type-mismatch
otherwise). When a condition reads a value that is missing or stale, it does not hold.
Durations#
The durations of within, wait, every and for are literals with a time unit: 500 ms,
10 s, 3 min, 1 h. An expression or an input is refused (procedure::non-constant-duration),
and so is a value that is not a time (procedure::not-a-duration): the maximum duration of a
procedure is computed before it runs. See Safety Rules and Maximum Duration.
Diagnostics of expressions#
| Code | Meaning |
|---|---|
expr::syntax | The expression does not parse |
expr::unknown-name | Unknown name or path |
expr::unknown-enum-value | Not a value of the enum on the other side |
expr::type-mismatch | Operands of the wrong type, or a condition that is not boolean |
expr::unit-mismatch | Incompatible units |
expr::missing-unit | A number without unit next to a value with one |
expr::string-value | A string used as a value |
expr::unknown-function, expr::wrong-arguments | Unknown function, wrong arguments |
expr::temporal-not-allowed | A temporal function in a procedure |
expr::parameter-not-here | param in a catalogue expression |
procedure::unknown-mode, procedure::unknown-parameter | param … in names an undeclared mode, or param no parameter |