AirFASE - Scripting Language Manual
AirFASE - Scripting Language Manual
Since AirFASE is 100% programmable application, we want our customers to take a full advantage of this
powerful feature. This manual looks at ways to eliminate time consumption and provide you with answers that
you need by manipulating and tailoring the date to your specific needs by writing scripts that perform a specific
task. AirFASE is easily programmable by the user to add or change the Events or data being monitored, so it
can also be used to run a maintenance monitoring program, for example, providing the results of the analysis to
the airline Maintenance Department. But before we go ahead and start to write scripts, we want to first define
what a script is, and the purpose that it serves.
A scripting language differentiates itself from other typical languages in that they are usually simpler to learn
and use, as well as not needing to be compiled. The language is interpreted at run-time so you can execute
instructions immediately. You just need to identify a task that you need an answer for and write a script.
You might be asking yourself what the difference might be between programming and scripting. Well, the basic
difference between "programming" and "scripting" is better defined by usage, or application, as well as scope
and purpose. A programming language is used for building standalone projects, or "applications"; a scripting
language is used to write "scripts" that interact with other data or systems to perform parts of a task rather than
an entire workflow.
Scripting languages are designed for "gluing" applications; they use typeless approaches to achieve a higher
level of programming and more rapid application development than system programming languages.
Scripting languages are designed for gluing: they assume the existence of a set of powerful components and are
intended primarily for connecting components together. On the other hand, programming languages are strongly
typed to help manage complexity, while scripting languages are typeless to simplify connections between
components and provide rapid application development.
An example might make this clearer. Programming languages are used to write programs, which can run for a
while and do multiple things. Scripting languages are used to write scripts, which run for a short duration to
perform a single, simple task. That little snippet of local, customized programming would be a script, written in
a scripting language. The script would be started, perform its one task, and stop.
To summarize, scripting languages are designed for gluing applications. They provide a higher level of
programming than assembly or system programming languages, much weaker typing than system programming
languages, and an interpreted development environment. Scripting languages sacrifice execution speed to
improve development speed.
Before we start to write a script, we need to first learn the fundamentals of a scripting language.
Scripting in FAP’s is performed using a basic scripting language based on the C programming languages.
FAP Script Syntax
THIS IS CONFIDENTIAL AND PROPRIETARY INFORMATION OF TELEDYNE CONTROLS AND MAY NOT BE USED OR DISCLOSED BY THE RECIPIENT WITHOUT THE
PRIOR WRITTEN CONSENT OF TELEDYNE CONTROLS AND THEN ONLY IN ACCORDANCE WITH SPECIFIC WRITTEN INSTRUCTIONS OF TELEDYNE CONTROLS. BY
RECEIPT HEREOF, IN ADDITION TO ANY OBLIGATION THE RECIPIENT HAS UNDER ANY CONFIDENTIALITY AGREEMENT, CONTRACT, OR LICENSE WITH
TELEDYNE CONTROLS, NEITHER RECIPIENT NOR ITS AGENTS, REPRESENTATIVES OR EMPLOYEES WILL COPY, REPRODUCE OR DISTRIBUTE THIS
Tokens:
Keyword Numbers
Identifier
Number Number:
String-literal Integer-constant
Operator Integer-constant . Integer-constant
Punctuator . Integer-constant
Keyword: Integer-constant
break Digit
case Integer-constant Digit
continue
default String-Literals
do String-literal:
else ""
for "s-char-sequence"
if
return s-char-sequence:
switch s-char
while s-char-sequence s-char
and
or s-char:
div Digit
mod Non-digit
persist SPACE
Operators
Identifiers Punctuators
Identifier:
Non-digit Operators
Identifier Non-digit
Identifier Digit Operator:
% $ [ ] ( ) + - * / ^ ! > < == >= <= != && || =
Non-digit: one of
_abcdefghijklmnopqrstuvwxyz Punctuators
ABCDEFGHIJKLMNOPQRSTUV
Punctuator:
aaaaaa W X Y Z
{},:;
Digit: one of
0123456789
Phrase Structure Grammar
-Expression
Expressions
Compound-expression:
Expression: ( Expression )
Atom
Numeric-array-ref Sequence-expression:
Negative-expression Expression , Expression
Logical-expression
Arithmetic-expression Function-call-expression:
Compound-expression Function-name ( )
Relational-expression Function-name ( Argument-list )
Sequence-expression
Function-call-expression String-function-call:
Assignment-expression Function-name $ ( )
Function-name $ ( Argument-list )
String-expression:
String Argument-list:
String-expression + String Expression
String-function-call String-expression
Argument-list, expression
Logical-expression: Argument-list, String-expression
! Expression
Expression and Expression Function-name:
Expression or Expression Build-in-system-primitive-function
Expression && Expression => identifier
Expression || Expression Other-defined-condition-logic-function
=> identifier
Arithmetic-expression:
Expression ^ Expression Atom:
Expression * Expression Number
Expression / Expression Numeric-variable
Expression + Expression Numeric-parameter-from-DB
Expression - Expression => identifier
Expression div Expression Numeric-constant-from-DB
Expression mod Expression => identifier
Relational-expression: String:
Expression > Expression (greater than) String-literal
Expression == Expression (equal to) String-variable
Expression < Expression (less than) String-array-ref
Expression != Expression (not equal to) String-parameter-from-DB
Expression >= Expression (greater than or equal to) => identifier $
Expression <= Expression (less than or equal to)
String == String String-variable:
String != String Identifier $
Assignment-expression: Numeric-variable:
Numeric-L-value = Expression Real-variable
Integer-variable
String-assignment-expression:
String-L-value = String-expression Real-variable:
Identifier
Negative-expression: Integer-variable:
Identifier %
Expression-statement:
Numeric-L-value: Expression ;
Numeric-variable String-assignment ;
Numeric-parameter Numeric-initializer ;
Numeric-array-ref String-initializer ;
Static-declaration ;
Numeric-array-ref:
Numeric-variable [ Expression ] Statement-list:
Numeric-parameter-from-DB [ Expression ] Statement Statement
=> identifier [ Expression ] Statement-list Statement
String-L-value: Break-statement:
String-variable break ;
String-array-ref
Continue-statement:
String-array-ref: continue ;
String-variable [ Expression ]
String-parameter-from-DB [ Expression ] Return-statement:
=> identifier $ [ Expression ] return ;
return Expression ;
Numeric-initializer:
Numeric-variable [ ] = { Numeric-init-list } Compound-statement:
{ Statement }
Numeric-init-list: { Statement-list }
Expression
Numeric-init-list, Expression While-statement:
while Compound-expression Statement
String-initializer:
String-variable [ ] = { String-init-list } If-statement:
if Compound-expression Statement
String-init-list: if Compound-expression Statement else
String-expression Statement
String-init-list, String-expression
Switch-statement:
Static-declaration: switch Compound-expression Statement
persist Assignment-expression
persist String-assignment-expression Default-statement:
persist Numeric-initializer default : Statement
persist String-initializer
Case-statement:
case Expression : Statement
Statements
Statement: Do-statement:
Compound-statement do Statement while Compound-expression ;
Expression-statement
Break-statement For-statement:
Return-statement for ( Statement Statement ) Statement
Continue-statement for ( ; ; ) Statement
If-statement for ( Statement ; ) Statement
Switch-statement for ( ; Statement ) Statement
Case-statement for ( Statement Statement Expression )Statement
Default-statement for ( ; ; Expression ) Statement
While-statement for ( ; Statement Expression ) Statement
Do-statement for ( Statement ; Expression ) Statement
For-statement
Precedence and order of evaluation
The basics
When programming you often want to control the order in which the statements will be executed. This is done
by using Control Flow Statements, and some of those are the if-else statements.
The if-else statements enable your script program to selectively execute other statements, based on some criteria.
The simplest version, the if statement, is shown below. The block governed by if (delimited with '{' and '}') is
executed if the expression is true, otherwise the execution continues after the last '}'.
if (expressions)
{
statement(s)
}
If you want to execute other statements when the expression is false, you use the else statement.
if (expression)
{
statement(s) executed if expression is true
}
else
{
statement(s) executed if expression is false
}
For example: the following test decides whether a flight is in the initial climb phase or not.
This is used to decide whether to do something at a special point, or to decide between two courses of action.
Each version consists of a test, (this is the bracketed statement following the “if”). If the test is true, then the
next statement is obeyed. If it is false then the statement following the else is obeyed. After this, the rest of the
program continues as normal.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Loops in Scripting
Loops allow script programs to repeat one or more statements a bunch of times. There are three main kinds of
loops: for loops, while loops, and do loops.
FOR LOOPS
for (<initialization>; <stopping condition>; <expression)
{
<one or more statements>
} //end for
The <initialization> portion is often used to set the value of a counter variable. The <expression> is typically
used to increment the counter variable. The “for” loop continues executing the statements it contains until the
<stopping condition> is met.
The <stopping condition> may be a boolean expression which evaluates to true or false, or it actually may be an
expression which produces any value. In the latter case, this value is converted to an integer. If this integer is 0,
then the <stopping condition> is considered to be false. If this integer is not 0, the <stopping condition> is
considered to be true.
For example, lets create a for loop condition where it will continue to compare certain engine parameters as
long as it’s in a certain
// conditions over multiple samples number of seconds.
for (i% = 0; i% < NumOfSec%; i% = i% + 1)
{
N1_LT_11% = N1_LT_11% and ((_N1_1(i%) < 11.0) or (_N1_2(i%) < 11.0));
N2_LT_11% = N2_LT_11% and ((_N2_1(i%) < 11.0) or (_N2_2(i%) < 11.0));
N1_GT_60% = N1_GT_60% and ((_N1_1(i%) > 60.0) and (_N1_2(i%) > 60.0));
}
//end for
Note: The "++" operator adds one to a number, so count++ would be equivalent to count = count + 1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
WHILE LOOPS
while (<stopping condition>)
{
<one or more statements>
} //end while
The while loop checks to see if the <stopping condition> is true (or not -). If so, the statements inside the while
loop are executed, then the <stopping condition> is checked again, and so on. When the <stopping condition> is
found to be false (or -), execution continues with whatever statements follow at the end of the while loop.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DO LOOP
do {
<one or more statements>
} while (<stopping condition>)
The do loop is similar to the while loop, except that it checks the <stopping condition> after the statements that
it contains. This means that the statements inside a do loop are always executed at least once, whereas the
statements inside a while loop may never be executed.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Case Statements
Case statement can be used instead of if statement suitably when one condition could have multiple possibilities.
Following example illustrates the use of case statement in flight phase transition logic:
case 0: // PREFLIGHT
if (ALL_N1_AND_N2_GT_11%) {
l_FLIGHT_PHASE% = 1; // ENGINE START
break;
// return 1; // ENGINE START
}
break;
case 1: // ENGINE START
if (ANY_N1_OR_N2_LT_11%) {
l_FLIGHT_PHASE% = 0; // PREFLIGHT
break;
// return 0; // PREFLIGHT
}
if (GS_GT_10KT% and N2_GT_50%) {
l_FLIGHT_PHASE% = 2; // TAXI OUT
break;
// return 2; // TAXI OUT
}
// break;
case 2: // TAXI OUT
if (N1_GT_60% and GS_INCREASING% and GS_GT_50KT%)
{
l_FLIGHT_PHASE% = 3; // TAKE OFF
break;
// return 3; // TAKE OFF
}
break;
Functions/Primitives
Now that you have learned about if-else statements, loops, and case statements it is time to learn about functions.
In general, functions/primitives are blocks of code that perform a number of pre-defined commands to
accomplish something productive.
Functions that a programmer writes will generally require a prototype. Just like a blueprint, the prototype tells
the interpreter what the function will return, what the function will be called, as well as what arguments the
function can be passed. When I say that the function returns a value, I mean that the function can be used in the
same manner as a variable would be. For example, a variable can be set equal to a function that returns a value
between zero and four.
The general format for a prototype is simple: return-type function_name ( arg_type arg1, ..., arg_type argN );
“arg”_type just means the type for each argument -- for instance, an int, a float, or a char. It's exactly the same
thing as what you would put if you were declaring a variable.
There can be more than one argument passed to a function or none at all (where the parentheses are empty), and
it does not have to return a value. Functions that do not return values have a return type of void.
Lets look at a function prototype: int mult ( int x, int y );
This prototype specifies that the function “mult” will accept two arguments, both integers, and that it will return
an integer. Do not forget the trailing semi-colon. Without it, the interpreter will probably think that you are
trying to write the actual definition of the function.
Example:
To simplify usage of this primitive for a user in FAP Script, it will be written something like the following:
myResult = MAX(CAS, 5); // assume CAS is the acquired parameter;
return maximum CAS over 5 second period
So the function prototype for script has changed in FAP Script to the following:
MAX(ParamName, Duration)
So the function prototype for script has changed in FAP Script to the following:
AVERAGE(ParamName, Duration)
Example:
l_MyKeyValue = KeyValue("#kMyKeyValue"); // get key value "#kMyKeyValue"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NOTE: For a List of Primitives please look at the table in Appendix I at the end of the manual.
Lets now look at some real examples that combine all of the scripting methods that was discussed:
Event Logic:
– In Approach or Final Approach - If the FLAPS(at the current time) is less than the FLAPS(one second ago)
then add 1 to the time over limit counter (l_value).
New Event
persist l_event_flag = 0;
persist l_value = 0;
if( CurrentTime() == 0)
{
l_event_flag = 0;
l_value = 0;
}
// Flight Modes
// Preflight - 0, Engine Start - 1, Take Out - 2, Take Off - 3, Inital Climb - 4,
// Climb - 5, Cruise - 6, Descent - 7, Approach - 8, Final Approach - 9, Go Around - 10,
// Landing - 11, Touch and Go - 12, Taxi In - 13, Engine Stop - 14, Unknown - 99
return l_severity;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Annotations:
Once the event see run the FAP Generator and Build FAP.
In the AirFASE FAP Editor – First select aircraft type. Then under menu item FAP Application select
Event Browser.
l_n2_1 = _N2_1(0);
l_n2_2 = _N2_2(0);
// if only 2 engine aircraft
l_n2_3 = 100;
l_n2_4 = 100;
// uncomment if 4 engine aircraft
//l_n2_3 = _N2_3(0);
//l_n2_4 = _N2_4(0);
if(CurrentTime()==0)
{
l_count1% = 0;
l_count2% = 0;
l_count3% = 0;
l_count4% = 0;
l_event_flag% = 0;
}
return l_severity%;
//****************************************************************************************************************
Set return type
Fill in the Annotations tab as follows
Then under menu item FAP Application select Key Value Browser.
Now go back to the Event Browser and Edit Event 3000 (right mouse click)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Appendix I
Script Primitives
OVERVIEW
This table describes the Derived Parameter Primitives or Functions that are implemented in
AirFASE System and available to a user to develop Flight Analysis Program (FAP) through FAPScript
or Form-Base Editor. Primitives are intended to be used by the logics to compute derived parameter
values, create logic to detect events, define flight detection and time block detection logics.
Function prototype means signature of a function with a given return type and signature of argument list
including number of arguments and their data types.