Add framework for new Emesary based display framework. This is based off work by Richard Harrison on the F-15, making use of the FrameNotification concept
This commit is contained in:
parent
cbaa9f2aa8
commit
6bb53d70d1
8 changed files with 524 additions and 112 deletions
|
@ -1182,6 +1182,7 @@
|
|||
</comm>
|
||||
<electrical n="0">
|
||||
<bus>
|
||||
<ac-ess type="double">0</ac-ess>
|
||||
<dc-1 type="double">0</dc-1>
|
||||
<dc-2 type="double">0</dc-2>
|
||||
</bus>
|
||||
|
@ -4335,6 +4336,9 @@
|
|||
</aircraft>
|
||||
|
||||
<nasal>
|
||||
<notifications>
|
||||
<file>Aircraft/A320-family/Nasal/emesary/M_frame_notification.nas</file>
|
||||
</notifications>
|
||||
<pts>
|
||||
<file>Aircraft/A320-family/Nasal/Libraries/property-tree-setup.nas</file>
|
||||
</pts>
|
||||
|
@ -4442,7 +4446,9 @@
|
|||
<file>Aircraft/A320-family/Models/Instruments/ND/canvas/ND.nas</file>
|
||||
</canvas_nd>
|
||||
<canvas_ecam>
|
||||
<file>Aircraft/A320-family/Models/Instruments/Upper-ECAM/Upper-ECAM.nas</file>
|
||||
<file>Aircraft/A320-family/Nasal/emesary/exec.nas</file>
|
||||
<!--<file>Aircraft/A320-family/Models/Instruments/Upper-ECAM/Upper-ECAM.nas</file>-->
|
||||
<file>Aircraft/A320-family/Models/Instruments/Upper-ECAM/Upper-ECAM.new.nas</file>
|
||||
<file>Aircraft/A320-family/Models/Instruments/Lower-ECAM/Lower-ECAM.nas</file>
|
||||
</canvas_ecam>
|
||||
<canvas_iesi>
|
||||
|
|
|
@ -118,31 +118,8 @@ var thrLimit = 0;
|
|||
|
||||
var canvas_upperECAM_base = {
|
||||
init: func(canvas_group, file) {
|
||||
var font_mapper = func(family, weight) {
|
||||
return "LiberationFonts/LiberationSans-Regular.ttf";
|
||||
};
|
||||
|
||||
canvas.parsesvg(canvas_group, file, {"font-mapper": font_mapper});
|
||||
|
||||
var svg_keys = me.getKeys();
|
||||
foreach(var key; svg_keys) {
|
||||
me[key] = canvas_group.getElementById(key);
|
||||
|
||||
var clip_el = canvas_group.getElementById(key ~ "_clip");
|
||||
if (clip_el != nil) {
|
||||
clip_el.setVisible(0);
|
||||
var tran_rect = clip_el.getTransformedBounds();
|
||||
|
||||
var clip_rect = sprintf("rect(%d,%d, %d,%d)",
|
||||
tran_rect[1], # 0 ys
|
||||
tran_rect[2], # 1 xe
|
||||
tran_rect[3], # 2 ye
|
||||
tran_rect[0]); #3 xs
|
||||
# coordinates are top,right,bottom,left (ys, xe, ye, xs) ref: l621 of simgear/canvas/CanvasElement.cxx
|
||||
me[key].set("clip", clip_rect);
|
||||
me[key].set("clip-frame", canvas.Element.PARENT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# set font
|
||||
me["ECAML1"].setFont("LiberationMonoCustom.ttf");
|
||||
|
@ -199,29 +176,30 @@ var canvas_upperECAM_base = {
|
|||
update: func() {
|
||||
elapsedtime = pts.Sim.Time.elapsedSec.getValue();
|
||||
cur_eng_option = eng_option.getValue();
|
||||
|
||||
if (systems.ELEC.Bus.acEss.getValue() >= 110 and du3_lgt.getValue() > 0.01) {
|
||||
if (du3_test_time.getValue() + du3_test_amount.getValue() >= elapsedtime) {
|
||||
upperECAM_cfm_eis2.page.hide();
|
||||
upperECAM_iae_eis2.page.hide();
|
||||
upperECAM_test.page.show();
|
||||
upperECAM_test.update();
|
||||
if (1 == 0) {
|
||||
if (systems.ELEC.Bus.acEss.getValue() >= 110 and du3_lgt.getValue() > 0.01) {
|
||||
if (du3_test_time.getValue() + du3_test_amount.getValue() >= elapsedtime) {
|
||||
upperECAM_cfm_eis2.page.hide();
|
||||
upperECAM_iae_eis2.page.hide();
|
||||
upperECAM_test.page.show();
|
||||
upperECAM_test.update();
|
||||
} else {
|
||||
upperECAM_test.page.hide();
|
||||
if (cur_eng_option == "CFM") {
|
||||
upperECAM_cfm_eis2.page.show();
|
||||
upperECAM_iae_eis2.page.hide();
|
||||
upperECAM_cfm_eis2.update();
|
||||
} else if (cur_eng_option == "IAE") {
|
||||
upperECAM_cfm_eis2.page.hide();
|
||||
upperECAM_iae_eis2.page.show();
|
||||
upperECAM_iae_eis2.update();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
upperECAM_test.page.hide();
|
||||
if (cur_eng_option == "CFM") {
|
||||
upperECAM_cfm_eis2.page.show();
|
||||
upperECAM_iae_eis2.page.hide();
|
||||
upperECAM_cfm_eis2.update();
|
||||
} else if (cur_eng_option == "IAE") {
|
||||
upperECAM_cfm_eis2.page.hide();
|
||||
upperECAM_iae_eis2.page.show();
|
||||
upperECAM_iae_eis2.update();
|
||||
}
|
||||
upperECAM_cfm_eis2.page.hide();
|
||||
upperECAM_iae_eis2.page.hide();
|
||||
}
|
||||
} else {
|
||||
upperECAM_test.page.hide();
|
||||
upperECAM_cfm_eis2.page.hide();
|
||||
upperECAM_iae_eis2.page.hide();
|
||||
}
|
||||
},
|
||||
getColorString: func(color) {
|
||||
|
@ -241,7 +219,7 @@ var canvas_upperECAM_base = {
|
|||
return [1,1,1];
|
||||
}
|
||||
},
|
||||
updateBase: func() {
|
||||
updateBase: func(notification) {
|
||||
# Reversers
|
||||
rev_1_cur = pts.Engines.Engine.reverser[0].getValue();
|
||||
rev_2_cur = pts.Engines.Engine.reverser[1].getValue();
|
||||
|
@ -280,27 +258,6 @@ var canvas_upperECAM_base = {
|
|||
me["REV2"].setColor(0.7333,0.3803,0);
|
||||
}
|
||||
|
||||
# Flap Indicator
|
||||
flapsPos = pts.Controls.Flight.flapsPos.getValue();
|
||||
if (flapsPos == 1) {
|
||||
me["FlapTxt"].setText("1");
|
||||
} else if (flapsPos == 2) {
|
||||
me["FlapTxt"].setText("1+F");
|
||||
} else if (flapsPos == 3) {
|
||||
me["FlapTxt"].setText("2");
|
||||
} else if (flapsPos == 4) {
|
||||
me["FlapTxt"].setText("3");
|
||||
} else if (flapsPos == 5) {
|
||||
me["FlapTxt"].setText("FULL");
|
||||
} else {
|
||||
me["FlapTxt"].setText(" "); # More efficient then hide/show
|
||||
}
|
||||
|
||||
if (flapsPos > 0) {
|
||||
me["FlapDots"].show();
|
||||
} else {
|
||||
me["FlapDots"].hide();
|
||||
}
|
||||
|
||||
if (pts.Fdm.JSBsim.Fcs.slatLocked.getValue()) {
|
||||
if (slatLockGoing == 0) {
|
||||
|
@ -325,16 +282,6 @@ var canvas_upperECAM_base = {
|
|||
me["FlapLine"].setTranslation(flapXTranslate.getValue(),flapYTranslate.getValue());
|
||||
me["SlatLine"].setTranslation(slatXTranslate.getValue(),slatYTranslate.getValue());
|
||||
|
||||
# FOB
|
||||
if (acconfig_weight_kgs.getValue())
|
||||
{
|
||||
me["FOB-LBS"].setText(sprintf("%s", math.round(pts.Consumables.Fuel.totalFuelLbs.getValue() * LBS2KGS, 10)));
|
||||
me["FOB-weight-unit"].setText("KG");
|
||||
} else {
|
||||
me["FOB-LBS"].setText(sprintf("%s", math.round(pts.Consumables.Fuel.totalFuelLbs.getValue(), 10)));
|
||||
me["FOB-weight-unit"].setText("LBS");
|
||||
}
|
||||
|
||||
# ECAM Messages
|
||||
|
||||
me["ECAML1"].setText(sprintf("%s", ECAM_line1.getValue()));
|
||||
|
@ -358,24 +305,70 @@ var canvas_upperECAM_base = {
|
|||
me["ECAMR8"].setText(sprintf("%s", ECAM_line8r.getValue()));
|
||||
|
||||
me["ECAM_Right"].show();
|
||||
|
||||
foreach(var update_item; me.update_items)
|
||||
{
|
||||
update_item.update(notification);
|
||||
}
|
||||
},
|
||||
updateAFloor: func() {
|
||||
if (fadec.Thrust.alphaFloor.getBoolValue()) {
|
||||
me["aFloor"].show();
|
||||
} else {
|
||||
me["aFloor"].hide();
|
||||
}
|
||||
},
|
||||
updateFlaps: func() {
|
||||
# Flap Indicator
|
||||
flapsPos = pts.Controls.Flight.flapsPos.getValue();
|
||||
if (flapsPos == 1) {
|
||||
me["FlapTxt"].setText("1");
|
||||
} else if (flapsPos == 2) {
|
||||
me["FlapTxt"].setText("1+F");
|
||||
} else if (flapsPos == 3) {
|
||||
me["FlapTxt"].setText("2");
|
||||
} else if (flapsPos == 4) {
|
||||
me["FlapTxt"].setText("3");
|
||||
} else if (flapsPos == 5) {
|
||||
me["FlapTxt"].setText("FULL");
|
||||
} else {
|
||||
me["FlapTxt"].setText(" "); # More efficient then hide/show
|
||||
}
|
||||
|
||||
if (flapsPos > 0) {
|
||||
me["FlapDots"].show();
|
||||
} else {
|
||||
me["FlapDots"].hide();
|
||||
}
|
||||
},
|
||||
updateFlx: func() {
|
||||
if (fadec.Thrust.thrustLimit.getValue() == "FLX") {
|
||||
me["FlxLimDegreesC"].show();
|
||||
me["FlxLimTemp"].show();
|
||||
me["FlxLimTemp"].setText(sprintf("%2.0d",fmgc.FMGCNodes.flexTemp.getValue()));
|
||||
} else {
|
||||
me["FlxLimDegreesC"].hide();
|
||||
me["FlxLimTemp"].hide();
|
||||
}
|
||||
},
|
||||
update_items: [
|
||||
props.UpdateManager.FromHashValue("fuelTotalLbs", 1, func(val) {
|
||||
# FOB
|
||||
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
var canvas_upperECAM_cfm_eis2 = {
|
||||
new: func(canvas_group, file) {
|
||||
var m = {parents: [canvas_upperECAM_cfm_eis2, canvas_upperECAM_base]};
|
||||
m.init(canvas_group, file);
|
||||
|
||||
m.updateAFloor();
|
||||
m.updateFlx();
|
||||
return m;
|
||||
},
|
||||
getKeys: func() {
|
||||
return ["N11-needle","N11-thr","N11-ylim","N11","N11-decpnt","N11-decimal","N11-box","N11-scale","N11-scale2","N11-scaletick","N11-scalenum","N11-XX","N11-XX2","N11-XX-box","EGT1-needle","EGT1","EGT1-scale","EGT1-box","EGT1-scale2","EGT1-scaletick",
|
||||
"EGT1-XX","N21","N21-decpnt","N21-decimal","N21-XX","FF1","FF1-XX","N12-needle","N12-thr","N12-ylim","N12","N12-decpnt","N12-decimal","N12-box","N12-scale","N12-scale2","N12-scaletick","N12-scalenum","N12-XX","N12-XX2","N12-XX-box","EGT2-needle","EGT2",
|
||||
"EGT2-scale","EGT2-box","EGT2-scale2","EGT2-scaletick","EGT2-XX","N22","N22-decpnt","N22-decimal","N22-XX","FF2","FF2-XX","FOB-LBS","FlapTxt","FlapDots","N1Lim-mode","N1Lim","N1Lim-decpnt","N1Lim-decimal","N1Lim-percent","N1Lim-XX","N1Lim-XX2","REV1",
|
||||
"REV1-box","REV2","REV2-box","ECAM_Left","ECAML1","ECAML2","ECAML3","ECAML4","ECAML5","ECAML6","ECAML7","ECAML8","ECAMR1", "ECAMR2", "ECAMR3", "ECAMR4", "ECAMR5", "ECAMR6", "ECAMR7", "ECAMR8", "ECAM_Right",
|
||||
"FOB-weight-unit","FFlow-weight-unit","SlatAlphaLock","SlatIndicator","FlapIndicator","SlatLine","FlapLine"];
|
||||
},
|
||||
update: func() {
|
||||
|
||||
update: func(notification) {
|
||||
# N1
|
||||
N1_1_cur = N1_1.getValue();
|
||||
N1_2_cur = N1_2.getValue();
|
||||
|
@ -615,7 +608,7 @@ var canvas_upperECAM_cfm_eis2 = {
|
|||
me["N1Lim-percent"].hide();
|
||||
}
|
||||
|
||||
me.updateBase();
|
||||
me.updateBase(notification);
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -623,7 +616,8 @@ var canvas_upperECAM_iae_eis2 = {
|
|||
new: func(canvas_group, file) {
|
||||
var m = {parents: [canvas_upperECAM_iae_eis2, canvas_upperECAM_base]};
|
||||
m.init(canvas_group, file);
|
||||
|
||||
m.updateAFloor();
|
||||
m.updateFlx();
|
||||
return m;
|
||||
},
|
||||
getKeys: func() {
|
||||
|
@ -632,9 +626,9 @@ var canvas_upperECAM_iae_eis2 = {
|
|||
"EPR2-decimal","EPR2-box","EPR2-scale","EPR2-scaletick","EPR2-scalenum","EPR2-XX","EPR2-XX2","EGT2-needle","EGT2","EGT2-scale","EGT2-scale2","EGT2-box","EGT2-scaletick","EGT2-XX","N12-needle","N12-thr","N12-ylim","N12","N12-decpnt","N12-decimal",
|
||||
"N12-scale","N12-scale2","N12-scaletick","N12-scalenum","N12-XX","N22","N22-decpnt","N22-decimal","N22-XX","FF2","FF2-XX","FOB-LBS","FlapTxt","FlapDots","EPRLim-mode","EPRLim","EPRLim-decpnt","EPRLim-decimal","EPRLim-XX","EPRLim-XX2","REV1","REV1-box",
|
||||
"REV2","REV2-box","ECAM_Left","ECAML1","ECAML2","ECAML3","ECAML4","ECAML5","ECAML6","ECAML7","ECAML8", "ECAMR1", "ECAMR2", "ECAMR3", "ECAMR4", "ECAMR5", "ECAMR6", "ECAMR7", "ECAMR8", "ECAM_Right",
|
||||
"FFlow1-weight-unit", "FFlow2-weight-unit", "FOB-weight-unit","SlatAlphaLock","SlatIndicator","FlapIndicator","SlatLine","FlapLine"];
|
||||
"FFlow1-weight-unit", "FFlow2-weight-unit", "FOB-weight-unit","SlatAlphaLock","SlatIndicator","FlapIndicator","SlatLine","FlapLine","aFloor","FlxLimDegreesC","FlxLimTemp"];
|
||||
},
|
||||
update: func() {
|
||||
update: func(notification) {
|
||||
N1_1_cur = N1_1.getValue();
|
||||
N1_2_cur = N1_2.getValue();
|
||||
N1_1_act = pts.Engines.Engine.n1Actual[0].getValue();
|
||||
|
@ -942,7 +936,7 @@ var canvas_upperECAM_iae_eis2 = {
|
|||
me["EPRLim-decimal"].hide();
|
||||
}
|
||||
|
||||
me.updateBase();
|
||||
me.updateBase(notification);
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1009,22 +1003,58 @@ var createListenerForLine = func(prop, node, key) {
|
|||
}, 0, 0);
|
||||
};
|
||||
|
||||
var _init = 0;
|
||||
|
||||
|
||||
var UpperECAMRecipientCFM =
|
||||
{
|
||||
new: func(_ident, group)
|
||||
{
|
||||
var new_class = emesary.Recipient.new(_ident);
|
||||
new_class.MainScreen = nil;
|
||||
new_class.Receive = func(notification)
|
||||
{
|
||||
if (notification.NotificationType == "FrameNotification")
|
||||
{
|
||||
if (new_class.MainScreen == nil)
|
||||
new_class.MainScreen = canvas_upperECAM_cfm_eis2.new(group, "Aircraft/A320-family/Models/Instruments/Upper-ECAM/res/cfm-eis2.svg");
|
||||
upperECAM_cfm_eis2 = new_class.MainScreen;
|
||||
if (!math.mod(notifications.frameNotification.FrameCount,2)){
|
||||
new_class.MainScreen.update(notification);
|
||||
}
|
||||
return emesary.Transmitter.ReceiptStatus_OK;
|
||||
}
|
||||
return emesary.Transmitter.ReceiptStatus_NotProcessed;
|
||||
};
|
||||
return new_class;
|
||||
},
|
||||
};
|
||||
|
||||
var UpperECAMRecipientIAE =
|
||||
{
|
||||
new: func(_ident, group)
|
||||
{
|
||||
var new_class = emesary.Recipient.new(_ident);
|
||||
new_class.MainScreen = nil;
|
||||
new_class.Receive = func(notification)
|
||||
{
|
||||
if (notification.NotificationType == "FrameNotification")
|
||||
{
|
||||
if (new_class.MainScreen == nil)
|
||||
new_class.MainScreen = canvas_upperECAM_iae_eis2.new(group, "Aircraft/A320-family/Models/Instruments/Upper-ECAM/res/iae-eis2.svg");
|
||||
upperECAM_iae_eis2 = new_class.MainScreen;
|
||||
if (!math.mod(notifications.frameNotification.FrameCount,2)){
|
||||
new_class.MainScreen.update(notification);
|
||||
}
|
||||
return emesary.Transmitter.ReceiptStatus_OK;
|
||||
}
|
||||
return emesary.Transmitter.ReceiptStatus_NotProcessed;
|
||||
};
|
||||
return new_class;
|
||||
},
|
||||
};
|
||||
|
||||
setlistener("sim/signals/fdm-initialized", func {
|
||||
upperECAM_display = canvas.new({
|
||||
"name": "upperECAM",
|
||||
"size": [1024, 1024],
|
||||
"view": [1024, 1024],
|
||||
"mipmapping": 1
|
||||
});
|
||||
upperECAM_display.addPlacement({"node": "uecam.screen"});
|
||||
var group_cfm_eis2 = upperECAM_display.createGroup();
|
||||
var group_iae_eis2 = upperECAM_display.createGroup();
|
||||
var group_test = upperECAM_display.createGroup();
|
||||
|
||||
upperECAM_cfm_eis2 = canvas_upperECAM_cfm_eis2.new(group_cfm_eis2, "Aircraft/A320-family/Models/Instruments/Upper-ECAM/res/cfm-eis2.svg");
|
||||
upperECAM_iae_eis2 = canvas_upperECAM_iae_eis2.new(group_iae_eis2, "Aircraft/A320-family/Models/Instruments/Upper-ECAM/res/iae-eis2.svg");
|
||||
upperECAM_test = canvas_upperECAM_test.new(group_test, "Aircraft/A320-family/Models/Instruments/Common/res/du-test.svg");
|
||||
|
||||
createListenerForLine("/ECAM/msg/linec1", ECAM_line1c, "ECAML1");
|
||||
createListenerForLine("/ECAM/msg/linec2", ECAM_line2c, "ECAML2");
|
||||
|
@ -1044,6 +1074,10 @@ setlistener("sim/signals/fdm-initialized", func {
|
|||
createListenerForLine("/ECAM/rightmsg/linec7", ECAM_line7rc, "ECAMR7");
|
||||
createListenerForLine("/ECAM/rightmsg/linec8", ECAM_line8rc, "ECAMR8");
|
||||
|
||||
if (!_init) {
|
||||
|
||||
}
|
||||
|
||||
upperECAM_update.start();
|
||||
if (rate.getValue() > 1) {
|
||||
u_rateApply();
|
||||
|
@ -1067,7 +1101,6 @@ setlistener("/systems/electrical/bus/ac-ess", func() {
|
|||
canvas_upperECAM_base.updateDu3();
|
||||
}, 0, 0);
|
||||
|
||||
|
||||
var slatLockGoing = 0;
|
||||
var slatLockTimer = maketimer(0.50, func {
|
||||
if (!slatLockFlash.getBoolValue()) {
|
||||
|
|
113
Models/Instruments/Upper-ECAM/Upper-ECAM.new.nas
Normal file
113
Models/Instruments/Upper-ECAM/Upper-ECAM.new.nas
Normal file
|
@ -0,0 +1,113 @@
|
|||
var canvas_upperECAM = {
|
||||
new: func(svg) {
|
||||
var obj = {parents: [canvas_upperECAM] };
|
||||
obj.canvas = canvas.new({
|
||||
"name": "upperECAM",
|
||||
"size": [1024, 1024],
|
||||
"view": [1024, 1024],
|
||||
"mipmapping": 1,
|
||||
});
|
||||
|
||||
obj.canvas.addPlacement({"node": "uecam.screen"});
|
||||
obj.group = obj.canvas.createGroup();
|
||||
|
||||
obj.font_mapper = func(family, weight) {
|
||||
return "LiberationFonts/LiberationSans-Regular.ttf";
|
||||
};
|
||||
|
||||
canvas.parsesvg(obj.group, svg, {"font-mapper": obj.font_mapper} );
|
||||
|
||||
foreach(var key; obj.getKeys()) {
|
||||
obj[key] = obj.group.getElementById(key);
|
||||
|
||||
var clip_el = obj.group.getElementById(key ~ "_clip");
|
||||
if (clip_el != nil) {
|
||||
clip_el.setVisible(0);
|
||||
var tran_rect = clip_el.getTransformedBounds();
|
||||
|
||||
var clip_rect = sprintf("rect(%d,%d, %d,%d)",
|
||||
tran_rect[1],
|
||||
tran_rect[2],
|
||||
tran_rect[3],
|
||||
tran_rect[0]);
|
||||
obj[key].set("clip", clip_rect);
|
||||
obj[key].set("clip-frame", canvas.Element.PARENT);
|
||||
}
|
||||
};
|
||||
|
||||
obj.update_items = [
|
||||
props.UpdateManager.FromHashValue("fuelTotalLbs", 1, func(val) {
|
||||
if (acconfig_weight_kgs.getValue())
|
||||
{
|
||||
obj["FOB-LBS"].setText(sprintf("%s", math.round(val * LBS2KGS, 10)));
|
||||
obj["FOB-weight-unit"].setText("KG");
|
||||
} else {
|
||||
obj["FOB-LBS"].setText(sprintf("%s", math.round(val, 10)));
|
||||
obj["FOB-weight-unit"].setText("LBS");
|
||||
}
|
||||
}),
|
||||
props.UpdateManager.FromHashList(["AcEssBus", "DisplayBrightness"], 0.01, func(val) {
|
||||
if (val.DisplayBrightness > 0.01 and val.AcEssBus >= 110) {
|
||||
obj.group.setVisible(1);
|
||||
} else {
|
||||
obj.group.setVisible(0);
|
||||
}
|
||||
}),
|
||||
];
|
||||
|
||||
obj.page = obj.group;
|
||||
return obj;
|
||||
},
|
||||
getKeys: func() {
|
||||
return ["N11-needle","N11-thr","N11-ylim","N11","N11-decpnt","N11-decimal","N11-box","N11-scale","N11-scale2","N11-scaletick","N11-scalenum","N11-XX","N11-XX2","N11-XX-box","EGT1-needle","EGT1","EGT1-scale","EGT1-box","EGT1-scale2","EGT1-scaletick",
|
||||
"EGT1-XX","N21","N21-decpnt","N21-decimal","N21-XX","FF1","FF1-XX","N12-needle","N12-thr","N12-ylim","N12","N12-decpnt","N12-decimal","N12-box","N12-scale","N12-scale2","N12-scaletick","N12-scalenum","N12-XX","N12-XX2","N12-XX-box","EGT2-needle","EGT2",
|
||||
"EGT2-scale","EGT2-box","EGT2-scale2","EGT2-scaletick","EGT2-XX","N22","N22-decpnt","N22-decimal","N22-XX","FF2","FF2-XX","FOB-LBS","FlapTxt","FlapDots","N1Lim-mode","N1Lim","N1Lim-decpnt","N1Lim-decimal","N1Lim-percent","N1Lim-XX","N1Lim-XX2","REV1",
|
||||
"REV1-box","REV2","REV2-box","ECAM_Left","ECAML1","ECAML2","ECAML3","ECAML4","ECAML5","ECAML6","ECAML7","ECAML8","ECAMR1", "ECAMR2", "ECAMR3", "ECAMR4", "ECAMR5", "ECAMR6", "ECAMR7", "ECAMR8", "ECAM_Right",
|
||||
"FOB-weight-unit","FFlow-weight-unit","SlatAlphaLock","SlatIndicator","FlapIndicator","SlatLine","FlapLine","aFloor","FlxLimDegreesC","FlxLimTemp"];
|
||||
},
|
||||
update: func(notification) {
|
||||
foreach(var update_item; me.update_items)
|
||||
{
|
||||
update_item.update(notification);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var UpperECAMRecipient =
|
||||
{
|
||||
new: func(_ident)
|
||||
{
|
||||
var new_class = emesary.Recipient.new(_ident);
|
||||
new_class.MainScreen = nil;
|
||||
new_class.Receive = func(notification)
|
||||
{
|
||||
if (notification.NotificationType == "FrameNotification")
|
||||
{
|
||||
if (new_class.MainScreen == nil)
|
||||
new_class.MainScreen = canvas_upperECAM.new("Aircraft/A320-family/Models/Instruments/Upper-ECAM/res/cfm-eis2.svg", "A320 Upper ECAM CFM");
|
||||
if (!math.mod(notifications.frameNotification.FrameCount,2)){
|
||||
new_class.MainScreen.update(notification);
|
||||
}
|
||||
return emesary.Transmitter.ReceiptStatus_OK;
|
||||
}
|
||||
return emesary.Transmitter.ReceiptStatus_NotProcessed;
|
||||
};
|
||||
return new_class;
|
||||
},
|
||||
};
|
||||
|
||||
emesary.GlobalTransmitter.Register(UpperECAMRecipient.new("A320 Upper ECAM"));
|
||||
|
||||
input = {
|
||||
fuelTotalLbs: "/consumables/fuel/total-fuel-lbs",
|
||||
AcEssBus: "/systems/electrical/bus/ac-ess",
|
||||
DisplayBrightness: "/controls/lighting/DU/du3",
|
||||
};
|
||||
|
||||
foreach (var name; keys(input)) {
|
||||
emesary.GlobalTransmitter.NotifyAll(notifications.FrameNotificationAddProperty.new("A320 Upper ECAM", name, input[name]));
|
||||
}
|
||||
|
||||
setlistener("/sim/signals/fdm-initialized", func() {
|
||||
execLoop();
|
||||
}, 0, 0);
|
|
@ -41,9 +41,9 @@
|
|||
inkscape:window-height="705"
|
||||
id="namedview371"
|
||||
showgrid="true"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="718.57047"
|
||||
inkscape:cy="505.8628"
|
||||
inkscape:zoom="0.25"
|
||||
inkscape:cx="971.41703"
|
||||
inkscape:cy="1420.8195"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
|
@ -1428,4 +1428,43 @@
|
|||
width="137.63597"
|
||||
id="SlatLine_clip"
|
||||
style="opacity:0.5;fill:none;fill-opacity:1;stroke:none;stroke-width:3.34691048;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:31.71383667px;line-height:1.25;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.7928459"
|
||||
x="38.122616"
|
||||
y="47.904297"
|
||||
id="aFloor"
|
||||
transform="scale(0.94595932,1.0571279)"
|
||||
inkscape:label="#text1027"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan1025"
|
||||
x="38.122616"
|
||||
y="47.904297"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:39.99999902px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';fill:#c56100;fill-opacity:1;stroke-width:0.7928459">A FLOOR</tspan></text>
|
||||
<text
|
||||
transform="scale(0.97051272,1.0303832)"
|
||||
inkscape:label="#text4314"
|
||||
id="FlxLimTemp"
|
||||
y="122.78025"
|
||||
x="919.25299"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#179ab7;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.71494293px;line-height:1.25;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;text-anchor:middle;fill:#179ab7;fill-opacity:1;"
|
||||
y="122.78025"
|
||||
x="919.25299"
|
||||
id="tspan1029"
|
||||
sodipodi:role="line">00</tspan></text>
|
||||
<text
|
||||
inkscape:label="#text4443"
|
||||
id="FlxLimDegreesC"
|
||||
y="108.14707"
|
||||
x="1061.88"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#179ab7;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"
|
||||
transform="scale(0.87983286,1.1365795)"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:31.25978088px;line-height:1.25;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';fill:#179ab7;fill-opacity:1"
|
||||
y="108.14707"
|
||||
x="1061.88"
|
||||
id="tspan1033"
|
||||
sodipodi:role="line">°C</tspan></text>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 89 KiB |
|
@ -42,8 +42,8 @@
|
|||
id="namedview371"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.43942712"
|
||||
inkscape:cx="180.81625"
|
||||
inkscape:cy="433.53356"
|
||||
inkscape:cx="623.25944"
|
||||
inkscape:cy="936.15332"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
|
@ -1755,7 +1755,7 @@
|
|||
x="650.08069"
|
||||
y="575.68427"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:31.25px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';fill:#0dc04b;fill-opacity:1;stroke-width:0.75">A-LOCK</tspan></text>
|
||||
<path
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#0dc04b;stroke-width:5.44862556;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
|
||||
d="M 555.26245,639.8335 691.24239,597.33411"
|
||||
id="SlatLine"
|
||||
|
@ -1796,4 +1796,43 @@
|
|||
width="137.63597"
|
||||
id="SlatLine_clip"
|
||||
style="opacity:0.5;fill:none;fill-opacity:1;stroke:none;stroke-width:3.34691048;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:31.71383667px;line-height:1.25;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.7928459"
|
||||
x="38.122616"
|
||||
y="47.904297"
|
||||
id="aFloor"
|
||||
transform="scale(0.94595932,1.0571279)"
|
||||
inkscape:label="#text1027"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan1025"
|
||||
x="38.122616"
|
||||
y="47.904297"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:39.99999902px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';fill:#c56100;fill-opacity:1;stroke-width:0.7928459">A FLOOR</tspan></text>
|
||||
<text
|
||||
transform="scale(0.97051272,1.0303832)"
|
||||
inkscape:label="#text4314"
|
||||
id="FlxLimTemp"
|
||||
y="122.78025"
|
||||
x="919.25299"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#179ab7;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.71494293px;line-height:1.25;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;text-anchor:middle;fill:#179ab7;fill-opacity:1;"
|
||||
y="122.78025"
|
||||
x="919.25299"
|
||||
id="tspan1029"
|
||||
sodipodi:role="line">00</tspan></text>
|
||||
<text
|
||||
inkscape:label="#text4443"
|
||||
id="FlxLimDegreesC"
|
||||
y="108.14707"
|
||||
x="1061.88"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#179ab7;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"
|
||||
transform="scale(0.87983286,1.1365795)"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:31.25978088px;line-height:1.25;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';fill:#179ab7;fill-opacity:1"
|
||||
y="108.14707"
|
||||
x="1061.88"
|
||||
id="tspan1033"
|
||||
sodipodi:role="line">°C</tspan></text>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 112 KiB |
|
@ -247,6 +247,7 @@ var postInit = func() {
|
|||
var FMGCNodes = {
|
||||
costIndex: props.globals.initNode("/FMGC/internal/cost-index", 0, "DOUBLE"),
|
||||
flexSet: props.globals.initNode("/FMGC/internal/flex-set", 0, "BOOL"),
|
||||
flexTemp: props.globals.initNode("/FMGC/internal/flex", 0, "INT"),
|
||||
mngSpdAlt: props.globals.getNode("/FMGC/internal/mng-alt-spd"),
|
||||
mngMachAlt: props.globals.getNode("/FMGC/internal/mng-alt-mach"),
|
||||
toFromSet: props.globals.initNode("/FMGC/internal/tofrom-set", 0, "BOOL"),
|
||||
|
|
99
Nasal/emesary/M_frame_notification.nas
Normal file
99
Nasal/emesary/M_frame_notification.nas
Normal file
|
@ -0,0 +1,99 @@
|
|||
#---------------------------------------------------------------------------
|
||||
#
|
||||
# Title : Emesary based rt exec frame notifications
|
||||
#
|
||||
# File Type : Implementation File
|
||||
#
|
||||
# Description : Uses emesary notifications to permit nasal subsystems to be notified each frame.
|
||||
# : A frame is defined by the timer rate; which is usually the maximum rate as determined by the FPS.
|
||||
# : This is an alternative to the timer based or explicit function calling way of invoking
|
||||
# : aircraft systems.
|
||||
# : It has the advantage of using less timers and remaining modular, as each aircraft subsytem
|
||||
# : can simply register itself with the global transmitter to receive the frame notification.
|
||||
#
|
||||
# Author : Richard Harrison (richard@zaretto.com)
|
||||
#
|
||||
# Creation Date : 4 June 2018
|
||||
#
|
||||
# Version : 1.0
|
||||
#
|
||||
# Copyright (C) 2018 Richard Harrison Released under GPL V2
|
||||
#
|
||||
#---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
var FrameNotification =
|
||||
{
|
||||
debug: 0,
|
||||
new: func(_rate)
|
||||
{
|
||||
var new_class = emesary.Notification.new("FrameNotification", _rate);
|
||||
new_class.Rate = _rate;
|
||||
new_class.FrameRate = 60;
|
||||
new_class.FrameCount = 0;
|
||||
new_class.ElapsedSeconds = 0;
|
||||
new_class.monitored = {};
|
||||
new_class.properties = {};
|
||||
|
||||
#
|
||||
# embed a recipient within this notification to allow the monitored property
|
||||
# mapping list to be modified.
|
||||
new_class.Recipient = emesary.Recipient.new("FrameNotification");
|
||||
new_class.Recipient.Receive = func(notification)
|
||||
{
|
||||
if (notification.NotificationType == "FrameNotificationAddProperty")
|
||||
{
|
||||
var root_node = props.globals;
|
||||
if (notification.root_node != nil) {
|
||||
root_node = notification.root_node;
|
||||
}
|
||||
if (new_class.properties[notification.property] != nil
|
||||
and new_class.properties[notification.property] != notification.variable)
|
||||
print("[WARNING]: (",notification.module,") FrameNotification: already have variable ",new_class.properties[notification.property]," for ",notification.variable, " referencing property ",notification.property);
|
||||
|
||||
if (new_class.monitored[notification.variable] != nil
|
||||
and new_class.monitored[notification.variable].getPath() != notification.property
|
||||
and new_class.monitored[notification.variable].getPath() != "/"~notification.property)
|
||||
print("[WARNING]: (",notification.module,") FrameNotification: already have variable ",notification.variable,"=",new_class.monitored[notification.variable].getPath(), " using different property ",notification.property);
|
||||
# else if (new_class.monitored[notification.variable] == nil)
|
||||
# print("[INFO]: (",notification.module,") FrameNotification.",notification.variable, " = ",notification.property);
|
||||
|
||||
new_class.monitored[notification.variable] = root_node.getNode(notification.property,1);
|
||||
new_class.properties[notification.property] = notification.variable;
|
||||
|
||||
print("[INFO]: (",notification.module,") FrameNotification.",notification.variable, " = ",notification.property, " -> ", new_class.monitored[notification.variable].getPath() );
|
||||
return emesary.Transmitter.ReceiptStatus_OK;
|
||||
}
|
||||
return emesary.Transmitter.ReceiptStatus_NotProcessed;
|
||||
};
|
||||
new_class.fetchvars = func() {
|
||||
foreach (var mp; keys(new_class.monitored)){
|
||||
if(new_class.monitored[mp] != nil){
|
||||
if (FrameNotification.debug > 1)
|
||||
print(" ",mp, " = ",new_class.monitored[mp].getValue());
|
||||
new_class[mp] = new_class.monitored[mp].getValue();
|
||||
}
|
||||
}
|
||||
};
|
||||
emesary.GlobalTransmitter.Register(new_class.Recipient);
|
||||
return new_class;
|
||||
},
|
||||
};
|
||||
|
||||
var FrameNotificationAddProperty =
|
||||
{
|
||||
new: func(module, variable, property, root_node=nil)
|
||||
{
|
||||
var new_class = emesary.Notification.new("FrameNotificationAddProperty", variable);
|
||||
if (root_node == nil)
|
||||
root_node = props.globals;
|
||||
new_class.module = module ;
|
||||
new_class.variable = variable;
|
||||
new_class.property = property;
|
||||
new_class.root_node = root_node;
|
||||
return new_class;
|
||||
},
|
||||
};
|
||||
#
|
||||
var frameNotification = FrameNotification.new(1);
|
||||
|
82
Nasal/emesary/exec.nas
Normal file
82
Nasal/emesary/exec.nas
Normal file
|
@ -0,0 +1,82 @@
|
|||
#---------------------------------------------------------------------------
|
||||
#
|
||||
# Title : Emesary based real time executive
|
||||
#
|
||||
# File Type : Implementation File
|
||||
#
|
||||
# Description : Uses emesary notifications to permit nasal subsystems to
|
||||
# : be invoked in a controlled manner.
|
||||
#
|
||||
# Author : Richard Harrison (richard@zaretto.com)
|
||||
#
|
||||
# Creation Date : 4 June 2018
|
||||
#
|
||||
# Version : 1.0
|
||||
#
|
||||
# Copyright (C) 2018 Richard Harrison Released under GPL V2
|
||||
#
|
||||
#---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
# to add properties to the FrameNotification simply send a FrameNotificationAddProperty
|
||||
# to the global transmitter. This will be received by the frameNotifcation object and
|
||||
# included in the update.
|
||||
#emesary.GlobalTransmitter.NotifyAll(new FrameNotificationAddProperty("MODULE", "wow","gear/gear[0]/wow"));
|
||||
#emesary.GlobalTransmitter.NotifyAll(new FrameNotificationAddProperty("MODULE", "engine_n2", "engines/engine[0]/n2"));
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# real time exec loop.
|
||||
var frame_inc = 0;
|
||||
var cur_frame_inc = 0.05;
|
||||
var execLoop = func
|
||||
{
|
||||
#
|
||||
notifications.frameNotification.fetchvars();
|
||||
if (notifications.frameNotification.FrameCount >= 4) {
|
||||
notifications.frameNotification.FrameCount = 0;
|
||||
}
|
||||
emesary.GlobalTransmitter.NotifyAll(notifications.frameNotification);
|
||||
#
|
||||
|
||||
notifications.frameNotification.FrameCount = notifications.frameNotification.FrameCount + 1;
|
||||
#
|
||||
# framecount
|
||||
# 0: HUD targets, Radar, RWR
|
||||
# 1: HUD targets, RDR, VSD
|
||||
# 2: HUD targets, HUD trig, HUD text
|
||||
# 3: HUD targets, VSD, RDR
|
||||
#
|
||||
if (notifications.frameNotification.frame_rate_worst < 5) {
|
||||
frame_inc = 0.25;#3.3
|
||||
} elsif (notifications.frameNotification.frame_rate_worst < 10) {
|
||||
frame_inc = 0.125;#6.6
|
||||
} elsif (notifications.frameNotification.frame_rate_worst < 15) {
|
||||
frame_inc = 0.10;#8.3
|
||||
} elsif (notifications.frameNotification.frame_rate_worst < 20) {
|
||||
frame_inc = 0.075;#12.5
|
||||
} elsif (notifications.frameNotification.frame_rate_worst < 25) {
|
||||
frame_inc = 0.05;#14.3
|
||||
} else {
|
||||
frame_inc = 0.05;#20.0
|
||||
}
|
||||
|
||||
if (frame_inc != cur_frame_inc) {
|
||||
cur_frame_inc = frame_inc;
|
||||
}
|
||||
settimer(execLoop, cur_frame_inc);
|
||||
}
|
||||
|
||||
# setup the properties to monitor for this system
|
||||
input = {
|
||||
FrameRate : "/sim/frame-rate",
|
||||
frame_rate : "/sim/frame-rate",
|
||||
frame_rate_worst : "/sim/frame-rate-worst",
|
||||
elapsed_seconds : "/sim/time/elapsed-sec",
|
||||
};
|
||||
|
||||
foreach (var name; keys(input)) {
|
||||
emesary.GlobalTransmitter.NotifyAll(notifications.FrameNotificationAddProperty.new("EXEC", name, input[name]));
|
||||
}
|
Loading…
Reference in a new issue