Skip to content

Commit

Permalink
Merge branch 'release/1.1.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
sanhozay committed May 18, 2017
2 parents 6a19afd + a1e3ab8 commit 4865f3c
Show file tree
Hide file tree
Showing 10 changed files with 343 additions and 29 deletions.
18 changes: 13 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
build/**
bin/**
samples/**/*.xml
.gradle/**
.settings
# Gradle
.gradle/
build/

# Eclipse
.classpath
.project
.settings
bin/

# Ignore samples outputs
samples/**/*.dot
samples/**/*.pdf
samples/**/*.png
samples/**/*.xml
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,13 @@ The solution is to create a Nasal script file in the aircraft's Nasal directory
and add a custom fgcommand to it using `addcommand`. This command can then be
used from both the cockpit control and the checklist.

## What is checklists.dot and how can I view it?

The .dot file is a visualization of the checklists structure and can be
rendered to an image using a tool like Graphviz.

$ dot -o checklists.png -Tpng checklists.dot

## Checklist Definition Language

The language is designed to feel familiar to Flightgear developers who are
Expand Down
8 changes: 6 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apply plugin: 'antlr'
apply plugin: 'groovy'
apply plugin: 'java'

project.version = '1.1.0'
project.version = '1.1.1'

defaultTasks 'build'

Expand All @@ -24,6 +24,7 @@ dependencies {
antlr 'org.antlr:antlr4:4.7'
compile 'org.antlr:antlr4-runtime:4.7'
compile 'org.apache.velocity:velocity:1.7'
compile 'com.github.librepdf:openpdf:1.0.1'
testCompile 'org.codehaus.groovy:groovy-all:2.4.11'
testCompile 'cglib:cglib-nodep:3.2.5'
testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
Expand All @@ -34,8 +35,11 @@ jar {
attributes('Main-Class': 'org.flightgear.clgen.CLGen')
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) }
}
exclude "META-INF/*.SF"
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
}

