Initial FG1000 PFD
This commit is contained in:
parent
452ba72d51
commit
98e11ec207
18 changed files with 16393 additions and 24 deletions
7627
Aircraft/Instruments-3d/FG1000/MFDPages/PFDInstruments.bck1.svg
Normal file
7627
Aircraft/Instruments-3d/FG1000/MFDPages/PFDInstruments.bck1.svg
Normal file
File diff suppressed because it is too large
Load diff
After Width: | Height: | Size: 461 KiB |
7629
Aircraft/Instruments-3d/FG1000/MFDPages/PFDInstruments.svg
Normal file
7629
Aircraft/Instruments-3d/FG1000/MFDPages/PFDInstruments.svg
Normal file
File diff suppressed because it is too large
Load diff
After Width: | Height: | Size: 461 KiB |
|
@ -70,6 +70,20 @@ var ConfigStore = {
|
||||||
"MFDHeader2": ["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"] ,
|
"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"] ,
|
"MFDHeader4": ["BRG", "XTK", "DIS", "DTK", "END", "ESA", "ETA", "ETE", "FOD", "FOB", "GS", "MSA", "TAS", "TKE", "TRK", "VSR"] ,
|
||||||
|
|
||||||
|
# V-speeds (Cessna 182T)
|
||||||
|
"Vx" : 54, # Short field takeoff, 2600lbs
|
||||||
|
"Vy" : 78, # 4000ft, 3100lbs
|
||||||
|
"Vr" : 78,
|
||||||
|
"Vglide" : 70, # 2600lbs
|
||||||
|
"Vne": 175,
|
||||||
|
|
||||||
|
"Vx-visible" : 1,
|
||||||
|
"Vy-visible" : 1,
|
||||||
|
"Vr-visible" : 1,
|
||||||
|
"Vglide-visible" : 1,
|
||||||
|
"Vne-visible": 1,
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
new : func()
|
new : func()
|
||||||
|
@ -81,7 +95,8 @@ var ConfigStore = {
|
||||||
|
|
||||||
foreach (var i; keys(ConfigStore.configValues)) {
|
foreach (var i; keys(ConfigStore.configValues)) {
|
||||||
var values = ConfigStore.configValues[i];
|
var values = ConfigStore.configValues[i];
|
||||||
obj.set(i, values[0]);
|
if (typeof(values) == "vector") obj.set(i, values[0]);
|
||||||
|
if (typeof(values) == "scalar") obj.set(i, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Special case defaults
|
# Special case defaults
|
||||||
|
@ -99,10 +114,7 @@ var ConfigStore = {
|
||||||
# Validate name is something we know.
|
# Validate name is something we know.
|
||||||
assert(contains(ConfigStore.configValues, name), "ConfigStore does not contain name " ~ name);
|
assert(contains(ConfigStore.configValues, name), "ConfigStore does not contain name " ~ name);
|
||||||
|
|
||||||
if (size(ConfigStore.configValues[name]) == 0) {
|
if (typeof(ConfigStore.configValues[name]) == "vector") {
|
||||||
# If not valid values, then anything goes.
|
|
||||||
me._values[name] = value;
|
|
||||||
} else {
|
|
||||||
# Validate the value is part of the set of acceptable values
|
# Validate the value is part of the set of acceptable values
|
||||||
var found = 0;
|
var found = 0;
|
||||||
foreach(var val; ConfigStore.configValues[name]) {
|
foreach(var val; ConfigStore.configValues[name]) {
|
||||||
|
@ -117,6 +129,11 @@ var ConfigStore = {
|
||||||
"(Should be one of " ~ string.join(", ", ConfigStore.configValues[name]) ~ ")");
|
"(Should be one of " ~ string.join(", ", ConfigStore.configValues[name]) ~ ")");
|
||||||
|
|
||||||
me._values[name] = value;
|
me._values[name] = value;
|
||||||
|
}elsif (typeof(ConfigStore.configValues[name]) == "scalar") {
|
||||||
|
# If not valid values, then anything goes.
|
||||||
|
me._values[name] = value;
|
||||||
|
} else {
|
||||||
|
die("Unknown ConfigStore type " ~ typeof(ConfigStore.configValues[name]));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ var EISController =
|
||||||
transmitter = emesary.GlobalTransmitter;
|
transmitter = emesary.GlobalTransmitter;
|
||||||
|
|
||||||
if (me._recipient == nil){
|
if (me._recipient == nil){
|
||||||
me._recipient = emesary.Recipient.new("AirportInfoController_" ~ me._page.device.designation);
|
me._recipient = emesary.Recipient.new("EISController_" ~ me._page.device.designation);
|
||||||
var pfd_obj = me._page.device;
|
var pfd_obj = me._page.device;
|
||||||
var controller = me;
|
var controller = me;
|
||||||
me._recipient.Receive = func(notification)
|
me._recipient.Receive = func(notification)
|
||||||
|
|
|
@ -28,6 +28,7 @@ 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 ~ '/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");
|
||||||
|
io.load_nasal(nasal_dir ~ '/PFD.nas', "fg1000");
|
||||||
io.load_nasal(nasal_dir ~ '/MFD.nas', "fg1000");
|
io.load_nasal(nasal_dir ~ '/MFD.nas', "fg1000");
|
||||||
io.load_nasal(nasal_dir ~ '/GUI.nas', "fg1000");
|
io.load_nasal(nasal_dir ~ '/GUI.nas', "fg1000");
|
||||||
|
|
||||||
|
@ -101,11 +102,36 @@ addMFD : func(index=nil, targetcanvas=nil, screenObject=nil) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var mfd = fg1000.MFD.new(me, me.EIS_Class, me.EIS_SVG, targetcanvas, index);
|
var mfd = fg1000.MFDDisplay.new(me, me.EIS_Class, me.EIS_SVG, targetcanvas, index);
|
||||||
me.displays[index] = mfd;
|
me.displays[index] = mfd;
|
||||||
return index;
|
return index;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
# Add a PFD, optionally setting the index. Returns the index of the PFD.
|
||||||
|
addPFD : func(index=nil, targetcanvas=nil, screenObject=nil) {
|
||||||
|
|
||||||
|
if (index == nil) {
|
||||||
|
index = size(keys(me.displays));
|
||||||
|
} else if (me.displays[index] != nil) {
|
||||||
|
print("FG1000 Index " ~ index ~ " already exists!");
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetcanvas == nil) {
|
||||||
|
targetcanvas = canvas.new({
|
||||||
|
"name" : "PFD Canvas",
|
||||||
|
"size" : [1024, 768],
|
||||||
|
"view" : [1024, 768],
|
||||||
|
"mipmapping": 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var pfd = fg1000.PFDDisplay.new(me, me.EIS_Class, me.EIS_SVG, targetcanvas, index);
|
||||||
|
me.displays[index] = pfd;
|
||||||
|
return index;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
display : func(index, target_object=nil) {
|
display : func(index, target_object=nil) {
|
||||||
if (me.displays[index] == nil) {
|
if (me.displays[index] == nil) {
|
||||||
print("displayMFD: unknown display index " ~ index);
|
print("displayMFD: unknown display index " ~ index);
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
var GenericADCPublisher =
|
var GenericADCPublisher =
|
||||||
{
|
{
|
||||||
|
|
||||||
new : func (frequency=0.5) {
|
new : func (frequency=0.2) {
|
||||||
var obj = {
|
var obj = {
|
||||||
parents : [
|
parents : [
|
||||||
GenericADCPublisher,
|
GenericADCPublisher,
|
||||||
|
@ -38,7 +38,24 @@ var GenericADCPublisher =
|
||||||
};
|
};
|
||||||
|
|
||||||
obj.addPropMap("ADCTrueAirspeed", "/instrumentation/airspeed-indicator/true-speed-kt");
|
obj.addPropMap("ADCTrueAirspeed", "/instrumentation/airspeed-indicator/true-speed-kt");
|
||||||
|
obj.addPropMap("ADCIndicatedAirspeed", "/instrumentation/airspeed-indicator/indicated-speed-kt");
|
||||||
|
|
||||||
|
obj.addPropMap("ADCPitchDeg", "/instrumentation/attitude-indicator/indicated-pitch-deg");
|
||||||
|
obj.addPropMap("ADCRollDeg", "/instrumentation/attitude-indicator/indicated-roll-deg");
|
||||||
|
obj.addPropMap("ADCTurnRate", "/instrumentation/turn-indicator/indicated-turn-rate");
|
||||||
|
obj.addPropMap("ADCSlipSkid", "/instrumentation/slip-skid-ball/indicated-slip-skid");
|
||||||
|
|
||||||
|
# Assume an accurate solid-state compass
|
||||||
|
obj.addPropMap("ADCHeadingDeg", "/orientation/heading-deg");
|
||||||
|
|
||||||
|
obj.addPropMap("ADCAltitudeFT", "/instrumentation/altimeter/indicated-altitude-ft");
|
||||||
|
obj.addPropMap("ADCPressureSettingInHG", "/instrumentation/altimeter/setting-inhg");
|
||||||
|
|
||||||
|
obj.addPropMap("ADCVerticalSpeedFPM", "/instrumentation/vertical-speed-indicator/indicated-speed-fpm");
|
||||||
|
|
||||||
|
obj.addPropMap("ADCOutsideAirTemperatureC", "/environment/temperature-degc");
|
||||||
|
obj.addPropMap("ADCWindHeadingDeg", "/environment/wind-from-heading-deg");
|
||||||
|
obj.addPropMap("ADCWindSpeedKt", "/environment/wind-speed-kt");
|
||||||
return obj;
|
return obj;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,6 +26,9 @@ var GenericFMSPublisher =
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
obj.addPropMap("FMSHeadingBug", "/autopilot/settings/heading-bug-deg");
|
||||||
|
obj.addPropMap("FMSSelectedAlt", "/autopilot/settings/target-alt-ft");
|
||||||
|
|
||||||
obj.addPropMap("FMSLegBearing", "/instrumentation/gps/wp/wp[1]/bearing-mag-deg");
|
obj.addPropMap("FMSLegBearing", "/instrumentation/gps/wp/wp[1]/bearing-mag-deg");
|
||||||
obj.addPropMap("FMSLegCourseError", "/instrumentation/gps/wp/wp[1]/course-error-nm");
|
obj.addPropMap("FMSLegCourseError", "/instrumentation/gps/wp/wp[1]/course-error-nm");
|
||||||
obj.addPropMap("FMSLegDesiredTrack", "/instrumentation/gps/indicated-track-magnetic-deg");
|
obj.addPropMap("FMSLegDesiredTrack", "/instrumentation/gps/indicated-track-magnetic-deg");
|
||||||
|
@ -34,6 +37,9 @@ var GenericFMSPublisher =
|
||||||
obj.addPropMap("FMSGroundspeed", "/instrumentation/gps/indicated-ground-speed-kt");
|
obj.addPropMap("FMSGroundspeed", "/instrumentation/gps/indicated-ground-speed-kt");
|
||||||
obj.addPropMap("FMSWayPointCourseError", "/instrumentation/gps/wp/wp[1]/course-error-nm");
|
obj.addPropMap("FMSWayPointCourseError", "/instrumentation/gps/wp/wp[1]/course-error-nm");
|
||||||
|
|
||||||
|
obj.addPropMap("FMSNav1From", "/instrumentation/nav/from-flag");
|
||||||
|
obj.addPropMap("FMSNav2From", "/instrumentation/nav[1]/from-flag");
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,11 @@ var PropMap = {
|
||||||
|
|
||||||
getName : func() { return me._name; },
|
getName : func() { return me._name; },
|
||||||
getPropPath : func() { return me._prop.getPath(); },
|
getPropPath : func() { return me._prop.getPath(); },
|
||||||
getValue : func() { return me._prop.getValue(); },
|
getValue : func() {
|
||||||
|
var val = me._prop.getValue();
|
||||||
|
if (val == nil) val = 0;
|
||||||
|
return val;
|
||||||
|
},
|
||||||
getProp: func() { return me._prop; },
|
getProp: func() { return me._prop; },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -67,12 +67,12 @@ foreach (var page; MFDPages) {
|
||||||
io.load_nasal(nasal_dir ~ "MFDPages/" ~ page ~ '/' ~ page ~ 'Controller.nas', "fg1000");
|
io.load_nasal(nasal_dir ~ "MFDPages/" ~ page ~ '/' ~ page ~ 'Controller.nas', "fg1000");
|
||||||
}
|
}
|
||||||
|
|
||||||
var MFD =
|
var MFDDisplay =
|
||||||
{
|
{
|
||||||
new : func (fg1000instance, EIS_Class, EIS_SVG, myCanvas, device_id=1)
|
new : func (fg1000instance, EIS_Class, EIS_SVG, myCanvas, device_id=1)
|
||||||
{
|
{
|
||||||
var obj = {
|
var obj = {
|
||||||
parents : [ MFD ],
|
parents : [ MFDDisplay ],
|
||||||
EIS : nil,
|
EIS : nil,
|
||||||
NavigationMap: nil,
|
NavigationMap: nil,
|
||||||
Surround : nil,
|
Surround : nil,
|
||||||
|
|
|
@ -40,8 +40,9 @@ new : func (mfd, myCanvas, device, SVGGroup, pageName, title)
|
||||||
_group : myCanvas.createGroup(pageName ~ "Layer"),
|
_group : myCanvas.createGroup(pageName ~ "Layer"),
|
||||||
_SVGGroup : SVGGroup,
|
_SVGGroup : SVGGroup,
|
||||||
parents : [ MFDPage, device.addPage(title, pageName ~ "Group") ],
|
parents : [ MFDPage, device.addPage(title, pageName ~ "Group") ],
|
||||||
_symbols : {},
|
_textElements : {},
|
||||||
_controller : nil,
|
_controller : nil,
|
||||||
|
_elements : {},
|
||||||
};
|
};
|
||||||
|
|
||||||
obj.device = device;
|
obj.device = device;
|
||||||
|
@ -60,32 +61,64 @@ new : func (mfd, myCanvas, device, SVGGroup, pageName, title)
|
||||||
return obj;
|
return obj;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
addElement : func(e) {
|
||||||
|
if (me._elements[e] == nil) {
|
||||||
|
var element = me._SVGGroup.getElementById(me.pageName ~ e);
|
||||||
|
if (element != nil) {
|
||||||
|
me._elements[e] = element;
|
||||||
|
} else {
|
||||||
|
die("Unable to find element " ~ me.pageName ~ e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
die("Element already exists: "~ me.pageName ~ e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addElements : func(elements) {
|
||||||
|
foreach (var e; elements) {
|
||||||
|
me.addElement(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getElement : func(e) {
|
||||||
|
if (me._elements[e] == nil) me.addElement(e);
|
||||||
|
return me._elements[e];
|
||||||
|
},
|
||||||
|
|
||||||
addTextElements : func(symbols) {
|
addTextElements : func(symbols) {
|
||||||
foreach (var s; symbols) {
|
foreach (var s; symbols) {
|
||||||
me._symbols[s] = PFD.TextElement.new(me.pageName, me._SVGGroup, s);
|
me._textElements[s] = PFD.TextElement.new(me.pageName, me._SVGGroup, s);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addTextElement : func(e) {
|
||||||
|
if (me._textElements[e] == nil) {
|
||||||
|
me._textElements[e] = PFD.TextElement.new(me.pageName, me._SVGGroup, e);
|
||||||
|
} else {
|
||||||
|
die("addTextElement element already exists: "~ me.pageName ~ e);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getTextElement : func(symbolName) {
|
getTextElement : func(symbolName) {
|
||||||
return me._symbols[symbolName];
|
return me._textElements[symbolName];
|
||||||
},
|
},
|
||||||
|
|
||||||
highlightTextElement : func(symbolName) {
|
highlightTextElement : func(symbolName) {
|
||||||
me._symbols[symbolName].highlightElement();
|
me._textElements[symbolName].highlightElement();
|
||||||
},
|
},
|
||||||
|
|
||||||
unhighlightTextElement : func(symbolName) {
|
unhighlightTextElement : func(symbolName) {
|
||||||
me._symbols[symbolName].unhighlightElement();
|
me._textElements[symbolName].unhighlightElement();
|
||||||
},
|
},
|
||||||
|
|
||||||
getTextValue : func(symbolName) {
|
getTextValue : func(symbolName) {
|
||||||
var sym = me._symbols[symbolName];
|
var sym = me._textElements[symbolName];
|
||||||
assert(sym != nil, "Unknown text element " ~ symbolName ~ " (check your addTextElements call?)");
|
assert(sym != nil, "Unknown text element " ~ symbolName ~ " (check your addTextElements call?)");
|
||||||
return sym.getValue();
|
return sym.getValue();
|
||||||
},
|
},
|
||||||
|
|
||||||
setTextElement : func(symbolName, value) {
|
setTextElement : func(symbolName, value) {
|
||||||
var sym = me._symbols[symbolName];
|
var sym = me._textElements[symbolName];
|
||||||
assert(sym != nil, "Unknown text element " ~ symbolName ~ " (check your addTextElements call?)");
|
assert(sym != nil, "Unknown text element " ~ symbolName ~ " (check your addTextElements call?)");
|
||||||
if (value == nil ) value = "";
|
if (value == nil ) value = "";
|
||||||
sym.setValue(value);
|
sym.setValue(value);
|
||||||
|
|
|
@ -0,0 +1,574 @@
|
||||||
|
# Copyright 2018 Stuart Buchanan
|
||||||
|
# This file is part of FlightGear.
|
||||||
|
#
|
||||||
|
# Foobar 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 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# FlightGear 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 FlightGear. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# PFDInstruments
|
||||||
|
var PFDInstruments =
|
||||||
|
{
|
||||||
|
|
||||||
|
COLORS : {
|
||||||
|
green : [0, 1, 0],
|
||||||
|
white : [1, 1, 1],
|
||||||
|
black : [0, 0, 0],
|
||||||
|
lightblue : [0, 1, 1],
|
||||||
|
darkblue : [0, 0, 1],
|
||||||
|
red : [1, 0, 0],
|
||||||
|
magenta : [1, 0, 1],
|
||||||
|
},
|
||||||
|
|
||||||
|
new : func (mfd, myCanvas, device, svg)
|
||||||
|
{
|
||||||
|
var obj = {
|
||||||
|
parents : [
|
||||||
|
PFDInstruments,
|
||||||
|
MFDPage.new(mfd, myCanvas, device, svg, "PFDInstruments", "PFD Instruments")
|
||||||
|
],
|
||||||
|
|
||||||
|
_ias_already_exceeded : 0,
|
||||||
|
_windDataDisplay : 0,
|
||||||
|
_CDISource : "OFF",
|
||||||
|
_BRG1 : "OFF",
|
||||||
|
_BRG2 : "OFF",
|
||||||
|
_DME : 0,
|
||||||
|
_OMI : "",
|
||||||
|
_Map : 0,
|
||||||
|
_Multiline : 0,
|
||||||
|
_annunciation : 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
# Hide various elements for the moment. TODO - implement
|
||||||
|
obj.device.svg.getElementById("PFDInstrumentsFailures").setVisible(0);
|
||||||
|
obj.device.svg.getElementById("PFDInstrumentsGSPD").setVisible(0);
|
||||||
|
|
||||||
|
obj.addTextElements([
|
||||||
|
"Speed110",
|
||||||
|
"VSIText",
|
||||||
|
"TAS-text", "GSPD-text",
|
||||||
|
"Alt11100",
|
||||||
|
"AltBigC", "AltSmallC",
|
||||||
|
"BARO-text", "OAT-text",
|
||||||
|
"HDG-text",
|
||||||
|
"SelectedHDG-text",
|
||||||
|
"SelectedALT-text",
|
||||||
|
]);
|
||||||
|
|
||||||
|
# Set clipping for the various tapes
|
||||||
|
var clips = {
|
||||||
|
PitchScale : "rect(70,664,370,256)",
|
||||||
|
SpeedLint1 : "rect(252,226,318,204)",
|
||||||
|
SpeedTape : "rect(115,239,455,156)",
|
||||||
|
LintAlt : "rect(115,808,455,704)",
|
||||||
|
AltLint00011 : "rect(252,804,318,771)",
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach(var id; keys(clips)) {
|
||||||
|
var clip = clips[id];
|
||||||
|
obj.device.svg.getElementById("PFDInstruments" ~ id).set("clip", clip);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
obj.topMenu(device, obj, nil);
|
||||||
|
|
||||||
|
obj.setController(fg1000.PFDInstrumentsController.new(obj, svg));
|
||||||
|
obj.setWindDisplay(0);
|
||||||
|
obj.setCDISource("OFF");
|
||||||
|
obj.setBRG1("OFF");
|
||||||
|
obj.setBRG2("OFF");
|
||||||
|
obj.setDME(0);
|
||||||
|
obj.setMap(0);
|
||||||
|
obj.setMultiline(0);
|
||||||
|
obj.setAnnunciation(0);
|
||||||
|
obj.setOMI("");
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
offdisplay : func() {
|
||||||
|
me._group.setVisible(0);
|
||||||
|
|
||||||
|
# Reset the menu colours. Shouldn't have to do this here, but
|
||||||
|
# there's not currently an obvious other location to do so.
|
||||||
|
for(var i = 0; i < 12; i +=1) {
|
||||||
|
var name = sprintf("SoftKey%d",i);
|
||||||
|
me.device.svg.getElementById(name ~ "-bg").setColorFill(0.0,0.0,0.0);
|
||||||
|
me.device.svg.getElementById(name).setColor(1.0,1.0,1.0);
|
||||||
|
}
|
||||||
|
me.getController().offdisplay();
|
||||||
|
},
|
||||||
|
ondisplay : func() {
|
||||||
|
me._group.setVisible(1);
|
||||||
|
me.mfd.setPageTitle(me.title);
|
||||||
|
me.getController().ondisplay();
|
||||||
|
},
|
||||||
|
topMenu : func(device, pg, menuitem) {
|
||||||
|
pg.clearMenu();
|
||||||
|
pg.resetMenuColors();
|
||||||
|
device.updateMenus();
|
||||||
|
},
|
||||||
|
|
||||||
|
updateAI: func(pitch, roll, slip) {
|
||||||
|
if (pitch > 80)
|
||||||
|
pitch = 80;
|
||||||
|
elsif (pitch < -80)
|
||||||
|
pitch = -80;
|
||||||
|
me.getElement("Horizon")
|
||||||
|
.setCenter(459, 282.8 - 6.849 * pitch)
|
||||||
|
.setRotation(-roll * D2R)
|
||||||
|
.setTranslation(0, pitch * 6.849);
|
||||||
|
me.getElement("bankPointer")
|
||||||
|
.setRotation(-roll * D2R);
|
||||||
|
me.getElement("SlipSkid")
|
||||||
|
.setTranslation(slip * 10, 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateIAS: func (ias, ias_trend) {
|
||||||
|
if (ias >= 10) {
|
||||||
|
me.setTextElement("Speed110", sprintf("% 2u",num(math.floor(ias/10))));
|
||||||
|
} else {
|
||||||
|
me.setTextElement("Speed110", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
me.getElement("SpeedLint1").setTranslation(0,(math.mod(ias,10) + (ias >= 10)*10) * 36);
|
||||||
|
me.getElement("SpeedTape").setTranslation(0,ias * 5.711);
|
||||||
|
|
||||||
|
ias_trend = math.clamp(ias_trend, -30, 30);
|
||||||
|
me.getElement("Airspeed-Trend-Indicator")
|
||||||
|
.setScale(1,ias_trend)
|
||||||
|
.setTranslation(0, -284.5 * (ias_trend - 1));
|
||||||
|
|
||||||
|
var vne = me.mfd.ConfigStore.get("Vne");
|
||||||
|
|
||||||
|
if (ias > vne and ! me._ias_already_exceeded) {
|
||||||
|
me._ias_already_exceeded = 1;
|
||||||
|
me.getElement("IAS-bg").setColorFill(1,0,0);
|
||||||
|
} elsif (ias < vne and me._ias_already_exceeded) {
|
||||||
|
me._ias_already_exceeded = 0;
|
||||||
|
me.getElement("IAS-bg").setColorFill(0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var v; ["Vx", "Vy", "Vr", "Vglide"]) {
|
||||||
|
var spd = me.mfd.ConfigStore.get(v);
|
||||||
|
var visible = me.mfd.ConfigStore.get(v ~ "-visible");
|
||||||
|
if (visible and abs(spd - ias) < 30) {
|
||||||
|
me.getElement("IAS-" ~ v)
|
||||||
|
.setTranslation(0, (ias - spd) * 5.711)
|
||||||
|
.show();
|
||||||
|
} else {
|
||||||
|
me.getElement("IAS-" ~ v).hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateVSI: func (vsi) {
|
||||||
|
me.getElement("VSI").setTranslation(0, math.clamp(vsi, -4500, 4500) * -0.03465);
|
||||||
|
me.setTextElement("VSIText", num(math.round(vsi, 10)));
|
||||||
|
},
|
||||||
|
|
||||||
|
updateTAS: func (tas) {
|
||||||
|
me.setTextElement("TAS-text", sprintf("%iKT", tas));
|
||||||
|
#me.getElement("GSPD-text").setText(sprintf("%iKT", tas));
|
||||||
|
},
|
||||||
|
|
||||||
|
updateALT: func (alt, alt_trend, selected_alt) {
|
||||||
|
if (alt < 0) {
|
||||||
|
me.setTextElement("Alt11100", sprintf("-% 3i",abs(math.ceil(alt/100))));
|
||||||
|
} elsif (alt < 100) {
|
||||||
|
me.setTextElement("Alt11100", "");
|
||||||
|
} else {
|
||||||
|
me.setTextElement("Alt11100", sprintf("% 3i",math.floor(alt/100)));
|
||||||
|
}
|
||||||
|
|
||||||
|
me.getElement("AltLint00011").setTranslation(0,math.fmod(alt,100) * 1.24);
|
||||||
|
|
||||||
|
if (alt> -1000 and alt< 1000000) {
|
||||||
|
var Offset10 = 0;
|
||||||
|
var Offset100 = 0;
|
||||||
|
var Offset1000 = 0;
|
||||||
|
var Ne = 0;
|
||||||
|
var Alt10 = math.mod(alt,100);
|
||||||
|
var Alt100 = int(math.mod(alt/100,10));
|
||||||
|
var Alt1000 = int(math.mod(alt/1000,10));
|
||||||
|
var Alt10000 = int(math.mod(alt/10000,10));
|
||||||
|
var Alt20 = math.mod(Alt10,20)/20;
|
||||||
|
|
||||||
|
|
||||||
|
if (alt< 0) {
|
||||||
|
var Ne = 1;
|
||||||
|
var alt= -alt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Alt10 >= 80) Alt100 += Alt20;
|
||||||
|
if (Alt10 >= 80 and Alt100 >= 9) Alt1000 += Alt20;
|
||||||
|
if (Alt10 >= 80 and Alt100 >= 9 and Alt1000 >= 9) Alt10000 += Alt20;
|
||||||
|
if (alt> 100) Offset10 = 100;
|
||||||
|
if (alt> 1000) Offset100 = 10;
|
||||||
|
if (alt> 10000) Offset1000 = 10;
|
||||||
|
|
||||||
|
if (Ne) {
|
||||||
|
me.getElement("LintAlt").setTranslation(0,(math.mod(alt,100))*-0.57375);
|
||||||
|
var altCentral = -(int(alt/100)*100);
|
||||||
|
} else {
|
||||||
|
me.getElement("LintAlt").setTranslation(0,(math.mod(alt,100))*0.57375);
|
||||||
|
var altCentral = (int(alt/100)*100);
|
||||||
|
}
|
||||||
|
|
||||||
|
me.setTextElement("AltBigC", "");
|
||||||
|
me.setTextElement("AltSmallC", "");
|
||||||
|
for (var place = 1; place <= 6; place += 1) {
|
||||||
|
var altUP = altCentral + (place*100);
|
||||||
|
var altDOWN = altCentral - (place*100);
|
||||||
|
var offset = -30.078;
|
||||||
|
var prefix = "";
|
||||||
|
|
||||||
|
if (altUP < 0) {
|
||||||
|
altUP = -altUP;
|
||||||
|
prefix = "-";
|
||||||
|
offset += 15.039;
|
||||||
|
}
|
||||||
|
var AltBigUP = "";
|
||||||
|
var AltSmallUP = "0";
|
||||||
|
|
||||||
|
if (altUP == 0) {
|
||||||
|
AltBigUP = "";
|
||||||
|
AltSmallUP = "0";
|
||||||
|
} elsif (math.mod(altUP,500) == 0 and altUP != 0) {
|
||||||
|
AltBigUP = sprintf(prefix~"%1d", altUP);
|
||||||
|
AltSmallUP = "";
|
||||||
|
} elsif (altUP < 1000 and (math.mod(altUP,500))) {
|
||||||
|
AltBigUP = "";
|
||||||
|
AltSmallUP = sprintf(prefix~"%1d", int(math.mod(altUP,1000)));
|
||||||
|
offset = -30.078;
|
||||||
|
} elsif ((altUP < 10000) and (altUP >= 1000) and (math.mod(altUP,500))) {
|
||||||
|
AltBigUP = sprintf(prefix~"%1d", int(altUP/1000));
|
||||||
|
AltSmallUP = sprintf("%1d", int(math.mod(altUP,1000)));
|
||||||
|
offset += 15.039;
|
||||||
|
} else {
|
||||||
|
AltBigUP = sprintf(prefix~"%1d", int(altUP/1000));
|
||||||
|
mod = int(math.mod(altUP,1000));
|
||||||
|
AltSmallUP = sprintf("%1d", mod);
|
||||||
|
offset += 30.078;
|
||||||
|
}
|
||||||
|
|
||||||
|
me.getElement("AltBigU"~place).setText(AltBigUP);
|
||||||
|
me.getElement("AltSmallU"~place).setText(AltSmallUP);
|
||||||
|
me.getElement("AltSmallU"~place).setTranslation(offset,0);
|
||||||
|
|
||||||
|
offset = -30.078;
|
||||||
|
prefix = "";
|
||||||
|
if (altDOWN < 0) {
|
||||||
|
altDOWN = -altDOWN;
|
||||||
|
prefix = "-";
|
||||||
|
offset += 15.039;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (altDOWN == 0) {
|
||||||
|
AltBigDOWN = "";
|
||||||
|
AltSmallDOWN = "0";
|
||||||
|
} elsif (math.mod(altDOWN,500) == 0 and altDOWN != 0) {
|
||||||
|
AltBigDOWN = sprintf(prefix~"%1d", altDOWN);
|
||||||
|
AltSmallDOWN = "";
|
||||||
|
} elsif (altDOWN < 1000 and (math.mod(altDOWN,500))) {
|
||||||
|
AltBigDOWN = "";
|
||||||
|
AltSmallDOWN = sprintf(prefix~"%1d", int(math.mod(altDOWN,1000)));
|
||||||
|
offset = -30.078;
|
||||||
|
} elsif ((altDOWN < 10000) and (altDOWN >= 1000) and (math.mod(altDOWN,500))) {
|
||||||
|
AltBigDOWN = sprintf(prefix~"%1d", int(altDOWN/1000));
|
||||||
|
AltSmallDOWN = sprintf("%1d", int(math.mod(altDOWN,1000)));
|
||||||
|
offset += 15.039;
|
||||||
|
} else {
|
||||||
|
AltBigDOWN = sprintf(prefix~"%1d", int(altDOWN/1000));
|
||||||
|
AltSmallDOWN = sprintf("%1d", int(math.mod(altDOWN,1000)));
|
||||||
|
offset += 30.078;
|
||||||
|
}
|
||||||
|
|
||||||
|
me.getElement("AltBigD"~place).setText(AltBigDOWN);
|
||||||
|
me.getElement("AltSmallD"~place).setText(AltSmallDOWN);
|
||||||
|
me.getElement("AltSmallD"~place).setTranslation(offset,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
alt_trend = math.clamp(alt_trend, -15, 15);
|
||||||
|
me.getElement("Altitude-Trend-Indicator")
|
||||||
|
.setScale(1,alt_trend)
|
||||||
|
.setTranslation(0, -284.5 * (alt_trend - 1));
|
||||||
|
|
||||||
|
var delta_alt = alt - selected_alt;
|
||||||
|
delta_alt = math.clamp(delta_alt, -300, 300);
|
||||||
|
me.getElement("SelectedALT-bug").setTranslation(0, delta_alt * 0.567); # 170/300 = 0.567
|
||||||
|
},
|
||||||
|
|
||||||
|
updateBARO : func (baro) {
|
||||||
|
# TODO: Support hPa and inhg
|
||||||
|
#var fmt = me._baro_unit == "inhg" ? "%.2fin" : "%i%shPa";
|
||||||
|
var fmt = "%.2fin";
|
||||||
|
me.setTextElement("BARO-text", sprintf(fmt, baro));
|
||||||
|
},
|
||||||
|
|
||||||
|
updateOAT : func (oat) {
|
||||||
|
# TODO: Support FAHRENHEIT
|
||||||
|
me.setTextElement("OAT-text", sprintf((abs(oat) < 10) ? "%.1f %s" : "%i %s", oat, "°C"));
|
||||||
|
},
|
||||||
|
|
||||||
|
updateHSI : func (hdg) {
|
||||||
|
me.getElement("Rose").setRotation(-hdg * D2R);
|
||||||
|
me.setTextElement("HDG-text", sprintf("%03u°", hdg));
|
||||||
|
},
|
||||||
|
|
||||||
|
updateHDG : func (hdg) {
|
||||||
|
if (hdg == nil)
|
||||||
|
me.getElement("Heading-bug").setRotation(hdg * D2R);
|
||||||
|
me.setTextElement("SelectedHDG-text", sprintf("%03d°%s", hdg, ""));
|
||||||
|
},
|
||||||
|
|
||||||
|
# Indicate the selected course, from a given source (OFF, NAV, GPS)
|
||||||
|
updateCRS : func (crs) {
|
||||||
|
me.getElement("SelectedCRS-text")
|
||||||
|
.setText(sprintf("%03d°%s", crs, ""))
|
||||||
|
.setColor(me._CDISource == "GPS" ? me.COLORS.magenta : me.COLORS.green);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateSelectedALT : func (selected_alt) {
|
||||||
|
me.setTextElement("SelectedALT-text", sprintf("%i", selected_alt));
|
||||||
|
},
|
||||||
|
|
||||||
|
# Bearing (BRG) settings
|
||||||
|
# "OFF", "NAV1", "NAV2", "GPS", "ADF"
|
||||||
|
getBRG1 : func() { return me._BRG1; },
|
||||||
|
getBRG2 : func() { return me._BRG2; },
|
||||||
|
|
||||||
|
setBRG1 : func(option) {
|
||||||
|
me._BRG1 = option;
|
||||||
|
me._setBRG("BRG1",option);
|
||||||
|
},
|
||||||
|
setBRG2 : func(option) {
|
||||||
|
me._BRG2 = option;
|
||||||
|
me._setBRG("BRG2",option);
|
||||||
|
},
|
||||||
|
_setBRG : func (brg, option) {
|
||||||
|
if (option == "OFF") {
|
||||||
|
me.getElement(brg).hide();
|
||||||
|
me.getElement(brg ~ "-pointer").hide();
|
||||||
|
if ((me._BRG1 == "OFF") and (me._BRG1 == "OFF")) {
|
||||||
|
me.getElement("BRG-circle").hide();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
me.getElement(brg).show();
|
||||||
|
me.getElement(brg ~ "-pointer").show();
|
||||||
|
me.getElement("BRG-circle").show();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
# Update BRG information
|
||||||
|
updateBRG1 : func(id, dst) {
|
||||||
|
me._updateBRG("BRG1", me._BRG1, id, dst);
|
||||||
|
},
|
||||||
|
updateBRG2 : func(id, dst) {
|
||||||
|
me._updateBRG("BRG2", me._BRG2, id, dst);
|
||||||
|
},
|
||||||
|
_updateBRG : func (brg, source, id, dst) {
|
||||||
|
if (source == "OFF") return;
|
||||||
|
|
||||||
|
me.getElement(brg ~ "-SRC-text").setText(source);
|
||||||
|
me.getElement(brg ~ "-WP-text").setText(id);
|
||||||
|
|
||||||
|
if (source == "ADF") {
|
||||||
|
# Special case. We won't have a distance and the "ID" will be the ADF
|
||||||
|
# frequency
|
||||||
|
me.getElement(brg ~ "-DST-text").setText("");
|
||||||
|
} else {
|
||||||
|
me.getElement(brg ~ "-DST-text").setText(sprintf("%.1fNM", dst));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setDME : func (enabled) {
|
||||||
|
me._DME = enabled;
|
||||||
|
me.getElement("DME1").setVisible(enabled);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateDME : func (mode, freq, dst) {
|
||||||
|
if (me._DME == 0) return;
|
||||||
|
me.getElement("DME1-SRC-text").setText(mode);
|
||||||
|
me.getElement("DME1-FREQ-text").setText(sprintf("%.2f", freq));
|
||||||
|
me.getElement("DME1-DST-text").setText(sprintf("%.2fNM", dst));
|
||||||
|
},
|
||||||
|
|
||||||
|
setCDISource : func(source) {
|
||||||
|
if (source == "OFF") {
|
||||||
|
foreach (var s; ["GPS", "NAV1", "NAV2"]) {
|
||||||
|
foreach (var t; ["pointer", "CDI", "FROM", "TO"]) {
|
||||||
|
me.getElement(s ~ "-" ~ t).hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
me.getElement("CDI-GPS-ANN-text").hide();
|
||||||
|
me.getElement("CDI-GPS-XTK-text").hide();
|
||||||
|
me.getElement("CDI-SRC-text").hide();
|
||||||
|
me.getElement("CDI").hide();
|
||||||
|
me.getElement("GPS-CTI-diamond").hide();
|
||||||
|
me.getElement("SelectedCRS").hide();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
me.getElement("CDI").show();
|
||||||
|
me.getElement("SelectedCRS").show();
|
||||||
|
|
||||||
|
if (source == "GPS") {
|
||||||
|
me.getElement("CDI-GPS-ANN-text").show();
|
||||||
|
me.getElement("GPS-CTI-diamond").show();
|
||||||
|
} else {
|
||||||
|
me.getElement("CDI-GPS-ANN-text").hide();
|
||||||
|
me.getElement("GPS-CTI-diamond").hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Localizers are mapped to the NAV1/2 elements, but have reduced deflection
|
||||||
|
# and a different label.
|
||||||
|
me.getElement("CDI-SRC-text")
|
||||||
|
.setText(source)
|
||||||
|
.setColor(source == "GPS" ? me.COLORS.magenta : me.COLORS.green)
|
||||||
|
.show();
|
||||||
|
|
||||||
|
if (source == "LOC1") source = "NAV1";
|
||||||
|
if (source == "LOC2") source = "NAV2";
|
||||||
|
|
||||||
|
foreach (var s; ["GPS", "NAV1", "NAV2"]) {
|
||||||
|
me.getElement(s ~ "-pointer").setVisible(source == s);
|
||||||
|
me.getElement(s ~ "-CDI").setVisible(source == s);
|
||||||
|
me.getElement(s ~ "-FROM").setVisible(source == s);
|
||||||
|
me.getElement(s ~ "-TO").setVisible(source == s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
me._CDISource = source;
|
||||||
|
},
|
||||||
|
|
||||||
|
updateCDI : func (heading, course, waypoint_valid, course_deviation_deg, deflection_dots, xtrk_nm, from) {
|
||||||
|
if (me._CDISource == "OFF") return;
|
||||||
|
|
||||||
|
var rot = (course - heading) * D2R;
|
||||||
|
me.getElement("CDI")
|
||||||
|
.setRotation(rot)
|
||||||
|
.show();
|
||||||
|
me.getElement("GPS-CTI-diamond")
|
||||||
|
.setVisible(waypoint_valid)
|
||||||
|
.setRotation(course_deviation_deg * D2R);
|
||||||
|
|
||||||
|
if ((me._CDISource == "GPS") and (deflection_dots > 2)) {
|
||||||
|
# Only display the cross-track error if the error exceeds the maximum
|
||||||
|
# deflection of two dots.
|
||||||
|
me.getElement("CDI-GPS-XTK-text")
|
||||||
|
.setText(sprintf("XTK %iNM", abs(xtrk_nm)))
|
||||||
|
.show();
|
||||||
|
} else {
|
||||||
|
me.getElement("CDI-GPS-XTK-text").hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
var scale = math.clamp(deflection_dots, -2.4, 2.4);
|
||||||
|
me.getElement(me._CDISource ~ "-CDI").setTranslation(65 * scale, 0);
|
||||||
|
|
||||||
|
# Display the appropriate TO/FROM indication for the selected source,
|
||||||
|
# switching all others off.
|
||||||
|
me.getElement(me._CDISource ~ "-TO").setVisible(from == 0);
|
||||||
|
me.getElement(me._CDISource ~ "-FROM").setVisible(from);
|
||||||
|
},
|
||||||
|
|
||||||
|
# Update the wind display. There are three options:
|
||||||
|
# -1 - Data invalid
|
||||||
|
# 0 - No wind data displayed
|
||||||
|
# 1 - Numeric headwind and crosswind components
|
||||||
|
# 2 - Direction arrow and numeric speed
|
||||||
|
# 3 - Direction arrow, and numeric True direction and speet
|
||||||
|
setWindDisplay : func(option) {
|
||||||
|
me.getElement("WindData").setVisible(option != 0);
|
||||||
|
me.getElement("WindData-NODATA").setVisible(option == -1);
|
||||||
|
me.getElement("WindData-OPTN1").setVisible(option == 1);
|
||||||
|
me.getElement("WindData-OPTN2").setVisible(option == 2);
|
||||||
|
me.getElement("WindData-OPTN3").setVisible(option == 3);
|
||||||
|
|
||||||
|
me._windDataDisplay = option;
|
||||||
|
},
|
||||||
|
|
||||||
|
updateWindData : func (hdg, wind_hdg, wind_spd) {
|
||||||
|
if ((me._windDataDisplay == -1) or (me._windDataDisplay == 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (me._windDataDisplay == 1) {
|
||||||
|
# Headwind/Crosswind numeric display
|
||||||
|
var alpha = (wind_hdg - hdg) * D2R;
|
||||||
|
var Vt = wind_spd * math.sin(alpha);
|
||||||
|
var Ve = wind_spd * math.cos(alpha);
|
||||||
|
if (Vt != 0) {
|
||||||
|
me.getElement("WindData-OPTN1-crosswind-text").setText(sprintf("%i", abs(Vt)));
|
||||||
|
me.getElement("WindData-OPTN1-crosswind")
|
||||||
|
.setScale(-abs(Vt)/Vt, 1)
|
||||||
|
.setTranslation(-35 * (abs(Vt)/Vt + 1), 0);
|
||||||
|
} else {
|
||||||
|
me.getElement("WindData-OPTN1-crosswind-text").setText("0");
|
||||||
|
me.getElement("WindData-OPTN1-crosswind")
|
||||||
|
.setScale(1, 1)
|
||||||
|
.setTranslation(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Ve != 0) {
|
||||||
|
me.getElement("WindData-OPTN1-headwind-text").setText(sprintf("%i", abs(Ve)));
|
||||||
|
me.getElement("WindData-OPTN1-headwind")
|
||||||
|
.setScale(1, abs(Ve)/Ve)
|
||||||
|
.setTranslation(0, 515 * (1 - abs(Ve)/Ve));
|
||||||
|
} else {
|
||||||
|
me.getElement("WindData-OPTN1-headwind-text").setText("0");
|
||||||
|
me.getElement("WindData-OPTN1-headwind")
|
||||||
|
.setScale(1, 1)
|
||||||
|
.setTranslation(0, 0);
|
||||||
|
}
|
||||||
|
} elsif (me._windDataDisplay == 2) {
|
||||||
|
# Direction arrow and numeric speed
|
||||||
|
me.getElement("WindData-OPTN2-HDG").setRotation((alpha + 180) * D2R);
|
||||||
|
me.getElement("WindData-OPTN2-SPD-text").setText(int(wind_spd));
|
||||||
|
} elsif (me._windDataDisplay == 3) {
|
||||||
|
# Direction arrow with numeric true direction and speed
|
||||||
|
me.getElement("WindData-OPTN3-HDG").setRotation((alpha + 180) * D2R);
|
||||||
|
me.getElement("WindData-OPTN3-HDG-text").setText(sprintf("%03i°T", wind_hdg));
|
||||||
|
me.getElement("WindData-OPTN3-SPD-text").setText(int(wind_spd) ~ "KT");
|
||||||
|
} else {
|
||||||
|
print("Unknown wind data option " ~ me._windDataDisplay);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
# Enable/disable the inset PFD Map.
|
||||||
|
setMap : func (enabled) {
|
||||||
|
me._Map = enabled;
|
||||||
|
me.getElement("PFD-Map").setVisible(enabled);
|
||||||
|
},
|
||||||
|
|
||||||
|
# Enable/disable the multiline display on the right hand side of the PFD
|
||||||
|
setMultiline : func(enabled) {
|
||||||
|
me._Multiline = enabled;
|
||||||
|
me.getElement("PFD-Multilines").setVisible(enabled);
|
||||||
|
},
|
||||||
|
|
||||||
|
# Enable/disable the warning annunication window.
|
||||||
|
setAnnunciation : func(enabled) {
|
||||||
|
me._annunciation = enabled;
|
||||||
|
me.getElement("Annunciation").setVisible(enabled);
|
||||||
|
},
|
||||||
|
|
||||||
|
# set the Outer, Middle, Inner indicator
|
||||||
|
setOMI : func(omi) {
|
||||||
|
if (omi == "") {
|
||||||
|
me.getElement("OMI").hide();
|
||||||
|
} else {
|
||||||
|
me.getElement("OMI").show();
|
||||||
|
me.getElement("MarkerText").setText(omi);
|
||||||
|
}
|
||||||
|
me._OMI = omi;
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,201 @@
|
||||||
|
# Copyright 2018 Stuart Buchanan
|
||||||
|
# This file is part of FlightGear.
|
||||||
|
#
|
||||||
|
# Foobar 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 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# FlightGear 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 FlightGear. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# PFDInstruments Controller
|
||||||
|
var PFDInstrumentsController =
|
||||||
|
{
|
||||||
|
new : func (page, svg)
|
||||||
|
{
|
||||||
|
var obj = {
|
||||||
|
parents : [ PFDInstrumentsController, MFDPageController.new(page) ],
|
||||||
|
_crsrToggle : 0,
|
||||||
|
_pfdrecipient : nil,
|
||||||
|
page : page,
|
||||||
|
_last_ias_kt : 0,
|
||||||
|
_last_alt_ft : 0,
|
||||||
|
_last_trend : systime(),
|
||||||
|
_selected_alt_ft : 0,
|
||||||
|
_heading : 0,
|
||||||
|
_source : "GPS",
|
||||||
|
};
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
# Input Handling
|
||||||
|
handleCRSR : func() {
|
||||||
|
me._crsrToggle = (! me._crsrToggle);
|
||||||
|
if (me._crsrToggle) {
|
||||||
|
} else {
|
||||||
|
me.page.hideCRSR();
|
||||||
|
}
|
||||||
|
return emesary.Transmitter.ReceiptStatus_Finished;
|
||||||
|
},
|
||||||
|
handleFMSInner : func(value) {
|
||||||
|
if (me._crsrToggle == 1) {
|
||||||
|
# Scroll through whatever is the current list
|
||||||
|
return emesary.Transmitter.ReceiptStatus_Finished;
|
||||||
|
} else {
|
||||||
|
# Pass to the page group controller to display and scroll through the page group menu
|
||||||
|
#return me.page.mfd.SurroundController.handleFMSInner(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleFMSOuter : func(value) {
|
||||||
|
if (me._crsrToggle == 1) {
|
||||||
|
return emesary.Transmitter.ReceiptStatus_Finished;
|
||||||
|
} else {
|
||||||
|
# Pass to the page group controller to display and scroll through the page group menu
|
||||||
|
#return me.page.mfd.SurroundController.handleFMSOuter(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleEnter : func(value) {
|
||||||
|
if (me._crsrToggle == 1) {
|
||||||
|
return emesary.Transmitter.ReceiptStatus_Finished;
|
||||||
|
} else {
|
||||||
|
return emesary.Transmitter.ReceiptStatus_NotProcessed;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
# Handle update of the airdata information.
|
||||||
|
# ADC data is produced periodically as an entire set
|
||||||
|
handleADCData : func(data) {
|
||||||
|
var ias = data["ADCIndicatedAirspeed"];
|
||||||
|
var alt = data["ADCAltitudeFT"];
|
||||||
|
# estimated speed and altitude in 6s
|
||||||
|
var now = systime();
|
||||||
|
var lookahead_ias_6sec = 6 * (ias - me._last_ias_kt) / (now - me._last_trend);
|
||||||
|
var lookahead_alt_6sec = .3 * (alt - me._last_alt_ft) / (now - me._last_trend); # scale = 1/20ft
|
||||||
|
me.page.updateIAS(ias, lookahead_ias_6sec);
|
||||||
|
me.page.updateALT(alt, lookahead_alt_6sec, me._selected_alt_ft);
|
||||||
|
me._last_ias_kt = ias;
|
||||||
|
me._last_alt_ft = alt;
|
||||||
|
me._last_trend = now;
|
||||||
|
|
||||||
|
var pitch = data["ADCPitchDeg"];
|
||||||
|
var roll = data["ADCRollDeg"];
|
||||||
|
var slip = data["ADCSlipSkid"];
|
||||||
|
me.page.updateAI(pitch, roll, slip);
|
||||||
|
|
||||||
|
me.page.updateVSI(data["ADCVerticalSpeedFPM"]);
|
||||||
|
me.page.updateTAS(data["ADCTrueAirspeed"]);
|
||||||
|
me.page.updateBARO(data["ADCPressureSettingInHG"]);
|
||||||
|
me.page.updateOAT(data["ADCOutsideAirTemperatureC"]);
|
||||||
|
me.page.updateHSI(data["ADCHeadingDeg"]);
|
||||||
|
me._heading = data["ADCHeadingDeg"];
|
||||||
|
|
||||||
|
me.page.updateWindData(
|
||||||
|
hdg : data["ADCHeadingDeg"],
|
||||||
|
wind_hdg : data["ADCWindHeadingDeg"],
|
||||||
|
wind_spd : data ["ADCWindSpeedKt"]
|
||||||
|
);
|
||||||
|
|
||||||
|
return emesary.Transmitter.ReceiptStatus_OK;
|
||||||
|
},
|
||||||
|
|
||||||
|
# Handle update to the FMS information.
|
||||||
|
handleFMSData : func(data) {
|
||||||
|
|
||||||
|
me.page.updateHDG(data["FMSHeadingBug"]);
|
||||||
|
me.page.updateSelectedALT(data["FMSSelectedAlt"]);
|
||||||
|
me._selected_alt_ft = data["FMSSelectedAlt"];
|
||||||
|
|
||||||
|
me.page.updateCRS(data["FMSLegBearing"]);
|
||||||
|
|
||||||
|
var from = 0;
|
||||||
|
if (me._navSelected == 1) {
|
||||||
|
from = data["FMSNav1From"];
|
||||||
|
} else {
|
||||||
|
from = data["FMSNav2From"];
|
||||||
|
}
|
||||||
|
|
||||||
|
me.page.updateCDI(
|
||||||
|
heading: me._heading,
|
||||||
|
course: data["FMSLegBearing"],
|
||||||
|
waypoint_valid: 1,
|
||||||
|
course_deviation_deg : data["FMSLegTrackErrorAngle"],
|
||||||
|
deflection_dots : data["FMSLegCourseError"], # TODO: proper conversion depending on source, environment
|
||||||
|
xtrk_nm : data["FMSLegCourseError"],
|
||||||
|
from: from,
|
||||||
|
);
|
||||||
|
|
||||||
|
return emesary.Transmitter.ReceiptStatus_OK;
|
||||||
|
},
|
||||||
|
|
||||||
|
# Handle update of the NavCom data.
|
||||||
|
# Note that this updated on a property by property basis, so we need to check
|
||||||
|
# that the data we want exists in this notification, unlike the periodic
|
||||||
|
# publishers
|
||||||
|
handleNavComData : func(data) {
|
||||||
|
if (data["NavSelected"] != nil) {
|
||||||
|
me._navSelected = data["NavSelected"];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
PFDRegisterWithEmesary : func(transmitter = nil){
|
||||||
|
if (transmitter == nil)
|
||||||
|
transmitter = emesary.GlobalTransmitter;
|
||||||
|
|
||||||
|
if (me._pfdrecipient == nil){
|
||||||
|
me._pfdrecipient = emesary.Recipient.new("PFDInstrumentsController_" ~ me._page.device.designation);
|
||||||
|
var pfd_obj = me._page.device;
|
||||||
|
var controller = me;
|
||||||
|
me._pfdrecipient.Receive = func(notification)
|
||||||
|
{
|
||||||
|
if (notification.NotificationType == notifications.PFDEventNotification.DefaultType and
|
||||||
|
notification.Event_Id == notifications.PFDEventNotification.ADCData and
|
||||||
|
notification.EventParameter != nil)
|
||||||
|
{
|
||||||
|
return controller.handleADCData(notification.EventParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notification.NotificationType == notifications.PFDEventNotification.DefaultType and
|
||||||
|
notification.Event_Id == notifications.PFDEventNotification.FMSData and
|
||||||
|
notification.EventParameter != nil)
|
||||||
|
{
|
||||||
|
return controller.handleFMSData(notification.EventParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notification.NotificationType == notifications.PFDEventNotification.DefaultType and
|
||||||
|
notification.Event_Id == notifications.PFDEventNotification.NavComData and
|
||||||
|
notification.EventParameter != nil)
|
||||||
|
{
|
||||||
|
return controller.handleNavComData(notification.EventParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return emesary.Transmitter.ReceiptStatus_NotProcessed;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
transmitter.Register(me._pfdrecipient);
|
||||||
|
me.transmitter = transmitter;
|
||||||
|
},
|
||||||
|
PFDDeRegisterWithEmesary : func(transmitter = nil){
|
||||||
|
# remove registration from transmitter; but keep the recipient once it is created.
|
||||||
|
if (me.transmitter != nil)
|
||||||
|
me.transmitter.DeRegister(me._pfdrecipient);
|
||||||
|
me.transmitter = nil;
|
||||||
|
},
|
||||||
|
|
||||||
|
# Reset controller if required when the page is displayed or hidden
|
||||||
|
ondisplay : func() {
|
||||||
|
me.RegisterWithEmesary();
|
||||||
|
me.PFDRegisterWithEmesary();
|
||||||
|
},
|
||||||
|
offdisplay : func() {
|
||||||
|
me.DeRegisterWithEmesary();
|
||||||
|
me.PFDDeRegisterWithEmesary();
|
||||||
|
},
|
||||||
|
};
|
|
@ -0,0 +1,44 @@
|
||||||
|
# Copyright 2018 Stuart Buchanan
|
||||||
|
# This file is part of FlightGear.
|
||||||
|
#
|
||||||
|
# Foobar 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 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# FlightGear 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 FlightGear. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# PFDInstruments Options
|
||||||
|
var PFDInstrumentsOptions =
|
||||||
|
{
|
||||||
|
new : func() {
|
||||||
|
var obj = { parents : [PFDInstrumentsOptions] };
|
||||||
|
obj.Options= {};
|
||||||
|
obj.loadOptions();
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
|
||||||
|
getOption : func(type) {
|
||||||
|
return me.Options[type];
|
||||||
|
},
|
||||||
|
|
||||||
|
setOption : func(type, name, value) {
|
||||||
|
me.Options[type][name] = value;
|
||||||
|
},
|
||||||
|
|
||||||
|
loadOptions : func() {
|
||||||
|
me.clearOptions();
|
||||||
|
me.Options.APS = {};
|
||||||
|
},
|
||||||
|
|
||||||
|
clearOptions : func() {
|
||||||
|
me.Options = {};
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
|
@ -0,0 +1,44 @@
|
||||||
|
# Copyright 2018 Stuart Buchanan
|
||||||
|
# This file is part of FlightGear.
|
||||||
|
#
|
||||||
|
# Foobar 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 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# FlightGear 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 FlightGear. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# PFDInstruments Styles
|
||||||
|
var PFDInstrumentsStyles =
|
||||||
|
{
|
||||||
|
new : func() {
|
||||||
|
var obj = { parents : [ PFDInstrumentsStyles ]};
|
||||||
|
obj.Styles = {};
|
||||||
|
obj.loadStyles();
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
|
||||||
|
getStyle : func(type) {
|
||||||
|
return me.Styles[type];
|
||||||
|
},
|
||||||
|
|
||||||
|
setStyle : func(type, name, value) {
|
||||||
|
me.Styles[type][name] = value;
|
||||||
|
},
|
||||||
|
|
||||||
|
loadStyles : func() {
|
||||||
|
me. clearStyles();
|
||||||
|
me.Styles.XXX = {};
|
||||||
|
},
|
||||||
|
|
||||||
|
clearStyles : func() {
|
||||||
|
me.Styles = {};
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
121
Aircraft/Instruments-3d/FG1000/Nasal/PFD.nas
Normal file
121
Aircraft/Instruments-3d/FG1000/Nasal/PFD.nas
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
# Copyright 2018 Stuart Buchanan
|
||||||
|
# This file is part of FlightGear.
|
||||||
|
#
|
||||||
|
# Foobar 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 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# FlightGear 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 FlightGear. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# FG1000 PFD
|
||||||
|
|
||||||
|
var PFDDisplay =
|
||||||
|
{
|
||||||
|
new : func (fg1000instance, EIS_Class, EIS_SVG, myCanvas, device_id=1)
|
||||||
|
{
|
||||||
|
var obj = {
|
||||||
|
parents : [ PFDDisplay ],
|
||||||
|
EIS : nil,
|
||||||
|
PFDInstruments : nil,
|
||||||
|
Surround : nil,
|
||||||
|
_pageList : {},
|
||||||
|
_fg1000 : fg1000instance,
|
||||||
|
_canvas : myCanvas,
|
||||||
|
};
|
||||||
|
|
||||||
|
var nasal_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/FG1000/Nasal/";
|
||||||
|
io.load_nasal(nasal_dir ~ "MFDPages/PFDInstruments/PFDInstruments.nas", "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ "MFDPages/PFDInstruments/PFDInstrumentsStyles.nas", "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ "MFDPages/PFDInstruments/PFDInstrumentsOptions.nas", "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ "MFDPages/PFDInstruments/PFDInstrumentsController.nas", "fg1000");
|
||||||
|
|
||||||
|
obj.ConfigStore = obj._fg1000.getConfigStore();
|
||||||
|
|
||||||
|
obj._svg = myCanvas.createGroup("softkeys");
|
||||||
|
obj._svg.set("clip-frame", canvas.Element.LOCAL);
|
||||||
|
obj._svg.set("clip", "rect(0px, 1024px, 768px, 0px)");
|
||||||
|
|
||||||
|
var fontmapper = func (family, weight) {
|
||||||
|
#if( family == "Liberation Sans" and weight == "narrow" ) {
|
||||||
|
return "LiberationFonts/LiberationSansNarrow-Regular.ttf";
|
||||||
|
#}
|
||||||
|
# If we don't return anything the default font is used
|
||||||
|
};
|
||||||
|
|
||||||
|
canvas.parsesvg(obj._svg,
|
||||||
|
EIS_SVG,
|
||||||
|
{'font-mapper': fontmapper});
|
||||||
|
|
||||||
|
canvas.parsesvg(obj._svg,
|
||||||
|
'/Aircraft/Instruments-3d/FG1000/MFDPages/PFDInstruments.svg',
|
||||||
|
{'font-mapper': fontmapper});
|
||||||
|
|
||||||
|
canvas.parsesvg(obj._svg,
|
||||||
|
'/Aircraft/Instruments-3d/FG1000/MFDPages/Surround.svg',
|
||||||
|
{'font-mapper': fontmapper});
|
||||||
|
|
||||||
|
obj._MFDDevice = canvas.PFD_Device.new(obj._svg, 12, "SoftKey", myCanvas, "PFD");
|
||||||
|
obj._MFDDevice.device_id = device_id;
|
||||||
|
obj._MFDDevice.RegisterWithEmesary();
|
||||||
|
|
||||||
|
# Surround dynamic elements
|
||||||
|
obj._pageTitle = obj._svg.getElementById("PageTitle");
|
||||||
|
|
||||||
|
# Controller for the header and display on the bottom left which allows selection
|
||||||
|
# of page groups and individual pages using the FMS controller.
|
||||||
|
obj.Surround = fg1000.Surround.new(obj, myCanvas, obj._MFDDevice, obj._svg);
|
||||||
|
obj.SurroundController = obj.Surround.getController();
|
||||||
|
|
||||||
|
# Engine Information System. A special case as it's always displayed on the MFD.
|
||||||
|
# Note that it is passed in on the constructor
|
||||||
|
obj.EIS = EIS_Class.new(obj, myCanvas, obj._MFDDevice, obj._svg);
|
||||||
|
obj.addPage("EIS", obj.EIS);
|
||||||
|
|
||||||
|
obj.PFDInstruments = fg1000.PFDInstruments.new(obj, myCanvas, obj._MFDDevice, obj._svg);
|
||||||
|
obj.addPage("PFDInstruments", obj.PFDInstruments);
|
||||||
|
obj.PFDInstruments.topMenu(obj._MFDDevice, obj.PFDInstruments, nil);
|
||||||
|
|
||||||
|
# Display the Surround, and PFD Instruments
|
||||||
|
obj.Surround.setVisible(1);
|
||||||
|
obj._MFDDevice.selectPage(obj.PFDInstruments);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
getDevice : func () {
|
||||||
|
return me._MFDDevice;
|
||||||
|
},
|
||||||
|
del: func()
|
||||||
|
{
|
||||||
|
me._MFDDevice.current_page.offdisplay();
|
||||||
|
me._MFDDevice.DeRegisterWithEmesary();
|
||||||
|
me.SurroundController.del();
|
||||||
|
},
|
||||||
|
setPageTitle: func(title)
|
||||||
|
{
|
||||||
|
me._pageTitle.setText(title);
|
||||||
|
},
|
||||||
|
addPage : func(name, page)
|
||||||
|
{
|
||||||
|
me._pageList[name] = page;
|
||||||
|
},
|
||||||
|
|
||||||
|
getPage : func(name)
|
||||||
|
{
|
||||||
|
return me._pageList[name];
|
||||||
|
},
|
||||||
|
|
||||||
|
getDeviceID : func() {
|
||||||
|
return me._MFDDevice.device_id;
|
||||||
|
},
|
||||||
|
|
||||||
|
getCanvas : func() {
|
||||||
|
return me._canvas;
|
||||||
|
}
|
||||||
|
};
|
|
@ -558,7 +558,7 @@ var PFDEventNotification =
|
||||||
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 single { Id: , Value: } tuple requesting a particular 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.)
|
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.)
|
ADCData : 9, #event parameter containing a hash of updated Air Data Computer information (track, ground-speed etc.)
|
||||||
|
|
||||||
DefaultType : "PFDEventNotification",
|
DefaultType : "PFDEventNotification",
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,8 @@
|
||||||
<performance-monitor>Monitor System Performance</performance-monitor>
|
<performance-monitor>Monitor System Performance</performance-monitor>
|
||||||
<write-video-config>Save Video Configuration</write-video-config>
|
<write-video-config>Save Video Configuration</write-video-config>
|
||||||
<property-browser>Browse Internal Properties</property-browser>
|
<property-browser>Browse Internal Properties</property-browser>
|
||||||
<fg1000>FG1000 MFD</fg1000>
|
<fg1000-pfd>FG1000 PFD</fg1000-pfd>
|
||||||
|
<fg1000-mfd>FG1000 MFD</fg1000-mfd>
|
||||||
<logging>Logging</logging>
|
<logging>Logging</logging>
|
||||||
<local_weather>Local Weather (Test)</local_weather>
|
<local_weather>Local Weather (Test)</local_weather>
|
||||||
<print-scene-info>Print Visible Scene Info</print-scene-info>
|
<print-scene-info>Print Visible Scene Info</print-scene-info>
|
||||||
|
|
|
@ -822,7 +822,7 @@
|
||||||
</item>
|
</item>
|
||||||
|
|
||||||
<item>
|
<item>
|
||||||
<name>fg1000</name>
|
<name>fg1000-pfd</name>
|
||||||
<binding>
|
<binding>
|
||||||
<command>nasal</command>
|
<command>nasal</command>
|
||||||
<script>
|
<script>
|
||||||
|
@ -833,8 +833,33 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
var fg1000system = fg1000.FG1000.getOrCreateInstance();
|
var fg1000system = fg1000.FG1000.getOrCreateInstance();
|
||||||
var index = fg1000system.addMFD();
|
var pfdindex = fg1000system.addPFD();
|
||||||
fg1000system.displayGUI(index);
|
fg1000system.displayGUI(pfdindex);
|
||||||
|
|
||||||
|
# Start the interface controller after the FG1000, as it will publish
|
||||||
|
# immediately and update the NAV/COM data.
|
||||||
|
var interfaceController = fg1000.GenericInterfaceController.getOrCreateInstance();
|
||||||
|
interfaceController.stop();
|
||||||
|
interfaceController.start();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item>
|
||||||
|
<name>fg1000-mfd</name>
|
||||||
|
<binding>
|
||||||
|
<command>nasal</command>
|
||||||
|
<script>
|
||||||
|
var nasal_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/FG1000/Nasal/";
|
||||||
|
if (! defined("fg1000")) {
|
||||||
|
io.load_nasal(nasal_dir ~ 'FG1000.nas', "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ 'Interfaces/GenericInterfaceController.nas', "fg1000");
|
||||||
|
}
|
||||||
|
|
||||||
|
var fg1000system = fg1000.FG1000.getOrCreateInstance();
|
||||||
|
var mfdindex = fg1000system.addMFD();
|
||||||
|
fg1000system.displayGUI(mfdindex);
|
||||||
|
|
||||||
# Start the interface controller after the FG1000, as it will publish
|
# Start the interface controller after the FG1000, as it will publish
|
||||||
# immediately and update the NAV/COM data.
|
# immediately and update the NAV/COM data.
|
||||||
|
|
Loading…
Reference in a new issue