1
0
Fork 0

FWC Phases

This commit is contained in:
legoboyvdlp R 2019-10-29 15:19:43 +00:00
parent 1fa30b2b97
commit d05de526ca
20 changed files with 764 additions and 116 deletions

View file

@ -136,6 +136,7 @@ xsi:noNamespaceSchemaLocation="http://jsbsim.sourceforge.net/JSBSim.xsd">
<system file="fuel"/>
<system file="glass-effect1"/>
<system file="a320-fcs"/>
<system file="a320-fwc"/>
<system file="a320-spoiler"/>
<system file="a320-electrical"/>
<system file="a320-hydraulic"/>

View file

@ -136,6 +136,7 @@ xsi:noNamespaceSchemaLocation="http://jsbsim.sourceforge.net/JSBSim.xsd">
<system file="fuel"/>
<system file="glass-effect1"/>
<system file="a320-fcs"/>
<system file="a320-fwc"/>
<system file="a320-spoiler"/>
<system file="a320-electrical"/>
<system file="a320-hydraulic"/>

View file

@ -136,6 +136,7 @@ xsi:noNamespaceSchemaLocation="http://jsbsim.sourceforge.net/JSBSim.xsd">
<system file="fuel"/>
<system file="glass-effect1"/>
<system file="a320-fcs"/>
<system file="a320-fwc"/>
<system file="a320-spoiler"/>
<system file="a320-electrical"/>
<system file="a320-hydraulic"/>

View file

@ -1580,6 +1580,9 @@
</aircraft>
<nasal>
<pts>
<file>Aircraft/A320-family/Nasal/property-tree-setup.nas</file>
</pts>
<libraries>
<file>Aircraft/A320-family/Nasal/libraries.nas</file>
<file>Aircraft/A320-family/Nasal/buttons.nas</file>
@ -1611,7 +1614,7 @@
<file>Aircraft/A320-family/Nasal/it-fbw.nas</file>
</fbw>
<fcu>
<file>Aircraft/A320-family/Nasal/FMGC/fcu.nas</file>
<file>Aircraft/A320-family/Nasal/FMGC/FCU.nas</file>
</fcu>
<fmgc>
<file>Aircraft/A320-family/Nasal/FMGC.nas</file>
@ -1650,6 +1653,7 @@
<file>Aircraft/A320-family/Nasal/ECAM/ECAM-controller.nas</file>
<file>Aircraft/A320-family/Nasal/ECAM/ECAM-logic.nas</file>
<file>Aircraft/A320-family/Nasal/ECAM/ECAM-messages.nas</file>
<file>Aircraft/A320-family/Nasal/ECAM/ECAM-phases.nas</file>
</ecam>
<icing>
<file>Aircraft/A320-family/Nasal/icing.nas</file>

View file

@ -136,6 +136,7 @@ xsi:noNamespaceSchemaLocation="http://jsbsim.sourceforge.net/JSBSim.xsd">
<system file="fuel"/>
<system file="glass-effect1"/>
<system file="a320-fcs"/>
<system file="a320-fwc"/>
<system file="a320-spoiler"/>
<system file="a320-electrical"/>
<system file="a320-hydraulic"/>

View file

@ -136,6 +136,7 @@ xsi:noNamespaceSchemaLocation="http://jsbsim.sourceforge.net/JSBSim.xsd">
<system file="fuel"/>
<system file="glass-effect1"/>
<system file="a320-fcs"/>
<system file="a320-fwc"/>
<system file="a320-spoiler"/>
<system file="a320-electrical"/>
<system file="a320-hydraulic"/>

View file

@ -506,7 +506,10 @@ var takeoff = func {
libraries.flaptimer.start();
setprop("/controls/flight/elevator-trim", -0.07);
systems.arm_autobrake(3);
libraries.ECAM.toConfig();
setprop("/ECAM/to-config-test", 1);
settimer(func {
setprop("/ECAM/to-config-test", 0);
}, 1);
}
});
}

View file

@ -1436,9 +1436,17 @@
<value>25</value>
</greater-than-equals>
</condition>
<command>nasal</command>
<script>libraries.ECAM.toConfig();</script>
<command>property-assign</command>
<property>/ECAM/to-config-test</property>
<value>1</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/ECAM/to-config-test</property>
<value>0</value>
</binding>
</mod-up>
</action>
</animation>

View file

