Add Config Store and MFD Header display.
ConfigStore for storing and retrieving config settings (needs XML import/export) Header display with 4 different header fields (all configurable) Publisher for ADC and FMS.
This commit is contained in:
parent
e0f721450a
commit
0c4544c1e1
11 changed files with 324 additions and 91 deletions
|
@ -23,11 +23,11 @@
|
||||||
borderopacity="0"
|
borderopacity="0"
|
||||||
inkscape:pageopacity="0.0"
|
inkscape:pageopacity="0.0"
|
||||||
inkscape:pageshadow="2"
|
inkscape:pageshadow="2"
|
||||||
inkscape:zoom="1.4142135"
|
inkscape:zoom="2.828427"
|
||||||
inkscape:cx="208.90255"
|
inkscape:cx="445.86013"
|
||||||
inkscape:cy="491.35422"
|
inkscape:cy="589.65442"
|
||||||
inkscape:document-units="px"
|
inkscape:document-units="px"
|
||||||
inkscape:current-layer="SurroundGroup"
|
inkscape:current-layer="MFD-navbox"
|
||||||
showgrid="true"
|
showgrid="true"
|
||||||
inkscape:window-width="2495"
|
inkscape:window-width="2495"
|
||||||
inkscape:window-height="1416"
|
inkscape:window-height="1416"
|
||||||
|
@ -450,73 +450,6 @@
|
||||||
id="path4370"
|
id="path4370"
|
||||||
inkscape:connector-curvature="0" />
|
inkscape:connector-curvature="0" />
|
||||||
</g>
|
</g>
|
||||||
<g
|
|
||||||
style="display:inline"
|
|
||||||
inkscape:label="PFD-navbox"
|
|
||||||
id="PFD-navbox">
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
x="263.75085"
|
|
||||||
y="22.123667"
|
|
||||||
id="LEG-text"
|
|
||||||
inkscape:label="LEG-text"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan4549"
|
|
||||||
x="263.75085"
|
|
||||||
y="22.123667"
|
|
||||||
style="fill:#ff00ff" /></text>
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
x="500.63165"
|
|
||||||
y="21.821583"
|
|
||||||
id="DIS"
|
|
||||||
inkscape:label="DIS"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan4553"
|
|
||||||
x="500.63165"
|
|
||||||
y="21.821583">DIS</tspan></text>
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-style:normal;font-weight:normal;font-size:26.66666603px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
x="540.22955"
|
|
||||||
y="21.746063"
|
|
||||||
id="DIS-text"
|
|
||||||
inkscape:label="DIS-text"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan4557"
|
|
||||||
x="540.22955"
|
|
||||||
y="21.746063">--.-</tspan></text>
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
x="639.22455"
|
|
||||||
y="22.123667"
|
|
||||||
id="ETE"
|
|
||||||
inkscape:label="ETE"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan4561"
|
|
||||||
x="639.22455"
|
|
||||||
y="22.123667">ETE</tspan></text>
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-style:normal;font-weight:normal;font-size:26.66666603px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
x="681.65094"
|
|
||||||
y="21.746063"
|
|
||||||
id="ETE-text"
|
|
||||||
inkscape:label="ETE-text"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan4569"
|
|
||||||
x="681.65094"
|
|
||||||
y="21.746063"
|
|
||||||
style="fill:#ff00ff">--:--</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
<g
|
||||||
style="display:inline"
|
style="display:inline"
|
||||||
inkscape:label="MFD-navbox"
|
inkscape:label="MFD-navbox"
|
||||||
|
@ -527,7 +460,7 @@
|
||||||
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
x="265.87216"
|
x="265.87216"
|
||||||
y="22.002344"
|
y="22.002344"
|
||||||
id="DATA-FIELD1-ID-text"
|
id="SurroundHeader1Label"
|
||||||
inkscape:label="DATA-FIELD1-ID-text"><tspan
|
inkscape:label="DATA-FIELD1-ID-text"><tspan
|
||||||
sodipodi:role="line"
|
sodipodi:role="line"
|
||||||
id="tspan4587"
|
id="tspan4587"
|
||||||
|
@ -539,39 +472,39 @@
|
||||||
xml:space="preserve"
|
xml:space="preserve"
|
||||||
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
x="389.5159"
|
x="389.5159"
|
||||||
y="22.002344"
|
y="22.01276"
|
||||||
id="DATA-FIELD2-ID-text"
|
id="SurroundHeader2Label"
|
||||||
inkscape:label="DATA-FIELD2-ID-text"><tspan
|
inkscape:label="DATA-FIELD2-ID-text"><tspan
|
||||||
sodipodi:role="line"
|
sodipodi:role="line"
|
||||||
id="tspan4587-6"
|
id="tspan4587-6"
|
||||||
x="389.5159"
|
x="389.5159"
|
||||||
y="22.002344"
|
y="22.01276"
|
||||||
style="fill:#ffffff">DTK</tspan></text>
|
style="fill:#ffffff">DTK</tspan></text>
|
||||||
<text
|
<text
|
||||||
sodipodi:linespacing="125%"
|
sodipodi:linespacing="125%"
|
||||||
xml:space="preserve"
|
xml:space="preserve"
|
||||||
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
x="513.15961"
|
x="513.15961"
|
||||||
y="22.002344"
|
y="22.01276"
|
||||||
id="DATA-FIELD3-ID-text"
|
id="SurroundHeader3Label"
|
||||||
inkscape:label="DATA-FIELD3-ID-text"><tspan
|
inkscape:label="DATA-FIELD3-ID-text"><tspan
|
||||||
sodipodi:role="line"
|
sodipodi:role="line"
|
||||||
id="tspan4587-5"
|
id="tspan4587-5"
|
||||||
x="513.15961"
|
x="513.15961"
|
||||||
y="22.002344"
|
y="22.01276"
|
||||||
style="fill:#ffffff">TRK</tspan></text>
|
style="fill:#ffffff">TRK</tspan></text>
|
||||||
<text
|
<text
|
||||||
sodipodi:linespacing="125%"
|
sodipodi:linespacing="125%"
|
||||||
xml:space="preserve"
|
xml:space="preserve"
|
||||||
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
x="636.80328"
|
x="636.80328"
|
||||||
y="22.002344"
|
y="22.01276"
|
||||||
id="DATA-FIELD4-ID-text"
|
id="SurroundHeader4Label"
|
||||||
inkscape:label="DATA-FIELD4-ID-text"><tspan
|
inkscape:label="DATA-FIELD4-ID-text"><tspan
|
||||||
sodipodi:role="line"
|
sodipodi:role="line"
|
||||||
id="tspan4587-62"
|
id="tspan4587-62"
|
||||||
x="636.80328"
|
x="636.80328"
|
||||||
y="22.002344"
|
y="22.01276"
|
||||||
style="fill:#ffffff">ETE</tspan></text>
|
style="fill:#ffffff">ETE</tspan></text>
|
||||||
<text
|
<text
|
||||||
sodipodi:linespacing="125%"
|
sodipodi:linespacing="125%"
|
||||||
|
@ -579,7 +512,7 @@
|
||||||
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
x="313.06903"
|
x="313.06903"
|
||||||
y="22.002344"
|
y="22.002344"
|
||||||
id="DATA-FIELD1-VAL-text"
|
id="SurroundHeader1Value"
|
||||||
inkscape:label="DATA-FIELD1-VAL-text"><tspan
|
inkscape:label="DATA-FIELD1-VAL-text"><tspan
|
||||||
sodipodi:role="line"
|
sodipodi:role="line"
|
||||||
id="tspan4625"
|
id="tspan4625"
|
||||||
|
@ -591,7 +524,7 @@
|
||||||
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
x="436.71277"
|
x="436.71277"
|
||||||
y="22.002344"
|
y="22.002344"
|
||||||
id="DATA-FIELD2-VAL-text"
|
id="SurroundHeader2Value"
|
||||||
inkscape:label="DATA-FIELD2-VAL-text"><tspan
|
inkscape:label="DATA-FIELD2-VAL-text"><tspan
|
||||||
sodipodi:role="line"
|
sodipodi:role="line"
|
||||||
id="tspan4625-1"
|
id="tspan4625-1"
|
||||||
|
@ -603,7 +536,7 @@
|
||||||
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
x="560.35645"
|
x="560.35645"
|
||||||
y="22.002344"
|
y="22.002344"
|
||||||
id="DATA-FIELD3-VAL-text"
|
id="SurroundHeader3Value"
|
||||||
inkscape:label="DATA-FIELD3-VAL-text"><tspan
|
inkscape:label="DATA-FIELD3-VAL-text"><tspan
|
||||||
sodipodi:role="line"
|
sodipodi:role="line"
|
||||||
id="tspan4625-7"
|
id="tspan4625-7"
|
||||||
|
@ -614,13 +547,13 @@
|
||||||
xml:space="preserve"
|
xml:space="preserve"
|
||||||
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
style="font-style:normal;font-weight:normal;font-size:21.33333397px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
x="684.00012"
|
x="684.00012"
|
||||||
y="22.002344"
|
y="19.752344"
|
||||||
id="DATA-FIELD4-VAL-text"
|
id="SurroundHeader4Value"
|
||||||
inkscape:label="DATA-FIELD4-VAL-text"><tspan
|
inkscape:label="DATA-FIELD4-VAL-text"><tspan
|
||||||
sodipodi:role="line"
|
sodipodi:role="line"
|
||||||
id="tspan4625-2"
|
id="tspan4625-2"
|
||||||
x="684.00012"
|
x="684.00012"
|
||||||
y="22.002344">--:--</tspan></text>
|
y="19.752344">--:--</tspan></text>
|
||||||
</g>
|
</g>
|
||||||
<rect
|
<rect
|
||||||
y="743.99951"
|
y="743.99951"
|
||||||
|
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 78 KiB |
|
@ -165,7 +165,6 @@ var AirportInfoController =
|
||||||
me.page.mfd.SurroundController.setStandbyNavComFreq(me.page.freqSelect.getValue());
|
me.page.mfd.SurroundController.setStandbyNavComFreq(me.page.freqSelect.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return emesary.Transmitter.ReceiptStatus_Finished;
|
return emesary.Transmitter.ReceiptStatus_Finished;
|
||||||
} else {
|
} else {
|
||||||
return emesary.Transmitter.ReceiptStatus_NotProcessed;
|
return emesary.Transmitter.ReceiptStatus_NotProcessed;
|
||||||
|
|
110
Aircraft/Instruments-3d/FG1000/Nasal/ConfigStore.nas
Normal file
110
Aircraft/Instruments-3d/FG1000/Nasal/ConfigStore.nas
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
# Copyright (C) 2018 Stuart Buchanan
|
||||||
|
# FG1000 Configuration store
|
||||||
|
#
|
||||||
|
# This only stores configuration with pre-defined values
|
||||||
|
#
|
||||||
|
|
||||||
|
var ConfigStore = {
|
||||||
|
|
||||||
|
configValues : {
|
||||||
|
"DisplayUnitsNavAngle": ["MAGNETIC", "TRUE"] ,
|
||||||
|
"DisplayUnitsDistanceAndSpeed": ["NAUTICAL", "METRIC"] ,
|
||||||
|
"DisplayUnitsAltitude": ["FEET", "METERS"] ,
|
||||||
|
"DisplayUnitsTemperature": ["CELCIUS", "FAHRENHEIT"] ,
|
||||||
|
|
||||||
|
"BaroTransitionAlert": ["ON", "OFF"] ,
|
||||||
|
"BaroTransitionAltitude": ["6000", "18000"] ,
|
||||||
|
|
||||||
|
"AirspaceAlertBuffer": ["100", "200", "300", "400", "500", "750", "1000"] ,
|
||||||
|
"AirspaceAlertClassB": ["OFF", "ON"] ,
|
||||||
|
"AirspaceAlertClassC": ["OFF", "ON"] ,
|
||||||
|
"AirspaceAlertClassD": ["OFF", "ON"] ,
|
||||||
|
"AirspaceAlertRestricted": ["OFF", "ON"] ,
|
||||||
|
"AirspaceAlertMOA": ["OFF", "ON"] ,
|
||||||
|
"AirspaceAlertOther": ["OFF", "ON"] ,
|
||||||
|
|
||||||
|
"ArrivalAlert": ["OFF", "ON"] ,
|
||||||
|
"ArrivalDistance": ["0.0", "1.0", "2.0", "3.0", "4.0", "6.0", "8.0", "10.0"] ,
|
||||||
|
"AudioAlertVoice": ["MALE", "FEMALE"] ,
|
||||||
|
|
||||||
|
"PageNavigationChangeOnFirstClick": ["OFF", "ON"] ,
|
||||||
|
"PageNavigationTimeout" : [0.5, 1.0, 2.0, 3.0] ,
|
||||||
|
|
||||||
|
|
||||||
|
# MFD Header Fields
|
||||||
|
#
|
||||||
|
# Bearing (BRG)
|
||||||
|
# Crosstrack Error (XTK)
|
||||||
|
# Distance (DIS)
|
||||||
|
# Desired Track (DTK)
|
||||||
|
# Endurance (END)
|
||||||
|
# En Route Safe Altitude (ESA)
|
||||||
|
# Estimated Time of Arrival (ETA)
|
||||||
|
# Estimated Time En Route (ETE)
|
||||||
|
# Fuel Over Destination (FOD)
|
||||||
|
# Fuel On Board (FOB)
|
||||||
|
# Ground Speed (GS)
|
||||||
|
# Minimum Safe Altitude (MSA)
|
||||||
|
# True Air Speed (TAS)
|
||||||
|
# Track Angle Error (TKE)
|
||||||
|
# Track (TRK)
|
||||||
|
# Vertical Speed Required (VSR)
|
||||||
|
|
||||||
|
"MFDHeader1": ["BRG", "XTK", "DIS", "DTK", "END", "ESA", "ETA", "ETE", "FOD", "FOB", "GS", "MSA", "TAS", "TKE", "TRK", "VSR"] ,
|
||||||
|
"MFDHeader2": ["BRG", "XTK", "DIS", "DTK", "END", "ESA", "ETA", "ETE", "FOD", "FOB", "GS", "MSA", "TAS", "TKE", "TRK", "VSR"] ,
|
||||||
|
"MFDHeader3": ["BRG", "XTK", "DIS", "DTK", "END", "ESA", "ETA", "ETE", "FOD", "FOB", "GS", "MSA", "TAS", "TKE", "TRK", "VSR"] ,
|
||||||
|
"MFDHeader4": ["BRG", "XTK", "DIS", "DTK", "END", "ESA", "ETA", "ETE", "FOD", "FOB", "GS", "MSA", "TAS", "TKE", "TRK", "VSR"] ,
|
||||||
|
},
|
||||||
|
|
||||||
|
new : func()
|
||||||
|
{
|
||||||
|
var obj ={
|
||||||
|
parents : [ ConfigStore ],
|
||||||
|
_values : {},
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var i; keys(ConfigStore.configValues)) {
|
||||||
|
var values = ConfigStore.configValues[i];
|
||||||
|
obj.set(i, values[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Special case defaults
|
||||||
|
obj.set("MFDHeader1", "GS");
|
||||||
|
obj.set("MFDHeader2", "DIS");
|
||||||
|
obj.set("MFDHeader3", "ETE");
|
||||||
|
# ESA should be the default, but it's not implemented right now, so use FOD
|
||||||
|
#obj.set("MFDHeader4", "ESA");
|
||||||
|
obj.set("MFDHeader4", "FOD");
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
|
||||||
|
set : func(name, value) {
|
||||||
|
# Validate name is something we know.
|
||||||
|
assert(contains(ConfigStore.configValues, name), "ConfigStore does not contain name " ~ name);
|
||||||
|
|
||||||
|
if (size(ConfigStore.configValues[name]) == 0) {
|
||||||
|
# If not valid values, then anything goes.
|
||||||
|
me._values[name] = value;
|
||||||
|
} else {
|
||||||
|
# Validate the value is part of the set of acceptable values
|
||||||
|
var found = 0;
|
||||||
|
foreach(var val; ConfigStore.configValues[name]) {
|
||||||
|
if (value == val) {
|
||||||
|
found =1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(found == 1,
|
||||||
|
"Invalid value for " ~ name ~ ": " ~ value ~
|
||||||
|
"(Should be one of " ~ string.join(", ", ConfigStore.configValues[name]) ~ ")");
|
||||||
|
|
||||||
|
me._values[name] = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
get : func(name) {
|
||||||
|
return me._values[name];
|
||||||
|
},
|
||||||
|
};
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Air Data Computer Driver using Emesary to publish data such as
|
||||||
|
#
|
||||||
|
# Airspeed
|
||||||
|
# Orientation
|
||||||
|
# Rate of turn
|
||||||
|
# Heading
|
||||||
|
# Air Temperature
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# For the moment these are just taken directly from the raw properties. They
|
||||||
|
# should probably come from aircraft-specific instrumentation.
|
||||||
|
|
||||||
|
var GenericADCPublisher =
|
||||||
|
{
|
||||||
|
|
||||||
|
new : func (frequency=0.5) {
|
||||||
|
var obj = {
|
||||||
|
parents : [
|
||||||
|
GenericADCPublisher,
|
||||||
|
PeriodicPropertyPublisher.new(notifications.PFDEventNotification.ADCData, frequency)
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
obj.addPropMap("ADCTrueAirspeed", "/instrumentation/airspeed-indicator/true-speed-kt");
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
};
|
|
@ -30,7 +30,6 @@ var GenericEISPublisher =
|
||||||
|
|
||||||
# Custom publish method as we package the values into an array of engines,
|
# Custom publish method as we package the values into an array of engines,
|
||||||
# in this case, only one!
|
# in this case, only one!
|
||||||
|
|
||||||
publish : func() {
|
publish : func() {
|
||||||
var engineData0 = {};
|
var engineData0 = {};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
# FMS Driver using Emesary to publish data from the inbuilt FMS properties
|
||||||
|
var GenericFMSPublisher =
|
||||||
|
{
|
||||||
|
|
||||||
|
new : func (frequency=0.5) {
|
||||||
|
var obj = {
|
||||||
|
parents : [
|
||||||
|
GenericFMSPublisher,
|
||||||
|
PeriodicPropertyPublisher.new(notifications.PFDEventNotification.FMSData, frequency)
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
obj.addPropMap("FMSLegBearing", "/instrumentation/gps/wp/wp[1]/bearing-mag-deg");
|
||||||
|
obj.addPropMap("FMSLegCourseError", "/instrumentation/gps/wp/wp[1]/course-error-nm");
|
||||||
|
obj.addPropMap("FMSLegDesiredTrack", "/instrumentation/gps/indicated-track-magnetic-deg");
|
||||||
|
obj.addPropMap("FMSLegTrackErrorAngle", "/instrumentation/gps/wp/wp[1]/course-deviation-deg");
|
||||||
|
obj.addPropMap("FMSLegTrack", "/instrumentation/gps/indicated-track-magnetic-deg");
|
||||||
|
obj.addPropMap("FMSGroundspeed", "/instrumentation/gps/indicated-ground-speed-kt");
|
||||||
|
obj.addPropMap("FMSWayPointCourseError", "/instrumentation/gps/wp/wp[1]/course-error-nm");
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
|
||||||
|
# Custom publish method as we need to calculate some particular values manually.
|
||||||
|
publish : func() {
|
||||||
|
var gpsdata = {};
|
||||||
|
|
||||||
|
foreach (var propmap; me._propmaps) {
|
||||||
|
var name = propmap.getName();
|
||||||
|
gpsdata[name] = propmap.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
# A couple of calculated values used by the MFD Header display
|
||||||
|
var total_fuel = getprop("/consumables/fuel/tank[0]/indicated-level-gal_us") or 0.0;
|
||||||
|
total_fuel = total_fuel + (getprop("/consumables/fuel/tank[1]/indicated-level-gal_us") or 0.0);
|
||||||
|
var fuel_flow = getprop("/engines/engine[0]/fuel-flow-gph") or 1.0;
|
||||||
|
gpsdata["FuelOnBoard"] = total_fuel;
|
||||||
|
gpsdata["EnduranceHrs"] = total_fuel / fuel_flow;
|
||||||
|
|
||||||
|
var plan = flightplan();
|
||||||
|
|
||||||
|
var dst = 0.0;
|
||||||
|
if (plan.getPlanSize() > 0) {
|
||||||
|
# Determine the distance to travel, based on
|
||||||
|
# - current distance to the next WP,
|
||||||
|
# - length of each subsequent leg.
|
||||||
|
dst = getprop("/instrumentation/gps/wp/wp[1]/distance-nm") or 0.0;
|
||||||
|
|
||||||
|
if (plan.indexOfWP(plan.currentWP()) < (plan.getPlanSize() -1)) {
|
||||||
|
for(var i=plan.indexOfWP(plan.currentWP()) + 1; i < plan.getPlanSize(); i = i+1) {
|
||||||
|
var leg = plan.getWP(i);
|
||||||
|
if (leg != nil ) dst = dst + leg.leg_distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gpsdata["FMSDistance"] = dst;
|
||||||
|
var spd = getprop("/instrumentation/gps/indicated-ground-speed-kt") or 1.0;
|
||||||
|
var time_hrs = dst / spd;
|
||||||
|
|
||||||
|
gpsdata["FMSEstimatedTimeEnroute"] = time_hrs;
|
||||||
|
gpsdata["FMSFuelOverDestination"] = total_fuel - time_hrs * fuel_flow;
|
||||||
|
|
||||||
|
var notification = notifications.PFDEventNotification.new(
|
||||||
|
"MFD",
|
||||||
|
1,
|
||||||
|
notifications.PFDEventNotification.FMSData,
|
||||||
|
gpsdata);
|
||||||
|
|
||||||
|
me._transmitter.NotifyAll(notification);
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
|
@ -8,6 +8,8 @@ io.include("constants.nas");
|
||||||
|
|
||||||
var nasal_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/FG1000/Nasal/";
|
var nasal_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/FG1000/Nasal/";
|
||||||
|
|
||||||
|
io.load_nasal(nasal_dir ~ '/ConfigStore.nas', "fg1000");
|
||||||
|
|
||||||
io.load_nasal(nasal_dir ~ '/MFDPage.nas', "fg1000");
|
io.load_nasal(nasal_dir ~ '/MFDPage.nas', "fg1000");
|
||||||
io.load_nasal(nasal_dir ~ '/MFDPageController.nas', "fg1000");
|
io.load_nasal(nasal_dir ~ '/MFDPageController.nas', "fg1000");
|
||||||
|
|
||||||
|
@ -71,6 +73,8 @@ var MFD =
|
||||||
Surround : nil,
|
Surround : nil,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
obj.ConfigStore = fg1000.ConfigStore.new();
|
||||||
|
|
||||||
obj._svg = myCanvas.createGroup("softkeys");
|
obj._svg = myCanvas.createGroup("softkeys");
|
||||||
obj._svg.set("clip-frame", canvas.Element.LOCAL);
|
obj._svg.set("clip-frame", canvas.Element.LOCAL);
|
||||||
obj._svg.set("clip", "rect(0px, 1024px, 768px, 0px)");
|
obj._svg.set("clip", "rect(0px, 1024px, 768px, 0px)");
|
||||||
|
|
|
@ -38,6 +38,27 @@ var PAGE_GROUPS = [
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# Mapping for header labels to specific FMS or ADC messages, and sprintf formatting
|
||||||
|
# to use
|
||||||
|
var HEADER_MAPPING = {
|
||||||
|
"BRG" : { message : "FMSLegBearing", format : "%d"},
|
||||||
|
"XTK" : { message : "FMSLegCourseError", format : "%.1fnm"},
|
||||||
|
"DIS" : { message : "FMSDistance", format : "%.1fnm"},
|
||||||
|
"DTK" : { message : "FMSLegDesiredTrack", format : "%d"},
|
||||||
|
"END" : { message : "EnduranceHrs", format : "%.1fhrs"},
|
||||||
|
"ESA" : { message : "EnRouteSafeAltitude", format : "%dft"}, # TODO
|
||||||
|
"ETA" : { message : "FMSEstimatedTimeArrival", format : ""}, # TODO
|
||||||
|
"ETE" : { message : "FMSEstimatedTimeEnroute", format : ""},
|
||||||
|
"FOD" : { message : "FMSFuelOverDestination", format : "%dgal"},
|
||||||
|
"FOB" : { message : "FuelOnBoard", format : "%dgal"},
|
||||||
|
"GS" : { message : "FMSGroundspeed", format : "%dkts"},
|
||||||
|
"MSA" : { message : "MinimumSafeAltitude", format : "%dft"}, # TODO
|
||||||
|
"TAS" : { message : "ADCTrueAirspeed", format : "%dkts"},
|
||||||
|
"TKE" : { message : "FMSLegTrackErrorAngle", format : "%d"},
|
||||||
|
"TRK" : { message : "FMSLegTrack", format : "%d"},
|
||||||
|
"VSR" : { message : "FMSLegVerticalSpeedRequired", format : "%dfpm"}, # TODO
|
||||||
|
};
|
||||||
|
|
||||||
var Surround =
|
var Surround =
|
||||||
{
|
{
|
||||||
new : func (mfd, myCanvas, device, svg)
|
new : func (mfd, myCanvas, device, svg)
|
||||||
|
@ -52,7 +73,11 @@ var Surround =
|
||||||
"Comm2StandbyFreq", "Comm2SelectedFreq",
|
"Comm2StandbyFreq", "Comm2SelectedFreq",
|
||||||
"Nav1StandbyFreq", "Nav1SelectedFreq",
|
"Nav1StandbyFreq", "Nav1SelectedFreq",
|
||||||
"Nav2StandbyFreq", "Nav2SelectedFreq",
|
"Nav2StandbyFreq", "Nav2SelectedFreq",
|
||||||
"Nav1ID", "Nav2ID"
|
"Nav1ID", "Nav2ID",
|
||||||
|
"Header1Label", "Header1Value",
|
||||||
|
"Header2Label", "Header2Value",
|
||||||
|
"Header3Label", "Header3Value",
|
||||||
|
"Header4Label", "Header4Value",
|
||||||
];
|
];
|
||||||
|
|
||||||
obj.addTextElements(textElements);
|
obj.addTextElements(textElements);
|
||||||
|
@ -181,6 +206,41 @@ var Surround =
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
# Update Header data with FMS or ADC data.
|
||||||
|
updateHeaderData : func(data) {
|
||||||
|
var headers = ["Header1", "Header2", "Header3", "Header4"];
|
||||||
|
foreach (var header; headers) {
|
||||||
|
|
||||||
|
# Get the currently configured heading and set the surround to display it.
|
||||||
|
var label = me.mfd.ConfigStore.get("MFD" ~ header);
|
||||||
|
assert(label != nil, "No header configured in ConfigStore for " ~ header);
|
||||||
|
me.setTextElement(header ~ "Label", label);
|
||||||
|
|
||||||
|
# Determine how it maps to Emesary data notifications
|
||||||
|
var mapping = HEADER_MAPPING[label];
|
||||||
|
assert(mapping != nil, "No header mapping for " ~ label);
|
||||||
|
|
||||||
|
if (data[mapping.message] != nil) {
|
||||||
|
# Format and display the value
|
||||||
|
var value = sprintf(mapping.format, data[mapping.message]);
|
||||||
|
|
||||||
|
if (mapping.message == "FMSEstimatedTimeEnroute") {
|
||||||
|
# Special case to format time strings.
|
||||||
|
var hrs = int(data[mapping.message]);
|
||||||
|
var mins = int(60*(data[mapping.message] - hrs));
|
||||||
|
var secs = int(3600*(data[mapping.message] - hrs - mins/60));
|
||||||
|
|
||||||
|
if (hrs == 0) {
|
||||||
|
value = sprintf("%d:%02d", mins, secs);
|
||||||
|
} else {
|
||||||
|
value = sprintf("%d:%02d", hrs, mins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
me.setTextElement(header ~ "Value", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
addPage : func(name, page)
|
addPage : func(name, page)
|
||||||
{
|
{
|
||||||
me._pageList[name] = page;
|
me._pageList[name] = page;
|
||||||
|
|
|
@ -359,11 +359,21 @@ var SurroundController =
|
||||||
{
|
{
|
||||||
if (notification.Device_Id == pfd_obj.device_id
|
if (notification.Device_Id == pfd_obj.device_id
|
||||||
and notification.NotificationType == notifications.PFDEventNotification.DefaultType) {
|
and notification.NotificationType == notifications.PFDEventNotification.DefaultType) {
|
||||||
|
|
||||||
if (notification.Event_Id == notifications.PFDEventNotification.NavComData
|
if (notification.Event_Id == notifications.PFDEventNotification.NavComData
|
||||||
and notification.EventParameter != nil)
|
and notification.EventParameter != nil)
|
||||||
{
|
{
|
||||||
return controller.handleNavComData(notification.EventParameter);
|
return controller.handleNavComData(notification.EventParameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (((notification.Event_Id == notifications.PFDEventNotification.FMSData) or
|
||||||
|
(notification.Event_Id == notifications.PFDEventNotification.ADCData) )
|
||||||
|
and notification.EventParameter != nil)
|
||||||
|
{
|
||||||
|
# Pass FMS and ADC data straight to the page to display in the header fields
|
||||||
|
return controller._page.updateHeaderData(notification.EventParameter);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return emesary.Transmitter.ReceiptStatus_NotProcessed;
|
return emesary.Transmitter.ReceiptStatus_NotProcessed;
|
||||||
};
|
};
|
||||||
|
|
|
@ -110,6 +110,9 @@ var MFDGUI =
|
||||||
io.load_nasal(nasal_dir ~ 'Interfaces/GenericNavComUpdater.nas', "fg1000");
|
io.load_nasal(nasal_dir ~ 'Interfaces/GenericNavComUpdater.nas', "fg1000");
|
||||||
io.load_nasal(nasal_dir ~ 'Interfaces/NavDataInterface.nas', "fg1000");
|
io.load_nasal(nasal_dir ~ 'Interfaces/NavDataInterface.nas', "fg1000");
|
||||||
|
|
||||||
|
io.load_nasal(nasal_dir ~ 'Interfaces/GenericFMSPublisher.nas', "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ 'Interfaces/GenericADCPublisher.nas', "fg1000");
|
||||||
|
|
||||||
# Now create the MFD itself
|
# Now create the MFD itself
|
||||||
if (obj.scale > 0.999) {
|
if (obj.scale > 0.999) {
|
||||||
# If we're at full scale, then create it directly in this Canvas as that
|
# If we're at full scale, then create it directly in this Canvas as that
|
||||||
|
@ -154,6 +157,12 @@ var MFDGUI =
|
||||||
obj.navdataInterface = fg1000.NavDataInterface.new(obj.mfd.getDevice());
|
obj.navdataInterface = fg1000.NavDataInterface.new(obj.mfd.getDevice());
|
||||||
obj.navdataInterface.start();
|
obj.navdataInterface.start();
|
||||||
|
|
||||||
|
obj.gpsPublisher = fg1000.GenericFMSPublisher.new();
|
||||||
|
obj.gpsPublisher.start();
|
||||||
|
|
||||||
|
obj.adcPublisher = fg1000.GenericADCPublisher.new();
|
||||||
|
obj.adcPublisher.start();
|
||||||
|
|
||||||
# Add a event listener for the mouse wheel, which is used for turning the
|
# Add a event listener for the mouse wheel, which is used for turning the
|
||||||
# knobs.
|
# knobs.
|
||||||
obj.myCanvas.addEventListener("wheel", func(e)
|
obj.myCanvas.addEventListener("wheel", func(e)
|
||||||
|
@ -231,6 +240,12 @@ var MFDGUI =
|
||||||
me.navdataInterface.stop();
|
me.navdataInterface.stop();
|
||||||
me.navdataInterface =nil;
|
me.navdataInterface =nil;
|
||||||
|
|
||||||
|
me.gpsPublisher.stop();
|
||||||
|
me.gpsPublisher = nil;
|
||||||
|
|
||||||
|
me.adcPublisher.stop();
|
||||||
|
me.adcPublisher = nil;
|
||||||
|
|
||||||
# Clean up the window itself
|
# Clean up the window itself
|
||||||
call(canvas.Window.del, [], me.window);
|
call(canvas.Window.del, [], me.window);
|
||||||
},
|
},
|
||||||
|
|
|
@ -554,7 +554,9 @@ var PFDEventNotification =
|
||||||
HardKeyPushed : 4, #event parameter contains single { Id: , Value: } tuple
|
HardKeyPushed : 4, #event parameter contains single { Id: , Value: } tuple
|
||||||
EngineData : 5, #event parameter contains an array of hashes, each containing information about a given engine.
|
EngineData : 5, #event parameter contains an array of hashes, each containing information about a given engine.
|
||||||
NavComData : 6, #event parameter contains a hash of updated Nav/Com settings
|
NavComData : 6, #event parameter contains a hash of updated Nav/Com settings
|
||||||
NavData : 7, #event parameter contrains a singel { Id: , Value: } tuple requesting a paricular type of NavData
|
NavData : 7, #event parameter contrains a single { Id: , Value: } tuple requesting a particular type of NavData
|
||||||
|
FMSData : 8, #event parameter containing a hash of updated GPS/FMS information (track, ground-speed, waypoint legs etc.)
|
||||||
|
ADCData : 8, #event parameter containing a hash of updated Air Data Computer information (track, ground-speed etc.)
|
||||||
|
|
||||||
DefaultType : "PFDEventNotification",
|
DefaultType : "PFDEventNotification",
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue