Board index FlightGear Development Aircraft

Checklist Generation DSL

Questions and discussion about creating aircraft. Flight dynamics, 3d models, cockpits, systems, animation, textures.

Checklist Generation DSL

Postby sanhozay » Fri May 12, 2017 3:26 pm

For some time, I've thought Domain Specific Languages (DSLs) could be useful for some aspects of Flightgear aircraft development, specifically checklists. In fact, looking back though my posts, I was thinking about this two years ago.

Over the past few weeks, I've been playing around with the ANTLR parser generator and, after attempts in Groovy and Flex/Bison that ran into the buffers, I've finally come up with something usable for checklist generation.

CLGen

The basic premise is that checklists are verbose and repetitive. This is one check:

Code: Select all
<!-- Landing Lights OFF -->
<item>
  <name>Landing Lights</name>
  <value>OFF</value>
  <condition>
    <less-than>
      <property>systems/electrical/outputs/landing-lights</property>
      <value>6.0</value>
    </less-than>
  </condition>
  <binding>
    <command>property-assign</command>
    <property>controls/switches/landing-lights</property>
    <value>0</value>
  </binding>
  <marker>
    <x-m>0.2543</x-m>
    <y-m>0.6453</y-m>
    <z-m>0.2983</z-m>
    <scale>2</scale>
  </marker>
</item>

In aircraft that care about checklists, such an item would be repeated five times with slight variations: initially off, on before takeoff, off during climb, on before landing and off after landing.

In the CLGen DSL, all of the checks at different points of a flight are expressed as:

Code: Select all
item("Landing Lights") {
    volts = "systems/electrical/outputs/landing-lights";
    switch = "controls/switches/landing-lights";
    state("OFF", volts == 0) switch = false;
    state("ON", volts > 0) switch = true;
    marker(0.2543, 0.6453, 0.2983, 2);
}

checklist("Before Starting Engines") {
    check("Landing Lights", "OFF");
}

checklist("Before Takeoff") {
    check("Landing Lights", "ON");
}

checklist("During Climb") {
    check("Landing Lights", "OFF");
}

checklist("Approach") {
    check("Landing Lights", "ON");
}

checklist("After Landing") {
    check("Landing Lights", "OFF");
}

Those 27 lines will spit out over 150 lines of XML (in multiple files, one per checklist, plus a wrapper):

Code: Select all
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PropertyList>
  <checklist include="before-starting-engines.xml"/>
  <checklist include="before-takeoff.xml"/>
  <checklist include="during-climb.xml"/>
  <checklist include="approach.xml"/>
  <checklist include="after-landing.xml"/>
</PropertyList>

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PropertyList>

  <title>After Landing</title>

  <!-- Landing Lights: OFF -->
  <item>
    <name>Landing Lights</name>
    <value>OFF</value>
    <condition>
      <equals>
        <property>systems/electrical/outputs/landing-lights</property>
        <value>0</value>
      </equals>
    </condition>
    <binding>
      <command>property-assign</command>
      <property>controls/switches/landing-lights</property>
      <value type="bool">false</value>
    </binding>
    <marker>
      <x-m>0.2543</x-m>
      <y-m>0.6453</y-m>
      <z-m>0.2983</z-m>
      <scale>2.0</scale>
    </marker>
  </item>

</PropertyList>

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PropertyList>

  <title>Approach</title>

  <!-- Landing Lights: ON -->
  <item>
    <name>Landing Lights</name>
    <value>ON</value>
    <condition>
      <greater-than>
        <property>systems/electrical/outputs/landing-lights</property>
        <value>0</value>
      </greater-than>
    </condition>
    <binding>
      <command>property-assign</command>
      <property>controls/switches/landing-lights</property>
      <value type="bool">true</value>
    </binding>
    <marker>
      <x-m>0.2543</x-m>
      <y-m>0.6453</y-m>
      <z-m>0.2983</z-m>
      <scale>2.0</scale>
    </marker>
  </item>

</PropertyList>

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PropertyList>

  <title>Before Starting Engines</title>

  <!-- Landing Lights: OFF -->
  <item>
    <name>Landing Lights</name>
    <value>OFF</value>
    <condition>
      <equals>
        <property>systems/electrical/outputs/landing-lights</property>
        <value>0</value>
      </equals>
    </condition>
    <binding>
      <command>property-assign</command>
      <property>controls/switches/landing-lights</property>
      <value type="bool">false</value>
    </binding>
    <marker>
      <x-m>0.2543</x-m>
      <y-m>0.6453</y-m>
      <z-m>0.2983</z-m>
      <scale>2.0</scale>
    </marker>
  </item>

</PropertyList>

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PropertyList>

  <title>Before Takeoff</title>

  <!-- Landing Lights: ON -->
  <item>
    <name>Landing Lights</name>
    <value>ON</value>
    <condition>
      <greater-than>
        <property>systems/electrical/outputs/landing-lights</property>
        <value>0</value>
      </greater-than>
    </condition>
    <binding>
      <command>property-assign</command>
      <property>controls/switches/landing-lights</property>
      <value type="bool">true</value>
    </binding>
    <marker>
      <x-m>0.2543</x-m>
      <y-m>0.6453</y-m>
      <z-m>0.2983</z-m>
      <scale>2.0</scale>
    </marker>
  </item>

</PropertyList>

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PropertyList>

  <title>During Climb</title>

  <!-- Landing Lights: OFF -->
  <item>
    <name>Landing Lights</name>
    <value>OFF</value>
    <condition>
      <equals>
        <property>systems/electrical/outputs/landing-lights</property>
        <value>0</value>
      </equals>
    </condition>
    <binding>
      <command>property-assign</command>
      <property>controls/switches/landing-lights</property>
      <value type="bool">false</value>
    </binding>
    <marker>
      <x-m>0.2543</x-m>
      <y-m>0.6453</y-m>
      <z-m>0.2983</z-m>
      <scale>2.0</scale>
    </marker>
  </item>

</PropertyList>

The language supports most checklist features that I can think of: conditions with multiple properties and correct operator precedence, multiple bindings, conditional bindings, fgcommands with arbitrary parameters.

If you only create checklists with titles and conditions (no bindings and no markers) it probably doesn't buy you much. For comprehensive checklists though, perhaps used also for autostart and tutorials, you should see CLGen source about 20-25% of the size of the XML it produces. There's much less copy & paste and, because item definitions are re-used across checklists, it should be more maintainable. It's more readable too, it looks more like Nasal than XML.

I wrote it to learn ANTLR, but if you are about to embark on the mind-numbing task of creating a set of checklists, you might save yourself a lot of time. The README (which is included in the binary distribution) covers the language but refer also to the samples. If you start using it, post links to your source files here and I'll tell you if you are missing any tricks or we can tweak the language a bit.

It's written in Java so it's cross-platform. I've tested it on Linux, Mac OS and briefly on Windows. It's simple to run -- just download the zip and run the batch file, specifying your input file:

Code: Select all
$ ./clgen ~/Desktop/test.clg
CLGen 1.0.0
~/Desktop/before-starting-engines.xml
~/Desktop/before-takeoff.xml
~/Desktop/during-climb.xml
~/Desktop/approach.xml
~/Desktop/after-landing.xml
~/Desktop/checklists.xml
Generation complete.
sanhozay
 
Posts: 1207
Joined: Thu Dec 26, 2013 11:57 am
Location: EGNM
Callsign: G-SHOZ
Version: Git
OS: Ubuntu 16.04

Return to Aircraft

Who is online

Users browsing this forum: WoodSTokk and 2 guests