Page ContentsPage Contents (click to expand)
  1. RPN In Microsoft Flight Simulator
  2. Converting InFix To PostFix

REVERSE POLISH NOTATION

The  Microsoft Flight Simulator SDK has full support for the PostFix notation also known as Reverse Polish Notation (RPN). This is used in various places, such as Gauges and Model Behaviors.

 

In Reverse Polish Notation, the operators follow their operands - for instance, to add 3 and 4, one would write:

3 4 +

rather than:

3 + 4

If there are multiple operations, operators are given immediately after their second operands, so the conventional expression:

3 - 4 + 5

would be written:

3 4 - 5 +

in reverse Polish notation. Essentially this means that 4 is first subtracted from 3, then 5 is added to it. An advantage of reverse Polish notation is that it removes the need for the parentheses () that are required by InFix notation (InFix notation is simply the name given to conventional notation for expressions such as these). Using the example above it could possibly have the following two interpretations:

3 - (4 × 5)
(3 - 4) × 5

Both those expressions will give quite different results, yet use the same values and operands. In Reverse Polish Notation this ambiguity is removed. The former example 3 - (4 x 5) of could be written:

3 4 5 × -

which unambiguously means 3 (4 5 ×) - which in turn reduces to 3 20 - , which finally gives -17. On the other hand the second "version" could be written

3 4 - 5 ×

which unambiguously means (3 4 -) 5 × which gives -5.

 

 

RPN In Microsoft Flight Simulator

Reverse Polish Notation is  not a programming language, it is simply a compiler-friendly way of creating complex logical expressions. However, it is used along with some built-in sim functions and variables to create short scripts that are then used to do different things within the sim. Typically these a scripts will use one or more expressions to define what a gauge or model does, and - in their simplest form - the expressions are the names of simulation parameters along with the units in which the element requires, both enclosed in parentheses, followed by operands.

 

In the following example the expression returns the value of the NAV1 OBS parameter:

(A:NAV1 OBS, degrees)

The "A" before the colon indicates that this parameter is an Aircraft parameter. NAV1 OBS is a simulation variable (see the Simulation Variable document for a full list of variables) and degrees are the units of measure in which the aircraft parameter will display. Let's look at how this would be used along with Reverse Polish Notation to write a small script:

(A:NAV1 OBS, degrees) d (A:PARTIAL PANEL HEADING, bool) (A:PARTIAL PANEL ELECTRICAL, bool) or 0 == if{ (A:PLANE HEADING DEGREES GYRO, degrees) 90 - - } dgrd

This would translate as:

"If the PARTIAL PANEL HEADING is false and the PARTIAL PANEL ELECTRICAL is false, then this expression returns the NAV1 OBS reading minus the ( PLANE HEADING DEGREES GYRO reading minus 90), converted to radians."

 

Here is a full example of how Reverse Polish Notation is used along with the available parameters and operands within the XML for model behaviors:

<PartInfo>
    <Name>btn_rudder</Name>
    <AnimLength>100</AnimLength>
    <PartID>BTN_RUDDER</PartID>
    <CameraGUID>{7E10EDEC-E1BD-4221-87F3-C00775D5281D}</CameraGUID>
    <Animation>
        <Parameter>
            <Code>
                (L:LastPos) 0 == if{ 50 (&gt;L:RudderTrimtabPos) }
                (A:RUDDER TRIM PCT, percent) (L:RudderTrimtabPos) 50 - 30 / + (&gt;L:NextValue, percent) (L:NextValue, percent) -100 &gt; (L:NextValue, percent) 100 &lt; and if{ (L:NextValue, percent) (&gt;K:RUDDER_TRIM_SET) }
                (L:RudderTrimtabPos)
            </Code>
        </Parameter>
        <Lag>50</Lag>
    </Animation>
    <MouseRect>
        <Cursor>Grab</Cursor>
        <MouseFlags>WheelUp+WheelDown+LeftDrag+LeftSingle+MoveRepeat+LeftRelease+Leave</MouseFlags>
        <CallbackCode>
            (M:Event) 'LeftSingle'  scmi 0 == if{ (M:X) (&gt;L:LastPos) }
            (M:Event) 'WheelUp'     scmi 0 == if{ 0 (&gt;K:RUDDER_TRIM_RIGHT) }
            (M:Event) 'WheelDown'   scmi 0 == if{ 0 (&gt;K:RUDDER_TRIM_LEFT) }
            (M:Event) 'LeftDrag'    scmi 0 == if{
            (M:X) (L:LastPos) - 5 &gt; if{ (L:RudderTrimtabPos) 2 + (&gt;L:RudderTrimtabPos) (M:X) (&gt;L:LastPos) }
            (M:X) (L:LastPos) - -5 &lt; if{ (L:RudderTrimtabPos) 2 - (&gt;L:RudderTrimtabPos) (M:X) (&gt;L:LastPos) } }
            (M:Event) 'LeftRelease'    scmi 0 == if{ 50 (&gt;L:RudderTrimtabPos) }
            (M:Event) 'Leave'    scmi 0 == if{ 50 (&gt;L:RudderTrimtabPos) }
        </CallbackCode>
    </MouseRect>
</PartInfo>

IMPORTANT! When writing expressions in an XML file you need to use the markup  &gt; and  &lt; for the symbols > and <, otherwise you'll get an XML parsing error.

 

 

 

Converting InFix To PostFix

Unfortunately there is no  easy way to automatically convert InFix expressions into RPN (PostFix) expressions, especially with the use of SimVars and things specific to the  Microsoft Flight Simulator SDK. However, there are third-party tools that may be of some use to you and that can work quite well, although they are not perfect. One in particular may be worth looking at which you can find from the link below:

 

 

©2021 Microsoft      Contact Us      Privacy Policy      MSFS Forums