349 lines
No EOL
11 KiB
Text
349 lines
No EOL
11 KiB
Text
# A3XX IESI
|
|
|
|
# Copyright (c) 2020 Josh Davidson (Octal450)
|
|
|
|
# props.nas nodes
|
|
var iesi_init = props.globals.initNode("/instrumentation/iesi/iesi-init", 0, "BOOL");
|
|
var iesi_reset = props.globals.initNode("/instrumentation/iesi/att-reset", 0, "DOUBLE");
|
|
|
|
var pinPrograms = {
|
|
metricAltitude: 1,
|
|
showInHg: 1,
|
|
};
|
|
|
|
var canvas_IESI = {
|
|
new: func(svg, name) {
|
|
var obj = {parents: [canvas_IESI] };
|
|
obj.canvas = canvas.new({
|
|
"name": "IESI",
|
|
"size": [1024, 1024],
|
|
"view": [1024, 1024],
|
|
"mipmapping": 1,
|
|
});
|
|
|
|
obj.canvas.addPlacement({"node": "iesi.screen"});
|
|
obj.group = obj.canvas.createGroup();
|
|
|
|
obj.font_mapper = func(family, weight) {
|
|
return "ECAMFontRegular.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.AI_horizon_trans = obj["AI_horizon"].createTransform();
|
|
obj.AI_horizon_rot = obj["AI_horizon"].createTransform();
|
|
|
|
obj._aiCenter = obj["AI_center"].getCenter();
|
|
obj._cachedInhg = nil;
|
|
obj._cachedMode = nil;
|
|
obj._canReset = 0;
|
|
obj._excessMotionInInit = 0;
|
|
obj._fastInit = 0;
|
|
obj._IESITime = 0;
|
|
obj._isNegativeAlt = 0;
|
|
obj._middleAltOffset = nil;
|
|
obj._powerResult = 0;
|
|
obj._roll = 0;
|
|
|
|
obj.update_items = [
|
|
props.UpdateManager.FromHashValue("airspeed", nil, func(val) {
|
|
obj["ASI_scale"].setTranslation(0, math.clamp(val - 30, 0, 490) * 8.295);
|
|
}),
|
|
props.UpdateManager.FromHashList(["altitude","altitude_ind"], nil, func(val) {
|
|
val.altitude = math.clamp(val.altitude, -2000, 50000);
|
|
if (val.altitude < 0) {
|
|
obj["negText"].show();
|
|
obj._isNegativeAlt = 1;
|
|
} else {
|
|
obj["negText"].hide();
|
|
obj._isNegativeAlt = 0;
|
|
}
|
|
|
|
obj.altOffset = (val.altitude / 500) - int(val.altitude / 500);
|
|
obj.middleAltText = roundaboutAlt(val.altitude / 100);
|
|
if (obj.altOffset > 0.5) {
|
|
obj._middleAltOffset = -(obj.altOffset - 1) * 258.5528;
|
|
} else {
|
|
obj._middleAltOffset = -obj.altOffset * 258.5528;
|
|
}
|
|
|
|
obj["ALT_scale"].setTranslation(0, -obj._middleAltOffset);
|
|
obj["ALT_scale"].update();
|
|
obj["ALT_five"].setText(sprintf("%03d", abs(obj.middleAltText+10)));
|
|
obj["ALT_four"].setText(sprintf("%03d", abs(obj.middleAltText+5)));
|
|
obj["ALT_three"].setText(sprintf("%03d", abs(obj.middleAltText)));
|
|
obj["ALT_two"].setText(sprintf("%03d", abs(obj.middleAltText-5)));
|
|
obj["ALT_one"].setText(sprintf("%03d", abs(obj.middleAltText-10)));
|
|
|
|
|
|
if (val.altitude < 0 and val.altitude_ind > 20) {
|
|
val.altitude_ind = 20;
|
|
} elsif (val.altitude > 0 and val.altitude_ind > 500) {
|
|
val.altitude_ind = 500;
|
|
}
|
|
|
|
obj["ALT_digits"].setText(sprintf("%s", val.altitude_ind));
|
|
obj["ALT_meters"].setText(sprintf("%5.0f", math.round(val.altitude * 0.3048, 10)));
|
|
obj.altTens = num(right(sprintf("%02d", val.altitude), 2));
|
|
obj["ALT_tens"].setTranslation(0, obj.altTens * 3.16);
|
|
}),
|
|
props.UpdateManager.FromHashValue("showMach", nil, func(val) {
|
|
if (val) {
|
|
obj["ASI_mach_decimal"].show();
|
|
obj["ASI_mach"].show();
|
|
} else {
|
|
obj["ASI_mach_decimal"].hide();
|
|
obj["ASI_mach"].hide();
|
|
}
|
|
}),
|
|
props.UpdateManager.FromHashValue("mach", nil, func(val) {
|
|
if (val >= 0.999) {
|
|
obj["ASI_mach"].setText("99");
|
|
} else {
|
|
obj["ASI_mach"].setText(sprintf("%2.0f", val * 100));
|
|
}
|
|
}),
|
|
props.UpdateManager.FromHashValue("pitch", nil, func(val) {
|
|
obj.AI_horizon_trans.setTranslation(0, val * 16.74);
|
|
}),
|
|
props.UpdateManager.FromHashValue("roll", nil, func(val) {
|
|
obj._roll = -val * D2R;
|
|
obj.AI_horizon_rot.setRotation(obj._roll, obj._aiCenter);
|
|
obj["AI_bank"].setRotation(obj._roll);
|
|
}),
|
|
props.UpdateManager.FromHashValue("skid", nil, func(val) {
|
|
if (abs(val) >= 84.99) {
|
|
obj["AI_slipskid"].hide();
|
|
} else {
|
|
obj["AI_slipskid"].setTranslation(-val, 0);
|
|
obj["AI_slipskid"].show();
|
|
}
|
|
}),
|
|
];
|
|
return obj;
|
|
},
|
|
getKeys: func() {
|
|
return ["IESI","IESI_Init","attRst","attRstRect","att90s","ATTflag","ATTflag_rect","ATTflag_text","ALTwarn","SPDwarn","ASI_scale","ASI_mach","ASI_mach_decimal","AI_center","AI_index","AI_horizon","AI_sky_bank","AI_bank","AI_bank_center","AI_slipskid","ALT_scale","ALT_one","ALT_two","ALT_three","ALT_four","ALT_five","ALT_digits","ALT_tens","ALT_meters","QNH_setting","QNH_std","negText","negText2","AI_bank_scale","metricM","metricBox"];
|
|
},
|
|
alignFault: props.globals.getNode("/systems/navigation/align-fault"),
|
|
update: func(notification) {
|
|
me._powerResult = me.updatePower(notification);
|
|
if (me._powerResult == 0) { return; }
|
|
|
|
if (notification.qnh_inhg != me._cachedInhg or notification.altimeter_mode != me._cachedMode) {
|
|
me._cachedInhg = notification.qnh_inhg;
|
|
me._cachedMode = notification.altimeter_mode;
|
|
me.updateQNH(notification);
|
|
}
|
|
|
|
if (me._IESITime + 90 >= notification.elapsedTime) {
|
|
if (!me._fastInit and me.alignFault.getBoolValue()) {
|
|
me._excessMotionInInit = 1;
|
|
}
|
|
|
|
if (me._fastInit) {
|
|
me["IESI"].show();
|
|
me["IESI_Init"].hide();
|
|
me["AI_bank"].hide();
|
|
me["AI_bank_center"].hide();
|
|
me["AI_bank_scale"].hide();
|
|
me["AI_horizon"].hide();
|
|
me["AI_sky_bank"].hide();
|
|
me["ATTflag_text"].setText("ATT 10s");
|
|
me["ATTflag_text"].setColor(0,0,0);
|
|
me["ATTflag_rect"].setScale(1.5,1);
|
|
me["ATTflag_rect"].setTranslation(-250,0);
|
|
me["ATTflag_rect"].setColorFill(1,1,0);
|
|
me["ATTflag_rect"].setColor(1,1,0);
|
|
me["ATTflag"].show();
|
|
me["attRst"].hide();
|
|
me["attRstRect"].hide();
|
|
} else {
|
|
me["IESI"].hide();
|
|
me["IESI_Init"].show();
|
|
me["ATTflag"].hide();
|
|
}
|
|
return;
|
|
} else {
|
|
if (pinPrograms.metricAltitude) {
|
|
me["ALT_meters"].show();
|
|
me["metricM"].show();
|
|
me["metricBox"].show();
|
|
|
|
if (me._isNegativeAlt) {
|
|
me["negText2"].show();
|
|
} else {
|
|
me["negText2"].hide();
|
|
}
|
|
} else {
|
|
me["ALT_meters"].hide();
|
|
me["metricM"].hide();
|
|
me["metricBox"].hide();
|
|
me["negText2"].hide();
|
|
}
|
|
|
|
if (!me._excessMotionInInit) {
|
|
me["IESI_Init"].hide();
|
|
me["IESI"].show();
|
|
me["AI_bank"].show();
|
|
me["AI_bank_center"].show();
|
|
me["AI_bank_scale"].show();
|
|
me["AI_index"].show();
|
|
me["AI_horizon"].show();
|
|
me["AI_sky_bank"].show();
|
|
me["ATTflag"].hide();
|
|
} else {
|
|
me["IESI_Init"].hide();
|
|
me["IESI"].show();
|
|
me["AI_bank"].hide();
|
|
me["AI_bank_center"].hide();
|
|
me["AI_bank_scale"].hide();
|
|
me["AI_horizon"].hide();
|
|
me["AI_sky_bank"].hide();
|
|
me["ATTflag_text"].setText("ATT");
|
|
me["ATTflag_text"].setColor(1,0,0);
|
|
me["ATTflag_rect"].setScale(1,1);
|
|
me["ATTflag_rect"].setTranslation(0,0);
|
|
me["ATTflag_rect"].setColorFill(0,0,0);
|
|
me["ATTflag_rect"].setColor(0,0,0);
|
|
me["ATTflag"].show();
|
|
me["attRst"].show();
|
|
me["attRstRect"].show();
|
|
}
|
|
}
|
|
|
|
foreach(var update_item; me.update_items)
|
|
{
|
|
update_item.update(notification);
|
|
}
|
|
},
|
|
updateQNH: func(notification) {
|
|
if (notification.altimeter_mode) {
|
|
me["QNH_setting"].hide();
|
|
me["QNH_std"].show();
|
|
} else {
|
|
if (pinPrograms.showInHg) {
|
|
me["QNH_setting"].setText(sprintf("%4.0f", notification.qnh_hpa) ~ "/" ~ sprintf("%2.2f", notification.qnh_inhg));
|
|
} else {
|
|
me["QNH_setting"].setText(sprintf("%4.0f", notification.qnh_hpa));
|
|
}
|
|
me["QNH_std"].hide();
|
|
me["QNH_setting"].show();
|
|
}
|
|
},
|
|
updatePower: func(notification) {
|
|
if (notification.attReset == 1 and me._canReset) {
|
|
me._canReset = 0;
|
|
me._excessMotionInInit = 0;
|
|
me._fastInit = 1;
|
|
iesi_init.setBoolValue(0);
|
|
} else if (me._IESITime + 90 < notification.elapsedTime and notification.iesiInit and !me._canReset) {
|
|
me._canReset = 1;
|
|
}
|
|
|
|
if (notification.iesiPowered) {
|
|
if (notification.acconfig != 1 and notification.iesiInit != 1) {
|
|
iesi_init.setBoolValue(1);
|
|
me._IESITime = notification.elapsedTime - (me._fastInit ? 80 : 0);
|
|
} else if (notification.acconfig == 1 and notification.iesiInit != 1) {
|
|
iesi_init.setBoolValue(1);
|
|
me._IESITime = notification.elapsedTime - 87;
|
|
}
|
|
} elsif (notification.iesiInit) {
|
|
me._canReset = 0;
|
|
me._excessMotionInInit = 0;
|
|
me._fastInit = 0;
|
|
iesi_init.setBoolValue(0);
|
|
}
|
|
|
|
if (notification.iesiPowered and notification.iesiBrt > 0.01) {
|
|
me.group.setVisible(1);
|
|
return 1;
|
|
} else {
|
|
me.group.setVisible(0);
|
|
return 0;
|
|
}
|
|
},
|
|
};
|
|
|
|
var IESIRecipient =
|
|
{
|
|
new: func(_ident)
|
|
{
|
|
var NewIESIRecipient = emesary.Recipient.new(_ident);
|
|
NewIESIRecipient.MainScreen = nil;
|
|
NewIESIRecipient.Receive = func(notification)
|
|
{
|
|
if (notification.NotificationType == "FrameNotification")
|
|
{
|
|
if (NewIESIRecipient.MainScreen == nil) {
|
|
NewIESIRecipient.MainScreen = canvas_IESI.new("Aircraft/A320-family/Models/Instruments/IESI/res/iesi.svg", "A320 IESI");
|
|
}
|
|
|
|
if (math.mod(notifications.frameNotification.FrameCount,2) == 0) {
|
|
NewIESIRecipient.MainScreen.update(notification);
|
|
}
|
|
return emesary.Transmitter.ReceiptStatus_OK;
|
|
}
|
|
return emesary.Transmitter.ReceiptStatus_NotProcessed;
|
|
};
|
|
return NewIESIRecipient;
|
|
},
|
|
};
|
|
|
|
var A320IESI = IESIRecipient.new("A320 IESI");
|
|
emesary.GlobalTransmitter.Register(A320IESI);
|
|
|
|
var input = {
|
|
"acconfig": "/systems/acconfig/autoconfig-running",
|
|
"airspeed": "/instrumentation/airspeed-indicator[0]/indicated-speed-kt",
|
|
"altitude": "/instrumentation/altimeter[6]/indicated-altitude-ft",
|
|
"altitude_ind": "/instrumentation/altimeter[6]/indicated-altitude-ft-pfd",
|
|
"altimeter_mode": "/instrumentation/altimeter[6]/std",
|
|
"attReset": "/instrumentation/iesi/att-reset",
|
|
"iesiBrt": "/controls/lighting/DU/iesi",
|
|
"iesiInit": "/instrumentation/iesi/iesi-init",
|
|
"iesiPowered": "/instrumentation/iesi/power/power-on",
|
|
"mach": "/instrumentation/airspeed-indicator/indicated-mach",
|
|
"pitch": "/instrumentation/iesi/pitch-deg",
|
|
"qnh_hpa": "/instrumentation/altimeter[6]/setting-hpa",
|
|
"qnh_inhg": "/instrumentation/altimeter[6]/setting-inhg",
|
|
"roll": "/orientation/roll-deg",
|
|
"skid": "/instrumentation/iesi/slip-skid",
|
|
"showMach": "/instrumentation/iesi/display/show-mach",
|
|
};
|
|
|
|
foreach (var name; keys(input)) {
|
|
emesary.GlobalTransmitter.NotifyAll(notifications.FrameNotificationAddProperty.new("A320 IESI", name, input[name]));
|
|
}
|
|
|
|
var showIESI = func {
|
|
var dlg = canvas.Window.new([512, 512], "dialog").set("resize", 1);
|
|
dlg.setCanvas(A320IESI.MainScreen.canvas);
|
|
}
|
|
|
|
var roundabout = func(x) {
|
|
var y = x - int(x);
|
|
return y < 0.5 ? int(x) : 1 + int(x);
|
|
};
|
|
|
|
var roundaboutAlt = func(x) {
|
|
var y = x * 0.2 - int(x * 0.2);
|
|
return y < 0.5 ? 5 * int(x * 0.2) : 5 + 5 * int(x * 0.2);
|
|
}; |