@ -52,9 +52,6 @@ var ECAM = {
init: func() {
setprop("/ECAM/engine-start-time", 0);
setprop("/ECAM/engine-start-time-switch", 0);
setprop("/ECAM/to-memo-enable", 1);
setprop("/ECAM/to-config", 0);
setprop("/ECAM/ldg-memo-enable", 0);
setprop("/systems/gear/landing-gear-warning-light", 0);
setprop("/ECAM/Lower/page", "door");
setprop("/ECAM/Lower/man-select", 0);
@ -132,7 +129,12 @@ var ECAM = {
wow = getprop("/gear/gear[0]/wow");
eng = getprop("/options/eng");
if (stateL == 3 and stateR == 3 and wow == 1) {
if (stateL != 3 or stateR != 3) {
if (getprop("/ECAM/engine-start-time-switch") != 0) {
setprop("/ECAM/engine-start-time-switch", 0);
setprop("/ECAM/engine-start-time", 0);
}
} else if (stateL == 3 and stateR == 3 and wow == 1) {
if (getprop("/ECAM/engine-start-time-switch") != 1) {
setprop("/ECAM/engine-start-time", getprop("/sim/time/elapsed-sec"));
setprop("/ECAM/engine-start-time-switch", 1);
@ -143,26 +145,8 @@ var ECAM = {
}
}
if (getprop("/ECAM/warning-phase") >= 3) {
setprop("/ECAM/to-memo-enable", 0);
} else {
setprop("/ECAM/to-memo-enable", 1);
}
if (getprop("/position/gear-agl-ft") <= 2000 and (getprop("/FMGC/status/phase") == 3 or getprop("/FMGC/status/phase") == 4 or getprop("/FMGC/status/phase") == 5) and wow == 0) {
setprop("/ECAM/ldg-memo-enable", 1);
} else if (getprop("/ECAM/left-msg") == "LDG-MEMO" and speed <= 80 and wow == 1) {
setprop("/ECAM/ldg-memo-enable", 0);
} else if (getprop("/ECAM/left-msg") != "LDG-MEMO") {
setprop("/ECAM/ldg-memo-enable", 0);
}
if (stateL == 3 and stateR == 3 and getprop("/ECAM/engine-start-time") + 120 < getprop("/sim/time/elapsed-sec") and getprop("/ECAM/to-memo-enable") == 1 and wow == 1) {
setprop("/ECAM/left-msg", "TO-MEMO");
} elsif (getprop("/ECAM/ldg-memo-enable") == 1) {
setprop("/ECAM/left-msg", "LDG-MEMO");
} elsif (getprop("/ECAM/show-left-msg") == 1) {
setprop("/ECAM/left-msg", "MSG"); # messages should have priority over memos - how?
if (getprop("/ECAM/show-left-msg") == 1) {
setprop("/ECAM/left-msg", "MSG");
} else {
setprop("/ECAM/left-msg", "NONE");
}
@ -173,29 +157,6 @@ var ECAM = {
setprop("/ECAM/right-msg", "NONE");
}
if (getprop("/controls/autobrake/mode") == 3 and getprop("/controls/lighting/no-smoking-sign") == 1 and getprop("/controls/lighting/seatbelt-sign") == 1 and getprop("/controls/flight/speedbrake-arm") == 1 and getprop("/controls/flight/flap-pos") > 0
and getprop("/controls/flight/flap-pos") < 5) {
# Do nothing
} else {
setprop("/ECAM/to-config", 0);
}
if (eng == "IAE") {
eprlim = getprop("/controls/engines/epr-limit");
if (abs(getprop("/engines/engine[0]/epr-actual") - eprlim) <= 0.005 or abs(getprop("/engines/engine[0]/epr-actual") - eprlim) <= 0.005) {
toPowerSet = 1;
} else {
toPowerSet = 0;
}
} else {
n1lim = getprop("/controls/engines/n1-limit");
if (abs(getprop("/engines/engine[0]/n1-actual") - n1lim) <= 0.1 or abs(getprop("/engines/engine[0]/n1-actual") - n1lim) <= 0.1) {
toPowerSet = 1;
} else {
toPowerSet = 0;
}
}
# AP / ATHR warnings
if (ap_active == 1 and getprop("/it-autoflight/output/ap-warning") == 0) {
ap_active = 0;
@ -232,62 +193,8 @@ var ECAM = {
setprop("/it-autoflight/output/athr-warning", 0);
}
# Warning Phases
if (getprop("/systems/electrical/bus/ac-1") < 110 and getprop("/systems/electrical/bus/ac-2") < 110 and getprop("/systems/electrical/bus/ac-ess") < 110) { # Reset warning phases
if (getprop("/ECAM/warning-phase") != 1) {
setprop("/ECAM/warning-phase", 1);
}
} else {
phase = getprop("/ECAM/warning-phase");
mode = getprop("/modes/pfd/fma/pitch-mode");
modeI = getprop("/it-autoflight/mode/vert");
if (phase == 1 and (stateL == 3 or stateR == 3)) {
setprop("/ECAM/warning-phase", 2);
} else if (phase == 2 and toPowerSet) {
setprop("/ECAM/warning-phase", 3);
} else if (phase == 3 and speed >= 80) {
setprop("/ECAM/warning-phase", 4);
} else if ((phase >= 2 and phase <= 4) and getprop("/fdm/jsbsim/position/wow") == 0) { # Liftoff
setprop("/ECAM/warning-phase", 5);
} else if (phase == 5 and getprop("/position/gear-agl-ft") >= 1500) {
setprop("/ECAM/warning-phase", 6);
} else if (phase == 6 and getprop("/position/gear-agl-ft") < 800) {
if (mode == "OP CLB" or mode == "CLB" or (modeI == "V/S" and getprop("/it-autoflight/input/vs") >= 100) or (modeI == "FPA" and getprop("/it-autoflight/input/fpa") >= 0.1)) {
# Do not do this if we are climbing, not in FCOM, but prevents terrain from causing early mode change. If this ends up using baro alt, not radio, then delete this if
} else {
setprop("/ECAM/warning-phase", 7);
}
} else if (phase == 7 and getprop("/fdm/jsbsim/position/wow") == 1) { # Touchdown
setprop("/ECAM/warning-phase", 8);
} else if (phase == 8 and speed < 80) {
setprop("/ECAM/warning-phase", 9);
} else if (phase == 9 and (stateL == 0 or stateR == 0)) {
setprop("/ECAM/warning-phase", 10);
setprop("/ECAM/warning-phase-10-time", getprop("/sim/time/elapsed-sec"));
} else if (phase == 10 and getprop("/ECAM/warning-phase-10-time") + 300 < getprop("/sim/time/elapsed-sec")) { # After 5 mins, reset to phase 1
setprop("/ECAM/warning-phase", 1);
}
}
LowerECAM.loop();
},
toConfig: func() {
stateL = getprop("/engines/engine[0]/state");
stateR = getprop("/engines/engine[1]/state");
wow = getprop("/gear/gear[0]/wow");
if ((getprop("/ECAM/warning-phase") == 2 or getprop("/ECAM/warning-phase") == 9) and wow == 1 and (stateL == 3 or stateR == 3) and getprop("/ECAM/left-msg") != "TO-MEMO") {
setprop("/ECAM/to-memo-enable", 1);
setprop("/ECAM/engine-start-time", getprop("/ECAM/engine-start-time") - 120);
}
if (getprop("/controls/autobrake/mode") == 3 and getprop("/controls/switches/no-smoking-sign") == 1 and getprop("/controls/switches/seatbelt-sign") == 1 and getprop("/controls/flight/speedbrake-arm") == 1 and getprop("/controls/flight/flap-pos") > 0
and getprop("/controls/flight/flap-pos") < 5) {
setprop("/ECAM/to-config", 1);
}
},
};
ECAM.MSGclr();
@ -477,7 +384,7 @@ var LowerECAM = {
} else if (warnPhase == 6) {
flapLever = getprop("/controls/flight/flap-lever");
gearLever = getprop("/controls/gear/gear-down");
agl = getprop("/position/gear-agl-ft");
agl = pts.Position.gearAglFt.getValue();
if (CRZCounting and (toPowerSet or flapLever > 0) and !CRZCondition) {
if (CRZTime + 60 < elapsedSec) {

View file

@ -30,7 +30,7 @@ var hasCleared = 0;
var statusFlag = 0;
var warning = {
new: func(msg,colour = "g",aural = 9,light = 9,hasSubmsg = 0,lastSubmsg = 0, sdPage = "nil") {
new: func(msg,colour = "g",aural = 9,light = 9,hasSubmsg = 0,lastSubmsg = 0, sdPage = "nil", isMemo = 0) {
var t = {parents:[warning]};
t.msg = msg;
@ -44,6 +44,7 @@ var warning = {
t.noRepeat2 = 0;
t.clearFlag = 0;
t.sdPage = sdPage;
t.isMemo = isMemo;
t.hasCalled = 0;
return t
@ -150,12 +151,16 @@ var ECAM_controller = {
me.reset();
},
loop: func() {
# check active messages
if ((systems.ELEC.Bus.acEss.getValue() >= 110 or systems.ELEC.Bus.ac2.getValue() >= 110) and !getprop("/systems/acconfig/acconfig-running")) {
# update FWC phases
phaseLoop();
# check active messages
messages_priority_3();
messages_priority_2();
messages_priority_1();
messages_priority_0();
messages_config_memo();
messages_memo();
messages_right_memo();
} else {
@ -176,6 +181,8 @@ var ECAM_controller = {
rightLines[n].setValue("");
}
if (getprop("/systems/acconfig/autoconfig-running")) { return; }
# write to ECAM
var counter = 0;
@ -188,6 +195,12 @@ var ECAM_controller = {
counter += 1;
}
}
if (lines[0].getValue() == "" and flash == 0) { # disable left memos if a warning exists. Warnings are processed first, so this stops leftmemos if line1 is not empty
foreach (var c; configmemos.vector) {
c.write();
}
}
if (lines[0].getValue() == "" and flash == 0) { # disable left memos if a warning exists. Warnings are processed first, so this stops leftmemos if line1 is not empty
foreach (var l; leftmemos.vector) {
@ -220,6 +233,12 @@ var ECAM_controller = {
}
}
foreach (var l; configmemos.vector) {
if (l.active == 1) {
l.active = 0;
}
}
foreach (var l; leftmemos.vector) {
if (l.active == 1) {
l.active = 0;
@ -251,7 +270,7 @@ var ECAM_controller = {
if (leftOverflow.getBoolValue()) {
foreach (var w; warnings.vector) {
if (counter >= 8) { break; }
if (w.active == 1 and w.clearFlag != 1) {
if (w.active == 1 and w.clearFlag != 1 and w.isMemo != 1) {
counter += 1;
if (w.hasSubmsg == 1) { continue; }
w.clearFlag = 1;
@ -261,7 +280,7 @@ var ECAM_controller = {
}
} else {
foreach (var w; warnings.vector) {
if (w.active == 1 and w.clearFlag != 1 and w.hasSubmsg == 1) {
if (w.active == 1 and w.clearFlag != 1 and w.hasSubmsg == 1 and w.isMemo != 1) {
w.clearFlag = 1;
hasCleared = 1;
statusFlag = 1;

View file

@ -23,10 +23,12 @@ var gear = props.globals.getNode("/gear/gear-pos-norm", 1);
var cutoff1 = props.globals.getNode("/controls/engines/engine[0]/cutoff-switch", 1);
var cutoff2 = props.globals.getNode("/controls/engines/engine[1]/cutoff-switch", 1);
var engOpt = props.globals.getNode("/options/eng", 1);
# local variables
var phaseVar = nil;
var dualFailFACActive = 1;
var emerConfigFACActive = 1;
var gear_agl_cur = nil;
var messages_priority_3 = func {
phaseVar = phaseNode.getValue();
@ -935,6 +937,30 @@ var messages_priority_2 = func {
ECAM_controller.warningReset(dcEmerconfigManOn);
}
if (fcu.FCUController.FCU1.failed and fcu.FCUController.FCU2.failed and systems.ELEC.Bus.dcEss.getValue() >= 25 and systems.ELEC.Bus.dcEss.getValue() >= 25) {
fcuFault.active = 1;
fcuFaultBaro.active = 1;
} else {
ECAM_controller.warningReset(fcuFault);
ECAM_controller.warningReset(fcuFaultBaro);
}
if (fcu.FCUController.FCU1.failed and !fcu.FCUController.FCU2.failed and systems.ELEC.Bus.dcEss.getValue() >= 25) {
fcuFault1.active = 1;
fcuFault1Baro.active = 1;
} else {
ECAM_controller.warningReset(fcuFault1);
ECAM_controller.warningReset(fcuFault1Baro);
}
if (fcu.FCUController.FCU2.failed and !fcu.FCUController.FCU1.failed and systems.ELEC.Bus.dc2.getValue() >= 25) {
fcuFault2.active = 1;
fcuFault2Baro.active = 1;
} else {
ECAM_controller.warningReset(fcuFault2);
ECAM_controller.warningReset(fcuFault2Baro);
}
# APU EMER SHUT DOWN
if (apuEmerShutdown.clearFlag == 0 and systems.apuEmerShutdown.getBoolValue() and !getprop("/systems/fire/apu/warning-active") and (getprop("/ECAM/warning-phase") == 6 or getprop("/ECAM/warning-phase") >= 9 or getprop("/ECAM/warning-phase") <= 2)) {
apuEmerShutdown.active = 1;
@ -1020,6 +1046,171 @@ var messages_priority_2 = func {
var messages_priority_1 = func {}
var messages_priority_0 = func {}
var messages_config_memo = func {
if (getprop("/controls/flight/flap-lever") == 0 or getprop("/controls/flight/flap-lever") == 4 or getprop("/controls/flight/speedbrake") != 0 or getprop("/fdm/jsbsim/hydraulics/elevator-trim/final-deg") > 1.75 or getprop("/fdm/jsbsim/hydraulics/elevator-trim/final-deg") < -3.65 or getprop("/fdm/jsbsim/hydraulics/rudder/trim-cmd-deg") < -3.55 or getprop("/fdm/jsbsim/hydraulics/rudder/trim-cmd-deg") > 3.55) {
setprop("/ECAM/to-config-normal", 0);
} else {
setprop("/ECAM/to-config-normal", 1);
}
if (getprop("/ECAM/to-config-test") and (getprop("/ECAM/warning-phase") == 2 or getprop("/ECAM/warning-phase") == 9)) {
setprop("/ECAM/to-config-set", 1);
} else {
setprop("/ECAM/to-config-set", 0);
}
if (!getprop("/ECAM/to-config-normal") or getprop("/ECAM/warning-phase") == 6) {
setprop("/ECAM/to-config-reset", 1);
} else {
setprop("/ECAM/to-config-reset", 0);
}
if (getprop("/controls/autobrake/mode") == 3) {
toMemoLine1.msg = "T.O AUTO BRK MAX";
toMemoLine1.colour = "g";
} else {
toMemoLine1.msg = "T.O AUTO BRK.....MAX";
toMemoLine1.colour = "c";
}
if (getprop("/controls/switches/seatbelt-sign") and getprop("/controls/switches/no-smoking-sign")) {
toMemoLine2.msg = " SIGNS ON";
toMemoLine2.colour = "g";
} else {
toMemoLine2.msg = " SIGNS.........ON";
toMemoLine2.colour = "c";
}
if (getprop("/controls/flight/speedbrake-arm")) {
toMemoLine3.msg = " SPLRS ARM";
toMemoLine3.colour = "g";
} else {
toMemoLine3.msg = " SPLRS........ARM";
toMemoLine3.colour = "c";
}
if (getprop("/controls/flight/flap-pos") > 0 and getprop("/controls/flight/flap-pos") < 5) {
toMemoLine4.msg = " FLAPS T.O";
toMemoLine4.colour = "g";
} else {
toMemoLine4.msg = " FLAPS........T.O";
toMemoLine4.colour = "c";
}
if (getprop("/ECAM/to-config-flipflop") and getprop("/ECAM/to-config-normal")) {
toMemoLine5.msg = " T.O CONFIG NORMAL";
toMemoLine5.colour = "g";
} else {
toMemoLine5.msg = " T.O CONFIG..TEST";
toMemoLine5.colour = "c";
}
if (getprop("/ECAM/to-config-test") and (getprop("/ECAM/warning-phase") == 2 or getprop("/ECAM/warning-phase") == 9)) {
setprop("/ECAM/to-memo-set", 1);
} else {
setprop("/ECAM/to-memo-set", 0);
}
if (getprop("/ECAM/warning-phase") == 1 or getprop("/ECAM/warning-phase") == 3 or getprop("/ECAM/warning-phase") == 6 or getprop("/ECAM/warning-phase") == 10) {
setprop("/ECAM/to-memo-reset", 1);
} else {
setprop("/ECAM/to-memo-reset", 0);
}
if ((getprop("/ECAM/warning-phase") == 2 and getprop("/ECAM/engine-start-time") != 0 and getprop("/ECAM/engine-start-time") + 120 < getprop("/sim/time/elapsed-sec")) or getprop("/ECAM/to-memo-flipflop")) {
toMemoLine1.active = 1;
toMemoLine2.active = 1;
toMemoLine3.active = 1;
toMemoLine4.active = 1;
toMemoLine5.active = 1;
} else {
ECAM_controller.warningReset(toMemoLine1);
ECAM_controller.warningReset(toMemoLine2);
ECAM_controller.warningReset(toMemoLine3);
ECAM_controller.warningReset(toMemoLine4);
ECAM_controller.warningReset(toMemoLine5);
}
if (getprop("/fdm/jsbsim/gear/gear-pos-norm") == 1) {
ldgMemoLine1.msg = "LDG LDG GEAR DN";
ldgMemoLine1.colour = "g";
} else {
ldgMemoLine1.msg = "LDG LDG GEAR......DN";
ldgMemoLine1.colour = "c";
}
if (getprop("/controls/switches/seatbelt-sign") and getprop("/controls/switches/no-smoking-sign")) {
ldgMemoLine2.msg = " SIGNS ON";
ldgMemoLine2.colour = "g";
} else {
ldgMemoLine2.msg = " SIGNS.........ON";
ldgMemoLine2.colour = "c";
}
if (getprop("/controls/flight/speedbrake-arm")) {
ldgMemoLine3.msg = " SPLRS ARM";
ldgMemoLine3.colour = "g";
} else {
ldgMemoLine3.msg = " SPLRS........ARM";
ldgMemoLine3.colour = "c";
}
if (getprop("/it-fbw/law") == 1 or getprop("instrumentation/mk-viii/inputs/discretes/momentary-flap-3-override")) {
if (getprop("/controls/flight/flap-pos") == 4) {
ldgMemoLine4.msg = " FLAPS CONF 3";
ldgMemoLine4.colour = "g";
} else {
ldgMemoLine4.msg = " FLAPS.....CONF 3";
ldgMemoLine4.colour = "c";
}
} else {
if (getprop("/controls/flight/flap-pos") == 5) {
ldgMemoLine4.msg = " FLAPS FULL";
ldgMemoLine4.colour = "g";
} else {
ldgMemoLine4.msg = " FLAPS.......FULL";
ldgMemoLine4.colour = "c";
}
}
gear_agl_cur = pts.Position.gearAglFt.getValue();
if (gear_agl_cur < 2000) {
setprop("/ECAM/ldg-memo-set", 1);
} else {
setprop("/ECAM/ldg-memo-set", 0);
}
if (gear_agl_cur > 2200) {
setprop("/ECAM/ldg-memo-reset", 1);
} else {
setprop("/ECAM/ldg-memo-reset", 0);
}
if (gear_agl_cur > 2200) {
setprop("/ECAM/ldg-memo-2200-set", 1);
} else {
setprop("/ECAM/ldg-memo-2200-set", 0);
}
if (getprop("/ECAM/warning-phase") >= 6 and getprop("/ECAM/warning-phase") <= 8) {
setprop("/ECAM/ldg-memo-2200-reset", 1);
} else {
setprop("/ECAM/ldg-memo-2200-reset", 0);
}
if ((getprop("/ECAM/warning-phase") == 6 and getprop("/ECAM/ldg-memo-flipflop") and getprop("/ECAM/ldg-memo-2200-flipflop")) or getprop("/ECAM/warning-phase") == 7 or getprop("/ECAM/warning-phase") == 8) {
ldgMemoLine1.active = 1;
ldgMemoLine2.active = 1;
ldgMemoLine3.active = 1;
ldgMemoLine4.active = 1;
} else {
ECAM_controller.warningReset(ldgMemoLine1);
ECAM_controller.warningReset(ldgMemoLine2);
ECAM_controller.warningReset(ldgMemoLine3);
ECAM_controller.warningReset(ldgMemoLine4);
}
}
var messages_memo = func {
phaseVar = phaseNode.getValue();
if (getprop("/services/fuel-truck/enable") == 1 and leftMsgNode.getValue() != "TO-MEMO" and leftMsgNode.getValue() != "LDG-MEMO") {

View file

@ -165,6 +165,14 @@ var warnings = std.Vector.new([
var dcEmerconfig = warning.new(msg: "ELEC DC EMER CONFIG", colour: "a", aural: 1, light: 0, hasSubmsg: 1),
var dcEmerconfigManOn = warning.new(msg: " -EMER ELEC PWR...MAN ON", colour: "c"),
# FCU fault
var fcuFault = warning.new(msg: "AUTO FLT FCU 1+2 FAULT", colour: "a", aural: 1, light: 1, hasSubmsg: 1),
var fcuFaultBaro = warning.new(msg: " -PFD BARO REF: STD ONLY", colour: "c"),
var fcuFault1 = warning.new(msg: "AUTO FLT FCU 1 FAULT", colour: "a", hasSubmsg: 1),
var fcuFault1Baro = warning.new(msg: " -BARO REF.......X CHECK", colour: "c"),
var fcuFault2 = warning.new(msg: "AUTO FLT FCU 2 FAULT", colour: "a", hasSubmsg: 1),
var fcuFault2Baro = warning.new(msg: " -BARO REF.......X CHECK", colour: "c"),
# APU shutdown
var apuEmerShutdown = warning.new(msg: "APU EMER SHUT DOWN", colour: "a", aural: 1, light: 1, hasSubmsg: 1),
var apuEmerShutdownMast = warning.new(msg: " -MASTER SW..........OFF", colour: "c"),
@ -183,6 +191,19 @@ var warnings = std.Vector.new([
var crgAftFireDetFault = warning.new(msg: "AFT CRG DET FAULT", colour: "a"),
]);
var configmemos = std.Vector.new([
var toMemoLine1 = warning.new(msg: "T.O AUTO BRK.....MAX", colour: "c", isMemo: 1),
var toMemoLine2 = warning.new(msg: " SIGNS.........ON", colour: "c", isMemo: 1),
var toMemoLine3 = warning.new(msg: " SPLRS........ARM", colour: "c", isMemo: 1),
var toMemoLine4 = warning.new(msg: " FLAPS........T.O", colour: "c", isMemo: 1),
var toMemoLine5 = warning.new(msg: " T.O CONFIG..TEST", colour: "c", isMemo: 1),
var ldgMemoLine1 = warning.new(msg: "LDG LDG GEAR......DN", colour: "c", isMemo: 1),
var ldgMemoLine2 = warning.new(msg: " SIGNS.........ON", colour: "c", isMemo: 1),
var ldgMemoLine3 = warning.new(msg: " SPLRS........ARM", colour: "c", isMemo: 1),
var ldgMemoLine4 = warning.new(msg: " FLAPS.......FULL", colour: "c", isMemo: 1),
]);
var leftmemos = std.Vector.new([
var company_alert = warning.new(msg: "COMPANY ALERT" ), # Not yet implemented, buzzer sound
var refuelg = warning.new(msg: "REFUELG" ),

241
Nasal/ECAM/ECAM-phases.nas Normal file
View file

@ -0,0 +1,241 @@
# A3XX FWC Phases
# Copyright (c) 2019 Jonathan Redpath (legoboyvdlp)
var gnd = 0;
var twoEngOff = 0;
var gear_agl = nil;
var gear_comp = nil;
var myPhase = nil;
var eng = nil;
var eng1epr = nil;
var eng2epr = nil;
var eng1n1 = nil;
var eng2n1 = nil;
var eng1n2 = nil;
var eng2n2 = nil;
var eprlim = nil;
var master1 = nil;
var master2 = nil;
var n1lim = nil;
var gear_agl_cur = nil;
var FWC = {
Monostable: {
phase1: props.globals.initNode("/ECAM/phases/monostable/phase-1-300", 0, "BOOL"),
phase5: props.globals.initNode("/ECAM/phases/monostable/phase-5", 0, "BOOL"),
phase7: props.globals.initNode("/ECAM/phases/monostable/phase-7", 0, "BOOL"),
phase9: props.globals.initNode("/ECAM/phases/monostable/phase-9", 0, "BOOL"),
phase1Output: props.globals.initNode("/ECAM/phases/monostable/phase-1-output"),
phase5Output: props.globals.initNode("/ECAM/phases/monostable/phase-5-output"),
phase7Output: props.globals.initNode("/ECAM/phases/monostable/phase-7-output"),
phase9Output: props.globals.initNode("/ECAM/phases/monostable/phase-9-output"),
toPowerOutput: props.globals.getNode("/ECAM/phases/monostable/to-power-set-output"),
m80kt: props.globals.getNode("/ECAM/phases/monostable-80kt"),
},
Flipflop: {
gearSet: props.globals.initNode("/ECAM/phases/flipflop/gear-set", 0, "BOOL"),
gearReset: props.globals.initNode("/ECAM/phases/flipflop/gear-reset", 0, "BOOL"),
gearOutput: props.globals.initNode("/ECAM/phases/flipflop/gear-output", 0, "BOOL"),
phase2Set: props.globals.initNode("/ECAM/phases/flipflop/phase-2-set", 0, "BOOL"),
phase2Reset: props.globals.initNode("/ECAM/phases/flipflop/phase-2-reset", 0, "BOOL"),
phase2Output: props.globals.initNode("/ECAM/phases/flipflop/phase-2-output", 0, "BOOL"),
phase10Set: props.globals.initNode("/ECAM/phases/flipflop/phase-10-set", 0, "BOOL"),
phase10Reset: props.globals.initNode("/ECAM/phases/flipflop/phase-10-reset", 0, "BOOL"),
phase10Output: props.globals.initNode("/ECAM/phases/flipflop/phase-10-output", 0, "BOOL"),
},
Timer: {
eng1idle: props.globals.initNode("/ECAM/phases/timer/eng1idle", 0, "INT"),
eng2idle: props.globals.initNode("/ECAM/phases/timer/eng2idle", 0, "INT"),
eng1or2: props.globals.initNode("/ECAM/phases/timer/eng1or2", 0, "INT"),
eng1idleOutput: props.globals.getNode("/ECAM/phases/timer/eng1idle-output"),
eng2idleOutput: props.globals.getNode("/ECAM/phases/timer/eng2idle-output"),
eng1or2Output: props.globals.initNode("/ECAM/phases/timer/eng1or2-output", 0, "INT"),
},
speed80: props.globals.initNode("/ECAM/phases/speed-gt-80", 0, "BOOL"),
toPower: props.globals.initNode("/ECAM/phases/to-power-set", 0, "BOOL"),
};
var phaseLoop = func() {
gear_agl = pts.Position.gearAglFt.getValue();
gear_comp = pts.Gear.compression[1].getValue();
myPhase = pts.ECAM.fwcWarningPhase.getValue();
eng = pts.Options.eng.getValue();
eng1epr = pts.Engines.Engine1.epractual.getValue();
eng2epr = pts.Engines.Engine2.epractual.getValue();
eng1n1 = pts.Engines.Engine1.n1actual.getValue();
eng2n1 = pts.Engines.Engine2.n1actual.getValue();
eng1n2 = pts.Engines.Engine1.n2actual.getValue();
eng2n2 = pts.Engines.Engine2.n2actual.getValue();
master1 = pts.Controls.Engines.Engine1.cutoffSw.getBoolValue();
master2 = pts.Controls.Engines.Engine2.cutoffSw.getBoolValue();
# Various things
if (gear_agl < 5) {
FWC.Flipflop.gearSet.setBoolValue(1);
} else {
FWC.Flipflop.gearSet.setBoolValue(0);
}
if (!gear_comp) {
FWC.Flipflop.gearReset.setBoolValue(1);
} else {
FWC.Flipflop.gearReset.setBoolValue(0);
}
if ((gear_agl < 5 or FWC.Flipflop.gearOutput.getBoolValue()) and gear_comp > 0) {
gnd = 1;
} else {
gnd = 0;
}
if (eng1n2 < 59.4) {
FWC.Timer.eng1idle.setValue(1);
} else {
FWC.Timer.eng1idle.setValue(0);
}
if (eng2n2 < 59.4) {
FWC.Timer.eng2idle.setValue(1);
} else {
FWC.Timer.eng2idle.setValue(0);
}
if (eng1n2 >= 59.4 or eng2n2 >= 59.4) {
FWC.Timer.eng1or2.setValue(1);
} else {
FWC.Timer.eng1or2.setValue(0);
}
if ((FWC.Timer.eng1idleOutput.getBoolValue() or master1) and (FWC.Timer.eng2idleOutput.getBoolValue() or master2)) {
twoEngOff = 1;
} else {
twoEngOff = 0;
}
if (eng == "IAE") {
eprlim = getprop("/controls/engines/epr-limit");
if ((!getprop("/controls/engines/engine[0]/reverser") and !getprop("/controls/engines/engine[1]/reverser")) and (abs(eng1epr - eprlim) <= 0.005 or abs(eng2epr - eprlim) <= 0.005)) {
FWC.toPower.setBoolValue(1);
} else {
FWC.toPower.setBoolValue(0);
}
} else {
n1lim = getprop("/controls/engines/n1-limit");
if ((!getprop("/controls/engines/engine[0]/reverser") and !getprop("/controls/engines/engine[1]/reverser")) and (abs(eng1n1 - n1lim) <= 0.1 or abs(eng2n1 - n1lim) <= 0.1)) {
FWC.toPower.setBoolValue(1);
} else {
FWC.toPower.setBoolValue(0);
}
}
if (pts.Instrumentation.AirspeedIndicator.indicatedSpdKt.getValue() > 80 and pts.Sim.Time.elapsedSec.getValue() > 5) {
FWC.speed80.setBoolValue(1);
} else {
FWC.speed80.setBoolValue(0);
}
if (myPhase == 9) {
FWC.Monostable.phase9.setBoolValue(1);
} else {
FWC.Monostable.phase9.setBoolValue(0);
}
# Phase 1 / 10 flipflop
if (myPhase == 9) {
FWC.Flipflop.phase10Set.setBoolValue(1);
} else {
FWC.Flipflop.phase10Set.setBoolValue(0);
}
if (gnd and pts.Controls.Engines.Engine1.firePb.getBoolValue()) {
FWC.Flipflop.phase10Reset.setBoolValue(1);
} else {
FWC.Flipflop.phase10Reset.setBoolValue(0);
}
if ((gnd and twoEngOff and myPhase == 9) and FWC.Flipflop.phase10Output.getBoolValue()) {
FWC.Monostable.phase1.setBoolValue(1);
} else {
FWC.Monostable.phase1.setBoolValue(0);
}
# Phase 2 flipflop
if (myPhase == 3 or myPhase == 8) {
FWC.Flipflop.phase2Set.setBoolValue(1);
} else {
FWC.Flipflop.phase2Set.setBoolValue(0);
}
if (!FWC.Monostable.m80kt.getBoolValue() and myPhase != 9 and ((!FWC.Monostable.phase9Output.getBoolValue() and gnd) or (!FWC.Monostable.toPowerOutput.getBoolValue() and gnd))) {
FWC.Flipflop.phase2Reset.setBoolValue(1);
} else {
FWC.Flipflop.phase2Reset.setBoolValue(0);
}
gear_agl_cur = pts.Position.gearAglFt.getValue();
# Phase 5 monostable
if (FWC.toPower.getBoolValue() and (gear_agl_cur <= 1500 and !gnd)) {
FWC.Monostable.phase5.setBoolValue(1);
} else {
FWC.Monostable.phase5.setBoolValue(0);
}
# Phase 7 monostable
if (!FWC.toPower.getBoolValue() and gear_agl_cur <= 1500 and gear_agl_cur <= 800 and !gnd) {
FWC.Monostable.phase7.setBoolValue(1);
} else {
FWC.Monostable.phase7.setBoolValue(0);
}
# Actual Phases
if ((gnd and twoEngOff and myPhase != 9) and !FWC.Monostable.phase1Output.getBoolValue()) {
setPhase(1);
}
if (FWC.Timer.eng1or2Output.getBoolValue() and (gnd and !FWC.toPower.getBoolValue() and !FWC.speed80.getBoolValue()) and !FWC.Flipflop.phase2Output.getBoolValue()) {
setPhase(2);
}
if (FWC.Timer.eng1or2Output.getBoolValue() and (gnd and FWC.toPower.getBoolValue()) and !FWC.speed80.getBoolValue()) {
setPhase(3);
}
if ((gnd and FWC.toPower.getBoolValue()) and FWC.speed80.getBoolValue()) {
setPhase(4);
}
if (FWC.Monostable.phase5.getBoolValue() and FWC.Monostable.phase5Output.getBoolValue()) {
setPhase(5);
}
if (!gnd and !(FWC.Monostable.phase5.getBoolValue() and FWC.Monostable.phase5Output.getBoolValue()) and !(FWC.Monostable.phase7.getBoolValue() and FWC.Monostable.phase7Output.getBoolValue())) {
setPhase(6);
}
if ((FWC.Monostable.phase7.getBoolValue() and FWC.Monostable.phase7Output.getBoolValue()) and myPhase != 8) {
setPhase(7);
}
if (!FWC.toPower.getBoolValue() and FWC.speed80.getBoolValue() and gnd) {
setPhase(8);
}
if (FWC.Flipflop.phase2Output.getBoolValue() and (gnd and !FWC.toPower.getBoolValue() and !FWC.speed80.getBoolValue()) and FWC.Timer.eng1or2.getBoolValue()) {
setPhase(9);
}
if ((gnd and twoEngOff and myPhase == 9) and FWC.Monostable.phase1Output.getBoolValue()) {
setPhase(10);
}
}
var _lastPhase = nil;
var setPhase = func(newPhase) {
if (newPhase >= 1 and newPhase <= 10 and _lastPhase != newPhase) {
pts.ECAM.fwcWarningPhase.setValue(newPhase);
print("Phase " ~ newPhase);
_lastPhase = newPhase;
}
}

View file

@ -179,7 +179,7 @@ var masterFMGC = maketimer(0.2, func {
modeI = getprop("/it-autoflight/mode/vert");
gs = getprop("/velocities/groundspeed-kt");
alt = getprop("/instrumentation/altimeter/indicated-altitude-ft");
aglalt = getprop("/position/gear-agl-ft");
aglalt = pts.Position.gearAglFt.getValue();
cruiseft = getprop("/FMGC/internal/cruise-ft");
cruiseft_b = getprop("/FMGC/internal/cruise-ft") - 200;
newcruise = getprop("/it-autoflight/internal/alt");
@ -288,7 +288,7 @@ var masterFMGC = maketimer(0.2, func {
if (gear0 == 1 and (state1 == "MCT" or state1 == "MAN THR" or state1 == "TOGA") and (state2 == "MCT" or state2 == "MAN THR" or state2 == "TOGA") and flaps < 5) {
setprop("/FMGC/status/to-state", 1);
}
if (getprop("/position/gear-agl-ft") >= 55) {
if (pts.Position.gearAglFt.getValue() >= 55) {
setprop("/FMGC/status/to-state", 0);
}
});

View file

@ -199,9 +199,9 @@ var atoff_request = func {
state1 = getprop("/systems/thrust/state1");
state2 = getprop("/systems/thrust/state2");
if ((state1 == "IDLE") and (state2 == "IDLE") and (getprop("/systems/thrust/alpha-floor") == 0) and (getprop("/systems/thrust/toga-lk") == 0)) {
if (getprop("/it-autoflight/input/athr") == 1 and getprop("/position/gear-agl-ft") > 50) {
if (getprop("/it-autoflight/input/athr") == 1 and pts.Position.gearAglFt.getValue() > 50) {
fcu.athrOff("soft");
} elsif (getprop("/position/gear-agl-ft") < 50) {
} elsif (pts.Position.gearAglFt.getValue() < 50) {
fcu.athrOff("none");
}
}
@ -280,7 +280,7 @@ var thrust_loop = maketimer(0.04, func {
togaLock = alphaProt - 1;
if (getprop("/gear/gear[1]/wow") == 0 and getprop("/gear/gear[2]/wow") == 0 and getprop("/it-fbw/law") == 0 and (getprop("/systems/thrust/eng-out") == 0 or (getprop("/systems/thrust/eng-out") == 1 and flaps == 0)) and getprop("/systems/fadec/n1mode1") == 0
and getprop("/systems/fadec/n1mode2") == 0) {
if (alpha > alphaProt and getprop("/position/gear-agl-ft") >= 100) {
if (alpha > alphaProt and pts.Position.gearAglFt.getValue() >= 100) {
setprop("/systems/thrust/alpha-floor", 1);
setprop("/systems/thrust/toga-lk", 0);
setprop("/it-autoflight/input/athr", 1);

View file

@ -312,6 +312,14 @@ canvas.Element.setVisible = func(vis) {
me._lastVisible = vis;
me.setBool("visible", vis);
};
canvas.Element._lastX = nil;
canvas.Element._lastY = nil;
canvas.Element.setScale = func(x, y) {
if (x == me._lastX and y == me._lastY) {return me;}
me._lastX = x;
me._lastY = y;
me.setScale(x, y);
};
# In air, flaps 1 is slats only. On ground, it is slats and flaps.

View file

@ -0,0 +1,62 @@
# A320 Property Tree Setup
# Copyright (c) 2019 Joshua Davidson (Octal450)
# Modified by Jonathan Redpath for A320
# Nodes organized like property tree, except when lots of identical (example: Gear wow), where vectors are used to make it easier
# Anything that says Temp is set by another file to avoid multiple getValue calls
# Usage Example: pts.Class.SubClass.node.getValue()
var Controls = {
Engines: {
Engine1: {
cutoffSw: props.globals.getNode("/controls/engines/engine[0]/cutoff-switch"),
firePb: props.globals.getNode("/controls/engines/engine[0]/fire-btn"),
},
Engine2: {
cutoffSw: props.globals.getNode("/controls/engines/engine[1]/cutoff-switch"),
firePb: props.globals.getNode("/controls/engines/engine[1]/fire-btn"),
},
},
};
var ECAM = {
fwcWarningPhase: props.globals.initNode("/ECAM/warning-phase", 1, "INT"),
};
var Engines = {
Engine1: {
epractual: props.globals.getNode("/engines/engine[0]/epr-actual"),
n1actual: props.globals.getNode("/engines/engine[0]/n1-actual"),
n2actual: props.globals.getNode("/engines/engine[0]/n2-actual"),
},
Engine2: {
epractual: props.globals.getNode("/engines/engine[1]/epr-actual"),
n1actual: props.globals.getNode("/engines/engine[1]/n1-actual"),
n2actual: props.globals.getNode("/engines/engine[1]/n2-actual"),
},
};
var Gear = {
compression: [props.globals.getNode("/gear/gear[0]/compression-norm"),props.globals.getNode("/gear/gear[1]/compression-norm"),props.globals.getNode("/gear/gear[2]/compression-norm")],
};
var Instrumentation = {
AirspeedIndicator: {
indicatedSpdKt: props.globals.getNode("/instrumentation/airspeed-indicator/indicated-speed-kt"),
},
};
var Options = {
eng: props.globals.getNode("/options/eng"),
};
var Position = {
gearAglFt: props.globals.getNode("/position/gear-agl-ft"),
};
var Sim = {
Time: {
elapsedSec: props.globals.getNode("/sim/time/elapsed-sec"),
},
};
setprop("/systems/acconfig/property-tree-setup-loaded", 1);

31
Systems/a320-fwc.xml Normal file
View file

@ -0,0 +1,31 @@
<!-- Airbus A320 FWC -->
<!-- Copyright (c) 2019 Jonathan Redpath -->
<system name="A320: FWC">
<channel name="FWC">
<actuator name="/ECAM/phases/timer/eng1idle-output">
<description>Timer for the ECAM system</description>
<input>/ECAM/phases/timer/eng1idle</input>
<rate_limit sense="decr">100</rate_limit> <!-- Instant -->
<rate_limit sense="incr">0.033</rate_limit> <!-- 30 seconds -->
</actuator>
<actuator name="/ECAM/phases/timer/eng2idle-output">
<description>Timer for the ECAM system</description>
<input>/ECAM/phases/timer/eng2idle</input>
<rate_limit sense="decr">100</rate_limit> <!-- Instant -->
<rate_limit sense="incr">0.033</rate_limit> <!-- 30 seconds -->
</actuator>
<actuator name="/ECAM/phases/timer/eng1or2-output">
<description>Timer for the ECAM system</description>
<input>/ECAM/phases/timer/eng1or2</input>
<rate_limit sense="decr">100</rate_limit> <!-- Instant -->
<rate_limit sense="incr">0.033</rate_limit> <!-- 30 seconds -->
</actuator>
</channel>
</system>

View file

@ -452,4 +452,152 @@
</R>
<output>/systems/electrical/some-electric-thingie/generator-2-reset</output>
</flipflop>
<flipflop>
<type>RS</type>
<S>
<property>/ECAM/to-config-set</property>
</S>
<R>
<property>/ECAM/to-config-reset</property>
</R>
<output>/ECAM/to-config-flipflop</output>
</flipflop>
<flipflop>
<type>RS</type>
<S>
<property>/ECAM/to-memo-set</property>
</S>
<R>
<property>/ECAM/to-memo-reset</property>
</R>
<output>/ECAM/to-memo-flipflop</output>
</flipflop>
<flipflop>
<type>SR</type>
<S>
<property>/ECAM/ldg-memo-set</property>
</S>
<R>
<property>/ECAM/ldg-memo-reset</property>
</R>
<output>/ECAM/ldg-memo-flipflop</output>
</flipflop>
<flipflop>
<type>RS</type>
<S>
<property>/ECAM/ldg-memo-2200-set</property>
</S>
<R>
<property>/ECAM/ldg-memo-2200-reset</property>
</R>
<output>/ECAM/ldg-memo-2200-flipflop</output>
</flipflop>
<flipflop>
<type>SR</type>
<S>
<property>/ECAM/phases/flipflop/gear-set</property>
</S>
<R>
<property>/ECAM/phases/flipflop/gear-reset</property>
</R>
<output>/ECAM/phases/flipflop/gear-output</output>
</flipflop>
<flipflop>
<type>SR</type>
<S>
<property>/ECAM/phases/flipflop/phase-2-set</property>
</S>
<R>
<property>/ECAM/phases/flipflop/phase-2-reset</property>
</R>
<output>/ECAM/phases/flipflop/phase-2-output</output>
</flipflop>
<flipflop>
<type>RS</type>
<S>
<property>/ECAM/phases/flipflop/phase-10-set</property>
</S>
<R>
<property>/ECAM/phases/flipflop/phase-10-reset</property>
</R>
<output>/ECAM/phases/flipflop/phase-10-output</output>
</flipflop>
<flipflop>
<type>monostable</type>
<time>
<value>2.0</value>
</time>
<S>
<not>
<property>/ECAM/phases/speed-gt-80</property>
</not>
</S>
<output>/ECAM/phases/monostable-80kt</output>
</flipflop>
<flipflop>
<type>monostable</type>
<time>
<value>300.0</value>
</time>
<S>
<property>/ECAM/phases/monostable/phase-1-300</property>
</S>
<output>/ECAM/phases/monostable/phase-1-output</output>
</flipflop>
<flipflop>
<type>monostable</type>
<time>
<value>120.0</value>
</time>
<S>
<property>/ECAM/phases/monostable/phase-5</property>
</S>
<output>/ECAM/phases/monostable/phase-5-output</output>
</flipflop>
<flipflop>
<type>monostable</type>
<time>
<value>180.0</value>
</time>
<S>
<property>/ECAM/phases/monostable/phase-7</property>
</S>
<output>/ECAM/phases/monostable/phase-7-output</output>
</flipflop>
<!-- falling edge detector - take inverse of following -->
<flipflop>
<type>monostable</type>
<inverted type="bool">true</inverted>
<time>
<value>3.0</value>
</time>
<S>
<property>/ECAM/phases/monostable/phase-9</property>
</S>
<output>/ECAM/phases/monostable/phase-9-output</output>
</flipflop>
<flipflop>
<type>monostable</type>
<inverted type="bool">true</inverted>
<time>
<value>1.0</value>
</time>
<S>
<property>/ECAM/phases/to-power-set</property>
</S>
<output>/ECAM/phases/monostable/to-power-set-output</output>
</flipflop>
</PropertyList>

View file

@ -1 +1 @@
6
7