hi there, the main stuff of the new electrical system is done. if attached 3 nasal files which should be put into the Systems directory. also i've attached a diff file which registers the nasal stuff in the set-xml and connects the pfds and the eicas to the system (as example). the whole system is currently working parallel to the old one and is not affecting it. it implements the all the generators, busses, switches, relays, lights and gauges of the system. what is not done, is connecting all the systems to the busses (except of the the pfds and eicas mentioned above).
electrical.nas implements the abstract elect. system classes. could maybe used for other aircrafts too. i think its pretty flexible, but could need some improvments. :) 737-electrical.nas implements the electrical system of the 737-300 737-electrical-devices.nas implements the connectionion to the aircrafts devices. for the people who want to connect new (or old) devices to the system: the basic function of the system is, that a tree structure of ElecNodes is created (by connecting the nodes). then the current and voltage of each node is calculated (you find them in the property tree, described below). i will not describe the system in detail here (read the code in electrical.nas, i hope its not hard to understand). important for implementing is (take a look at the examples in 737-electrical-devices.nas): - create a node and give it a name and 'device' as type - overwrite the GetMyCurrent function. it should return the current sources at that time. you can read me.voltage to get the voltage currently attached to the device. - connect the node to to a bus with the e.concatNodes() function (you can find all the busses under /systems/electrics/bus/*) to the property tree: /systems/electrics/* contains the current state of each component of the system. they are grouped by their type (bus,device,relay,source,tr). /systems/electric/* contains the the interface for the panels. (input and output). they are grouped by panels. now a little extended description of the panel interfaces: Meter Panel (/controls/electric/meterpanel/*): ----------------------------------------------- Switches: dc_selector: The DC Source Selector 0: DC Standby Bus 1: Battery Bus 2: Battery 3: TR1 4: TR2 5: TR3 6: Test ac_selector: The AC Source Selector 0: AC Standby Bus 1: External AC 2: Engine Generator 1 3: APU 4: Engine Generator 2 5: Static Inverter 6: Test batteryswitch: The Battery Switch galleyswitch: The Galley Bus Switch not implemented yet: - Residual volts switch Gauges (round analog): dc_amps: DC ampere meter dc_volts: DC volts meter ac_freq: AC frequency meter ac_volts: AC volts meter Generator Bus Panel (/controls/electric/genbuspanel/*): -------------------------------------------------------- Switches: grdpwr: Ground Power switch bustrans: Bus Transfer switch (0: off, 1: auto) (the next 4 have 3 positions 0=center 1=on 2=off. they automaticly flip back from on or off to the center position) gen0: Generator 1 on genbus 1 (left) apugen0: APU Generator on genbus 1 (left) gen1: Generator 2 on genbus 2 (right) apugen1: APU Generator on genbus 2 (right) Lights: grdpwravailable: [GND POWER AVAILABLE] (blue) transferbusoff0: [TRANSFER BUS OFF] (red) left transferbusoff1: [TRANSFER BUS OFF] (red) right busoff0: [BUS OFF] (red) left busoff1: [BUS OFF] (red) right genoffbus0: [GEN OFF BUS] (blue) left genoffbus1: [GEN OFF BUS] (blue) right Gauges (round analog): acamps0: AC ampere meter (left) acamps1: AC ampere meter (right) Misc (/controls/electric/misc/*): ---------------------------------- grdsvcswitch: Ground Service Switch Standby Panel (/controls/electric/standbypanel/*): -------------------------------------------------- standbypower: Standby Switch 0:off, 1:auto 2:battery TODO: - the FIXMEs :) - generator drive disconnect - res. volts switch in the meter panel - attach all the devices of the aircraft - external DC - the APU - better current calculation in the framework closing - i think it is a good time for cvs :) cu markus -- Markus Barenhoff - Hamburg - Germany - Earth url: http://www.alios.org/ - mail: [EMAIL PROTECTED] pgpkey: 0xAE7C7759 fp: 79 64 AA D9 B7 16 F5 06 6A 88 5F A9 4D 49 45 BB
? Systems/737-electrical-devices.nas ? Systems/737-electrical.nas ? Systems/electrical.nas Index: 737-300-set.xml =================================================================== RCS file: /var/cvs/FlightGear-0.9/data/Aircraft/737-300/737-300-set.xml,v retrieving revision 1.2 diff -r1.2 737-300-set.xml 109,111c109,121 < <airground> < <file>Aircraft/737-300/Systems/air-ground.nas</file> < </airground> --- > <airground> > <file>Aircraft/737-300/Systems/air-ground.nas</file> > </airground> > <electrical-base> > <file>Aircraft/737-300/Systems/electrical.nas</file> > <module>e</module> > </electrical-base> > <electrical> > <file>Aircraft/737-300/Systems/737-electrical.nas</file> > </electrical> > <electrical-devices> > <file>Aircraft/737-300/Systems/737-electrical-devices.nas</file> > </electrical-devices> Index: Panels/737-ifr-panel.xml =================================================================== RCS file: /var/cvs/FlightGear-0.9/data/Aircraft/737-300/Panels/737-ifr-panel.xml,v retrieving revision 1.2 diff -r1.2 737-ifr-panel.xml 144a145,150 > <condition> > <greater-than> > <property>/systems/electrics/device/eicas/voltage</property> > <value type="double">27.0</value> > </greater-than> > </condition> 152a159,164 > <condition> > <greater-than> > <property>/systems/electrics/device/pfd1-lh/voltage</property> > <value type="double">27.0</value> > </greater-than> > </condition> 160a173,178 > <condition> > <greater-than> > <property>/systems/electrics/device/pfd2-lh/voltage</property> > <value type="double">27.0</value> > </greater-than> > </condition> 168a187,192 > <condition> > <greater-than> > <property>/systems/electrics/device/pfd1-rh/voltage</property> > <value type="double">27.0</value> > </greater-than> > </condition> 176a201,206 > <condition> > <greater-than> > <property>/systems/electrics/device/pfd2-rh/voltage</property> > <value type="double">27.0</value> > </greater-than> > </condition>
########################################################################## # Copyright (c) 2006 Markus Barenhoff <[EMAIL PROTECTED]> # # This file is protected by the GNU Public License. For more details, # please see the text file COPYING. ########################################################################## # TODO: # - all the FIXMEs # - generator drive disconnect # - res. volts switch in the meter panel # - attach the devices with their work load to the busses # - external DC net = e.ElecNet.new(); # # helper functions # setprop_b() = func { props.globals.getNode(arg[0], 1).setBoolValue(arg[1]); }; # # sources # apu = e.ElecNode.new(); apu.type = "source"; apu.name = "apu"; apu.u_transformer = func { # FIXME: implment apu stuff me.voltage = 115.0; }; net.addSourceNode(apu); external_ac = e.ElecNode.new(); external_ac.type = "source"; external_ac.name = "external_ac"; external_ac.u_transformer = func { if(getprop("/controls/gear/brake-parking")) { me.voltage = 115.0; } else { me.voltage = 0.0; } }; net.addSourceNode(external_ac); external_dc = e.ElecNode.new(); external_dc.type = "source"; external_dc.name = "external_dc"; external_dc.u_transformer = func { if(getprop("/controls/gear/brake-parking")) { me.voltage = 28.0; } else { me.voltage = 0.0; } }; net.addSourceNode(external_dc); enggen1 = e.ElecNode.new(); enggen1.type = "source"; enggen1.name = "generator1"; enggen1.u_transformer = func { rpm = getprop("/engines/engine[0]/n1"); factor = rpm / 20; if(factor > 1.0) { factor = 1.0; } me.voltage = (115 * factor) + (3.0 * (rand() - 0.5)); }; net.addSourceNode(enggen1); enggen2 = e.ElecNode.new(); enggen2.type = "source"; enggen2.name = "generator2"; enggen2.u_transformer = func { rpm = getprop("/engines/engine[1]/n1"); factor = rpm / 20; if(factor > 1.0) { factor = 1.0; } me.voltage = (115 * factor) + (3.0 * (rand() - 0.5)); }; net.addSourceNode(enggen2); # FIXME: implement battery stuff battery = e.ElecNode.new(); battery.type = "source"; battery.name = "battery"; battery.remaining = 600; # in A/h FIXME: get correct values battery.charging = 0; battery.charger_powered = 0; battery.u_transformer = func { me.charging = 0; me.charger_powered = 0; foreach(node; me.inputs) { if(node.voltage > 25.0) { me.charger_powered = 1; if(me.remaining < 600.0) { me.charging = 1; } } } if((me.charger_powered) or (me.remaining > 0.0)) { me.voltage = 28.0; } else { me.voltage = 0.0; } }; battery.i_transformer = func { me.default_i_transformer(); if(me.charging) { me.current = me.current + 20; # FIXME: correct load current me.remaining = me.remaining + 20; } if(!me.charger_powered) { me.remaining = me.remaining - me.current; } }; net.addSourceNode(battery); # busses genbus1 = e.ElecNode.new(); genbus1.name = "genbus1"; genbus2 = e.ElecNode.new(); genbus2.name = "genbus2"; extern_ac_bus = e.ElecNode.new(); extern_ac_bus.name = "extern_ac_bus"; grd_svc_bus = e.ElecNode.new(); grd_svc_bus.name = "ground_service_bus"; main_bus1 = e.ElecNode.new(); main_bus1.name = "main_bus1"; main_bus2 = e.ElecNode.new(); main_bus2.name = "main_bus2"; xfr_bus1 = e.ElecNode.new(); xfr_bus1.name = "xfr_bus1"; xfr_bus2 = e.ElecNode.new(); xfr_bus2.name = "xfr_bus2"; dc_bus1 = e.ElecNode.new(); dc_bus1.name = "dc_bus1"; dc_bus2 = e.ElecNode.new(); dc_bus2.name = "dc_bus2"; dctie_bus = e.ElecNode.new(); dctie_bus.name = "dctie_bus"; battery_bus = e.ElecNode.new(); battery_bus.name = "battery_bus"; hot_battery_bus = e.ElecNode.new(); hot_battery_bus.name = "hot_battery_bus"; sw_hot_battery_bus = e.ElecNode.new(); sw_hot_battery_bus.name = "sw_hot_battery_bus"; ac_stby_bus = e.ElecNode.new(); ac_stby_bus.name = "ac_stby_bus"; dc_stby_bus = e.ElecNode.new(); dc_stby_bus.name = "dc_stby_bus"; galley_bus1 = e.ElecNode.new(); galley_bus1.name = "galley_bus1"; galley_bus2 = e.ElecNode.new(); galley_bus2.name = "galley_bus2"; # relays grdpwrrelay = e.ElecNode.new(); grdpwrrelay.name = "grdpwrrelay"; grdpwrrelay.type = "relay"; grdpwrrelay.switch = func { getprop("/controls/electric/genbuspanel/grdpwr"); }; grdsvcrelay1 = e.ElecNode.new(); grdsvcrelay1.name = "grdsvcrelay1"; grdsvcrelay1.type = "relay"; grdsvcrelay1.switch = func { getprop("/controls/electric/misc/grdsvcswitch"); }; grdsvcrelay2 = e.ElecNode.new(); grdsvcrelay2.name = "grdsvcrelay2"; grdsvcrelay2.type = "relay"; grdsvcrelay2.switch = func { (!getprop("/controls/electric/misc/grdsvcswitch")); }; gengenbusrelay1 = e.ElecNode.new(); gengenbusrelay1.name = "gengenbusrelay1"; gengenbusrelay1.type = "relay"; gengenbusrelay1.switch = func {1;}; apugenbusrelay1 = e.ElecNode.new(); apugenbusrelay1.name = "apugenbusrelay1"; apugenbusrelay1.type = "relay"; apugenbusrelay1.switch = func {0;}; extgenbusrelay1 = e.ElecNode.new(); extgenbusrelay1.name = "extgenbusrelay1"; extgenbusrelay1.type = "relay"; extgenbusrelay1.switch = func {0;}; gengenbusrelay2 = e.ElecNode.new(); gengenbusrelay2.name = "gengenbusrelay2"; gengenbusrelay2.type = "relay"; gengenbusrelay2.switch = func {1;}; apugenbusrelay2 = e.ElecNode.new(); apugenbusrelay2.name = "apugenbusrelay2"; apugenbusrelay2.type = "relay"; apugenbusrelay2.switch = func {0;}; extgenbusrelay2 = e.ElecNode.new(); extgenbusrelay2.name = "extgenbusrelay2"; extgenbusrelay2.type = "relay"; extgenbusrelay2.switch = func {0;}; xfrbusrelay1norm = e.ElecNode.new(); xfrbusrelay1norm.name = "xfrbusrelay1norm"; xfrbusrelay1norm.type = "relay"; xfrbusrelay1norm.switch = func { 1; }; xfrbusrelay1alt = e.ElecNode.new(); xfrbusrelay1alt.name = "xfrbusrelay1alt"; xfrbusrelay1alt.type = "relay"; xfrbusrelay1alt.switch = func { 0; }; xfrbusrelay2norm = e.ElecNode.new(); xfrbusrelay2norm.name = "xfrbusrelay2norm"; xfrbusrelay2norm.type = "relay"; xfrbusrelay2norm.switch = func { 1; }; xfrbusrelay2alt = e.ElecNode.new(); xfrbusrelay2alt.name = "xfrbusrelay2alt"; xfrbusrelay2alt.type = "relay"; xfrbusrelay2alt.switch = func { 0; }; batchrgrelaynorm = e.ElecNode.new(); batchrgrelaynorm.name = "batchrgrelaynorm"; batchrgrelaynorm.type = "relay"; batchrgrelaynorm.switch = func { 1; }; batchrgrelayalt = e.ElecNode.new(); batchrgrelayalt.name = "batchrgrelaynorm"; batchrgrelayalt.type = "relay"; batchrgrelayalt.switch = func { 1; }; batteryrelay = e.ElecNode.new(); batteryrelay.name = "batteryrelay"; batteryrelay.type = "relay"; batteryrelay.switch = func { getprop("/controls/electric/meterpanel/batteryswitch"); }; stbynormalrelay1 = e.ElecNode.new(); stbynormalrelay1.name = "stbynormalrelay1"; stbynormalrelay1.type = "relay"; stbynormalrelay1.switch = func { 1; }; stbynormalrelay2 = e.ElecNode.new(); stbynormalrelay2.name = "stbynormalrelay2"; stbynormalrelay2.type = "relay"; stbynormalrelay2.switch = func { 1; }; stbyaltrelay1 = e.ElecNode.new(); stbyaltrelay1.name = "stbyaltrelay1"; stbyaltrelay1.type = "relay"; stbyaltrelay1.switch = func { 0; }; stbyaltrelay2 = e.ElecNode.new(); stbyaltrelay2.name = "stbyaltrelay2"; stbyaltrelay2.type = "relay"; stbyaltrelay2.switch = func { 0; }; batbusnormrelay = e.ElecNode.new(); batbusnormrelay.name = "batbusnormrelay"; batbusnormrelay.type = "relay"; batbusnormrelay.switch = func { 1; }; batbusaltrelay = e.ElecNode.new(); batbusaltrelay.name = "batbusaltrelay"; batbusaltrelay.type = "relay"; batbusaltrelay.switch = func { 0; }; tr3discrelay = e.ElecNode.new(); tr3discrelay.name = "tr3disconnectrelay"; tr3discrelay.type = "relay"; tr3discrelay.switch = func { 1; }; f = func { v = getprop("/controls/electric/meterpanel/galleyswitch"); # if switch is off -> open relay if(!v) { return 0; } # if apu power exceeds 167A on the ground if((apu.current > 167) and (airground.INAIR == "true")) { return 0; }; # close relay if one of the generator buses is not powered if((genbus1.voltage < 110) or (genbus2.voltage < 110)) { return 0;}; return 1; }; galleybusrelay1 = e.ElecNode.new(); galleybusrelay1.name = "galleybusrelay1"; galleybusrelay1.type = "relay"; galleybusrelay1.switch = f; galleybusrelay2 = e.ElecNode.new(); galleybusrelay2.name = "galleybusrelay2"; galleybusrelay2.type = "relay"; galleybusrelay2.switch = f; # TRs tr_u_transformer = func { fact = 4.1071428571428568; me.default_u_transformer(); me.voltage = me.voltage / fact; }; tr_i_transformer = func { fact = 4.1071428571428568; me.default_i_transformer(); me.current = me.current / fact; }; tr1 = e.ElecNode.new(); tr1.type = "tr"; tr1.name = "TR1"; tr1.u_transformer = tr_u_transformer; tr1.i_transformer = tr_i_transformer; tr2 = e.ElecNode.new(); tr2.type = "tr"; tr2.name = "TR2"; tr2.u_transformer = tr_u_transformer; tr2.i_transformer = tr_i_transformer; tr3 = e.ElecNode.new(); tr3.type = "tr"; tr3.name = "TR3"; tr3.u_transformer = tr_u_transformer; tr3.i_transformer = tr_i_transformer; battery_chrg = e.ElecNode.new(); battery_chrg.type = "device"; battery_chrg.name = "battery_charger"; battery_chrg.u_transformer = tr_u_transformer; battery_chrg.i_transformer = tr_i_transformer; static_inverter = e.ElecNode.new(); static_inverter.type = "device"; static_inverter.name = "static_inverter"; static_inverter.u_transformer = func { fact = 0.24347826086956523; me.default_u_transformer(); me.voltage = me.voltage / fact; }; static_inverter.i_transformer = func { fact = 0.24347826086956523; me.default_i_transformer(); me.current = me.current / fact; }; # FIXME: implement battery charging stuff battery_chrg.getMyCurrent = func { if(me.voltage > 110.0) {23.0;} else {0.0;} }; # set initial switch positions ## genbus panel # this are all 3 way switches 0:neutral 1:on 2:off setprop("/controls/electric/genbuspanel/gen0", 0); gen1inlistener = 0; f = func { if(gen1inlistener) { return; } if(enggen1.voltage < 110) { return;} gen1inlistener = 1; v = getprop("/controls/electric/genbuspanel/gen0"); if(v == 1) { gengenbusrelay1.switch = func {1;}; apugenbusrelay1.switch = func {0;}; extgenbusrelay1.switch = func {0;}; } if(v == 2) { gengenbusrelay1.switch = func {0;}; } setprop("/controls/electric/genbuspanel/gen0", 0); gen1inlistener = 0; }; setlistener("/controls/electric/genbuspanel/gen0", f); setprop("/controls/electric/genbuspanel/gen1", 0); gen2inlistener = 0; f = func { if(gen2inlistener) { return; } if(enggen2.voltage < 110) { return;} gen2inlistener = 1; v = getprop("/controls/electric/genbuspanel/gen1"); if(v == 1) { gengenbusrelay2.switch = func {1}; apugenbusrelay2.switch = func {0}; extgenbusrelay2.switch = func {0}; } if(v == 2) { gengenbusrelay2.switch = func {0;}; } setprop("/controls/electric/genbuspanel/gen1", 0); gen2inlistener = 0; }; setlistener("/controls/electric/genbuspanel/gen1", f); setprop("/controls/electric/genbuspanel/apugen0", 0); apu1inlistener = 0; f = func { if(apu1inlistener) { return; } if(apu.voltage < 110) { return;} apu1inlistener = 1; v = getprop("/controls/electric/genbuspanel/apugen0"); if(v == 1) { gengenbusrelay1.switch = func {0}; apugenbusrelay1.switch = func {1}; extgenbusrelay1.switch = func {0}; } if(v == 2) { apugenbusrelay1.switch = func {0;}; } setprop("/controls/electric/genbuspanel/apugen0", 0); apu1inlistener = 0; }; setlistener("/controls/electric/genbuspanel/apugen0", f); setprop("/controls/electric/genbuspanel/apugen1", 0); apu2inlistener = 0; f = func { if(apu2inlistener) { return; } if(apu.voltage < 110) { return;} apu2inlistener = 1; v = getprop("/controls/electric/genbuspanel/apugen1"); if(v == 1) { gengenbusrelay2.switch = func {0}; apugenbusrelay2.switch = func {1}; extgenbusrelay2.switch = func {0}; } if(v == 2) { apugenbusrelay2.switch = func {0;}; } setprop("/controls/electric/genbuspanel/apugen1", 0); apu2inlistener = 0; }; setlistener("/controls/electric/genbuspanel/apugen1", f); setprop_b("/controls/electric/genbuspanel/grdpwr", 0); f = func { v = getprop("/controls/electric/genbuspanel/grdpwr"); if(v) { gengenbusrelay1.switch = func {0}; apugenbusrelay1.switch = func {0}; extgenbusrelay1.switch = func {1}; gengenbusrelay2.switch = func {0}; apugenbusrelay2.switch = func {0}; extgenbusrelay2.switch = func {1}; } else { extgenbusrelay2.switch = func {0}; extgenbusrelay2.switch = func {0}; } } setlistener("/controls/electric/genbuspanel/grdpwr", f); setprop_b("/controls/electric/genbuspanel/bustrans", 1); ## meter panel setprop_b("/controls/electric/meterpanel/batteryswitch", 1); setprop("/controls/electric/meterpanel/ac_selector", 0); setprop("/controls/electric/meterpanel/dc_selector", 0); setprop_b("/controls/electric/meterpanel/galleyswitch", 0); ## standby panel # Standby Power # 0 => off # 1 => auto # 2 => battery setprop("/controls/electric/standbypanel/standbypower", 1); ## misc panels setprop_b("/controls/electric/misc/grdsvcswitch", 0); # set initial light and gauge states ## genbus panel setprop_b("/controls/electric/genbuspanel/grdpwravailable", 0); setprop_b("/controls/electric/genbuspanel/apugenoffbus", 0); setprop_b("/controls/electric/genbuspanel/transferbusoff0", 0); setprop_b("/controls/electric/genbuspanel/transferbusoff1", 0); setprop_b("/controls/electric/genbuspanel/busoff0", 0); setprop_b("/controls/electric/genbuspanel/busoff1", 0); setprop_b("/controls/electric/genbuspanel/genoffbus0", 0); setprop_b("/controls/electric/genbuspanel/genoffbus1", 0); setprop("/controls/electric/genbuspanel/acamps0", 0.0); setprop("/controls/electric/genbuspanel/acamps1", 0.0); ## meter panel setprop("/controls/electric/meterpanel/ac_volts", 0); setprop("/controls/electric/meterpanel/ac_freq", 0); setprop("/controls/electric/meterpanel/dc_volts", 0); setprop("/controls/electric/meterpanel/dc_amps", 0); # geneartor bus 1 e.concatNodes(enggen1, gengenbusrelay1); e.concatNodes(gengenbusrelay1, genbus1); e.concatNodes(apu,apugenbusrelay1); e.concatNodes(apugenbusrelay1, genbus1); e.concatNodes(external_ac, grdpwrrelay); e.concatNodes(grdpwrrelay, extgenbusrelay1); e.concatNodes(extgenbusrelay1, genbus1); e.concatNodes(genbus1, galleybusrelay1); e.concatNodes(galleybusrelay1, galley_bus1); # generator bus 2 e.concatNodes(enggen2, gengenbusrelay2); e.concatNodes(gengenbusrelay2, genbus2); e.concatNodes(apu,apugenbusrelay2); e.concatNodes(apugenbusrelay2, genbus2); e.concatNodes(grdpwrrelay,extgenbusrelay2); e.concatNodes(extgenbusrelay2, genbus2); e.concatNodes(genbus2, galleybusrelay2); e.concatNodes(galleybusrelay2, galley_bus2); # external power e.concatNodes(external_ac, extern_ac_bus); e.concatNodes(extern_ac_bus,grdsvcrelay1); e.concatNodes(grdsvcrelay1, grd_svc_bus); e.concatNodes(genbus1, grdsvcrelay2); e.concatNodes(grdsvcrelay2, grd_svc_bus); # main busses e.concatNodes(genbus1, main_bus1); e.concatNodes(genbus2, main_bus2); # transfer busses e.concatNodes(genbus1, xfrbusrelay1norm); e.concatNodes(genbus1, xfrbusrelay2alt); e.concatNodes(genbus2, xfrbusrelay2norm); e.concatNodes(genbus2, xfrbusrelay1alt); e.concatNodes(xfrbusrelay1norm, xfr_bus1); e.concatNodes(xfrbusrelay1alt, xfr_bus1); e.concatNodes(xfrbusrelay2norm, xfr_bus2); e.concatNodes(xfrbusrelay2alt, xfr_bus2); # battery charger e.concatNodes(grd_svc_bus, batchrgrelaynorm); e.concatNodes(main_bus2, batchrgrelayalt); e.concatNodes(batchrgrelaynorm, battery_chrg); e.concatNodes(batchrgrelayalt, battery_chrg); e.concatNodes(battery_chrg, hot_battery_bus); e.concatNodes(battery, hot_battery_bus); e.concatNodes(battery_chrg, batteryrelay); e.concatNodes(battery, batteryrelay); e.concatNodes(batteryrelay, sw_hot_battery_bus); e.concatNodes(hot_battery_bus, batbusaltrelay); e.concatNodes(batbusaltrelay, battery_bus); e.concatNodes(tr3, batbusnormrelay); e.concatNodes(batbusnormrelay, battery_bus); #e.concatNodes(external_dc, hot_battery_bus); # TRs e.concatNodes(xfr_bus1, tr1); e.concatNodes(xfr_bus2, tr2); e.concatNodes(main_bus2, tr3); # DC busses e.concatNodes(tr1, dc_bus1); e.concatNodes(tr2, dc_bus2); e.concatNodes(tr3, dc_bus2); e.concatNodes(tr1, dctie_bus); e.concatNodes(tr2, dctie_bus); e.concatNodes(tr3, dctie_bus); e.concatNodes(dctie_bus, tr3discrelay); e.concatNodes(tr3discrelay, dc_bus1); e.concatNodes(tr3discrelay, dc_bus2); # standby stuff e.concatNodes(dc_bus1, stbynormalrelay2); e.concatNodes(stbynormalrelay2, dc_stby_bus); e.concatNodes(battery_bus, stbyaltrelay2); e.concatNodes(stbyaltrelay2, dc_stby_bus); e.concatNodes(battery_bus, static_inverter); e.concatNodes(xfr_bus1, stbynormalrelay1); e.concatNodes(stbynormalrelay1, ac_stby_bus); e.concatNodes(static_inverter, stbyaltrelay1); e.concatNodes(stbyaltrelay1, ac_stby_bus); updateLights() = func { v = (external_ac.voltage > 110); setprop_b("/controls/electric/genbuspanel/grdpwravailable", v); v = (gengenbusrelay1.voltage < 110); setprop_b("/controls/electric/genbuspanel/genoffbus0", v); v = (gengenbusrelay2.voltage < 110); setprop_b("/controls/electric/genbuspanel/genoffbus1", v); # FIXME: apugenoffbus sometimes has nan as value v = (apugenbusrelay1.voltage < 110) and (apugenbusrelay2.voltage < 110); setprop_b("/controls/electric/genbuspanel/apugenoffbus", v); v = (xfr_bus1.voltage < 110); setprop_b("/controls/electric/genbuspanel/transferbusoff0", v); v = (xfr_bus2.voltage < 110); setprop_b("/controls/electric/genbuspanel/transferbusoff1", v); v = (genbus1.voltage < 110); setprop_b("/controls/electric/genbuspanel/busoff0", v); v = (genbus2.voltage < 110); setprop_b("/controls/electric/genbuspanel/busoff1", v); setprop("/controls/electric/genbuspanel/acamps0", enggen1.current); setprop("/controls/electric/genbuspanel/acamps1", enggen2.current); # the meter panel setACMeters = func { u = arg[0]; if(u == nil) { u = 0.0; } setprop("/controls/electric/meterpanel/ac_volts", u); if(u > 0) { setprop("/controls/electric/meterpanel/ac_freq", 400.0); } else { setprop("/controls/electric/meterpanel/ac_freq", 0.0); } }; if(getprop("/controls/electric/meterpanel/ac_selector") == 0) { setACMeters(getprop("/systems/electrics/bus/ac_stby_bus/voltage")); } if(getprop("/controls/electric/meterpanel/ac_selector") == 1) { setACMeters(getprop("/systems/electrics/source/external_ac/voltage")); } if(getprop("/controls/electric/meterpanel/ac_selector") == 2) { setACMeters(getprop("/systems/electrics/source/generator1/voltage")); } if(getprop("/controls/electric/meterpanel/ac_selector") == 3) { setACMeters(getprop("/systems/electrics/source/apu/voltage")); } if(getprop("/controls/electric/meterpanel/ac_selector") == 4) { setACMeters(getprop("/systems/electrics/source/generator2/voltage")); } if(getprop("/controls/electric/meterpanel/ac_selector") == 5) { setACMeters(getprop("/systems/electrics/device/static_inverter/voltage")); } if(getprop("/controls/electric/meterpanel/ac_selector") == 6) { setACMeters(0.0); } if(getprop("/controls/electric/meterpanel/dc_selector") == 0) { u = getprop("/systems/electrics/bus/dc_stby_bus/voltage"); setprop("/controls/electric/meterpanel/dc_volts", u); setprop("/controls/electric/meterpanel/dc_amps", 0); } if(getprop("/controls/electric/meterpanel/dc_selector") == 1) { u = getprop("/systems/electrics/bus/battery_bus/voltage"); setprop("/controls/electric/meterpanel/dc_volts", u); setprop("/controls/electric/meterpanel/dc_amps", 0); } if(getprop("/controls/electric/meterpanel/dc_selector") == 2) { u = 0.0; i = 0.0; if(battery.charging) { u = getprop("/systems/electrics/device/battery_charger/voltage"); i = getprop("/systems/electrics/device/battery_charger/current"); } else { u = getprop("/systems/electrics/source/battery/voltage"); i = getprop("/systems/electrics/source/battery/current"); } setprop("/controls/electric/meterpanel/dc_volts", u); setprop("/controls/electric/meterpanel/dc_amps", i); } if(getprop("/controls/electric/meterpanel/dc_selector") == 3) { u = getprop("/systems/electrics/bus/dc_bus1/voltage"); i = getprop("/systems/electrics/tr/TR1/current"); setprop("/controls/electric/meterpanel/dc_volts", u); setprop("/controls/electric/meterpanel/dc_amps", i); } if(getprop("/controls/electric/meterpanel/dc_selector") == 4) { u = getprop("/systems/electrics/bus/dc_bus2/voltage"); i = getprop("/systems/electrics/tr/TR2/current"); setprop("/controls/electric/meterpanel/dc_volts", u); setprop("/controls/electric/meterpanel/dc_amps", i); } if(getprop("/controls/electric/meterpanel/dc_selector") == 5) { u = getprop("/systems/electrics/tr/TR3/voltage"); i = getprop("/systems/electrics/tr/TR3/current"); setprop("/controls/electric/meterpanel/dc_volts", u); setprop("/controls/electric/meterpanel/dc_amps", i); } if(getprop("/controls/electric/meterpanel/dc_selector") == 6) { u = getprop("/systems/electrics/bus/battery_bus/voltage"); setprop("/controls/electric/meterpanel/dc_volts", 0); setprop("/controls/electric/meterpanel/dc_amps", 0); } }; updateMisc() = func { # switch ground power off if batteryswitch is not on if(!getprop("/controls/electric/meterpanel/batteryswitch")) { setprop_b("/controls/electric/genbuspanel/grdpwr", 0); } # switch ground service to off if gndpwr is switched on if(getprop("/controls/electric/genbuspanel/grdpwr")) { setprop_b("/controls/electric/misc/grdsvcswitch", 0); } # the transfer bus stuff if(getprop("/controls/electric/genbuspanel/bustrans")) { if(genbus1.voltage < 110) { xfrbusrelay1norm.switch = func { 0; }; xfrbusrelay1alt.switch = func { 1; }; } else { xfrbusrelay1norm.switch = func { 1; }; xfrbusrelay1alt.switch = func { 0; }; } if(genbus2.voltage < 110) { xfrbusrelay2norm.switch = func { 0; }; xfrbusrelay2alt.switch = func { 1; }; } else { xfrbusrelay2norm.switch = func { 1; }; xfrbusrelay2alt.switch = func { 0; }; } # FIXME: check if in glide scope during fd or ap if(1) { tr3discrelay.switch = func { 1; }; } else { tr3discrelay.switch = func { 0; }; } } else { xfrbusrelay1norm.switch = func { 1; }; xfrbusrelay1alt.switch = func { 0; }; xfrbusrelay2norm.switch = func { 1; }; xfrbusrelay2alt.switch = func { 0; }; tr3discrelay.switch = func { 0; }; } # the battery charger: switch to mainbus if gen1 is offline if(gengenbusrelay1.voltage < 110) { batchrgrelaynorm.switch = func { 0; }; batchrgrelayalt.switch = func { 1; }; } else { batchrgrelaynorm.switch = func { 1; }; batchrgrelayalt.switch = func { 0; }; } # the battery switch & hot battery bus switching if(getprop("/controls/electric/meterpanel/batteryswitch")) { # on if(main_bus2.voltage < 110) { batbusaltrelay.switch = func { 1; }; batbusnormrelay.switch = func { 0; }; } else { batbusaltrelay.switch = func { 0; }; batbusnormrelay.switch = func { 1; }; } } else { # off batbusaltrelay.switch = func { 0; }; batbusnormrelay.switch = func { 0; }; } # switch to standby (battery) if no1 dc bus or not1 transfer bus # looses power if(getprop("/controls/electric/standbypanel/standbypower") == 0) { # off stbynormalrelay1.switch = func { 0; }; stbynormalrelay2.switch = func { 0; }; stbyaltrelay1.switch = func { 0; }; stbyaltrelay2.switch = func { 0; }; } if(getprop("/controls/electric/standbypanel/standbypower") == 1) { # auto if((dc_bus1.voltage < 25) or (xfr_bus1.voltage < 110)) { if(airground.INAIR == "true") { stbynormalrelay1.switch = func { 0; }; stbynormalrelay2.switch = func { 0; }; stbyaltrelay1.switch = func { 1; }; stbyaltrelay2.switch = func { 1; }; batbusaltrelay.switch = func { 1; }; batbusnormrelay.switch = func { 0; }; } else { batbusaltrelay.switch = func { 0; }; batbusnormrelay.switch = func { 1; }; } } else { stbynormalrelay1.switch = func { 1; }; stbynormalrelay2.switch = func { 1; }; stbyaltrelay1.switch = func { 0; }; stbyaltrelay2.switch = func { 0; }; } } if(getprop("/controls/electric/standbypanel/standbypower") == 2) { # battery batbusaltrelay.switch = func { 1; }; batbusnormrelay.switch = func { 0; }; stbynormalrelay1.switch = func { 0; }; stbynormalrelay2.switch = func { 0; }; stbyaltrelay1.switch = func { 1; }; stbyaltrelay2.switch = func { 1; }; } }; run = func { print("updateing electrical system"); net.updateNet(); updateLights(); updateMisc(); settimer(run,1.0); }; # start the electrical system settimer(run, 0);
########################################################################## # Copyright (c) 2006 Markus Barenhoff <[EMAIL PROTECTED]> # # This file is protected by the GNU Public License. For more details, # please see the text file COPYING. ########################################################################## # devices # FIXME: source current pfd1lh = e.ElecNode.new(); pfd1lh.type = "device"; pfd1lh.name = "pfd1-lh"; pfd1lh.getMyCurrent = func { if(me.voltage > 27.0) {1.0;} else {0.0;} }; e.concatNodes(electrical.dc_bus1, pfd1lh); # FIXME: source current pfd2lh = e.ElecNode.new(); pfd2lh.type = "device"; pfd2lh.name = "pfd2-lh"; pfd2lh.getMyCurrent = func { if(me.voltage > 27.0) {1.0;} else {0.0;} }; e.concatNodes(electrical.dc_bus2, pfd2lh); # FIXME: source current pfd1rh = e.ElecNode.new(); pfd1rh.type = "device"; pfd1rh.name = "pfd1-rh"; pfd1rh.getMyCurrent = func { if(me.voltage > 27.0) {1.0;} else {0.0;} }; e.concatNodes(electrical.dc_bus1, pfd1rh); # FIXME: source current pfd2rh = e.ElecNode.new(); pfd2rh.type = "device"; pfd2rh.name = "pfd2-rh"; pfd2rh.getMyCurrent = func { if(me.voltage > 27.0) {1.0;} else {0.0;} }; e.concatNodes(electrical.dc_bus2, pfd2rh); # FIXME: source current eicas = e.ElecNode.new(); eicas.type = "device"; eicas.name = "eicas"; eicas.getMyCurrent = func { if(me.voltage > 27.0) {1.0;} else {0.0;} }; e.concatNodes(electrical.dc_bus2, eicas);
########################################################################## # Copyright (c) 2006 Markus Barenhoff <[EMAIL PROTECTED]> # # This file is protected by the GNU Public License. For more details, # please see the text file COPYING. ########################################################################## # TODO: # - better current calculation if a bus has more than one powered sources # ElecNode = { # constructor new : func { obj = {}; obj.parents = [ElecNode]; # the type of the Node # possible types: bus, source, device obj.type = "bus"; obj.name = "default"; obj.altPropPath = nil; # current_voltage, current_current obj.voltage = 0.0; obj.current = 0.0; # overwrite getMyCurrent to implement a device # which sources current obj.getMyCurrent = func { return 0.0; }; # the inputs and outputs are a lists of ElecNode's obj.inputs = []; obj.outputs = []; obj.addInput = func { append(me.inputs, arg[0]); }; obj.addOutput = func { append(me.outputs, arg[0]); }; # the switch method # inputs are switched on outputs if method # returns a non nil value (used to implement # switches and relays obj.switch = func { 1; }; # the transform methods # overwrite it to change the calulation # can be used to implement a transformer or amplifier # # the u_transformer should calculate the voltage based on the # values of the inputs. # the i_transformer should calculate the current based on the # the value of the outputs outputs # obj.default_u_transformer = func { if(!me.switch()) { me.voltage = 0.0; return; } umax = 0.0; foreach(node; me.inputs) { if(node.voltage > umax) { umax = node.voltage; } } me.voltage = umax; }; obj.u_transformer = obj.default_u_transformer; obj.default_i_transformer = func { if(!me.switch()) { me.current = 0.0; return; } isum = 0.0; foreach(node; me.outputs) { isum = isum + node.current; } me.current = isum + me.getMyCurrent(); }; obj.i_transformer = obj.default_i_transformer; # updates the propery tree obj.updatePropTree = func { if (me.altPropPath) { prefix = me.altPropPath; } else { prefix = "/systems/electrics/" ~ me.type ~ "/" ~ me.name ~ "/"; } setprop(prefix, "voltage", me.voltage); setprop(prefix, "current", me.current); }; # reset the current voltage and current obj.reset = func { me.voltage = 0.0; me.current = 0.0; }; return obj; } }; # # This class represents a whole network # # You should construct your net with ElecNode objects. # Then create a ElecNet instance and add all the source-nodes # with the addSourceNode()-method. # # After that you can call updateNet() to recalculate the whole # network. # ElecNet = { new : func { obj = {}; obj.parents = [ElecNet]; obj.sources = []; # add a source node obj.addSourceNode = func { append(me.sources, arg[0]); } # apply function arg[1] on arg[0] and all its outputs obj.applyFuncNetDown = func { node = arg[0]; f = arg[1]; f(node); foreach(child; node.outputs) { me.applyFuncNetDown(child, f); } }; # apply function arg[1] on arg[0] and all its outputs... # ...starting from the bottom obj.applyFuncNetUp = func { node = arg[0]; f = arg[1]; foreach(child; node.outputs) { me.applyFuncNetUp(child, f); } f(node); return; }; # reset the network obj.resetNet = func { foreach(node; me.sources) { me.applyFuncNetDown(node, func { arg[0].reset(); }); } }; # calculate the voltage on each node obj.calcVoltage = func { foreach(node; me.sources) { me.applyFuncNetDown(node, func { arg[0].u_transformer(); }); } }; # calculate the current on each node obj.calcCurrent = func { foreach(node; me.sources) { me.applyFuncNetUp(node, func {arg[0].i_transformer(); }); } }; # update the property tree obj.updateNodeProps() = func { foreach(node; me.sources) { me.applyFuncNetDown(node, func { arg[0].updatePropTree(); }); } }; # updates the network obj.updateNet = func { me.resetNet(); me.calcVoltage(); me.calcCurrent(); me.updateNodeProps(); }; return obj; } }; # helper functions concatNodes = func { n1 = arg[0]; n2 = arg[1]; n1.addOutput(n2); n2.addInput(n1); };