LRAUV  revA
Mission Scripting

Tethys/LRAUV top-level mission syntax

NAME = "Mission Name"
STACK = \<stack\>

where the <stack> syntax is:

{
\<stateItem\>
[, <stateItem>]*
}

where a <stateItem> can be a Behavior, Command, or Substack

Behavior and Command syntax is either:

{
BEHAVIOR|COMMAND=<Behavior>
[, <URI>:SET( <DataValue> )]*
[, WHEN=<ValueClause>]
[, WHILE=<ValueClause>]
[, PREEMPTIVE=<ValueClause>]
[, UNTIL=<ValueClause>]
[, REPEAT=number]
}

or:

BEHAVIOR|COMMAND(<Behavior>)
[:SET( <URI>, <DataValue> | <URI>, Units::<unit>, number )]*
[:WHEN( <ValueClause>)]
[:WHILE( <ValueClause>)]
[:PREEMPTIVE( <ValueClause> )]
[:UNTIL( <ValueClause>)]
[:WITHIN( <TimeDataValue> | Units::<timeUnit>, number)]
[:REPEAT( number )]}

where <Behavior> and URI are typically defined in a module, <DataValue> is the result of calling a Units::<unitName>( value ) function,

ValueClause syntax is:

false|true|<DataValue>|<URI>[:NOT( )|:<BoolOperator>( <ValueClause> )|:<CompOperator>( <DataValue>|<URI> )]
where BoolOperator can be AND or OR
CompOperator can be NE, LT, LE, EQ, GE, or GT

Syntax for a Substack is

{
<stateItem>
[, <stateItem>]*
[, ID="Substack ID" ]
[, WHEN=<ValueClause>]
[, WHILE=<ValueClause>]
[, PREEMPTIVE=<ValueClause>]
[, UNTIL=<ValueClause>]
[, WITHIN=<TimeDataValue>]
[, REPEAT=<#>]
}
- First Behaviors in the stack have the highest priority,
     later items have lower priority.
- Execution of Commands and SubStacks goes from top to bottom
- WHEN clauses force out-of-order execution
  -  the SubStacks become active when the WHEN condition is true,
     and stay active until they complete
- WHILE clauses force out-of-order execution
  -  the SubStacks become active only while the WHILE condition is true
- PREEMPTIVE, if true, causes lower priority items to be pre-empted.
- UNTIL cause a SubStack to exit when its condition is true
- REPEAT causes a SubStack to be repeated the specified number of times.

Lua code can also be included in the script. For example, the example mission that follows, Lua code reads some values from a configuration file and sets some constant values for use later in the mission stack.

Example mission that navigates around 4 waypoints 2 times, and occasionally surfaces for GPS updates and satellite communications:

NAME = "Test Mission"
startLat = workSite.latitude; -- from workSite.cfg
startLon = workSite.longitude;
wp4 = Units.DEGREE( startLat, startLon ) -- start/end location
wp1 = Units.DEGREE( startLat, startLon-0.01 ) -- a bit west
wp2 = Units.DEGREE( startLat+0.01, startLon-0.01 ) -- a bit north from there
wp3 = Units.DEGREE( startLat+0.01, startLon ) -- and east again
STACK = {
-- some high priority behaviors
BEHAVIOR( Guidance.AltitudeEnvelope )
:SET( Guidance.AltitudeEnvelope.MIN_ALTITUDE, Units.METER, 20 );
BEHAVIOR( Guidance.OffshoreEnvelope )
:SET( Guidance.OffshoreEnvelope.MIN_OFFSHORE, Units.KILOMETER, 1 )
:SET( Guidance.OffshoreEnvelope.MAX_OFFSHORE, Units.KILOMETER, 50 );
BEHAVIOR( Guidance.DepthEnvelope )
:SET( Guidance.DepthEnvelope.MIN_DEPTH, Units.METER, 0 )
:SET( Guidance.DepthEnvelope.MAX_DEPTH, Units.METER, 300 );
-- GPS (and Iridium) Update
-- Once an hour, if we are already heading up,
-- Otherwise, once every two hours.
{
WHEN=( UniversalURI.PLATFORM_LOCATION_FIX:ELAPSED( Units.HOUR( 1 ) )
)
:OR( UniversalURI.PLATFORM_LOCATION_FIX:ELAPSED( Units.HOUR( 2 ) ) )
:OR( UniversalURI.PLATFORM_COMMUNICATIONS:ELAPSED( Units.HOUR( 2 ) ) );
ID="NeedSatFix";
COMMAND( Guidance.GoToSurface );
{
ID="SurfOps";
-- Surface operations are always preemptive
PREEMPTIVE = true;
COMMAND( Guidance.ReadSensor )
:SET(Guidance.ReadSensor.URI, UniversalURI.PLATFORM_LOCATION_FIX );
COMMAND( Guidance.ReadSensor )
:SET(Guidance.ReadSensor.URI, UniversalURI.PLATFORM_COMMUNICATIONS );
}
};
-- A set of commands to repeat two times:
{
ID="RepeatOps";
{
WHILE=UniversalURI.DEPTH:GT( Units.FOOT( 1 ) );
BEHAVIOR( Guidance.ReadSensor )
:SET( Guidance.ReadSensor.URI, UniversalURI.SEA_WATER_SALINITY );
BEHAVIOR( Guidance.ReadSensor )
:SET( Guidance.ReadSensor.URI, UniversalURI.SEA_WATER_TEMPERATURE );
};
BEHAVIOR( Guidance.DepthEnvelope )
:SET( Guidance.DepthEnvelope.MIN_DEPTH, Units.METER, 5 );
BEHAVIOR( Guidance.YoYo )
:SET( Guidance.YoYo.UP_SPEED, Units.METER_PER_SECOND, Control.SpeedControl.SPEED_SLOW)
:SET( Guidance.YoYo.DOWN_SPEED, Units.METER_PER_SECOND, Control.SpeedControl.SPEED_FAST);
COMMAND( Guidance.Waypoint )
:SET( Guidance.Waypoint.WAYPOINT, wp1 )
:SET( Guidance.Waypoint.CAPTURE_RADIUS, Units.METER, 100 );
COMMAND( Guidance.Waypoint )
:SET( Guidance.Waypoint.WAYPOINT, wp2 )
:SET( Guidance.Waypoint.CAPTURE_RADIUS, Units.METER, 100 );
COMMAND( Guidance.Waypoint )
:SET( Guidance.Waypoint.WAYPOINT, wp3 )
:SET( Guidance.Waypoint.CAPTURE_RADIUS, Units.METER, 100 );
COMMAND( Guidance.Waypoint )
:SET( Guidance.Waypoint.WAYPOINT, wp4 )
:SET( Guidance.Waypoint.CAPTURE_RADIUS, Units.METER, 100 );
REPEAT=2
};
} -- end of STACK