1
0
Fork 0

FG1000: Transponder

Transponder can now be set using PFD softkeys.

(Should also be settable using the FMS knob, but this is not implemented yet)
This commit is contained in:
Stuart Buchanan 2019-01-12 20:11:14 +00:00
parent f32a376a3e
commit e69c77aa8e
5 changed files with 227 additions and 4 deletions

View file

@ -207,3 +207,8 @@ var ORIENTATIONS = [
{ label: "DTK UP" },
{ label: "HDG UP" },
];
# Mapping from transponder mode integer values to transponder mode strings, as an array.
# Index values can be found in http://wiki.flightgear.org/Transponder#Knob.2FFunctional_Modes
# String values are menuitem labels on the PFD itself.
var TRANSPONDER_MODES = [ "OFF", "STBY", "TEST", "GND", "ON", "ALT"];

View file

@ -105,6 +105,9 @@ var GenericNavComPublisher =
obj._triggeredPublisher.addPropMap("NavSelected", "/instrumentation/nav-selected");
obj._triggeredPublisher.addPropMap("TransponderMode", "/instrumentation/transponder/inputs/knob-mode");
obj._triggeredPublisher.addPropMap("TransponderIdent", "/instrumentation/transponder/inputs/ident-btn");
obj._triggeredPublisher.addPropMap("TransponderCode", "/instrumentation/transponder/id-code");
return obj;
},

View file

@ -70,6 +70,9 @@ var GenericNavComUpdater =
obj.addPropMap("NavSelected", "/instrumentation/nav-selected");
obj.addPropMap("TransponderMode", "/instrumentation/transponder/inputs/knob-mode");
obj.addPropMap("TransponderIdent", "/instrumentation/transponder/inputs/ident-btn");
obj.addPropMap("TransponderCode", "/instrumentation/transponder/id-code");
return obj;
},

View file

