1
0
Fork 0
A320-family/Nasal/Systems/FADEC/fadec-common.nas
2020-04-27 09:58:38 -04:00

449 lines
18 KiB
Text

# A3XX FADEC/Throttle Control System
# Copyright (c) 2020 Josh Davidson (Octal450)
if (getprop("options/eng") == "IAE") {
io.include("fadec-iae.nas");
} else {
io.include("fadec-cfm.nas");
}
var Output = {
limFlex: props.globals.getNode("/systems/thrust/lim-flex"),
};
var thr1 = 0;
var thr2 = 0;
var state1 = 0;
var state2 = 0;
var engstate1 = 0;
var engstate2 = 0;
var eprtoga = 0;
var eprmct = 0;
var eprflx = 0;
var eprclb = 0;
var n1toga = 0;
var n1mct = 0;
var n1flx = 0;
var n1clb = 0;
var alpha = 0;
var flaps = 0;
var alphaProt = 0;
var togaLock = 0;
var gs = 0;
setprop("systems/thrust/alpha-floor", 0);
setprop("systems/thrust/toga-lk", 0);
setprop("systems/thrust/epr/toga-lim", 0.0);
setprop("systems/thrust/epr/mct-lim", 0.0);
setprop("systems/thrust/epr/flx-lim", 0.0);
setprop("systems/thrust/epr/clb-lim", 0.0);
setprop("systems/thrust/n1/toga-lim", 0.0);
setprop("systems/thrust/n1/mct-lim", 0.0);
setprop("systems/thrust/n1/flx-lim", 0.0);
setprop("systems/thrust/n1/clb-lim", 0.0);
setprop("engines/flx-thr", 0.0);
setprop("controls/engines/thrust-limit", "TOGA");
setprop("controls/engines/epr-limit", 0.0);
setprop("controls/engines/n1-limit", 0.0);
setprop("systems/thrust/state1", "IDLE");
setprop("systems/thrust/state2", "IDLE");
setprop("systems/thrust/lvrclb", 0);
setprop("systems/thrust/clbreduc-ft", "1500");
setprop("systems/thrust/toga-lim", 0.0);
setprop("systems/thrust/mct-lim", 0.0);
setprop("systems/thrust/clb-lim", 0.0);
setprop("systems/thrust/lim-flex", 0);
setprop("engines/flex-derate", 0);
setprop("systems/thrust/eng-out", 0);
setprop("systems/thrust/thr-locked", 0);
setprop("systems/thrust/thr-locked-alert", 0);
setprop("systems/thrust/thr-locked-flash", 0);
setprop("systems/thrust/thr-lock-time", 0);
setprop("systems/thrust/thr-lock-cmd[0]", 0);
setprop("systems/thrust/thr-lock-cmd[1]", 0);
setlistener("/sim/signals/fdm-initialized", func {
thrust_loop.start();
thrust_flash.start();
});
setlistener("/controls/engines/engine[0]/throttle-pos", func {
engstate1 = getprop("engines/engine[0]/state");
engstate2 = getprop("engines/engine[1]/state");
thr1 = getprop("controls/engines/engine[0]/throttle-pos");
if (getprop("systems/thrust/alpha-floor") == 0 and getprop("systems/thrust/toga-lk") == 0) {
if (thr1 < 0.01) {
setprop("systems/thrust/state1", "IDLE");
unflex();
atoff_request();
} else if (thr1 >= 0.01 and thr1 < 0.60) {
setprop("systems/thrust/state1", "MAN");
unflex();
} else if (thr1 >= 0.60 and thr1 < 0.65) {
setprop("systems/thrust/state1", "CL");
unflex();
} else if (thr1 >= 0.65 and thr1 < 0.78) {
setprop("systems/thrust/state1", "MAN THR");
unflex();
} else if (thr1 >= 0.78 and thr1 < 0.83) {
if (getprop("systems/thrust/eng-out") != 1) {
if (getprop("controls/engines/thrust-limit") == "FLX") {
if (getprop("gear/gear[0]/wow") == 1 and (engstate1 == 3 or engstate2 == 3)) {
setprop("it-autoflight/input/athr", 1);
}
setprop("controls/engines/engine[0]/throttle-fdm", 0.99);
} else {
setprop("controls/engines/engine[0]/throttle-fdm", 0.95);
}
}
setprop("systems/thrust/state1", "MCT");
} else if (thr1 >= 0.83 and thr1 < 0.95) {
setprop("systems/thrust/state1", "MAN THR");
unflex();
} else if (thr1 >= 0.95) {
if (getprop("gear/gear[0]/wow") == 1 and (engstate1 == 3 or engstate2 == 3)) {
setprop("it-autoflight/input/athr", 1);
}
setprop("controls/engines/engine[0]/throttle-fdm", 0.99);
setprop("systems/thrust/state1", "TOGA");
unflex();
}
} else {
if (thr1 < 0.01) {
setprop("systems/thrust/state1", "IDLE");
} else if (thr1 >= 0.01 and thr1 < 0.60) {
setprop("systems/thrust/state1", "MAN");
} else if (thr1 >= 0.60 and thr1 < 0.65) {
setprop("systems/thrust/state1", "CL");
} else if (thr1 >= 0.65 and thr1 < 0.78) {
setprop("systems/thrust/state1", "MAN THR");
} else if (thr1 >= 0.78 and thr1 < 0.83) {
setprop("systems/thrust/state1", "MCT");
} else if (thr1 >= 0.83 and thr1 < 0.95) {
setprop("systems/thrust/state1", "MAN THR");
} else if (thr1 >= 0.95) {
setprop("systems/thrust/state1", "TOGA");
}
setprop("controls/engines/engine[0]/throttle-fdm", 0.99);
}
}, 0, 0);
setlistener("/controls/engines/engine[1]/throttle-pos", func {
engstate1 = getprop("engines/engine[0]/state");
engstate2 = getprop("engines/engine[1]/state");
thr2 = getprop("controls/engines/engine[1]/throttle-pos");
if (getprop("systems/thrust/alpha-floor") == 0 and getprop("systems/thrust/toga-lk") == 0) {
if (thr2 < 0.01) {
setprop("systems/thrust/state2", "IDLE");
unflex();
atoff_request();
} else if (thr2 >= 0.01 and thr2 < 0.60) {
setprop("systems/thrust/state2", "MAN");
unflex();
} else if (thr2 >= 0.60 and thr2 < 0.65) {
setprop("systems/thrust/state2", "CL");
unflex();
} else if (thr2 >= 0.65 and thr2 < 0.78) {
setprop("systems/thrust/state2", "MAN THR");
unflex();
} else if (thr2 >= 0.78 and thr2 < 0.83) {
if (getprop("systems/thrust/eng-out") != 1) {
if (getprop("controls/engines/thrust-limit") == "FLX") {
if (getprop("gear/gear[0]/wow") == 1 and (engstate1 == 3 or engstate2 == 3)) {
setprop("it-autoflight/input/athr", 1);
}
setprop("controls/engines/engine[1]/throttle-fdm", 0.99);
} else {
setprop("controls/engines/engine[1]/throttle-fdm", 0.95);
}
}
setprop("systems/thrust/state2", "MCT");
} else if (thr2 >= 0.83 and thr2 < 0.95) {
setprop("systems/thrust/state2", "MAN THR");
unflex();
} else if (thr2 >= 0.95) {
if (getprop("gear/gear[0]/wow") == 1 and (engstate1 == 3 or engstate2 == 3)) {
setprop("it-autoflight/input/athr", 1);
}
setprop("controls/engines/engine[1]/throttle-fdm", 0.99);
setprop("systems/thrust/state2", "TOGA");
unflex();
}
} else {
if (thr2 < 0.01) {
setprop("systems/thrust/state2", "IDLE");
} else if (thr2 >= 0.01 and thr2 < 0.60) {
setprop("systems/thrust/state2", "MAN");
} else if (thr2 >= 0.60 and thr2 < 0.65) {
setprop("systems/thrust/state2", "CL");
} else if (thr2 >= 0.65 and thr2 < 0.78) {
setprop("systems/thrust/state2", "MAN THR");
} else if (thr2 >= 0.78 and thr2 < 0.83) {
setprop("systems/thrust/state2", "MCT");
} else if (thr2 >= 0.83 and thr2 < 0.95) {
setprop("systems/thrust/state2", "MAN THR");
} else if (thr2 >= 0.95) {
setprop("systems/thrust/state2", "TOGA");
}
setprop("controls/engines/engine[1]/throttle-fdm", 0.99);
}
}, 0, 0);
# Alpha Floor and Toga Lock
setlistener("/it-autoflight/input/athr", func {
if (getprop("systems/thrust/alpha-floor") == 1) {
setprop("it-autoflight/input/athr", 1);
} else {
setprop("systems/thrust/toga-lk", 0);
}
});
# Checks if all throttles are in the IDLE position, before tuning off the A/THR.
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 pts.Position.gearAglFt.getValue() > 50) {
fcu.athrOff("soft");
} elsif (pts.Position.gearAglFt.getValue() < 50) {
fcu.athrOff("none");
}
}
}
var thrust_loop = maketimer(0.04, func {
state1 = getprop("systems/thrust/state1");
state2 = getprop("systems/thrust/state2");
engstate1 = getprop("engines/engine[0]/state");
engstate2 = getprop("engines/engine[1]/state");
thr1 = getprop("controls/engines/engine[0]/throttle-pos");
thr2 = getprop("controls/engines/engine[1]/throttle-pos");
eprtoga = getprop("systems/thrust/epr/toga-lim");
eprmct = getprop("systems/thrust/epr/mct-lim");
eprflx = getprop("systems/thrust/epr/flx-lim");
eprclb = getprop("systems/thrust/epr/clb-lim");
n1toga = getprop("systems/thrust/n1/toga-lim");
n1mct = getprop("systems/thrust/n1/mct-lim");
n1flx = getprop("systems/thrust/n1/flx-lim");
n1clb = getprop("systems/thrust/n1/clb-lim");
gs = getprop("velocities/groundspeed-kt");
if (getprop("FMGC/internal/flex-set") == 1 and getprop("systems/fadec/n1mode1") == 0 and getprop("systems/fadec/n1mode2") == 0 and getprop("gear/gear[1]/wow") == 1 and getprop("gear/gear[2]/wow") == 1 and gs < 40) {
setprop("systems/thrust/lim-flex", 1);
} else if (getprop("FMGC/internal/flex-set") == 0 or engstate1 != 3 or engstate2 != 3) {
setprop("systems/thrust/lim-flex", 0);
}
if (getprop("controls/engines/engine[0]/reverser") == "1" or getprop("controls/engines/engine[1]/reverser") == "1") {
setprop("controls/engines/thrust-limit", "MREV");
setprop("controls/engines/epr-limit", 1.000);
setprop("controls/engines/n1-limit", 0.0);
} else if (getprop("gear/gear[1]/wow") == 0 or getprop("gear/gear[2]/wow") == 0 or (engstate1 != 3 and engstate2 != 3)) {
if ((state1 == "TOGA" or state2 == "TOGA" or (state1 == "MAN THR" and thr1 >= 0.83) or (state2 == "MAN THR" and thr2 >= 0.83)) or getprop("systems/thrust/alpha-floor") == 1 or getprop("systems/thrust/toga-lk") == 1) {
setprop("controls/engines/thrust-limit", "TOGA");
setprop("controls/engines/epr-limit", eprtoga);
setprop("controls/engines/n1-limit", n1toga);
} else if ((state1 == "MCT" or state2 == "MCT" or (state1 == "MAN THR" and thr1 < 0.83) or (state2 == "MAN THR" and thr2 < 0.83)) and getprop("systems/thrust/lim-flex") == 0) {
setprop("controls/engines/thrust-limit", "MCT");
setprop("controls/engines/epr-limit", eprmct);
setprop("controls/engines/n1-limit", n1mct);
} else if ((state1 == "MCT" or state2 == "MCT" or (state1 == "MAN THR" and thr1 < 0.83) or (state2 == "MAN THR" and thr2 < 0.83)) and getprop("systems/thrust/lim-flex") == 1) {
setprop("controls/engines/thrust-limit", "FLX");
setprop("controls/engines/epr-limit", eprflx);
setprop("controls/engines/n1-limit", n1flx);
} else if (state1 == "CL" or state2 == "CL" or state1 == "MAN" or state2 == "MAN" or state1 == "IDLE" or state2 == "IDLE") {
setprop("controls/engines/thrust-limit", "CLB");
setprop("controls/engines/epr-limit", eprclb);
setprop("controls/engines/n1-limit", n1clb);
}
} else if (getprop("FMGC/internal/flex-set") == 1 and getprop("systems/fadec/n1mode1") == 0 and getprop("systems/fadec/n1mode2") == 0) {
if ((state1 == "TOGA" or state2 == "TOGA" or (state1 == "MAN THR" and thr1 >= 0.83) or (state2 == "MAN THR" and thr2 >= 0.83)) or getprop("systems/thrust/alpha-floor") == 1 or getprop("systems/thrust/toga-lk") == 1) {
setprop("controls/engines/thrust-limit", "TOGA");
setprop("controls/engines/epr-limit", eprtoga);
setprop("controls/engines/n1-limit", n1toga);
} else {
setprop("controls/engines/thrust-limit", "FLX");
setprop("controls/engines/epr-limit", eprflx);
setprop("controls/engines/n1-limit", n1flx);
}
} else {
setprop("controls/engines/thrust-limit", "TOGA");
setprop("controls/engines/epr-limit", eprtoga);
setprop("controls/engines/n1-limit", n1toga);
}
alpha = getprop("fdm/jsbsim/aero/alpha-deg");
flaps = getprop("controls/flight/flap-pos");
if (flaps == 0) {
alphaProt = 9.5;
} else if (flaps == 1 or flaps == 2 or flaps == 3) {
alphaProt = 15.0;
} else if (flaps == 4) {
alphaProt = 14.0;
} else if (flaps == 5) {
alphaProt = 13.0;
}
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 pts.Position.gearAglFt.getValue() >= 100) {
setprop("systems/thrust/alpha-floor", 1);
setprop("systems/thrust/toga-lk", 0);
setprop("it-autoflight/input/athr", 1);
setprop("controls/engines/engine[0]/throttle-fdm", 0.99);
setprop("controls/engines/engine[1]/throttle-fdm", 0.99);
} else if (getprop("systems/thrust/alpha-floor") == 1 and alpha < togaLock) {
setprop("systems/thrust/alpha-floor", 0);
setprop("it-autoflight/input/athr", 1);
setprop("systems/thrust/toga-lk", 1);
setprop("controls/engines/engine[0]/throttle-fdm", 0.99);
setprop("controls/engines/engine[1]/throttle-fdm", 0.99);
}
} else {
setprop("systems/thrust/alpha-floor", 0);
setprop("systems/thrust/toga-lk", 0);
}
});
var unflex = func {
state1 = getprop("systems/thrust/state1");
state2 = getprop("systems/thrust/state2");
if (state1 != "MCT" and state2 != "MCT" and getprop("gear/gear[1]/wow") == 0 and getprop("gear/gear[2]/wow") == 0) {
setprop("systems/thrust/lim-flex", 0);
}
}
var thrust_flash = maketimer(0.5, func {
state1 = getprop("systems/thrust/state1");
state2 = getprop("systems/thrust/state2");
if (getprop("gear/gear[1]/wow") == 0 and getprop("gear/gear[2]/wow") == 0 and (getprop("engines/engine[0]/state") != 3 or getprop("engines/engine[1]/state") != 3)) {
setprop("systems/thrust/eng-out", 1);
} else {
setprop("systems/thrust/eng-out", 0);
}
if (state1 == "CL" and state2 == "CL" and getprop("systems/thrust/eng-out") != 1) {
setprop("systems/thrust/lvrclb", 0);
} else if (state1 == "MCT" and state2 == "MCT" and getprop("systems/thrust/lim-flex") != 1 and getprop("systems/thrust/eng-out") == 1) {
setprop("systems/thrust/lvrclb", 0);
} else {
var status = getprop("systems/thrust/lvrclb");
if (status == 0) {
if (getprop("gear/gear[0]/wow") == 0) {
if (getprop("systems/thrust/state1") == "MAN" or getprop("systems/thrust/state2") == "MAN") {
setprop("systems/thrust/lvrclb", 1);
} else {
if (getprop("instrumentation/altimeter/indicated-altitude-ft") >= getprop("systems/thrust/clbreduc-ft") and getprop("gear/gear[1]/wow") == 0 and getprop("gear/gear[2]/wow") == 0) {
setprop("systems/thrust/lvrclb", 1);
} else if ((state1 == "CL" and state2 != "CL") or (state1 != "CL" and state2 == "CL") and getprop("systems/thrust/eng-out") != 1) {
setprop("systems/thrust/lvrclb", 1);
} else {
setprop("systems/thrust/lvrclb", 0);
}
}
}
} else if (status == 1) {
setprop("systems/thrust/lvrclb", 0);
}
}
});
var lockThr = func() {
state1 = getprop("systems/thrust/state1");
state2 = getprop("systems/thrust/state2");
if ((state1 == "CL" and state2 == "CL" and getprop("systems/thrust/eng-out") == 0) or (state1 == "MCT" and state2 == "MCT" and getprop("systems/thrust/eng-out") == 1)) {
setprop("systems/thrust/thr-lock-time", getprop("sim/time/elapsed-sec"));
setprop("systems/thrust/thr-locked", 1);
lockTimer.start();
}
}
var checkLockThr = func() {
if (getprop("systems/thrust/thr-lock-time") + 5 > getprop("sim/time/elapsed-sec")) { return; }
if (fmgc.Output.athr.getBoolValue()) {
lockTimer.stop();
setprop("systems/thrust/thr-locked", 0);
setprop("systems/thrust/thr-locked-alert", 0);
setprop("systems/thrust/thr-lock-time", 0);
setprop("systems/thrust/thr-locked-flash", 0);
return;
}
if (getprop("systems/thrust/thr-locked") == 0) {
lockTimer.stop();
setprop("systems/thrust/thr-locked", 0);
setprop("systems/thrust/thr-locked-alert", 0);
setprop("systems/thrust/thr-lock-time", 0);
setprop("systems/thrust/thr-locked-flash", 0);
return;
}
state1 = getprop("systems/thrust/state1");
state2 = getprop("systems/thrust/state2");
if ((state1 != "CL" and state2 != "CL" and getprop("systems/thrust/eng-out") == 0) or (state1 != "MCT" and state2 != "MCT" and getprop("systems/thrust/eng-out") == 1)) {
lockTimer.stop();
setprop("systems/thrust/thr-locked", 0);
setprop("systems/thrust/thr-locked-alert", 0);
setprop("systems/thrust/thr-lock-time", 0);
setprop("systems/thrust/thr-locked-flash", 0);
} elsif ((state1 == "CL" and state2 == "CL" and getprop("systems/thrust/eng-out") == 0) or (state1 == "MCT" and state2 == "MCT" and getprop("systems/thrust/eng-out") == 1)) {
setprop("systems/thrust/thr-locked-alert", 1);
setprop("systems/thrust/thr-lock-time", getprop("sim/time/elapsed-sec"));
setprop("systems/thrust/thr-locked-flash", 1);
lockTimer.stop();
lockTimer2.start();
}
}
var checkLockThr2 = func() {
if (fmgc.Output.athr.getBoolValue()) {
lockTimer2.stop();
setprop("systems/thrust/thr-locked", 0);
setprop("systems/thrust/thr-locked-alert", 0);
setprop("systems/thrust/thr-lock-time", 0);
setprop("systems/thrust/thr-locked-flash", 0);
return;
}
if (getprop("systems/thrust/thr-locked") == 0) {
lockTimer2.stop();
setprop("systems/thrust/thr-locked", 0);
setprop("systems/thrust/thr-locked-alert", 0);
setprop("systems/thrust/thr-lock-time", 0);
setprop("systems/thrust/thr-locked-flash", 0);
return;
}
if (getprop("systems/thrust/thr-lock-time") + 5 < getprop("sim/time/elapsed-sec")) {
setprop("systems/thrust/thr-locked-flash", 0);
settimer(func() {
setprop("systems/thrust/thr-locked-flash", 1);
setprop("systems/thrust/thr-lock-time", getprop("sim/time/elapsed-sec"));
ecam.athr_lock.noRepeat = 0;
ecam.athr_lock.noRepeat2 = 0;
}, 0.2);
}
state1 = getprop("systems/thrust/state1");
state2 = getprop("systems/thrust/state2");
if ((state1 != "CL" and state2 != "CL" and getprop("systems/thrust/eng-out") == 0) or (state1 != "MCT" and state2 != "MCT" and getprop("systems/thrust/eng-out") == 1)) {
lockTimer2.stop();
setprop("systems/thrust/thr-locked", 0);
setprop("systems/thrust/thr-locked-alert", 0);
setprop("systems/thrust/thr-lock-time", 0);
setprop("systems/thrust/thr-locked-flash", 0);
}
}
setlistener("/systems/thrust/thr-locked", func {
if (getprop("systems/thrust/thr-locked") == 1) {
setprop("systems/thrust/thr-lock-cmd[0]", getprop("controls/engines/engine[0]/throttle-output"));
setprop("systems/thrust/thr-lock-cmd[1]", getprop("controls/engines/engine[1]/throttle-output"));
}
}, 0, 0);
var lockTimer = maketimer(0.1, checkLockThr);
var lockTimer2 = maketimer(0.1, checkLockThr2);