task release(type: Zip, dependsOn: build) {
Expand Down
2 changes: 1 addition & 1 deletion clgen
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#!/bin/sh
java -jar $(dirname $0)/build/libs/CLGen-1.1.0.jar $*
java -jar $(dirname $0)/build/libs/CLGen-1.1.1.jar $*
2 changes: 1 addition & 1 deletion clgen.bat
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
@echo off
java -jar %~dp0/build/libs/CLGen-1.1.0.jar %*
java -jar %~dp0/build/libs/CLGen-1.1.1.jar %*
36 changes: 20 additions & 16 deletions samples/Beagle-Pup/pup.clg
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,15 @@ item("Beacon") {
volts = "systems/electrical/outputs/beacon";
breaker = "controls/switches/circuit-breakers/beacon";
beaconChecked = "sim/checklists/status/beacon";
state("OFF", volts == 0 && beaconChecked) {
state("OFF", volts == 0) {
fgcommand("switch-assign", property=breaker, value=false);
}
state("ON", volts > 0) {
fgcommand("switch-assign", property=breaker, value=true);
}
state("CHECK", volts > 0 || beaconChecked) {
state("CHECK & OFF", volts == 0 && beaconChecked) {
fgcommand("switch-assign", property=breaker, value=true);
fgcommand("switch-assign", property=breaker, value=false);
}
}

Expand Down Expand Up @@ -141,6 +142,7 @@ item("Flaps") {
item("Fuel Tank Selector") {
tank1 = "consumables/fuel/tank[1]/selected";
tank2 = "consumables/fuel/tank[2]/selected";
state("EITHER", tank1 || tank2) fgcommand("tank-select-left");
state("BOTH", tank1 && tank2) fgcommand("tank-select-both");
state("OFF", !(tank1 || tank2)) fgcommand("tank-select-off");
}
Expand Down Expand Up @@ -227,7 +229,7 @@ item("Pitot Heater") {
item("Carburettor") {
min = "fdm/jsbsim/propulsion/engine/prime-min";
primeLevel= "fdm/jsbsim/propulsion/engine/prime-norm";
state("PRIMED", primeLevel >= min) primeLevel = 1;
state("PRIME", primeLevel >= min) primeLevel = 1;
}

item("Propeller") {
Expand Down Expand Up @@ -309,19 +311,18 @@ checklist("Before Starting Engines") {
check("Parking Brake", "ON");
check("Main Battery", "CHECK");
check("Navigation Lights", "CHECK");
check("Beacon", "CHECK");
check("Beacon", "OFF");
check("Beacon", "CHECK & OFF");
check("Main Battery", "OFF");
check("Refuel", "AS REQUIRED");
}

checklist("Start Engines") {
check("Parking Brake", "ON");
check("Carb Heat", "COLD");
check("Fuel Tank Selector", "BOTH");
check("Fuel Tank Selector", "EITHER");
check("Mixture", "FULL RICH");
check("Circuit Breakers", "ALL IN");
check("Carburettor", "PRIMED", "(1-4 strokes of throttle)");
check("Carburettor", "PRIME", "(1-4 strokes of throttle)");
check("Throttle", "APPROX 1/4");
check("Main Battery", "ON");
check("Navigation Lights", "ON");
Expand All @@ -332,19 +333,22 @@ checklist("Start Engines") {
check("Propeller", "CLEAR");
check("Beacon", "ON");
check("Engine", "START");
check("Carb Heat", "AS REQUIRED");
check("Throttle", "TICK OVER");
}

checklist("During Warm Up") {
check("Throttle", "TICK OVER", "(800-1200rpm)");
check("Oil Pressure", "CHECK", "(minimum 25psi)");
check("Suction", "CHECK", "(minimum 3\")");
check("Starter Master", "OFF");
check("Boost Pump", "OFF");
check("Alternator Warning", "OFF");
check("Transponder", "SBY");
check("Carb Heat", "AS REQUIRED");
}

checklist("Before Taxi") {
check("Autopilot", "CHECK");
check("Transponder", "SBY");
check("Radios", "ON");
check("Suction", "CHECK", "(minimum 3\")");
check("Heading Indicator", "ALIGN");
check("Altimeter", "SET");
check("Taxi Light", "ON");
Expand Down Expand Up @@ -387,11 +391,11 @@ checklist("Traffic Pattern") {
}

checklist("After Landing") {
check("Taxi Light", "ON");
check("Flaps", "UP");
check("Boost Pump", "OFF");
check("Carb Heat", "COLD");
check("Pitot Heater", "OFF");
check("Carb Heat", "COLD");
check("Boost Pump", "OFF");
check("Flaps", "UP");
check("Taxi Light", "ON");
check("Transponder", "SBY");
}

Expand All @@ -400,7 +404,7 @@ checklist("Parking") {
check("Taxi Light", "OFF");
check("Transponder", "OFF");
check("Radios", "OFF");
check("Throttle", "TICK OVER");
check("Throttle", "TICK OVER", "(800-1200rpm)");
check("Mixture", "IDLE CUTOFF");
check("Beacon", "OFF");
check("Alternator", "OFF");
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/flightgear/clgen/CLGen.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import org.flightgear.clgen.CLGenParser.SpecificationContext;
import org.flightgear.clgen.ast.AbstractSyntaxTree;
import org.flightgear.clgen.ast.Item;
import org.flightgear.clgen.backend.DotVisitor;
import org.flightgear.clgen.backend.PdfVisitor;
import org.flightgear.clgen.backend.UsageVisitor;
import org.flightgear.clgen.backend.XmlVisitor;
import org.flightgear.clgen.listener.ChecklistListener;
Expand Down Expand Up @@ -127,6 +129,8 @@ private void run() throws IOException, GeneratorException {
ast.accept(usageVisitor);
warnings += usageVisitor.getNumberOfWarnings();
ast.accept(new XmlVisitor(input.toAbsolutePath().getParent()));
ast.accept(new DotVisitor(input.toAbsolutePath().getParent()));
ast.accept(new PdfVisitor(input.toAbsolutePath().getParent()));
if (warnings > 0)
System.out.format(
"Generation complete with %d warning%s.\n",
Expand Down
119 changes: 119 additions & 0 deletions src/main/java/org/flightgear/clgen/backend/DotVisitor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* Copyright (C) 2017 Richard Senior
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.flightgear.clgen.backend;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

import org.flightgear.clgen.GeneratorException;
import org.flightgear.clgen.ast.AbstractSyntaxTree;
import org.flightgear.clgen.ast.Check;
import org.flightgear.clgen.ast.Checklist;

/**
* Creates a Graphviz DOT representation of the checklists.
* <p>
* This can be rendered to an image using:
* <code>$ dot -ochecklists.png -Tpng checklists.dot</code>
*
* @author Richard Senior
*/
public class DotVisitor extends AbstractVisitor {

private final Path outputDir;

private final StringBuilder dot = new StringBuilder();
private final StringBuilder nodes = new StringBuilder();
private final StringBuilder edges = new StringBuilder();

private int index = 0;
private double hue = 0.0;
private double colorCycle;

public DotVisitor(final Path outputDir) {
this.outputDir = outputDir;
}

@Override
public void enter(final AbstractSyntaxTree ast) {
colorCycle = 1.0 / ast.getChecklists().size();
dot.append("digraph G {\n")
.append(" pad=0.5;\n")
.append(" ranksep=0.35;\n")
.append(" node [fontsize=12];\n")
.append(" node [fontcolor=white,fontname=\"helvetica-bold\"];\n")
.append(" node [shape=Mrecord,width=2.5,style=filled];\n");
}

@Override
public void exit(final AbstractSyntaxTree ast) {
dot.append(" node [color=\"#404040\",fontcolor=\"#404040\",fontname=\"helvetica\"];\n")
.append(" node [shape=note,width=2.25,style=\"\"];\n");

dot.append(nodes.toString());
dot.append(edges.toString());

dot.append("}\n");
Path path = outputDir.resolve("checklists.dot");
try {
Files.write(path, dot.toString().getBytes());
System.out.println(path.toAbsolutePath().normalize().toString());
} catch (IOException e) {
String message = String.format("Failed to create DOT file at '%s'", path);
throw new GeneratorException(message, e);
}
}

@Override
public void enter(final Checklist checklist) {
String s = String.format(" node [color=\"%.04f,0.6,0.6\"]; %s;\n",
hue, quote(checklist.getTitle())
);
dot.append(s);
edges.append(" " + quote(checklist.getTitle()));
int totalChecks = checklist.getPages()
.parallelStream()
.mapToInt(page -> page.getChecks().size())
.sum();
for (int i = 0; i < totalChecks; ++i)
edges.append(" -> ").append(index + i);
edges.append(";\n");
}

@Override
public void exit(final Checklist checklist) {
hue += colorCycle;
}

@Override
public void enter(final Check check) {
StringBuilder sb = new StringBuilder();
sb.append(String.format(" %d [label=\"%s %s",
index++, check.getItem().getName(), check.getState().getName()
));
for (String value : check.getAdditionalValues())
sb.append("&#92;n" + value.replaceAll("[\"]", "\\\\\""));
sb.append("\"];\n");
nodes.append(sb.toString());
}

private String quote(final String s) {
return String.format("\"%s\"", s);
}

}
Loading

0 comments on commit 4865f3c

Please sign in to comment.