See also: Studio
The aseba programming language allows to implement distributed control inside aseba nodes. Syntactically, this language resembles matlab; this similarity allows developers with previous knowledge of some scripting language to feel quickly at ease with aseba and thus lowers the learning curve. Semantically, it is a simple imperative programming language with a single basic type (16 bit signed integers) and arrays. This simplicity allows developers to program behaviours with no prior knowledge of a type system, integers being the most natural type of variables and well suited for programming microcontroller-based mobile robots.
Comments begin with a # and terminate at the end of the line.
Example:
# this is a comment var b # another comment
Variables refer either to single scalar values or to arrays of scalar values. The values are comprised between -32768 and 32767, which is the range of 16 bit signed integers. You can access arrays elements using the usual square parenthesis operator; arrays indexes begin at zero. You must declare all user-defined variables at the beginning of the aseba script before doing any processing.
Example:
var a var c[10] var b = 0 var d[3] = 2, 3, 4
Aseba is an event-based architecture, which means that events trigger code execution asynchronously.
Events can be external, for instance a user-defined event coming from another aseba node, or internal, for instance emitted by a sensor which provides updated data.
The reception of an event executes, if defined, the block of code that begins with the onevent
keyword followed by the name of the event; the code at the top of the script is executed when the script is started or reset.
The script can also send events by using the emit
keyword, followed by the name of the event and the name of the variable to send, if any.
If a variable is provided, the size of the event must match the size of the argument to emit.
Events allow the script to trigger the execution of code on another node or to communicate with an external program.
To allow the execution of related code upon new events, scripts must not block and thus not contain any infinite loop. For instance in the context of robotics, where a traditional robot control program would do some processing inside an infinite loop, an aseba script would just do the processing inside a sensor-related event.
Example:
var run = 0 onevent start run = 1 onevent stop run = 0 onevent ir_sensors if run == 1 then emit sensors_values proximity_sensors_values end
Expressions allow mathematical computations and are written using the normal mathematical infix syntax.
Assignations use the keyword =
and set the result of the computation of an expression to a scalar variable or to an array element.
Aseba provides, by order of precedence, the binary operators *
, /
, %
(modulo); followed by +
and -
; followed by <<
(left shift) and >>
(right shift); followed by |
(binary or); followed by ^
(binary exclusive or); followed by &
(binary and).
The binary operators and left associative.
Aseba also provides the unary operators -
, ~
(binary not), and abs
(absolute value).
To evaluate an expression in a different order, you can use a pair of parenthesis to group a sub-expression.
Example:
a = 1 + 1 b = b + d[0] b = (a - 7) % 5 c[a] = d[a]
Aseba provides two types of conditionals: if
and when
.
Comparison operators are ==
, !=
, >
, >=
, <
, and <=
; you can compare arbitrary expressions.
You can group comparisons using the and
, or
, and not
operators, and by using parenthesis.
Both if
and when
execute a different block of code whether a condition is true or false; but when
executes the block corresponding to true only if the last evaluation of the condition was false and the current is true.
This allows the execution of code only when something changes.
Example:
if a - b > c[0] then c[0] = a else b = 0 end when a > b do leds[0] = 1 end
Here when
bloc executes only when a
becomes bigger than b
.
Two constructs allow the creation of loops: while
and for
.
A while
loop repeatedly executes a block of code as long as the condition is true.
The condition is of the same form as the one if
uses.
Example:
while i < 10 do v = v + i * i i = i + 1 end
A for
loop allows a variable to iterate over a range of integers, with an optional step size.
Example:
for i in 1:10 do v = v + i * i end for i in 30:1 step -3 do v = v - i * i end
When you perform the same sequence of operations at two or more different places in the code, you can write the common code only once in a subroutine and then call this subroutine from different places.
You define a subroutine using the sub
keyword followed by the name of the subroutine.
You call the subroutine using the callsub
keyword, followed by the name of the subroutine.
Subroutines cannot have arguments, nor be recursive, either directly or indirectly.
Subroutines can access any variable.
Example:
var v = 0 sub toto v = 1 onevent test callsub toto
We designed aseba script to be simple to allow a quick understanding even by novice developers and to implement the virtual machine efficiently on a microcontroller. To perform complex or resource consuming processing, we provide native functions that are implemented in native code for efficient execution. For instance, a native function is the natural way to implement a scalar product.
Native functions are safe, as they specify and check the size of their arguments, which can be constants, variables, or array accesses.
In the latter, you can access the whole array, a single element, or a sub-range of the array.
Native functions take their arguments as reference and can modify their contents but do not return any value.
You can use native functions through the call
keyword.
Example:
var a[3] = 1, 2, 3 var b[3] = 2, 3, 4 var c[5] = 5, 10, 15 var d call math.dot(d, a, b, 3) call math.dot(d, a, c[0:2], 3) call math.dot(a[0], c[0:2], 3)