Quantity expressions¶
Anywhere a reference value, a snapshot, or a constraint’s view, threshold, reference, or tolerance is authored, a full arithmetic expression over quantity refs and measures is accepted: standard precedence, parentheses, and mixed operators.
mass k = 1.2 kg,
force residual = <shared.world.ext-force>.force.x - <spec.k> * <shared.world.acc-ee-base>.linacc.x,
force with-paren = (<a>.force.x + <b>.force.x) * 0.5 1
*// bind tighter than +/-; parentheses group; -// are left-associative binary
operators; repeated +/* stay one operation. Unary minus (- <x>) lowers to multiplication
by a dimensionless -1. A leaf is either a <quantity> reference (with the usual
.subspace.axis selector) or a bare measure such as 0.5 1 or 9.81 m/s^2.
There are no functions (abs, …) – a vector’s length is a view, norm of, not an
expression – and no exponent operator, and an expression never
combines a whole vector/tensor quantity (a pose, a wrench, a velocity twist) – select a scalar
subspace axis first.
Named and inline expressions¶
A named context quantity declared with an expression is usable everywhere a context quantity is usable, including as a constraint’s view:
spec {
force residual = <shared.world.ext-force>.force.x - <spec.k> * <shared.world.acc-ee-base>.linacc.x
}
...
constraints {
slip: keeping <spec.residual> outside <spec.min-lim> and <spec.max-lim>
}
Every reference slot – a constraint’s view, threshold, reference, or tolerance, a saturation bound, a profile limit, or a solver’s gravity – also accepts a parenthesized inline expression, compiled into a quantity owned by the declaration that authors it:
slip: keeping (<shared.world.ext-force>.force.x - <spec.k> * <shared.world.acc-ee-base>.linacc.x)
outside <spec.min-lim> and <spec.max-lim>,
tight: keeping <spec.error> outside (0.0 N - <spec.thr>) and <spec.thr>
within (<shared.spec.band> * 2 1)
Parentheses are required at these slots: a bare <x> still stays a plain reference, and a bare
measure still stays a literal.
A snapshot’s trailing expression works the same way, over what the snapshot samples:
length support-z = snapshot of <shared.world.pose-ee-base>.position.z - <spec.lift>
Dimension inference¶
+/-: both operands must be the same kind of quantity; the result keeps that kind. Kinds that share one physical dimension under different authored spellings (alengthand adistance, anangleand anorientation) are the same kind here – the result takes the dimension’s canonical spelling (lengthwins overdistance/position,anglewins overplane-angle/orientation).*//: the operands’ dimension vectors (mass, length, time, angle exponents) combine, and the result must map back to a known quantity kind, or the model fails to validate, naming the offending subexpression and its derived dimension.Geometry kinds (
position,pose,orientation) only add/subtract with their own kind – exactly what a snapshot offset already did. Multiplying or dividing a geometry kind is an error: select a scalar subspace axis instead.A composite quantity referenced with no scalar axis (a whole wrench or twist,
.forcerather than.force.x) is an error inside*//.A named quantity’s declared type must equal what its expression infers; a mismatch is a validation error naming both.
Dividing by a literal zero is a validation error, not a runtime one.
Controlled expressions¶
A monitor accepts the full algebra. A controlled expression constraint – one a controller
drives through a solver, or pushes or turns with a force or a moment – is driven along the
expression’s gradient. The gradient is the same arithmetic over its terms’ gradients: a sum’s is
the sum of its terms’, a product’s follows the product rule, a quotient’s is the dividend’s over
the divisor. A term the motion moves contributes its own direction – a world quantity’s
component its axis, a derived scalar (distance of ..., projection of ..., a cone or plane
angle) the gradient its view publishes – and a constant, a snapshot or a configured value
contributes none. The gradient is recomputed every cycle, since a derived scalar’s direction
moves with the robot; the solver row runs along it normalized, and the controller divides its
error by the norm, so the authored gains act on the error along that direction.
The rules below keep that gradient one vector in one frame and one half; an expression that breaks one is still fine to monitor.
Every moved term has a direction: a component selects one axis of one subspace, and a derived scalar’s view publishes a gradient. A joint moves in no Cartesian direction.
No moved term in a divisor: the expression has no value where that term crosses zero.
One frame: every moved term is stated in the same frame.
One half: all linear or all angular; one solver row carries one of them, so split a mixed expression into one constraint per half. A force follows a linear gradient, a moment an angular one.
Something moves: an expression over constants only has no direction to drive.
Where the gradient vanishes there is no direction: the row and the command along it are zero for that cycle.
// Driven along z: identical to constraining .position.z directly.
hold-z: keeping (<shared.world.pose-ee-base>.position.z + 0.0 m) equal to <spec.hold-height>,
// Driven along the (1,1,0)/sqrt(2) diagonal, its error divided by sqrt(2).
diag: keeping (<shared.world.pose-ee-base>.position.x + <shared.world.pose-ee-base>.position.y)
equal to <spec.diag-target>,
// Centred between two edges: driven along the difference of the two projections' gradients.
centred: keeping (<spec.left-along> - <spec.right-along>) equal to 0.0 m
Errors¶
Expression |
Error |
|---|---|
|
“‘Length’ and ‘LinearVelocity’ cannot be added or subtracted – they are different kinds of quantity.” |
|
“dimension (2, 0, 0, 0) from ‘multiply’ of [Mass, Mass] names no known quantity kind.” |
|
“‘Position’ is a geometry kind; multiply/divide need a scalar subspace axis on each operand instead.” |
|
“select a scalar subspace axis.” |
|
“division by zero.” |
|
“Constraint ‘…’ names a whole pose; select ‘.position’ or ‘.orientation’, each with its own tolerance.” |
|
“Constraint ‘…’: no constraint type for kind Mass.” |