Skip to content

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=true refId="defineBlock"
    """
    A description of this call.
    """
}

The elements of a call construct are:

  • id: Optional. ...
  • priorityHere: Optional. ...
  • refId: Required. Indicates the mission or aggregate to call.
  • description: Optional. ...

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_
    ...
that item would be the 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
  • ⟨body⟩

    • One or more of: redefineArg ⟨identifier⟩ = ⟨expression⟩
      where:
      • ⟨identifier⟩ is an argument in the inserted file
      • ⟨expression⟩ is valid and with compatible units
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

When the default call keyword is used, the referenced behavior runs at the layered control priority where it was originally defined or included in the mission. Adding the priorityHere keyword includes the referenced behavior as if it were defined or included at the call keyword location.

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

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: