Keywords
Note
- This section mainly uses TethysL syntax for illustration, but the conceptual model of the language applies regardless of the particular syntax (XML or TethysL).
- In general, the documentation structure for language constructs, keywords, grammar description, etc., is still being worked out.
- For the notation used in various parts to this documentation, see Notation.
aggregate
¶
todo: expand/review
The aggregate
keyword starts one of the two possible top-level
constructs in a mission script
(the other one being a mission
).
The definition of an aggregate behavior can also be embedded within a mission
or another aggregate aggregate.
Examples:
aggregate AbortDrift {
"""
Limit drifting period without receiving any acoustic signals.
"""
arguments {
AcousticTimeout = 96 hour
"""
Drifting for longer than this period without receiving any acoustic
signals will trigger the abort.
"""
}
run in parallel
syslog info "Insert acoustic timeout set to " + AcousticTimeout~hour + "."
behavior Guidance:AbortDrift {
run in sequence
set acousticTimeout = AcousticTimeout
}
behavior Guidance:Execute {
run in sequence
set command = "stop"
}
}
⟨aggregate⟩
syntax
aggregate ⟨id⟩ {
⟨description⟩?
⟨defineArgs⟩?
⟨defineOutput⟩?
⟨executionMode⟩?
⟨break⟩?
⟨timeout⟩?
⟨preemptive⟩?
⟨behaviors⟩*
}
arguments
¶
todo: expand/review
Starts a block where the arguments of a mission or aggregate are defined.
mission {
"""
Mission description.
"""
arguments {
MissionTimeout = 2 hour
"""
Maximum duration of mission.
"""
NeedCommsTime = 60 minute
"""
How often to surface for communications.
"""
...
}
...
}
assign
¶
todo: expand/review
assign
is one of the LRAUV core behaviors.
Examples:
mission {
arguments {
MissionTimeout = 90 minute
"""
Maximum duration of mission
"""
...
}
insert Insert/NeedComms id="NeedComms"
assign in sequence NeedComms:DiveInterval = MissionTimeout
...
⟨assign⟩ syntax
assign ⟦ id = "str" ⟧? ⟨executionMode⟩ ⟨id⟩ = ⟨expression⟩
behavior
¶
todo: expand/review
This keyword is used to invoke a particular LRAUV module behavior.
⟨moduleBehavior⟩
syntax
behavior ⟨moduleName⟩:⟨behaviorName⟩ ⟦ id = "someId" ⟧? {
⟨description⟩?
⟨executionMode⟩
⟨break⟩?
⟨timeout⟩?
⟦ ⟨behaviorChoice1⟩ | ⟨behaviorChoice2⟩ ⟧*
}
Examples:
mission {
...
behavior Guidance:Point {
run in parallel
set heading = -135 degree
}
...
}
break
¶
todo: expand/review
Allows to terminate a behavior execution according to a given condition.
behavior Some:Behavior {
run in parallel
break if ( ⟨condition⟩ )
set xyz = -135 degree
}
call
¶
A core behavior that calls a previously defined or inserted aggregate behavior.
mission {
arguments {
someTime = 5 minute
}
insert _examples/defineBlock {
redefineArg foo = someTime
}
call refId="defineBlock"
call id="StartingMission" priorityHere=false refId="defineBlock"
"""
A description of this call.
"""
}
refId
is the only required element of a call
statement.
It indicates the mission or aggregate to call.
Other elements are optional:
-
id
: An optional ID for this call. -
priorityHere
: IfpriorityHere=false
is indicated, the referenced behavior runs at the layered control priority where it was originally defined or included in the mission. Otherwise, i.e., either omittingpriorityHere
or indicatingpriorityHere=true
, then the referenced behavior is included as if it were defined or included at thecall
location. -
description
: An optional description for the call.
called
¶
todo: expand/review
This is a boolean expression that evaluates to true
only when ...
Example:
mission {
...
aggregate GPSFIX {
run when ( called )
behavior Guidance:GoToSurface {
run in progression
}
...
}
}
customUri
¶
todo: expand/review
mission {
arguments {
MassDeadband = customUri "VerticalControl.massDeadband"
}
syslog "Rudder limit = " + customUri "HorizontalControl.rudLimit" ~ degree
}
description
¶
todo: expand/review
destination
¶
todo: expand/review
See sendData
.
elapsed
¶
todo: expand/review
elapsed_
¶
todo: expand/review
Similar to elapsed
,
elapsed_
returns the elapsed time since the start of the mission item that contains
the elapsed_
element.
In the following example:
mission {
...
aggregate Test {
...
output {
elapsed = 0 second
}
run in sequence
...
assign in parallel elapsed = elapsed_
...
assign
, which starts running in parallel
as soon as the surrounding aggregate,
aggregate Test
,
starts running in sequence.
insert
¶
todo: expand/review
Similar to an import statement in various programming languages, this construct imports
the aggregate (or mission) defined in another script at the location of the insert
element.
The basic forms of this statement are:
insert ⟨filename⟩
insert ⟨filename⟩ { ⟨body⟩ }
where:
-
⟨filename⟩
:- Can refer to a TethysL or XML script, that is, with
.tl
or.xml
file extension - The inserted script must exist and be valid
- Can refer to a TethysL or XML script, that is, with
-
⟨body⟩
- One or more of:
redefineArg ⟨identifier⟩ = ⟨expression⟩
where:⟨identifier⟩
is an argument in the inserted file⟨expression⟩
is valid and with compatible units
- One or more of:
mission {
...
insert Insert/Science
...
insert Transport/transit {
redefineArg MissionTimeout = 90 minute
redefineArg Latitude = 36.8049 degree
redefineArg Longitude = -121.8108 degree
redefineArg MinOffshore = 750 meter
}
...
}
⟨insert⟩
syntax
insert ⟦ id = "str" ⟧? ⟨filename⟩ ⟨block⟩?
⟨block⟩ = {
⟨description⟩?
⟦ redefineArg ⟨identifier⟩ = ⟨expression⟩ ⟧+
}
isNaN
¶
todo: expand/review
macro
¶
TethysL includes syntax extensions that can significantly help capture similar constructs in a mission script with a concise, readable, and less error-prone syntax compared to the traditional XML based language. More details in the section about Macro extensions in TethysL.
mission
¶
The mission
keyword starts one of the two possible top-level constructs in a mission script
(the other one being an aggregate
).
More details in this section.
An example:
mission transit_1km {
"""
Vehicle transits to the 1km waypoint.
"""
insert Transport/transit {
redefineArg Latitude = 36.8156 degree
redefineArg Longitude = -121.806 degree
}
}
Not
¶
todo: expand/review
output
¶
Starts a block defining the output parameters of a mission or aggregate.
mission {
...
arguments {
...
}
output {
DoingComms = false
"""
The mission sets this to true *before* the vehicle surfaces for comms.
"""
StartFromSurface = true
"""
The mission sets this to true *after* the vehicle surfaces for comms.
"""
}
...
}
outputArg
¶
Sets the value for an output parameter from a behavior output.
See behavior
.
parallel
¶
run in parallel
This is the most basic execution mode. The behavior runs along with any other active
behaviors, and does not stop either until the mission or aggregate behavior that
contains it completes or until a break
condition is satisfied.
Example:
mission {
...
aggregate SurfaceOps {
run in parallel
...
}
}
preemptive
¶
A boolean condition which can apply to Aggregate, Module, and Timeout behaviors: if the behavior is active and the condition evaluates to true, then all lower priority behaviors are not just preempted -- rather, they are skipped as if they did not exist on the stack.
See also:
priorityHere
¶
This is an optional setting for the call
statement.
See call
.
progression
¶
run in progression
The progression
execution mode is equivalent to running a behavior both in parallel
and in sequence
. The behavior runs continuously, but does not allow subsequent
sequence
behaviors to become active until it reaches it goal. Conceptually,
this could be behavior like drive to depth X and stay there
which could be
followed by a behavior like take a measurement every Y minutes, Z times
.
The progression
execution mode can also be followed by repeat = ⟨value⟩
which
causes the goal to be achieved the specified number of times before the
next sequence
behavior to becomes active (or the container becomes inactive
if there is no next sequence
behavior).
readData
¶
todo: expand/review
Examples:
readData {
Universal:sea_water_salinity
Universal:sea_water_temperature
}
readData strategy="MinError" {
while ( EnabledNeilBrown or EnabledSeabird )
Universal:sea_water_temperature
Universal:sea_water_salinity
}
readData {
while ( not ( Drifting ) and Universal:depth >= ScienceOnDepth )
Universal:sea_water_temperature
Universal:sea_water_salinity
Universal:mass_concentration_of_chlorophyll_in_sea_water
Universal:mass_concentration_of_oxygen_in_sea_water
}
⟨readData⟩
syntax
readData ⟦ id = "str" ⟧? ⟦ strategy = "str" ⟧? {
⟨description⟩?
⟨while_⟩?
⟨break⟩?
⟨timeout⟩?
⟨intPerChoice⟩?
⟨idExpression⟩+
}
readDatum
¶
todo: expand/review
Examples:
readDatum {
Universal:latitude_fix
}
readDatum id="Read_GPS" {
timeout duration=P5M
Universal:time_fix
}
readDatum {
timeout duration=P10S
Science:ESPComponent.sample_number
}
readDatum {
timeout duration=CANONSamplerTimeout {
syslog important "Timed out sampling with CANONSampler."
}
Science:CANONSampler.sample_number
}
⟨readDatum⟩
syntax
readDatum ⟦ id = "str" ⟧? ⟨repeatGetsChoice⟩? {
⟨description⟩?
⟨break⟩?
⟨timeout⟩?
⟨idExpression⟩
}
redefineArg
¶
todo: expand/review
See insert
.
repeat
¶
repeat = ⟨expression⟩
Optional qualification in:
run
¶
run in parallel
run in progression
run in sequence ⟦ repeat = ⟨expression⟩ ⟧?
run when ( ⟨condition⟩ ) ⟦ repeat = ⟨expression⟩ ⟧?
run while ( ⟨condition⟩ )
Determines under which condition or execution mode to run the associated behavior.
See also:
sendData
¶
todo: expand/review
sendData service=express (
Control:HorizontalControl.latitudeCmd ~ degree,
Control:HorizontalControl.longitudeCmd ~ degree
)
sequence
¶
run in sequence
In the sequence
execution mode, the behavior becomes active if it is the first sequence
behavior in the mission or aggregate behavior that contains it, or when a preceding
sequence
behavior reaches a state of completion. Then the behavior remains
active until it reaches a state of completion, either because it is a goal oriented
behavior or because either a break
or timeout
condition becomes true. Then
the next (if any) sequence
behavior becomes active. If this is the last sequence
behavior in the mission or aggregate behavior that contains it, then the mission
or aggregate behavior also reaches a state of completion.
The sequence
execution mode can also be followed by repeat = ⟨value⟩
where the value
is a countable integer. This causes the behavior to repeat the specified number
of times.
Examples:
behavior Trigger:PeakDetectVsDepth {
run in sequence
outputArg out1 = deepBound
}
mission {
...
behavior Guidance:Waypoint {
run in sequence
set latitude = 36.82 degree
}
}
mission {
...
aggregate Loop {
run in sequence repeat=72
...
}
...
}
service
¶
todo: expand/review
See syslog
.
set
¶
todo: expand/review
Allows to set the value for a behavior setting.
See behavior
.
syslog
¶
⟨syslog⟩
syntax
syslog ⟨severity⟩? ⟦ service = ⟨service-name⟩ ⟧? ⟨contents⟩
where:
-
⟨severity⟩
is one of:none
,debug
,info
,error
,important
,fault
,critical
-
⟨service-name⟩
is one of:direct
,courier
,express
,priority
,normal
,bulk
,count
,multi
-
⟨contents⟩
can be:- A literal string, e.g.,
"some value = "
- An identifier or
customUri
, with desired reported units, e.g.,newTime ~ second
- A concatenation of the above elements with the
+
operator
- A literal string, e.g.,
Examples:
syslog "hello world"
syslog info "SkipComms = " + SkipComms~bool
syslog important service=express "newTime = " + newTime ~ second
syslog important "newTime = " + newTime~second
syslog "newTime = " + newTime ~ hour + " SkipComms = " + SkipComms~bool
syslog "Rudder limit = " + customUri "HorizontalControl.rudLimit" ~ degree
syslog info "Updating YoYoMaxDepth " + customUri "_.YoYoMaxDepth" ~ meter
test_code
¶
⟨test_code⟩
syntax
test_code ⟦ valgrind ⟧? {{{
⟨python-code⟩
}}}
Allows wrapping python code for mission testing purposes.
todo: expand/review
Section started with paraphrasing from the README under RegressionTests.
Regression test missions
Regression test missions are normal LRAUV missions, with the addition of
python code wrapped in an test_code
section.
For example:
mission {
test_code {{{
# python code that sets value of "passed" variable, i.e.,
passed = True
}}}
...
}
One way to write a regression test is to just provide the above simple test
script, and use when
clauses in the mission with
syslog critical
elements that are activated when the mission goes awry.
Any triggered syslog critical ...
will
cause the test mission to terminate, and fail the regression test.
Another way (which can be used in tandem with the above method) is to analyze
the data from the simulation in the python procedure.
Under the lrauv-application codebase, utility library classes are provided in
Tools/regression
, which do not need to be explicitly imported.
The most used library is Slate.py
, which provides:
[array of data] = slate.read("var1", "var2", "var3")
Examples:
depth = slate.read("depth")[0]
(lats, lons) = slate.read("latitude", "longitude")
Missions run at faster-than-realtime speed during testing.
However, if the tag
valgrind
is added after test_code
and before the python code,
then the mission is simulated with valgrind
running in verbose mode, and will catch memory leaks and faults such as using
uninitialized memory. Any fault or memory leak will cause the test to fail.
Note that the simulation will run much more slowly, approaching real-time.
So, test_code valgrind ...
is recommended only for missions that will
complete within a few minutes of real-time.
Running regression tests
Under the lrauv-application codebase, regression tests are run using Tools/regression/runTest.py
.
Without any arguments, all missions in the RegressionTests/
folder with filenames that
start with the word "test".
Optionally the path to a mission can be provided to run only that mission.
If a 2nd argument is provided, the mission won't be run, but the python test
code will be run using the logs from a previous run of the mission.
timeout
¶
todo: expand/review
mission {
arguments {
timeout = 3.5 hour
}
timeout duration=timeout
}
touch
¶
todo: expand/review
touch
is similar to assign
,
except there is no right-hand-side expression for the identifier
as only the time of last write is updated but the value is not changed
(so, the effect is similar to a filesystem touch operation).
Example with Universal:platform_communications
:
readDatum {
timeout duration=P30M {
touch in sequence Universal:platform_communications
}
Universal:platform_communications
}
valgrind
¶
todo: expand/review
See test_code
.
when
¶
run when ( ⟨condition⟩ ) ⟦ repeat = ⟨expression⟩ ⟧?
The when
execution mode kicks off a goal-oriented behavior, similar to a sequence
behavior, except that the behavior only becomes active when the when
condition
becomes true. When the goal is achieved (or a break
or timeout
occurs),
the behavior becomes inactive until the when
condition becomes true again.
The when
execution mode can also be followed by repeat = ⟨value⟩
, which causes
the behavior to run the specified number of times after the when
condition
becomes true.
Examples:
mission {
...
aggregate NeedComms {
run when ( Universal:platform_pitch_angle > 0 degree and
elapsed ( Universal:time_fix ) > 120 minute )
...
}
...
}
while
¶
run while ( ⟨condition⟩ )
The while
execution mode kicks off a continuous behavior, similar to a parallel
behavior, except that the behavior is only active when the while
condition
is true. When while
condition becomes false (or a break
occurs),
the behavior becomes inactive until the while
condition becomes true again.
Examples:
readData strategy="MinError" {
while ( EnabledNeilBrown or EnabledSeabird )
Universal:sea_water_temperature
Universal:sea_water_salinity
}
See also: