123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- # Victor Engines - modified by Algernon from generic-yasim-engine.nas
- # -- a generic Nasal-based engine control system for YASim
- # Version 1.0.0
- #
- # Copyright (C) 2011 Ryan Miller
- #
- # This program is free software; you can redistribute it and/or
- # modify it under the terms of the GNU General Public License as
- # published by the Free Software Foundation; either version 2 of the
- # License, or (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful, but
- # WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- # General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- #
- var UPDATE_PERIOD = 0; # update interval for engine init() functions
- print("Initialising Yasim Engines");
- # jet engine class
- var Jet =
- {
- # creates a new engine object
- new: func(n, running = 0, idle_throttle = 0.01, max_start_n1 = 5.21, start_threshold = 3, spool_time = 4, start_time = 0.02, shutdown_time = 4,)
- {
- # copy the Jet object
- var m = { parents: [Jet] };
- # declare object variables
- m.number = n;
- m.name = "Engine " ~ ( n + 1 );
- m.autostart_status = 0;
- m.autostart_id = -1;
- m.loop_running = 0;
- m.started = 0;
- m.starting = 0;
- m.idle_throttle = idle_throttle;
- m.max_start_n1 = max_start_n1;
- m.start_threshold = start_threshold;
- m.spool_time = spool_time;
- m.start_time = start_time;
- m.shutdown_time = shutdown_time;
- m.overspeed_rpm = 121; # 111
- m.failure_prob = 0;
- m.crashed = props.globals.getNode("/sim/crashed");
- # create references to properties and set default values
- m.cutoff = props.globals.getNode("controls/engines/engine[" ~ n ~ "]/cutoff", 1);
- m.cutoff.setBoolValue(!running);
- m.HPcock = props.globals.getNode("controls/engines/engine[" ~ n ~ "]/HP-cock", 1);
- m.HPcock.setBoolValue(0);
- m.LPcock = props.globals.getNode("controls/engines/engine[" ~ n ~ "]/LP-cock", 1);
- m.LPcock.setBoolValue(0);
- m.n1 = props.globals.getNode("engines/engine[" ~ n ~ "]/n1", 1);
- m.n1.setDoubleValue(0);
- m.out_of_fuel = props.globals.getNode("engines/engine[" ~ n ~ "]/out-of-fuel", 1);
- m.out_of_fuel.setBoolValue(0);
- m.reverser = props.globals.getNode("controls/engines/engine[" ~ n ~ "]/reverser", 1);
- m.reverser.setBoolValue(0);
- m.rpm = props.globals.getNode("engines/engine[" ~ n ~ "]/rpm", 1);
- m.rpm.setDoubleValue(running ? 100 : 0);
- m.running = props.globals.getNode("engines/engine[" ~ n ~ "]/running", 1);
- m.running.setBoolValue(running);
- m.serviceable = props.globals.getNode("engines/engine[" ~ n ~ "]/serviceable", 1);
- m.serviceable.setBoolValue(1);
- m.starter = props.globals.getNode("controls/engines/engine[" ~ n ~ "]/starter", 1);
- m.starter.setBoolValue(0);
- m.state = props.globals.getNode("engines/engine[" ~ n ~ "]/state",1 );
- m.state.setIntValue(0);
- m.sip = props.globals.getNode("engines/engine[" ~ n ~ "]/start-in-progress", 1);
- m.sip.setBoolValue();
- m.throttle = props.globals.getNode("controls/engines/engine[" ~ n ~ "]/throttle", 1);
- m.throttle.setDoubleValue(0);
- m.throttle_lever = props.globals.getNode("controls/engines/engine[" ~ n ~ "]/throttle-lever", 1);
- m.throttle_lever.setDoubleValue(0);
- m.reheat = props.globals.getNode("engines/engine[" ~ n ~ "]/reheat",1 );
- m.reheat.setValue(0);
- m.overspeed = props.globals.getNode("engines/engine[" ~ n ~ "]/overspeed",1);
- m.overspeed.setBoolValue(0);
- m.dambase = props.globals.getNode("sim/damage/damage-zones/engine[" ~ n ~"]",1);
- m.damage = m.dambase.getNode("damage-norm", 1);
- m.damage.setValue(0);
- m.powerloss = m.dambase.getNode("power-loss-norm", 1);
- m.powerloss.setValue(0);
- m.smoking = m.dambase.getNode("smoke-norm", 1);
- m.smoking.setValue(0);
- m.fire = m.dambase.getNode("fire", 1);
- m.fire.setValue(0);
- m.stable = m.dambase.getNode("stable", 1);
- m.stable.setBoolValue(1);
- m.explosion = m.dambase.getNode("explosion", 1);
- m.explosion.setValue(0);
- m.mpexplosion = m.dambase.getNode("mp-explosion", 1);
- m.mpexplosion.setBoolValue(0);
- # return our new object
- return m;
- },
-
- # engine-specific autostart
- autostart: func
- {
- if (me.autostart_status)
- {
- me.autostart_status = 0;
- me.cutoff.setBoolValue(1);
- }
- else
- {
- me.autostart_status = 1;
- me.starter.setBoolValue(1);
- settimer(func
- {
- me.cutoff.setBoolValue(0);
- }, me.max_start_n1 / me.start_time);
- }
- },
- # creates an engine update loop (optional)
- init: func
- {
- props.globals.getNode("engines/engine["~me.number~"]/serviceable",1).alias("/sim/failure-manager/engines/engine["~me.number~"]/serviceable");
-
- setlistener("/sim/damage/damage-zones/engine["~me.number~"]/damage-norm", func { me.fail_check(); } );
-
- if (me.loop_running) return;
- me.loop_running = 1;
- var loop = func
- {
- me.update();
-
- settimer(loop, UPDATE_PERIOD);
- };
- var fail_loop = func {
- me.fail_check();
- # Debug
- #print("Failure Probability: "~ me.failure_prob);
- settimer(fail_loop, 10);
- }
-
- settimer(loop, 0);
- settimer(fail_loop, 0);
- },
- # updates the engine
- update: func {
- me.smoking.setValue( ( me.damage.getValue() * 0.55 ) + ( me.explosion.getValue() * 2 ) + ( me.fire.getValue() * 0.6 ) );
-
- if (me.running.getBoolValue() and !me.started)
- {
- me.running.setBoolValue(0);
- #me.state.setIntValue(0);
- }
-
- if ( !me.running.getBoolValue() and me.starter.getBoolValue() ) {
-
- if ( ( me.rpm.getValue() > 0.4 ) and ( me.rpm.getValue() <50 ) ) {
- me.sip.setBoolValue(1);
- me.state.setIntValue(1);
- }
-
- else {
- me.sip.setBoolValue(0);
- me.state.setIntValue(0);
- }
- }
-
- else {
- me.sip.setBoolValue(0);
- }
-
- if (me.cutoff.getBoolValue() or !me.serviceable.getBoolValue() or me.out_of_fuel.getBoolValue() )
- {
- var rpm = me.rpm.getValue();
- var time_delta = getprop("sim/time/delta-realtime-sec");
- if (me.starter.getBoolValue())
- {
- rpm += time_delta * me.spool_time;
- me.rpm.setValue(rpm >= me.max_start_n1 ? me.max_start_n1 : rpm);
- me.state.setIntValue(1);
- }
- else
- {
- rpm -= time_delta * me.shutdown_time;
- me.rpm.setValue(rpm <= 0 ? 0 : rpm);
- me.running.setBoolValue(0);
- me.throttle_lever.setDoubleValue(0);
- me.started = 0;
-
- if ( rpm > 0.5 ) {
- me.state.setIntValue(3);
- }
-
- else {
- me.state.setIntValue(0);
- }
- }
-
- }
- elsif (me.starter.getBoolValue())
- {
- var rpm = me.rpm.getValue();
- if (rpm >= me.start_threshold)
- {
- var time_delta = getprop("sim/time/delta-realtime-sec");
- rpm += time_delta * me.spool_time;
- me.rpm.setValue(rpm);
- if (rpm >= me.n1.getValue())
- {
- me.running.setBoolValue(1);
- me.starter.setBoolValue(0);
- me.started = 1;
- }
- else
- {
- me.running.setBoolValue(0);
- }
- }
- }
- elsif (me.running.getBoolValue())
- {
- if (!me.crashed.getBoolValue()) {
- me.throttle_lever.setValue(me.idle_throttle + (1 - me.idle_throttle) * me.throttle.getValue() - me.powerloss.getValue() );
-
- me.rpm.setValue( me.n1.getValue() );
- me.state.setIntValue(2);
- }
- else {
- me.reheat.setValue(0);
- me.state.setIntValue(3);
- interpolate(me.rpm,0,1);
- me.throttle_lever.setValue(0);
- }
- # me.smoking.setValue( ( me.damage.getValue() * 0.2 ) + ( me.rpm.getValue() * 0.009 ) );
- if ( me.rpm.getValue() < me.overspeed_rpm ) { me.overspeed.setBoolValue(0); }
- else { me.overspeed.setBoolValue(1); }
- }
- },
- fail_check: func {
- var x = rand();
- #print("Random Failure Generator: "~x);
- if ( me.damage.getValue() > 0.2 ) {
- me.stable.setBoolValue(0);
- }
- if ( me.damage.getValue() > 0.65 ) {
- me.serviceable.setBoolValue(0);
- }
-
- if (( me.damage.getValue() > 0.85 ) and ( me.running.getBoolValue() )) {
- me.explode(0.95);
- }
-
- if ( x < me.failure_prob ) {
- var sev = 0;
- if ( me.failure_prob < 0.01 ) { sev = ( rand() / 5 ); }
- else { sev = ( ( rand() + me.damage.getValue() ) / 4 ); }
- me.fail(sev);
-
- }
-
- if ( me.overspeed.getBoolValue() ) {
- me.failure_prob += (( rand() * 0.01 ) + ( ( ( me.rpm.getValue() * me.failure_prob ) / 1000 ) ));
- }
-
- if ( !me.stable.getBoolValue() and me.running.getBoolValue() ) {
- # Generate and add random damage
- }
- },
- fail: func (sev = 0.2) {
- print("Severity "~sev~" failure on "~ me.name );
- #me.damage.setValue( me.damage.getValue() += sev);
- var dx = ( me.damage.getValue() + sev );
- me.damage.setValue(dx);
- me.powerloss.setValue( dx * 4 );
- #interpolate(me.powerloss, ( dx * 4 ), 5);
- },
- explode: func (sev = 0.4) {
- print("Explosion in " ~ me.name );
- me.explosion.setValue(sev);
- interpolate( me.explosion, 0, ( sev * 1.15 ) );
- me.mpexplosion.setBoolValue(1);
- settimer( func {
- me.mpexplosion.setBoolValue(0);
- },2);
- if ( rand() < 0.85 ) { me.fire.setValue( ( sev + rand() ) * 0.5 ); }
- me.fail( sev );
- },
- };
- # Now do it!
- # var engine1 = Jet.new(0 , 0 , 0.01 , 5.21 , 4 , 4 , 0.05 , 1);
- #var engine2 = Jet.new(1 , 0 , 0.01 , 5.21 , 4 , 4 , 0.05 , 1);
- # engine1.init();
- # engine2.init();
- props.globals.initNode("/sim/autostart/started", 0, "BOOL");
- var eng1fuelon = func { setprop("/controls/engines/engine[0]/cutoff", 0); }
- var eng1fueloff = func { setprop("/controls/engines/engine[0]/cutoff", 1); }
- var eng2fuelon = func { setprop("/controls/engines/engine[1]/cutoff", 0); }
- var eng2fueloff = func { setprop("/controls/engines/engine[1]/cutoff", 1); }
- var eng1starter = func { setprop("/controls/engines/engine[0]/starter", 1); }
- var eng2starter = func { setprop("/controls/engines/engine[1]/starter", 1); }
- var eng1start = func {
- eng1fueloff();
- eng1starter();
- settimer(eng1fuelon, 2);
- }
- var eng2start = func {
- eng2fueloff();
- eng2starter();
- settimer(eng2fuelon, 2);
- };
- var engstart = func {
- settimer(eng1start, 2);
- settimer(eng2start, 8);
- }
- var engstop = func {
- eng1fueloff();
- eng2fueloff();
- }
- var autostart = func {
- var startstatus = getprop("/sim/autostart/started");
- if ( startstatus == 0 ) {
- gui.popupTip("Autostarting...");
- setprop("/sim/autostart/started", 1);
- setprop("/controls/electric/battery-switch", 1);
- settimer(engstart, 0.5);
- gui.popupTip("Starting Engines");
- }
- if ( startstatus == 1 ) {
- gui.popupTip("Shutting Down...");
- setprop("/sim/autostart/started", 0);
- eng1fueloff();
- eng2fueloff();
- }
- }
- var autostop = func {
- eng1fueloff();
- eng2fueloff();
- apufueloff();
- }
-
-
|