@ -60,6 +60,8 @@ var PFDInstruments =
"HDG-text",
"SelectedHDG-text",
"SelectedALT-text",
"XPDR-DIGIT-3-text", "XPDR-DIGIT-2-text", "XPDR-DIGIT-1-text", "XPDR-DIGIT-0-text",
"XPDR-MODE-text",
]);
# Set clipping for the various tapes
@ -111,7 +113,6 @@ var PFDInstruments =
return obj;
},
topMenu : func(device, pg, menuitem) {
pg.clearMenu();
pg.resetMenuColors();
@ -120,8 +121,8 @@ var PFDInstruments =
pg.addMenuItem(4, "OBS", pg); # TODO
pg.addMenuItem(5, "CDI", pg, func(dev, pg, mi) { pg.getController().incrCDISource(); } );
#pg.addMenuItem(6, "DME", pg, func(dev, pg, mi) { pg.toggleDME(); } ); # TODO
pg.addMenuItem(7, "XPDR", pg); # TODO
pg.addMenuItem(8, "IDENT", pg); # TODO
pg.addMenuItem(7, "XPDR", pg, pg.mfd.PFDInstruments.transponderMenu);
pg.addMenuItem(8, "IDENT", pg, pg.mfd.PFDInstruments.setIdent); # TODO
pg.addMenuItem(9, "TMR/REF", pg); # TODO
pg.addMenuItem(10, "NRST", pg); # TODO
pg.addMenuItem(11, "ALERTS", pg); # TODO
@ -196,7 +197,6 @@ var PFDInstruments =
pg.addMenuItem(4, "BRG1", pg, func(dev, pg, mi) { pg.getController().incrBRG1(); });
pg.addMenuItem(5, "HSI FRMT", pg); # TODO
pg.addMenuItem(6, "BRG2", pg, func(dev, pg, mi) { pg.getController().incrBRG2(); });
#pg.addMenuItem(8, "IDENT", pg); # TODO
pg.addMenuItem(8, "ALT UNIT ", pg); # TODO
pg.addMenuItem(9, "STD BARO", pg, func(dev, pg, mi) { pg.getController().setStdBaro(); } );
pg.addMenuItem(10, "BACK", pg, pg.mfd.PFDInstruments.topMenu);
@ -241,6 +241,59 @@ var PFDInstruments =
svg.setVisible(1); # display function
},
transponderMenu : func(device, pg, menuitem) {
pg.clearMenu();
pg.resetMenuColors();
pg.addMenuItem(2, "STBY", pg, pg.mfd.PFDInstruments.setTransponderMode);
pg.addMenuItem(3, "ON", pg, pg.mfd.PFDInstruments.setTransponderMode);
pg.addMenuItem(4, "ALT", pg, pg.mfd.PFDInstruments.setTransponderMode);
pg.addMenuItem(5, "GND", pg, pg.mfd.PFDInstruments.setTransponderMode);
pg.addMenuItem(6, "VFR", pg, pg.mfd.PFDInstruments.setVFR);
pg.addMenuItem(7, "CODE", pg, pg.mfd.PFDInstruments.codeMenu);
pg.addMenuItem(8, "IDENT", pg, pg.mfd.PFDInstruments.setIdent);
pg.addMenuItem(10, "BACK", pg, pg.mfd.PFDInstruments.topMenu);
pg.addMenuItem(11, "ALERTS", pg); # TODO
device.updateMenus();
},
codeMenu : func(device, pg, menuitem) {
pg.clearMenu();
pg.resetMenuColors();
pg.addMenuItem(0, "0", pg, pg.mfd.PFDInstruments.setTransponderDigit);
pg.addMenuItem(1, "1", pg, pg.mfd.PFDInstruments.setTransponderDigit);
pg.addMenuItem(2, "2", pg, pg.mfd.PFDInstruments.setTransponderDigit);
pg.addMenuItem(3, "3", pg, pg.mfd.PFDInstruments.setTransponderDigit);
pg.addMenuItem(4, "4", pg, pg.mfd.PFDInstruments.setTransponderDigit);
pg.addMenuItem(5, "5", pg, pg.mfd.PFDInstruments.setTransponderDigit);
pg.addMenuItem(6, "6", pg, pg.mfd.PFDInstruments.setTransponderDigit);
pg.addMenuItem(7, "7 ", pg, pg.mfd.PFDInstruments.setTransponderDigit);
pg.addMenuItem(8, "IDENT", pg, pg.mfd.PFDInstruments.setIdent);
pg.addMenuItem(9, "BKSP", pg, pg.mfd.PFDInstruments.setTransponderDigit);
pg.addMenuItem(10, "BACK", pg, pg.mfd.PFDInstruments.transponderMenu);
pg.addMenuItem(11, "ALERTS", pg); # TODO
device.updateMenus();
},
setTransponderMode : func(device, pg, menuitem) {
# Get the transponder mode from the menuitem itself.
pg.getController().setTransponderMode(menuitem.title);
},
setVFR : func(device, pg, menuitem) {
# Set VFR Mode - 1200
pg.getController().setTransponderCode(1200);
},
setIdent : func(device, pg, menuitem) {
# Ident the transponder
pg.getController().setTransponderIdent(1);
},
setTransponderDigit: func(device, pg, menuitem) {
# Set a transponder digit. Get digit from menu item.
pg.getController().setTransponderDigit(menuitem.title);
},
offdisplay : func() {
me._group.setVisible(0);
@ -779,4 +832,44 @@ var PFDInstruments =
me.flightplanList.setCRSR(current_wp);
me.flightplanList.displayGroup();
},
# Update the Transponder display
updateTransponder : func(mode, code, ident, edit=0) {
# Data validation on the mode
if (mode < 0) mode = 0;
if (mode > 5) mode = 5;
# Ensure the code is a 4 digit string representation of a number.
# Normally this means padding with 0's at the left e.g. 42 becomes 0042.
# In editing mode we enter values from the left, so we want " " padding on the
# right, so 42 becomes "42 ". Note also that the code is a string value
# so we can have "004 "
if (edit) {
code = sprintf("%-4s", code);
} else {
code = sprintf("%04i", code);
}
# Colour of display. White in OFF, STDBY, TEST modes, green in GND, ON, ALT
var r = 1.0;
var g = 1.0;
var b = 1.0;
if (mode > 2) {
r = 0.2;
g = 1.0;
b = 0.2;
}
if (ident) {
me.getElement("XPDR-MODE-text").setText("IDNT").setColor(r,g,b);
} else {
me.getElement("XPDR-MODE-text").setText(TRANSPONDER_MODES[mode]).setColor(r,g,b);
}
var codes = split("", code);
me.getElement("XPDR-DIGIT-3-text").setText(chr(code[0])).setColor(r,g,b);
me.getElement("XPDR-DIGIT-2-text").setText(chr(code[1])).setColor(r,g,b);
me.getElement("XPDR-DIGIT-1-text").setText(chr(code[2])).setColor(r,g,b);
me.getElement("XPDR-DIGIT-0-text").setText(chr(code[3])).setColor(r,g,b);
},
};

View file

