# A3XX JSB Engine System # Joshua Davidson (it0uchpods) ######################################### # Copyright (c) it0uchpods Design Group # ######################################### ##################### # Initializing Vars # ##################### var engines = props.globals.getNode("/engines").getChildren("engine"); var n1_min = 22.4; var n2_min = 60.7; var egt_min = 434; var n1_spin = 5.1; var n2_spin = 22.8; var n1_start = 22.3; var n2_start = 60.6; var egt_start = 587; var n1_max = 105.8; var n2_max = 102.1; var egt_max = 712; var n1_wm = 0; var n2_wm = 0; var apu_max = 100; var apu_egt_min = 352; var apu_egt_max = 704; var spinup_time = 49; var start_time = 10; var egt_lightup_time = 2; var egt_lightdn_time = 8; var shutdown_time = 20; var egt_shutdown_time = 20; setprop("/systems/apu/rpm", 0); setprop("/systems/apu/egt", 42); setprop("/controls/engines/engine[0]/reverser", 0); setprop("/controls/engines/engine[1]/reverser", 0); setprop("/controls/engines/engine[0]/igniter-a", 0); setprop("/controls/engines/engine[1]/igniter-a", 0); setprop("/controls/engines/engine[0]/igniter-b", 0); setprop("/controls/engines/engine[1]/igniter-b", 0); setprop("/controls/engines/engine[0]/last-igniter", "B"); setprop("/controls/engines/engine[1]/last-igniter", "B"); var eng_init = func { setprop("/controls/engines/engine[0]/man-start", 0); setprop("/controls/engines/engine[1]/man-start", 0); } ############################## # Trigger Startups and Stops # ############################## setlistener("/controls/engines/engine[0]/cutoff-switch", func { if (getprop("/controls/engines/engine[0]/cutoff-switch") == 0) { if (getprop("/systems/acconfig/autoconfig-running") == 1) { fast_start_one(); } else { if (getprop("/controls/engines/engine[0]/man-start") == 0) { start_one_check(); } else if (getprop("/controls/engines/engine[0]/man-start") == 1) { eng_one_man_startt.start(); } } } else if (getprop("/controls/engines/engine[0]/cutoff-switch") == 1) { eng_one_auto_startt.stop(); eng_one_man_startt.stop(); eng_one_n2_checkt.stop(); setprop("/controls/engines/engine[0]/igniter-a", 0); setprop("/controls/engines/engine[0]/igniter-b", 0); setprop("/controls/engines/engine[0]/man-start", 0); setprop("/systems/pneumatic/eng1-starter", 0); setprop("/controls/engines/engine[0]/starter", 0); setprop("/controls/engines/engine[0]/cutoff", 1); setprop("/engines/engine[0]/state", 0); interpolate(engines[0].getNode("egt-actual"), 0, egt_shutdown_time); eng_one_n2_checkt.stop(); } }); var fast_start_one = func { setprop("/controls/engines/engine[0]/cutoff", 0); setprop("/engines/engine[0]/out-of-fuel", 0); setprop("/engines/engine[0]/run", 1); setprop("/engines/engine[0]/cutoff", 0); setprop("/engines/engine[0]/starter", 0); setprop("/fdm/jsbsim/propulsion/set-running", 0); setprop("/engines/engine[0]/state", 3); setprop("/systems/pneumatic/eng1-starter", 0); } setlistener("/controls/engines/engine[0]/man-start", func { start_one_mancheck(); }); var start_one_mancheck = func { if (getprop("/controls/engines/engine[0]/man-start") == 1) { if (getprop("/controls/engines/engine-start-switch") == 2 and (getprop("/controls/engines/engine[0]/cutoff-switch") == 1)) { setprop("/systems/pneumatic/eng1-starter", 1); settimer(start_one_mancheck_b, 0.5); } } else { if (getprop("/engines/engine[0]/state") == 1 or getprop("/engines/engine[0]/state") == 2) { setprop("/systems/pneumatic/eng1-starter", 0); setprop("/engines/engine[0]/state", 0); setprop("/controls/engines/engine[0]/starter", 0); } } } var start_one_mancheck_b = func { if (getprop("/systems/pneumatic/total-psi") >= 28) { setprop("/engines/engine[0]/state", 1); setprop("/controls/engines/engine[0]/starter", 1); } } var start_one_check = func { if (getprop("/controls/engines/engine-start-switch") == 2 and getprop("/controls/engines/engine[0]/cutoff-switch") == 0) { setprop("/systems/pneumatic/eng1-starter", 1); settimer(start_one_check_b, 0.5); } } var start_one_check_b = func { if ((getprop("/controls/engines/engine-start-switch") == 2) and (getprop("/systems/pneumatic/total-psi") >= 28) and (getprop("/controls/engines/engine[0]/cutoff-switch") == 0)) { auto_start_one(); } } setlistener("/controls/engines/engine[1]/cutoff-switch", func { if (getprop("/controls/engines/engine[1]/cutoff-switch") == 0) { if (getprop("/systems/acconfig/autoconfig-running") == 1) { fast_start_two(); } else { if (getprop("/controls/engines/engine[1]/man-start") == 0) { start_two_check(); } else if (getprop("/controls/engines/engine[1]/man-start") == 1) { eng_two_man_startt.start(); } } } else if (getprop("/controls/engines/engine[1]/cutoff-switch") == 1) { eng_two_auto_startt.stop(); eng_two_man_startt.stop(); eng_two_n2_checkt.stop(); setprop("/controls/engines/engine[1]/igniter-a", 0); setprop("/controls/engines/engine[1]/igniter-b", 0); setprop("/controls/engines/engine[1]/man-start", 0); setprop("/systems/pneumatic/eng2-starter", 0); setprop("/controls/engines/engine[1]/starter", 0); setprop("/controls/engines/engine[1]/cutoff", 1); setprop("/engines/engine[1]/state", 0); interpolate(engines[1].getNode("egt-actual"), 0, egt_shutdown_time); } }); var fast_start_two = func { setprop("/controls/engines/engine[1]/cutoff", 0); setprop("/engines/engine[1]/out-of-fuel", 0); setprop("/engines/engine[1]/run", 1); setprop("/engines/engine[1]/cutoff", 0); setprop("/engines/engine[1]/starter", 0); setprop("/fdm/jsbsim/propulsion/set-running", 1); setprop("/engines/engine[1]/state", 3); setprop("/systems/pneumatic/eng2-starter", 0); } setlistener("/controls/engines/engine[1]/man-start", func { start_two_mancheck(); }); var start_two_mancheck = func { if (getprop("/controls/engines/engine[1]/man-start") == 1) { if (getprop("/controls/engines/engine-start-switch") == 2 and (getprop("/controls/engines/engine[1]/cutoff-switch") == 1)) { setprop("/systems/pneumatic/eng2-starter", 1); settimer(start_two_mancheck_b, 0.5); } } else { if (getprop("/engines/engine[1]/state") == 1 or getprop("/engines/engine[1]/state") == 2) { setprop("/systems/pneumatic/eng2-starter", 0); setprop("/engines/engine[1]/state", 0); setprop("/controls/engines/engine[1]/starter", 0); } } } var start_two_mancheck_b = func { if (getprop("/systems/pneumatic/total-psi") >= 28) { setprop("/engines/engine[1]/state", 1); setprop("/controls/engines/engine[1]/starter", 1); } } var start_two_check = func { if (getprop("/controls/engines/engine-start-switch") == 2 and getprop("/controls/engines/engine[1]/cutoff-switch") == 0) { setprop("/systems/pneumatic/eng2-starter", 1); settimer(start_two_check_b, 0.5); } } var start_two_check_b = func { if ((getprop("/controls/engines/engine-start-switch") == 2) and (getprop("/systems/pneumatic/total-psi") >= 28) and (getprop("/controls/engines/engine[1]/cutoff-switch") == 0)) { auto_start_two(); } } #################### # Start Engine One # #################### var auto_start_one = func { setprop("/engines/engine[0]/state", 1); setprop("/controls/engines/engine[0]/starter", 1); eng_one_auto_startt.start(); } var eng_one_auto_start = func { if (getprop("/engines/engine[0]/n2-actual") >= 24.1) { eng_one_auto_startt.stop(); setprop("/engines/engine[0]/state", 2); setprop("/controls/engines/engine[0]/cutoff", 0); if (getprop("/controls/engines/engine[0]/last-igniter") == "B") { setprop("/controls/engines/engine[0]/igniter-a", 1); setprop("/controls/engines/engine[0]/igniter-b", 0); setprop("/controls/engines/engine[0]/last-igniter", "A"); } else if (getprop("/controls/engines/engine[0]/last-igniter") == "A") { setprop("/controls/engines/engine[0]/igniter-a", 0); setprop("/controls/engines/engine[0]/igniter-b", 1); setprop("/controls/engines/engine[0]/last-igniter", "B"); } interpolate(engines[0].getNode("egt-actual"), egt_start, egt_lightup_time); eng_one_n2_checkt.start(); } } var eng_one_man_start = func { if (getprop("/engines/engine[0]/n2-actual") >= 16.7) { eng_one_man_startt.stop(); setprop("/engines/engine[0]/state", 2); setprop("/controls/engines/engine[0]/cutoff", 0); setprop("/controls/engines/engine[0]/igniter-a", 1); setprop("/controls/engines/engine[0]/igniter-b", 1); interpolate(engines[0].getNode("egt-actual"), egt_start, egt_lightup_time); eng_one_n2_checkt.start(); } } var eng_one_n2_check = func { if (getprop("/engines/engine[0]/egt-actual") >= egt_start) { interpolate(engines[0].getNode("egt-actual"), egt_min, egt_lightdn_time); } if (getprop("/engines/engine[0]/n2-actual") >= 43.0) { eng_one_n2_checkt.stop(); setprop("/controls/engines/engine[0]/igniter-a", 0); setprop("/controls/engines/engine[0]/igniter-b", 0); setprop("/systems/pneumatic/eng1-starter", 0); setprop("/engines/engine[0]/state", 3); } } #################### # Start Engine Two # #################### var auto_start_two = func { setprop("/engines/engine[1]/state", 1); setprop("/controls/engines/engine[1]/starter", 1); eng_two_auto_startt.start(); } var eng_two_auto_start = func { if (getprop("/engines/engine[1]/n2-actual") >= 24.1) { eng_two_auto_startt.stop(); setprop("/engines/engine[1]/state", 2); setprop("/controls/engines/engine[1]/cutoff", 0); if (getprop("/controls/engines/engine[1]/last-igniter") == "B") { setprop("/controls/engines/engine[1]/igniter-a", 1); setprop("/controls/engines/engine[1]/igniter-b", 0); setprop("/controls/engines/engine[1]/last-igniter", "A"); } else if (getprop("/controls/engines/engine[1]/last-igniter") == "A") { setprop("/controls/engines/engine[1]/igniter-a", 0); setprop("/controls/engines/engine[1]/igniter-b", 1); setprop("/controls/engines/engine[1]/last-igniter", "B"); } interpolate(engines[1].getNode("egt-actual"), egt_start, egt_lightup_time); eng_two_n2_checkt.start(); } } var eng_two_man_start = func { if (getprop("/engines/engine[1]/n2-actual") >= 16.7) { eng_two_man_startt.stop(); setprop("/engines/engine[1]/state", 2); setprop("/controls/engines/engine[1]/cutoff", 0); setprop("/controls/engines/engine[1]/igniter-a", 1); setprop("/controls/engines/engine[1]/igniter-b", 1); interpolate(engines[1].getNode("egt-actual"), egt_start, egt_lightup_time); eng_two_n2_checkt.start(); } } var eng_two_n2_check = func { if (getprop("/engines/engine[1]/egt-actual") >= egt_start) { interpolate(engines[1].getNode("egt-actual"), egt_min, egt_lightdn_time); } if (getprop("/engines/engine[1]/n2-actual") >= 43.0) { eng_two_n2_checkt.stop(); setprop("/controls/engines/engine[1]/igniter-a", 0); setprop("/controls/engines/engine[1]/igniter-b", 0); setprop("/systems/pneumatic/eng2-starter", 0); setprop("/engines/engine[1]/state", 3); } } ############# # Start APU # ############# setlistener("/controls/APU/start", func { if ((getprop("/controls/APU/master") == 1) and (getprop("/controls/APU/start") == 1)) { if (getprop("/systems/acconfig/autoconfig-running") == 0) { interpolate("/systems/apu/rpm", apu_max, spinup_time); apu_egt_checkt.start(); } else if (getprop("/systems/acconfig/autoconfig-running") == 1) { interpolate("/systems/apu/rpm", apu_max, 5); interpolate("/systems/apu/egt", apu_egt_max, 5); } } else if (getprop("/controls/APU/master") == 0) { apu_egt_checkt.stop(); apu_stop(); } }); var apu_egt_check = func { if (getprop("/systems/apu/rpm") >= 28) { apu_egt_checkt.stop(); interpolate("/systems/apu/egt", apu_egt_max, 5); apu_egt2_checkt.start(); } } var apu_egt2_check = func { if (getprop("/systems/apu/egt") >= 701) { apu_egt2_checkt.stop(); interpolate("/systems/apu/egt", apu_egt_min, 30); } } ############ # Stop APU # ############ setlistener("/controls/APU/master", func { if (getprop("/controls/APU/master") == 0) { setprop("/controls/APU/start", 0); apu_egt_checkt.stop(); apu_egt2_checkt.stop(); apu_stop(); } }); var apu_stop = func { interpolate("/systems/apu/rpm", 0, 30); interpolate("/systems/apu/egt", 42, 40); } ####################### # Various other stuff # ####################### setlistener("/controls/engines/engine-start-switch", func { if (getprop("/engines/engine[0]/state") == 0) { start_one_check(); start_one_mancheck(); } if (getprop("/engines/engine[1]/state") == 0) { start_two_check(); start_two_mancheck(); } if ((getprop("/controls/engines/engine-start-switch") == 0) or (getprop("/controls/engines/engine-start-switch") == 1)) { if (getprop("/engines/engine[0]/state") == 1 or getprop("/engines/engine[0]/state") == 2) { setprop("/controls/engines/engine[0]/starter", 0); setprop("/controls/engines/engine[0]/cutoff", 1); setprop("/systems/pneumatic/eng1-starter", 0); setprop("/engines/engine[0]/state", 0); interpolate(engines[0].getNode("egt-actual"), 0, egt_shutdown_time); } if (getprop("/engines/engine[1]/state") == 1 or getprop("/engines/engine[1]/state") == 2) { setprop("/controls/engines/engine[1]/starter", 0); setprop("/controls/engines/engine[1]/cutoff", 1); setprop("/systems/pneumatic/eng2-starter", 0); setprop("/engines/engine[1]/state", 0); interpolate(engines[1].getNode("egt-actual"), 0, egt_shutdown_time); } } }); setlistener("/systems/pneumatic/start-psi", func { if (getprop("/systems/pneumatic/total-psi") < 12) { if (getprop("/engines/engine[0]/state") == 1 or getprop("/engines/engine[0]/state") == 2) { setprop("/controls/engines/engine[0]/starter", 0); setprop("/controls/engines/engine[0]/cutoff", 1); setprop("/systems/pneumatic/eng1-starter", 0); setprop("/engines/engine[0]/state", 0); interpolate(engines[0].getNode("egt-actual"), 0, egt_shutdown_time); } if (getprop("/engines/engine[1]/state") == 1 or getprop("/engines/engine[1]/state") == 2) { setprop("/controls/engines/engine[1]/starter", 0); setprop("/controls/engines/engine[1]/cutoff", 1); setprop("/systems/pneumatic/eng2-starter", 0); setprop("/engines/engine[1]/state", 0); interpolate(engines[1].getNode("egt-actual"), 0, egt_shutdown_time); } } }); var doIdleThrust = func { setprop("/controls/engines/engine[0]/throttle", 0.0); setprop("/controls/engines/engine[1]/throttle", 0.0); } var doTOGAThrust = func { setprop("/controls/engines/engine[0]/throttle", 1.0); setprop("/controls/engines/engine[1]/throttle", 1.0); } ######################### # Reverse Thrust System # ######################### var toggleFastRevThrust = func { var state1 = getprop("/systems/thrust/state1"); var state2 = getprop("/systems/thrust/state2"); if (state1 == "IDLE" and state2 == "IDLE" and getprop("/controls/engines/engine[0]/reverser") == "0" and getprop("/controls/engines/engine[1]/reverser") == "0" and getprop("/gear/gear[1]/wow") == 1 and getprop("/gear/gear[2]/wow") == 1) { interpolate("/engines/engine[0]/reverser-pos-norm", 1, 1.4); interpolate("/engines/engine[1]/reverser-pos-norm", 1, 1.4); setprop("/controls/engines/engine[0]/reverser", 1); setprop("/controls/engines/engine[1]/reverser", 1); setprop("/controls/engines/engine[0]/throttle-rev", 0.4); setprop("/controls/engines/engine[1]/throttle-rev", 0.4); setprop("/fdm/jsbsim/propulsion/engine[0]/reverser-angle-rad", 3.14); setprop("/fdm/jsbsim/propulsion/engine[1]/reverser-angle-rad", 3.14); } else if ((getprop("/controls/engines/engine[0]/reverser") == "1") or (getprop("/controls/engines/engine[1]/reverser") == "1") and (getprop("/gear/gear[1]/wow") == 1) and (getprop("/gear/gear[2]/wow") == 1)) { setprop("/controls/engines/engine[0]/throttle-rev", 0); setprop("/controls/engines/engine[1]/throttle-rev", 0); interpolate("/engines/engine[0]/reverser-pos-norm", 0, 1.0); interpolate("/engines/engine[1]/reverser-pos-norm", 0, 1.0); setprop("/fdm/jsbsim/propulsion/engine[0]/reverser-angle-rad", 0); setprop("/fdm/jsbsim/propulsion/engine[1]/reverser-angle-rad", 0); setprop("/controls/engines/engine[0]/reverser", 0); setprop("/controls/engines/engine[1]/reverser", 0); } } var doRevThrust = func { if (getprop("/controls/engines/engine[0]/reverser") == "1" and getprop("/controls/engines/engine[1]/reverser") == "1" and getprop("/gear/gear[1]/wow") == 1 and getprop("/gear/gear[2]/wow") == 1) { var pos1 = getprop("/controls/engines/engine[0]/throttle-rev"); var pos2 = getprop("/controls/engines/engine[1]/throttle-rev"); if (pos1 < 0.4) { setprop("/controls/engines/engine[0]/throttle-rev", pos1 + 0.133333333); } if (pos2 < 0.4) { setprop("/controls/engines/engine[1]/throttle-rev", pos2 + 0.133333333); } } var state1 = getprop("/systems/thrust/state1"); var state2 = getprop("/systems/thrust/state2"); if (state1 == "IDLE" and state2 == "IDLE" and getprop("/controls/engines/engine[0]/reverser") == "0" and getprop("/controls/engines/engine[1]/reverser") == "0" and getprop("/gear/gear[1]/wow") == 1 and getprop("/gear/gear[2]/wow") == 1) { setprop("/controls/engines/engine[0]/throttle-rev", 0); setprop("/controls/engines/engine[1]/throttle-rev", 0); interpolate("/engines/engine[0]/reverser-pos-norm", 1, 1.4); interpolate("/engines/engine[1]/reverser-pos-norm", 1, 1.4); setprop("/controls/engines/engine[0]/reverser", 1); setprop("/controls/engines/engine[1]/reverser", 1); setprop("/fdm/jsbsim/propulsion/engine[0]/reverser-angle-rad", 3.14); setprop("/fdm/jsbsim/propulsion/engine[1]/reverser-angle-rad", 3.14); } } var unRevThrust = func { if (getprop("/controls/engines/engine[0]/reverser") == "1" or getprop("/controls/engines/engine[1]/reverser") == "1") { var pos1 = getprop("/controls/engines/engine[0]/throttle-rev"); var pos2 = getprop("/controls/engines/engine[1]/throttle-rev"); if (pos1 > 0.0) { setprop("/controls/engines/engine[0]/throttle-rev", pos1 - 0.133333333); } else { unRevThrust_b(); } if (pos2 > 0.0) { setprop("/controls/engines/engine[1]/throttle-rev", pos2 - 0.133333333); } else { unRevThrust_b(); } } } var unRevThrust_b = func { setprop("/controls/engines/engine[0]/throttle-rev", 0); setprop("/controls/engines/engine[1]/throttle-rev", 0); interpolate("/engines/engine[0]/reverser-pos-norm", 0, 1.0); interpolate("/engines/engine[1]/reverser-pos-norm", 0, 1.0); setprop("/fdm/jsbsim/propulsion/engine[0]/reverser-angle-rad", 0); setprop("/fdm/jsbsim/propulsion/engine[1]/reverser-angle-rad", 0); setprop("/controls/engines/engine[0]/reverser", 0); setprop("/controls/engines/engine[1]/reverser", 0); } # Timers var eng_one_auto_startt = maketimer(0.5, eng_one_auto_start); var eng_one_man_startt = maketimer(0.5, eng_one_man_start); var eng_one_n2_checkt = maketimer(0.5, eng_one_n2_check); var eng_two_auto_startt = maketimer(0.5, eng_two_auto_start); var eng_two_man_startt = maketimer(0.5, eng_two_man_start); var eng_two_n2_checkt = maketimer(0.5, eng_two_n2_check); var apu_egt_checkt = maketimer(0.5, apu_egt_check); var apu_egt2_checkt = maketimer(0.5, apu_egt2_check);