@ -83,6 +83,12 @@ var PFDInstrumentsController =
_adf_freq : 0.0,
_adf_in_range : 0,
_adf_heading_deg : 0.0,
_transponder_mode : 0,
_transponder_code : "1200", # Current code
_transponder_ident : 0,
_transponder_edit : 0, # If we're currently editing the transponder code
_transponder_edit_code : 0 # Current value being edited as transponder code
};
obj._current_flightplan = obj.getNavData("Flightplan");
@ -91,6 +97,16 @@ var PFDInstrumentsController =
obj.page.setFlightPlan(obj._current_flightplan);
}
# Timer used to reset a transponder IDENT
obj.transponderIdentResetTimer = maketimer(18, obj, func() { me.sendNavComDataNotification({"TransponderIdent" : 0}); });
obj.transponderIdentResetTimer.simulatedTime = 1;
obj.transponderIdentResetTimer.singleShot = 1;
# Timer used to reset a transponder edit, if pilot hasn't completed entering a new code in 45s.
obj.transponderEditResetTimer = maketimer(45, obj, obj.transponderEditCancel);
obj.transponderEditResetTimer.simulatedTime = 1;
obj.transponderEditResetTimer.singleShot = 1;
return obj;
},
@ -363,6 +379,10 @@ var PFDInstrumentsController =
if (data["ADFInRange"] != nil) me._adf_in_range = data["ADFInRange"];
if (data["ADFHeadingDeg"] !=nil) me._adf_heading_deg = data["ADFInRange"];
if (data["TransponderMode"] != nil) me._transponder_mode = data["TransponderMode"];
if (data["TransponderCode"] != nil) me._transponder_code = data["TransponderCode"];
if (data["TransponderIdent"] != nil) me._transponder_ident = data["TransponderIdent"];
if (me.getBRG1() == "NAV1") me.page.updateBRG1(me._nav1_in_range, me._nav1_id, me._nav1_distance_m * M2NM, me._heading_magnetic_deg, me._nav1_heading_deg);
if (me.getBRG1() == "NAV2") me.page.updateBRG1(me._nav2_in_range, me._nav2_id, me._nav2_distance_m * M2NM, me._heading_magnetic_deg, me._nav2_heading_deg);
if (me.getBRG1() == "ADF") me.page.updateBRG1(me._adf_in_range, sprintf("%.1f", me._adf_freq), 0, me._heading_magnetic_deg, me._adf_heading_deg);
@ -401,6 +421,13 @@ var PFDInstrumentsController =
);
}
if ((me._transponder_edit == 0) and
((data["TransponderMode"] != nil) or (data["TransponderCode"] != nil) or (data["TransponderIdent"] != nil))) {
# Transponder settings only change irregularly, so only redisplay on a change, and only if we are not currently
# editing the transponder code itself.
me.page.updateTransponder(me._transponder_mode, me._transponder_code, me._transponder_ident);
}
return emesary.Transmitter.ReceiptStatus_OK;
},
@ -466,6 +493,98 @@ var PFDInstrumentsController =
me.transmitter = nil;
},
setTransponderMode : func(mode) {
var idx = -1;
# Find the matching index for the transponder mode string
for(var i = 0; i < size(TRANSPONDER_MODES); i +=1) {
if (mode == TRANSPONDER_MODES[i]) {
idx = i;
break;
}
}
if (idx == -1) {
print("Unable to find transponder mode " ~ mode);
} else {
me.sendNavComDataNotification({"TransponderMode" : idx});
}
},
setTransponderCode : func(code) {
me.sendNavComDataNotification({"TransponderCode" : code});
},
setTransponderIdent : func(ident) {
# IDNT is active for 18 seconds, so we set a timer to reset it.
me.sendNavComDataNotification({"TransponderIdent" : ident});
# Reset any edit of the transponder code. Note that this also returns
# to the top level menu. This is correct behaviour.
me.transponderEditCancel();
if (ident == 1) {
me.transponderIdentResetTimer.restart(18);
}
},
setTransponderDigit : func(digit) {
if (me._transponder_edit == 0) {
# If this is the first time we've pressed a digit button, then go to editing
# mode, and set the first digit of the display
me._transponder_edit = 1;
# Start the transponder edit timer so we will exit out of edit mode
me.transponderEditResetTimer.restart(45);
if (digit == "BKSP") {
me._transponder_edit_code = "";
} else {
me._transponder_edit_code = digit;
}
me.page.updateTransponder(me._transponder_mode, me._transponder_edit_code, me._transponder_ident, 1);
} else {
# Already in edit mode, so we need to append the newly entered number.
if (digit == "BKSP") {
# Trim off the last digit
me._transponder_edit_code = substr(me._transponder_edit_code, 0, size(me._transponder_edit_code) -1);
} else {
# append the new digit
me._transponder_edit_code = me._transponder_edit_code ~ digit;
}
if (size(me._transponder_edit_code) == 4) {
# We've now got 4 digits, so set it both centrally and locally
me.sendNavComDataNotification({"TransponderCode" : me._transponder_edit_code});
me._transponder_code = me._transponder_edit_code;
me.transponderEditCancel();
} else {
# Display the code so far entered.
me.page.updateTransponder(me._transponder_mode, me._transponder_edit_code, me._transponder_ident, 1);
}
}
},
transponderEditCancel : func() {
me._transponder_edit = 0;
me.transponderEditResetTimer.stop();
me.page.updateTransponder(me._transponder_mode, me._transponder_code, me._transponder_ident);
me.page.topMenu(me.page.device, me.page, nil);
},
# Helper function to notify the Emesary bridge of a NavComData update.
sendNavComDataNotification : func(data) {
var notification = notifications.PFDEventNotification.new(
"MFD",
me._page.mfd.getDeviceID(),
notifications.PFDEventNotification.NavComData,
data);
me.transmitter.NotifyAll(notification);
},
# Reset controller if required when the page is displayed or hidden
ondisplay : func() {
me.RegisterWithEmesary();