ec130.nas 101 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363
  1. # (c) Melchior FRANZ < mfranz # flightgear : org > Thanks for it- currently there is no better solutionout there!
  2. #print("\x1b[35m
  3. if ( getprop("/sim/model/variant") == "1" ) {
  4. print("\x1b
  5. ______ _____ __ ____ ___ ____ _ _
  6. | ____| / ___| /_ | |__ \ / _ \ | _ \ | || |
  7. | |__ | | | | __) | | | | | | |_) | | || |_
  8. | __| | | | | |__ < | | | | | _ < |__ _|
  9. | |____ | |___ | | __) | | |_| | | |_) | | |
  10. |______| \_____| |_| |____/ \___/ |____/ |_|
  11. \x1b");
  12. } else {
  13. print("\x1b
  14. _ _ __ ____ ___
  15. | | | | /_ | |__ \ / _ \
  16. | |__| | | | __) | | | | |
  17. | __ | | | |__ < | | | |
  18. | | | | | | __) | | |_| |
  19. |_| |_| |_| |____/ \___/
  20. \x1b");
  21. }
  22. if (!contains(globals, "cprint"))
  23. var cprint = func nil;
  24. var devel = !!getprop("devel");
  25. var quickstart = !!getprop("quickstart");
  26. var sin = func(a) math.sin(a * D2R);
  27. var cos = func(a) math.cos(a * D2R);
  28. var pow = func(v, w) math.exp(math.ln(v) * w);
  29. var npow = func(v, w) v ? math.exp(math.ln(abs(v)) * w) * (v < 0 ? -1 : 1) : 0;
  30. var clamp = func(v, min = 0, max = 1) v < min ? min : v > max ? max : v;
  31. var normatan = func(x, slope = 1) math.atan2(x, slope) * 2 / math.pi;
  32. var bell = func(x, spread = 2) pow(math.e, -(x * x) / spread);
  33. var max = func(a, b) a > b ? a : b;
  34. var min = func(a, b) a < b ? a : b;
  35. # liveries =========================================================
  36. # mhab: use index in listing liveries
  37. if ( getprop("/sim/model/variant") == "1" ) {
  38. aircraft.livery.init("Aircraft/ec130/Models/Liveries_ec130b4", "sim/model/livery/name", "sim/model/livery/index");
  39. } else {
  40. aircraft.livery.init("Aircraft/ec130/Models/Liveries_ec130t2", "sim/model/livery/name", "sim/model/livery/index");
  41. }
  42. # timers ============================================================
  43. aircraft.timer.new("/sim/time/hobbs/helicopter", nil).start();
  44. # strobes ===========================================================
  45. var strobe_switch = props.globals.initNode("/controls/lighting/strobe", 1, "BOOL");
  46. aircraft.light.new("/sim/model/ec130/lighting/strobe-top", [0.05, 1.00], strobe_switch);
  47. aircraft.light.new("/sim/model/ec130/lighting/strobe-bottom", [0.05, 1.03], strobe_switch);
  48. # beacons ===========================================================
  49. var beacon_switch = props.globals.initNode("/controls/lighting/beacon", 1, "BOOL");
  50. aircraft.light.new("/sim/model/ec130/lighting/beacon-top", [0.62, 0.62], beacon_switch);
  51. aircraft.light.new("/sim/model/ec130/lighting/beacon-bottom", [0.63, 0.63], beacon_switch);
  52. # nav lights ========================================================
  53. var nav_light_switch = props.globals.initNode("/controls/lighting/nav-lights", 1, "BOOL");
  54. var visibility = props.globals.getNode("/environment/visibility-m", 1);
  55. var sun_angle = props.globals.getNode("/sim/time/sun-angle-rad", 1);
  56. var nav_lights = props.globals.getNode("/sim/model/ec130/lighting/nav-lights", 1);
  57. var nav_light_loop = func {
  58. if (nav_light_switch.getValue())
  59. nav_lights.setValue(visibility.getValue() < 5000 or sun_angle.getValue() > 1.4);
  60. else
  61. nav_lights.setValue(0);
  62. settimer(nav_light_loop, 3);
  63. }
  64. nav_light_loop();
  65. # fuel ==============================================================
  66. # density = 6.682 lb/gal [Flight Manual Section 9.2]
  67. # avtur/JET A-1/JP-8
  68. var FUEL_DENSITY = getprop("/consumables/fuel/tank/density-ppg"); # pound per gallon
  69. var GAL2LB = FUEL_DENSITY;
  70. var LB2GAL = 1 / GAL2LB;
  71. var KG2GAL = KG2LB * LB2GAL;
  72. var GAL2KG = 1 / KG2GAL;
  73. var Tank = {
  74. new: func(n) {
  75. var m = { parents: [Tank] };
  76. m.capacity = n.getValue("capacity-gal_us");
  77. m.level_galN = n.initNode("level-gal_us", m.capacity);
  78. m.level_lbN = n.getNode("level-lbs");
  79. m.consume(0);
  80. return m;
  81. },
  82. level: func {
  83. return me.level_galN.getValue();
  84. },
  85. consume: func(amount) { # US gal (neg. values for feeding)
  86. var level = me.level();
  87. if (amount > level)
  88. amount = level;
  89. level -= amount;
  90. if (level > me.capacity)
  91. level = me.capacity;
  92. me.level_galN.setDoubleValue(level);
  93. me.level_lbN.setDoubleValue(level * GAL2LB);
  94. return amount;
  95. },
  96. };
  97. var fuel = {
  98. init: func {
  99. var fuel = props.globals.getNode("/consumables/fuel");
  100. me.pump_capacity = 6.6 * L2GAL / 60; # same pumps for transfer and supply; from ec135: 6.6 l/min
  101. me.total_galN = fuel.getNode("total-fuel-gals", 1);
  102. me.total_lbN = fuel.getNode("total-fuel-lbs", 1);
  103. me.total_normN = fuel.getNode("total-fuel-norm", 1);
  104. #me.supply = Tank.new(fuel.getNode("tank[1]"));
  105. me.main = Tank.new(fuel.getNode("tank[0]"));
  106. #var sw = props.globals.getNode("/controls/switches");
  107. #setlistener(sw.initNode("/fuel/transfer-pump[0]", 1, "BOOL"), func(n) me.trans1 = n.getValue(), 1);
  108. #setlistener(sw.initNode("/fuel/transfer-pump[1]", 1, "BOOL"), func(n) me.trans2 = n.getValue(), 1);
  109. setlistener("/sim/freeze/fuel", func(n) me.freeze = n.getBoolValue(), 1);
  110. me.capacity = me.main.capacity;
  111. #me.warntime = 0;
  112. #me.update(0);
  113. },
  114. update: func(dt) {
  115. # transfer pumps (feed supply from main)
  116. #var free = me.supply.capacity - me.supply.level();
  117. #if (free > 0) {
  118. # var trans_flow = (me.trans1 + me.trans2) * me.pump_capacity;
  119. # me.supply.consume(-me.main.consume(min(trans_flow * dt, free)));
  120. #}
  121. # low fuel warning [POH "General Description" 0.28a]
  122. #var time = elapsedN.getValue();
  123. #if (time > me.warntime and me.supply.level() * GAL2KG < 60) {
  124. # screen.log.write("LOW FUEL WARNING", 1, 0, 0);
  125. # me.warntime = time + screen.log.autoscroll * 2;
  126. #}
  127. var level = me.main.level();
  128. me.total_galN.setDoubleValue(level);
  129. me.total_lbN.setDoubleValue(level * GAL2LB);
  130. me.total_normN.setDoubleValue(level / me.capacity);
  131. },
  132. level: func {
  133. return me.main.level();
  134. },
  135. consume: func(amount) {
  136. return me.freeze ? 0 : me.main.consume(amount);
  137. }
  138. };
  139. # engines/rotor =====================================================
  140. var rotor_rpm = props.globals.getNode("/rotors/main/rpm");
  141. var torque = props.globals.getNode("/rotors/gear/total-torque", 1);
  142. var collective = props.globals.getNode("/controls/engines/engine[0]/throttle");
  143. var turbine = props.globals.getNode("/sim/model/ec130/turbine-rpm-pct", 1);
  144. var torque_pct = props.globals.getNode("/sim/model/ec130/torque-pct", 1);
  145. var target_rel_rpm = props.globals.getNode("/controls/rotor/reltarget", 1);
  146. var max_rel_torque = props.globals.getNode("/controls/rotor/maxreltorque", 1);
  147. var Engine = {
  148. new: func(n) {
  149. var m = { parents: [Engine] };
  150. m.in = props.globals.getNode("/controls/engines", 1).getChild("engine", n, 1);
  151. m.out = props.globals.getNode("engines", 1).getChild("engine", n, 1);
  152. m.airtempN = props.globals.getNode("/environment/temperature-degc");
  153. # input
  154. m.ignitionN = m.in.initNode("ignition", 0, "BOOL");
  155. m.starterN = m.in.initNode("starter", 0, "BOOL");
  156. m.powerN = m.in.initNode("power", 0);
  157. m.magnetoN = m.in.initNode("magnetos", 1, "INT");
  158. # output
  159. m.runningN = m.out.initNode("running", 0, "BOOL");
  160. m.n1_pctN = m.out.initNode("n1-pct", 0);
  161. m.n2_pctN = m.out.initNode("n2-pct", 0);
  162. m.n1N = m.out.initNode("n1-rpm", 0);
  163. m.n2N = m.out.initNode("n2-rpm", 0);
  164. m.totN = m.out.initNode("tot-degc", m.airtempN.getValue());
  165. m.starterLP = aircraft.lowpass.new(3);
  166. m.n1LP = aircraft.lowpass.new(4);
  167. m.n2LP = aircraft.lowpass.new(4);
  168. setlistener("/sim/signals/reinit", func(n) n.getValue() or m.reset(), 1);
  169. m.timer = aircraft.timer.new("/sim/time/hobbs/turbines[" ~ n ~ "]", 10);
  170. m.running = 0;
  171. m.fuelflow = 0;
  172. m.n1 = -1;
  173. m.up = -1;
  174. return m;
  175. },
  176. reset: func {
  177. me.magnetoN.setIntValue(1);
  178. me.ignitionN.setBoolValue(0);
  179. me.starterN.setBoolValue(0);
  180. me.powerN.setDoubleValue(0);
  181. me.runningN.setBoolValue(me.running = 0);
  182. me.starterLP.set(0);
  183. me.n1LP.set(me.n1 = 0);
  184. me.n2LP.set(me.n2 = 0);
  185. },
  186. update: func(dt, trim = 0) {
  187. var starter = me.starterLP.filter(me.starterN.getValue() * 0.19); # starter 15-20% N1max
  188. me.powerN.setValue(me.power = clamp(me.powerN.getValue()));
  189. var power = me.power * 0.97 + trim; # 97% = N2% in flight position
  190. if (me.running)
  191. power += (1 - collective.getValue()) * 0.03; # droop compensator
  192. if (power > 1.12)
  193. power = 1.12; # overspeed restrictor
  194. me.fuelflow = 0;
  195. if (!me.running) {
  196. if (me.n1 > 0.05 and power > 0.05 and me.ignitionN.getValue()) {
  197. me.runningN.setBoolValue(me.running = 1);
  198. me.timer.start();
  199. }
  200. } elsif (power < 0.05 or !fuel.level()) {
  201. me.runningN.setBoolValue(me.running = 0);
  202. me.timer.stop();
  203. } else {
  204. me.fuelflow = power;
  205. }
  206. var lastn1 = me.n1;
  207. me.n1 = me.n1LP.filter(max(me.fuelflow, starter));
  208. me.n2 = me.n2LP.filter(me.n1);
  209. me.up = me.n1 - lastn1;
  210. # temperature
  211. if (me.fuelflow > me.pos.idle)
  212. var target = 440 + (779 - 440) * (0.03 + me.fuelflow - me.pos.idle) / (me.pos.flight - me.pos.idle);
  213. else
  214. var target = 440 * (0.03 + me.fuelflow) / me.pos.idle;
  215. if (me.n1 < 0.4 and me.fuelflow - me.n1 > 0.001) {
  216. target += (me.fuelflow - me.n1) * 7000;
  217. if (target > 865)
  218. target = 865;
  219. }
  220. var airtemp = me.airtempN.getValue();
  221. if (target < airtemp)
  222. target = airtemp;
  223. var decay = (me.up > 0 ? 10 : me.n1 > 0.02 ? 0.01 : 0.001) * dt;
  224. me.totN.setValue((me.totN.getValue() + decay * target) / (1 + decay));
  225. # constant 130 kg/h for now (one turbines)
  226. fuel.consume(65 * KG2GAL * me.fuelflow * dt / 3600);
  227. # derived gauge values
  228. me.n1_pctN.setDoubleValue(me.n1 * 100);
  229. me.n2_pctN.setDoubleValue(me.n2 * 100);
  230. me.n1N.setDoubleValue(me.n1 * 50970);
  231. me.n2N.setDoubleValue(me.n2 * 33290);
  232. },
  233. setpower: func(v) {
  234. var target = (int((me.power + 0.15) * 3) + v) / 3;
  235. var time = abs(me.power - target) * 4;
  236. interpolate(me.powerN, target, time);
  237. },
  238. adjust_power: func(delta, mode = 0) {
  239. if (delta) {
  240. var power = me.powerN.getValue();
  241. if (me.power_min == nil) {
  242. if (delta > 0) {
  243. if (power < me.pos.idle) {
  244. me.power_min = me.pos.idle;
  245. me.power_max = me.pos.flight;
  246. } else {
  247. me.power_min = me.pos.idle;
  248. me.power_max = me.pos.flight;
  249. }
  250. } else {
  251. if (power > me.pos.idle) {
  252. me.power_max = me.pos.flight;
  253. me.power_min = me.pos.idle;
  254. } else {
  255. me.power_max = me.pos.flight;
  256. me.power_min = me.pos.idle;
  257. }
  258. }
  259. }
  260. me.powerN.setValue(power = clamp(power + delta, me.power_min, me.power_max));
  261. return power;
  262. } elsif (mode) {
  263. me.power_min = me.power_max = nil;
  264. }
  265. },
  266. pos: { cutoff: 0.0, idle: 0.63, flight: 1 },
  267. };
  268. var engines = {
  269. init: func {
  270. me.engine = [Engine.new(0), Engine.new(1)];
  271. me.trimN = props.globals.initNode("/controls/engines/power-trim");
  272. me.balanceN = props.globals.initNode("/controls/engines/power-balance");
  273. me.commonrpmN = props.globals.initNode("/engines/engine/rpm");
  274. },
  275. reset: func {
  276. me.engine[0].reset();
  277. me.engine[1].reset();
  278. },
  279. update: func(dt) {
  280. # update engines
  281. var trim = me.trimN.getValue() * 0.1;
  282. var balance = me.balanceN.getValue() * 0.1;
  283. me.engine[0].update(dt, trim - balance);
  284. me.engine[1].update(dt, trim + balance);
  285. # set rotor
  286. var n2relrpm =me.engine[0].n2;
  287. var n2max =me.engine[0].n2;
  288. target_rel_rpm.setValue(n2relrpm);
  289. max_rel_torque.setValue(n2max);
  290. me.commonrpmN.setValue(n2max * 33290); # attitude indicator needs pressure
  291. },
  292. adjust_powerm: func(delta, mode = 0) {
  293. # fix mhab only 1 engine
  294. if (!delta) {
  295. engines.engine[0].adjust_power(0, mode);
  296. #engines.engine[1].adjust_power(0, mode);
  297. } else {
  298. var p = 0;
  299. #var p = [0, 0];
  300. #for (var i = 0; i < 2; i += 1) {
  301. # if (controls.engines[i].selected.getValue()) {
  302. # p[i] = engines.engine[i].adjust_power(delta);
  303. # }
  304. #}
  305. p = engines.engine[0].adjust_power(delta);
  306. gui.popupTip(sprintf("Twist Grip %d%%", 100 * p));
  307. # mhab
  308. if ( getprop("/controls/electric/external-power") ) {
  309. if (delta > 0) {
  310. settimer(func{ screen.log.write("Disconnect external power supply before Take-Off !!!"); },1.5);
  311. }
  312. }
  313. }
  314. },
  315. quickstart: func { # development only
  316. me.engine[0].n1LP.set(1);
  317. me.engine[0].n2LP.set(1);
  318. procedure.step = 1;
  319. procedure.next();
  320. },
  321. };
  322. var vert_speed_fpm = props.globals.initNode("/velocities/vertical-speed-fpm");
  323. if (devel) {
  324. setprop("/instrumentation/altimeter/setting-inhg", getprop("/environment/pressure-inhg"));
  325. setlistener("/sim/signals/fdm-initialized", func {
  326. settimer(func {
  327. screen.property_display.x = 760;
  328. screen.property_display.y = 200;
  329. screen.property_display.format = "%.3g";
  330. screen.property_display.add(
  331. rotor_rpm,
  332. torque_pct,
  333. target_rel_rpm,
  334. max_rel_torque,
  335. "controls/engines/power-trim",
  336. "controls/engines/power-balance",
  337. "consumables/fuel/total-fuel-gals",
  338. "L",
  339. engines.engine[0].runningN,
  340. engines.engine[0].ignitionN,
  341. "controls/engines/engine[0]/power",
  342. engines.engine[0].n1_pctN,
  343. engines.engine[0].n2_pctN,
  344. engines.engine[0].totN,
  345. #engines.engine[0].n1N,
  346. #engines.engine[0].n2N,
  347. "R",
  348. "X",
  349. "sim/model/gross-weight-kg",
  350. "/position/altitude-ft",
  351. "/position/altitude-agl-ft",
  352. "/instrumentation/altimeter/indicated-altitude-ft",
  353. "/environment/temperature-degc",
  354. vert_speed_fpm,
  355. "/velocities/airspeed-kt",
  356. );
  357. }, 1);
  358. });
  359. }
  360. var mouse = {
  361. init: func {
  362. me.x = me.y = nil;
  363. me.savex = nil;
  364. me.savey = nil;
  365. setlistener("/sim/startup/xsize", func(n) me.centerx = int(n.getValue() / 2), 1);
  366. setlistener("/sim/startup/ysize", func(n) me.centery = int(n.getValue() / 2), 1);
  367. setlistener("/devices/status/mice/mouse/mode", func(n) me.mode = n.getValue(), 1);
  368. setlistener("/devices/status/mice/mouse/button[1]", func(n) {
  369. me.mmb = n.getValue();
  370. if (me.mode)
  371. return;
  372. if (me.mmb) {
  373. engines.adjust_powerm(0.0, 1);
  374. me.savex = me.x;
  375. me.savey = me.y;
  376. gui.setCursor(me.centerx, me.centery, "none");
  377. } else {
  378. gui.setCursor(me.savex, me.savey, "pointer");
  379. }
  380. }, 1);
  381. setlistener("/devices/status/mice/mouse/x", func(n) me.x = n.getValue(), 1);
  382. setlistener("/devices/status/mice/mouse/y", func(n) me.update(me.y = n.getValue()), 1);
  383. },
  384. update: func {
  385. if (me.mode or !me.mmb)
  386. return;
  387. if (var dy = -me.y + me.centery)
  388. engines.adjust_powerm(dy * 0.005);
  389. gui.setCursor(me.centerx, me.centery);
  390. },
  391. };
  392. var power = func(v) {
  393. if (controls.engines[0].selected.getValue())
  394. engines.engine[0].setpower(v);
  395. }
  396. var startup = func {
  397. if (procedure.stage < 0) {
  398. procedure.step = 1;
  399. procedure.next();
  400. }
  401. }
  402. var shutdown = func {
  403. if (procedure.stage > 0) {
  404. procedure.step = -1;
  405. procedure.next();
  406. }
  407. }
  408. var procedure = {
  409. stage: -999,
  410. step: nil,
  411. loopid: 0,
  412. reset: func {
  413. me.loopid += 1;
  414. me.stage = -999;
  415. step = nil;
  416. engines.reset();
  417. },
  418. next: func(delay = 0) {
  419. if (crashed)
  420. return;
  421. if (me.stage < 0 and me.step > 0 or me.stage > 0 and me.step < 0)
  422. me.stage = 0;
  423. settimer(func { me.stage += me.step; me.process(me.loopid) }, delay * !quickstart);
  424. },
  425. process: func(id) {
  426. id == me.loopid or return;
  427. # startup
  428. if (me.stage == 1 ){
  429. cprint("", "1: press start button #1 -> spool up turbine #1 to N1 8.6--15%");
  430. engines.engine[0].ignitionN.setValue(1);
  431. engines.engine[0].starterN.setValue(1);
  432. } elsif (me.stage == 2) {
  433. cprint("", "2: move power lever #1 forward -> fuel injection");
  434. engines.engine[0].powerN.setValue(0.13);
  435. me.next(2.5);
  436. } elsif (me.stage == 3) {
  437. cprint("", "3: turbine #1 ignition (wait for EGT stabilization)");
  438. me.next(4.5);
  439. } elsif (me.stage == 4) {
  440. cprint("", "4: move power lever #1 to idle position -> engine #1 spools up to N1 63%");
  441. engines.engine[0].powerN.setValue(0.63);
  442. me.next(5);
  443. } elsif (me.stage == 5) {
  444. cprint("", "5: release start button #1\n");
  445. engines.engine[0].starterN.setValue(0);
  446. engines.engine[0].ignitionN.setValue(0);
  447. me.next(3);
  448. # shutdown
  449. } elsif (me.stage == -1) {
  450. cprint("", "-1: engines shut down");
  451. engines.engine[0].starterN.setValue(0);
  452. engines.engine[0].ignitionN.setValue(0);
  453. engines.engine[0].powerN.setValue(0);
  454. me.next(40);
  455. }
  456. },
  457. };
  458. ################################
  459. # toggle floats (inflate/repack)
  460. # mhab 20131104
  461. toggle_floats = func () {
  462. if ( getprop("/sim/model/ec130/emerg_floats") ) {
  463. if ( getprop("/controls/gear/floats-inflat") ) {
  464. if ( getprop("/gear/gear[0]/wow") or getprop("/gear/gear[1]/wow") or getprop("/gear/gear[2]/wow") or getprop("/gear/gear[3]/wow") ) {
  465. setprop("/controls/gear/floats-inflat",0);
  466. setprop("/controls/gear/floats-armed",0);
  467. } else {
  468. screen.log.write("Repack only possible on ground !!!");
  469. }
  470. } else {
  471. if ( getprop("/controls/gear/floats-armed") ) {
  472. setprop("/controls/gear/floats-inflat",1);
  473. } else {
  474. screen.log.write("Floats are not armed !!!");
  475. }
  476. }
  477. }
  478. }
  479. ###################################
  480. # floats reset (for options dialog)
  481. # mhab 20160312
  482. floats_reset = func () {
  483. setprop("/sim/model/ec130/emerg_floats",0);
  484. setprop("/controls/gear/floats-inflat",0);
  485. setprop("/controls/gear/floats-armed",0);
  486. }
  487. ####################
  488. # toggle_powersupply
  489. # mhab 20160429
  490. toggle_powersupply = func () {
  491. var p = getprop("/controls/electric/external-power");
  492. if ( !p and getprop("/rotors/main/rpm") < 300 ) {
  493. setprop("/controls/electric/external-power", 1);
  494. doors.doorsystem.mgpuexport();
  495. }
  496. if ( p ) {
  497. doors.doorsystem.mgpuexport();
  498. settimer(func {
  499. # if toggle was repeated make sure mgpu is offside before removing
  500. if ( getprop("/sim/model/ec130/mgpu/position-norm") < 0.01 ) {
  501. setprop("/controls/electric/external-power", 0);
  502. } else {
  503. settimer(thisfunc(), 1); # check once per second
  504. }
  505. }, 1); # check after 1 seconds
  506. }
  507. if ( !p ) {
  508. if ( !getprop("gear/gear[0]/wow") and !getprop("gear/gear[1]/wow") and !getprop("gear/gear[2]/wow") and !getprop("gear/gear[3]/wow") ) {
  509. screen.log.write("Only possible on ground !!!");
  510. } else {
  511. if ( getprop("/rotors/main/rpm") > 300 ) {
  512. screen.log.write("External power cannot be connected when Rotor RPM 300+ !!!");
  513. }
  514. }
  515. }
  516. }
  517. ###################
  518. # autostart routine
  519. # mhab 20130606
  520. autostart = func () {
  521. var ready_msg = func () {
  522. # switch off FUEL P
  523. setprop("/controls/fuel/tank/boost-pump", 0);
  524. # remove external power
  525. toggle_powersupply();
  526. # startup complete
  527. gui.popupTip("use Twist Grip for 100% ... Take-off when Rotor RPM 370+", 5);
  528. if ( getprop("/controls/engines/engine/power") < 1.0 ) {
  529. # wait 10 sec and run up if nothing happened
  530. settimer(func {
  531. if ( getprop("/controls/engines/engine/power") < 1.0 ) {
  532. adjust_twist_grip(1);
  533. settimer(thisfunc(), 0.2);
  534. }
  535. }, 10); # check after 10 seconds
  536. }
  537. settimer(func {
  538. #print ("rotor reach 275 rpm wait loop");
  539. if (getprop("/rotors/main/rpm") > 275) {
  540. settimer(func { setprop("/controls/electric/avionics-switch", 1); },0.5);
  541. settimer(func { setprop("/controls/electric/gyrocompass", 1); },1.0);
  542. settimer(func { setprop("/instrumentation/attitude-indicator/serviceable", 1); },1.5);
  543. settimer(func { setprop("/controls/anti-ice/pitot-heat", 1); },2.0);
  544. settimer(func { setprop("/controls/lighting/beacon", 1); },2.5);
  545. settimer(func { setprop("/controls/lighting/strobe", 1); },3.0);
  546. } else {
  547. settimer(thisfunc(), 1); # check once per second
  548. }
  549. }, 1); # check after 1 second
  550. settimer(func {
  551. #print ("rotor reach 340 rpm wait loop");
  552. if (getprop("/rotors/main/rpm") > 339) {
  553. setprop("/controls/electric/horn", 1);
  554. } else {
  555. settimer(thisfunc(), 1); # check once per second
  556. }
  557. }, 1); # check after 1 second
  558. }
  559. var fuellines_filled = func() {
  560. # start selector and switch guard
  561. setprop("/controls/engines/engine/startselector", 1);
  562. # switch guard delayed for 1 sec, looks more realistic
  563. settimer(func {
  564. setprop("/controls/engines/engine/switchguard", 1);
  565. },1);
  566. gui.popupTip("Fuel pipes are filled, Rotor is started ...",40);
  567. if ( getprop("/rotors/main/rpm") > 165 ) {
  568. ready_msg ();
  569. } else {
  570. settimer(func {
  571. # print ("ready message wait loop");
  572. if ( getprop("/rotors/main/rpm") > 165 ) {
  573. ready_msg ();
  574. } else {
  575. settimer(thisfunc(), 1); # check once per second
  576. }
  577. }, 1); # check after 1 second
  578. }
  579. }
  580. var runup_primary = func() {
  581. gui.popupTip("Automatic startup routine ... please wait ... ",28);
  582. # release rotorbreak
  583. settimer(func { setprop("/controls/rotor/brake-locked", 0); },0.3);
  584. settimer(func { interpolate("/controls/rotor/brake", 0, 1); },0.5);
  585. settimer(func { setprop("/controls/rotor/brake-locked", 1); },1.7);
  586. # release cutoff lever
  587. settimer(func { interpolate("/controls/engines/engine/cutoff-norm", 0, 1); },1.2);
  588. settimer(func { setprop("/controls/engines/engine/cutoff", 0); },2.0);
  589. settimer(func { setprop("/controls/engines/engine/cutoffguard", 1); },2.2);
  590. # activate all buttons
  591. settimer(func { setprop("/controls/electric/directbat-switch", 1); },2.5);
  592. settimer(func { setprop("/controls/electric/battery-switch", 1); },3.0);
  593. settimer(func { setprop("/controls/electric/engine/generator", 1); },3.5);
  594. settimer(func { setprop("/controls/fuel/tank/boost-pump", 1); },4.0);
  595. settimer(func { setprop("/controls/lighting/nav-lights", 1); },4.5);
  596. settimer(func { setprop("/controls/lighting/taxi-light", 1); },5.0);
  597. settimer(func { setprop("/controls/lighting/dome-light", 1); },5.5);
  598. settimer(func { setprop("/controls/lighting/instrument-lights", 1); },6.0);
  599. settimer(func { setprop("/controls/lighting/instrument-lights2", 1); },6.5);
  600. if ( getprop("/controls/fuel/tank/fuellines_filled") > 0.98 ) {
  601. fuellines_filled();
  602. } else {
  603. settimer(func {
  604. # print ("fuellines filled wait loop");
  605. if (getprop("/controls/fuel/tank/fuellines_filled") > 0.98) {
  606. fuellines_filled();
  607. } else {
  608. settimer(thisfunc(), 1); # check once per second
  609. }
  610. }, 1); # check after 1 second
  611. }
  612. }
  613. # check if autostart enabled
  614. if ( getprop("/sim/model/ec130/flightnumber") >= getprop("/sim/model/ec130/minflights") ) {
  615. if ( !getprop("/controls/electric/emergency-switch") ) {
  616. if ( getprop("/controls/electric/external-power") ) {
  617. runup_primary();
  618. } else {
  619. gui.popupTip("External power supply requested ...",10);
  620. toggle_powersupply();
  621. settimer(func {
  622. # print ("external power wait loop");
  623. if ( getprop("/sim/model/ec130/mgpu/position-norm") > 0.99 ) {
  624. runup_primary();
  625. } else {
  626. gui.popupTip("waiting for external power supply ...",4);
  627. settimer(thisfunc(), 2); # check every 2 seconds
  628. }
  629. }, 3); # check after 3 seconds
  630. }
  631. } else {
  632. screen.log.write("Emergency Shutdown is active !!!");
  633. }
  634. } else {
  635. gui.popupTip("Autostart is disabled !!!",4);
  636. }
  637. }
  638. ######################
  639. # autoshutdown routine
  640. # mhab
  641. autoshutdown = func () {
  642. var rotor_slow_enough_to_brake = func () {
  643. gui.popupTip("Rotor is slow enough ...",40);
  644. # set cutoff lever
  645. settimer(func { setprop("/controls/engines/engine/cutoffguard", 0); },0.3);
  646. settimer(func { setprop("/controls/engines/engine/cutoff", 1); },0.5);
  647. settimer(func { interpolate("/controls/engines/engine/cutoff-norm", 1, 1); },0.5);
  648. # set rotorbreak
  649. settimer(func { setprop("/controls/rotor/brake-locked", 0); },0.8);
  650. settimer(func { interpolate("/controls/rotor/brake", 1, 1); },1.0);
  651. settimer(func { setprop("/controls/rotor/brake-locked", 1); },2.2);
  652. # shutoff almost all buttons
  653. settimer(func { setprop("/controls/fuel/tank/boost-pump", 0); },2.5);
  654. settimer(func { setprop("/controls/lighting/beacon", 0); },3.0);
  655. settimer(func { setprop("/controls/lighting/strobe", 0); },3.5);
  656. settimer(func { setprop("/controls/anti-ice/pitot-heat", 0); },4.0);
  657. settimer(func { setprop("/instrumentation/attitude-indicator/serviceable", 0); },4.5);
  658. settimer(func { setprop("/controls/electric/gyrocompass", 0); },5.0);
  659. settimer(func { setprop("/controls/electric/avionics-switch", 0); },5.5);
  660. settimer(func { setprop("/controls/lighting/nav-lights", 0); },6.0);
  661. settimer(func { setprop("/controls/lighting/taxi-light", 0); },6.5);
  662. settimer(func { setprop("/controls/lighting/instrument-lights2", 0); },7.0);
  663. settimer(func { setprop("/controls/lighting/instrument-lights", 0); },7.5);
  664. settimer(func { setprop("/controls/lighting/dome-light", 0); },8.0);
  665. settimer(func { setprop("/controls/electric/directbat-switch", 0); },8.5);
  666. settimer(func { setprop("/controls/electric/engine/generator", 0); },9.0);
  667. if ( getprop("/rotors/main/rpm") < 70 ) {
  668. # avoid display if everything is already off
  669. if ( getprop("/controls/electric/battery-switch") ) {
  670. gui.popupTip("Flight Report visible on VEMD", 20);
  671. }
  672. } else {
  673. settimer(func {
  674. # print ("rotor slow down wait loop2");
  675. if (getprop("/rotors/main/rpm") < 70) {
  676. gui.popupTip("Flight Report visible on VEMD", 20);
  677. } else {
  678. settimer(thisfunc(), 1);
  679. }
  680. }, 1); # check once per second
  681. }
  682. if ( getprop("/controls/electric/battery-switch") ) {
  683. # shutdown complete after 20 sec
  684. settimer(func {
  685. setprop("/controls/electric/battery-switch", 0);
  686. gui.popupTip("Shutdown complete !", 4);
  687. },20);
  688. } else {
  689. screen.log.write("Everything is in shut down state !!!");
  690. }
  691. }
  692. # check if autoshutdown enabled
  693. if ( getprop("/sim/model/ec130/flightnumber") >= getprop("/sim/model/ec130/minflights") ) {
  694. gui.popupTip("Automatic shutdown routine ... please wait ... ",30);
  695. # switch guard
  696. setprop("/controls/engines/engine/switchguard", 0);
  697. # start selector delayed for 1 sec, otherwise switch guard gets blocked, reason unclear
  698. settimer(func { setprop("/controls/engines/engine/startselector", 0); },1);
  699. # switch off horn to avoid nerve wrecking alarm
  700. settimer(func { setprop("/controls/electric/horn", 0); },1.5);
  701. if ( getprop("/rotors/main/rpm") < 170 ) {
  702. rotor_slow_enough_to_brake();
  703. } else {
  704. settimer(func {
  705. # print ("rotor slow down wait loop");
  706. if (getprop("/rotors/main/rpm") < 170) {
  707. rotor_slow_enough_to_brake();
  708. } else {
  709. settimer(thisfunc(), 1);
  710. }
  711. }, 1); # check once per second
  712. }
  713. }
  714. }
  715. # torquemeter
  716. var torque_val = 0;
  717. torque.setDoubleValue(0);
  718. var update_torque = func(dt) {
  719. var f = dt / (0.2 + dt);
  720. torque_val = torque.getValue() * f + torque_val * (1 - f);
  721. torque_pct.setDoubleValue(torque_val / 5300);
  722. }
  723. # blade vibration absorber pendulum
  724. var pendulum = props.globals.getNode("/sim/model/ec130/absorber-angle-deg", 1);
  725. var update_absorber = func {
  726. pendulum.setDoubleValue(90 * clamp(abs(rotor_rpm.getValue()) / 90));
  727. }
  728. var vibration = { # and noise ...
  729. init: func {
  730. me.lonN = props.globals.initNode("/rotors/main/vibration/longitudinal");
  731. me.latN = props.globals.initNode("/rotors/main/vibration/lateral");
  732. me.soundN = props.globals.initNode("/sim/sound/vibration");
  733. # mhab fix
  734. me.airspeedN = props.globals.getValue("/velocities/airspeed-kt") or 0;
  735. if ( me.airspeedN == nil ) me.airspeedN=0;
  736. me.vertspeedN = props.globals.getValue("/velocities/vertical-speed-fps") or 0;
  737. if ( me.vertspeedN == nil ) me.vertspeedN=0;
  738. me.groundspeedN = props.globals.getNode("/velocities/groundspeed-kt");
  739. me.speeddownN = props.globals.getNode("/velocities/speed-down-fps");
  740. me.angleN = props.globals.initNode("/velocities/descent-angle-deg");
  741. me.dir = 0;
  742. },
  743. update: func(dt) {
  744. var airspeed = me.airspeedN;
  745. # fix mhab
  746. if ( airspeed == nil ) airspeed=0;
  747. # fix mhab added
  748. me.vertspeedN = props.globals.getValue("/velocities/vertical-speed-fps") or 0;
  749. if ( me.vertspeedN == nil ) me.vertspeedN=0;
  750. if (airspeed > 100) { # overspeed vibration
  751. var frequency = 2000 + 500 * rand();
  752. var v = 0.49 + 0.5 * normatan(airspeed - 100, 10);
  753. var intensity = v;
  754. var noise = v * internal;
  755. } elsif (airspeed > 30) { # Blade Vortex Interaction (BVI) 8 deg, 65 kts max?
  756. var frequency = rotor_rpm.getValue() * 3 * 60;
  757. # fix mhab
  758. #var down = me.speeddownN.getValue() * FT2M;
  759. var down = me.speeddownN.getValue();
  760. if ( down == nil ) down=0;
  761. down = down * FT2M;
  762. # fix mhab
  763. #var level = me.groundspeedN.getValue() * NM2M / 3600;
  764. var level = me.groundspeedN.getValue();
  765. if ( level == nil ) level=0;
  766. level = level * NM2M / 3600;
  767. me.angleN.setDoubleValue(var angle = math.atan2(down, level) * R2D);
  768. var speed = math.sqrt(level * level + down * down) * MPS2KT;
  769. angle = bell(angle - 9, 13);
  770. speed = bell(speed - 65, 450);
  771. var v = angle * speed;
  772. var intensity = v * 0.10;
  773. var noise = v * (1 - internal * 0.4);
  774. } else { # hover
  775. var rpm = rotor_rpm.getValue();
  776. var frequency = rpm * 4 * 60;
  777. var coll = bell(collective.getValue(), 0.5);
  778. var ias = bell(airspeed, 600);
  779. var vert = bell(me.vertspeedN * 0.5, 400);
  780. var rpm = 0.477 + 0.5 * normatan(rpm - 350, 30) * 1.025;
  781. var v = coll * ias * vert * rpm;
  782. var intensity = v * 0.10;
  783. var noise = v * (1 - internal * 0.4);
  784. }
  785. me.dir += dt * frequency;
  786. me.lonN.setValue(cos(me.dir) * intensity);
  787. me.latN.setValue(sin(me.dir) * intensity);
  788. me.soundN.setValue(noise);
  789. },
  790. };
  791. # sound =============================================================
  792. # stall sound
  793. var stall = props.globals.getNode("/rotors/main/stall", 1);
  794. var stall_filtered = props.globals.getNode("/rotors/main/stall-filtered", 1);
  795. var stall_val = 0;
  796. stall.setDoubleValue(0);
  797. var update_stall = func(dt) {
  798. var s = stall.getValue();
  799. if (s < stall_val) {
  800. var f = dt / (0.3 + dt);
  801. stall_val = s * f + stall_val * (1 - f);
  802. } else {
  803. stall_val = s;
  804. }
  805. var c = collective.getValue();
  806. stall_filtered.setDoubleValue(stall_val + 0.006 * (1 - c));
  807. }
  808. # skid slide sound
  809. var Skid = {
  810. new: func(n) {
  811. var m = { parents: [Skid] };
  812. var soundN = props.globals.getNode("/sim/model/ec130/sound", 1).getChild("slide", n, 1);
  813. var gearN = props.globals.getNode("gear", 1).getChild("gear", n, 1);
  814. m.compressionN = gearN.getNode("compression-norm", 1);
  815. m.rollspeedN = gearN.getNode("rollspeed-ms", 1);
  816. m.frictionN = gearN.getNode("ground-friction-factor", 1);
  817. m.wowN = gearN.getNode("wow", 1);
  818. m.volumeN = soundN.getNode("volume", 1);
  819. m.pitchN = soundN.getNode("pitch", 1);
  820. m.compressionN.setDoubleValue(0);
  821. m.rollspeedN.setDoubleValue(0);
  822. m.frictionN.setDoubleValue(0);
  823. m.volumeN.setDoubleValue(0);
  824. m.pitchN.setDoubleValue(0);
  825. m.wowN.setBoolValue(1);
  826. m.self = n;
  827. return m;
  828. },
  829. update: func {
  830. me.wow = me.wowN.getValue();
  831. if (me.wow < 0.5)
  832. return me.volumeN.setDoubleValue(0);
  833. var rollspeed = abs(me.rollspeedN.getValue());
  834. me.pitchN.setDoubleValue(rollspeed * 0.6);
  835. var s = normatan(20 * rollspeed);
  836. var f = clamp((me.frictionN.getValue() - 0.5) * 2);
  837. var c = clamp(me.compressionN.getValue() * 2);
  838. var vol = s * f * c;
  839. me.volumeN.setDoubleValue(vol > 0.1 ? vol : 0);
  840. #if (!me.self) {
  841. # cprint("33;1", sprintf("S=%0.3f F=%0.3f C=%0.3f >> %0.3f", s, f, c, s * f * c));
  842. #}
  843. },
  844. };
  845. var skids = [];
  846. for (var i = 0; i < 4; i += 1)
  847. append(skids, Skid.new(i));
  848. var update_slide = func {
  849. foreach (var s; skids)
  850. s.update();
  851. }
  852. var internal = 1;
  853. setlistener("/sim/current-view/view-number", func {
  854. internal = getprop("/sim/current-view/internal");
  855. }, 1);
  856. var volume = props.globals.getNode("/sim/model/ec130/sound/volume", 1);
  857. # crash handler =====================================================
  858. var crash = func {
  859. if (arg[0]) {
  860. # crash
  861. setprop("/sim/model/ec130/tail-angle-deg", 35);
  862. setprop("/sim/model/ec130/shadow", 0);
  863. setprop("/rotors/tail/rpm", 0);
  864. setprop("/rotors/main/rpm", 0);
  865. setprop("/rotors/main/blade[0]/flap-deg", -60);
  866. setprop("/rotors/main/blade[1]/flap-deg", -50);
  867. setprop("/rotors/main/blade[2]/flap-deg", -40);
  868. #setprop("/rotors/main/blade[3]/flap-deg", -30);
  869. setprop("/rotors/main/blade[0]/incidence-deg", -30);
  870. setprop("/rotors/main/blade[1]/incidence-deg", -20);
  871. setprop("/rotors/main/blade[2]/incidence-deg", -50);
  872. #setprop("/rotors/main/blade[3]/incidence-deg", -55);
  873. setprop("/sim/model/ec130/doors/frontl/position-norm", 0.9);
  874. setprop("/sim/model/ec130/doors/frontr/position-norm", 0.5);
  875. setprop("/sim/model/ec130/doors/passengerl/position-norm", 0.4);
  876. setprop("/sim/model/ec130/doors/passengerr/position-norm", 0.7);
  877. setprop("/sim/model/ec130/doors/luggagel/position-norm", 0.3);
  878. setprop("/sim/model/ec130/doors/luggager/position-norm", 0.5);
  879. strobe_switch.setValue(0);
  880. beacon_switch.setValue(0);
  881. nav_light_switch.setValue(0);
  882. engines.engine[0].n2_pctN.setValue(0);
  883. #engines.engine[1].n2_pctN.setValue(0);
  884. torque_pct.setValue(torque_val = 0);
  885. stall_filtered.setValue(stall_val = 0);
  886. } else {
  887. # uncrash (for replay)
  888. setprop("/sim/model/ec130/tail-angle-deg", 0);
  889. setprop("/sim/model/ec130/shadow", 1);
  890. setprop("/rotors/tail/rpm", 2219);
  891. setprop("/rotors/main/rpm", 442);
  892. for (i = 0; i < 4; i += 1) {
  893. setprop("/rotors/main/blade[" ~ i ~ "]/flap-deg", 0);
  894. setprop("/rotors/main/blade[" ~ i ~ "]/incidence-deg", 0);
  895. }
  896. strobe_switch.setValue(1);
  897. beacon_switch.setValue(1);
  898. engines.engine[0].n2_pct.setValue(100);
  899. #engines.engine[1].n2_pct.setValue(100);
  900. }
  901. }
  902. # "manual" rotor animation for flight data recorder replay ============
  903. var rotor_step = props.globals.getNode("/sim/model/ec130/rotor-step-deg");
  904. var blade1_pos = props.globals.getNode("/rotors/main/blade[0]/position-deg", 1);
  905. var blade2_pos = props.globals.getNode("/rotors/main/blade[1]/position-deg", 1);
  906. var blade3_pos = props.globals.getNode("/rotors/main/blade[2]/position-deg", 1);
  907. var blade4_pos = props.globals.getNode("/rotors/main/blade[3]/position-deg", 1);
  908. var rotorangle = 0;
  909. var rotoranim_loop = func {
  910. var i = rotor_step.getValue();
  911. if (i >= 0.0) {
  912. blade1_pos.setValue(rotorangle);
  913. blade2_pos.setValue(rotorangle + 120);
  914. blade3_pos.setValue(rotorangle + 240);
  915. # fix mhab: only 3 rotor blades
  916. # blade4_pos.setValue(rotorangle + 270);
  917. rotorangle += i;
  918. settimer(rotoranim_loop, 0.1);
  919. }
  920. }
  921. var init_rotoranim = func {
  922. if (rotor_step.getValue() >= 0.0)
  923. settimer(rotoranim_loop, 0.1);
  924. }
  925. # view management ===================================================
  926. var elapsedN = props.globals.getNode("/sim/time/elapsed-sec", 1);
  927. var flap_mode = 0;
  928. var down_time = 0;
  929. controls.flapsDown = func(v) {
  930. if (!flap_mode) {
  931. if (v < 0) {
  932. down_time = elapsedN.getValue();
  933. flap_mode = 1;
  934. dynamic_view.lookat(
  935. 5, # heading left
  936. -20, # pitch up
  937. 0, # roll right
  938. 0.2, # right
  939. 0.6, # up
  940. 0.85, # back
  941. 0.2, # time
  942. 55, # field of view
  943. );
  944. } elsif (v > 0) {
  945. flap_mode = 2;
  946. gui.popupTip("AUTOTRIM", 1e10);
  947. aircraft.autotrim.start();
  948. }
  949. } else {
  950. if (flap_mode == 1) {
  951. if (elapsedN.getValue() < down_time + 0.2)
  952. return;
  953. dynamic_view.resume();
  954. } elsif (flap_mode == 2) {
  955. aircraft.autotrim.stop();
  956. gui.popdown();
  957. }
  958. flap_mode = 0;
  959. }
  960. }
  961. # register function that may set me.heading_offset, me.pitch_offset, me.roll_offset,
  962. # me.x_offset, me.y_offset, me.z_offset, and me.fov_offset
  963. #
  964. dynamic_view.register(func {
  965. var lowspeed = 1 - normatan(me.speedN.getValue() / 50);
  966. var r = sin(me.roll) * cos(me.pitch);
  967. me.heading_offset = # heading change due to
  968. (me.roll < 0 ? -50 : -30) * r * abs(r); # roll left/right
  969. me.pitch_offset = # pitch change due to
  970. (me.pitch < 0 ? -50 : -50) * sin(me.pitch) * lowspeed # pitch down/up
  971. + 15 * sin(me.roll) * sin(me.roll); # roll
  972. me.roll_offset = # roll change due to
  973. -15 * r * lowspeed; # roll
  974. });
  975. var adjust_fov = func {
  976. var w = getprop("/sim/startup/xsize");
  977. var h = getprop("/sim/startup/ysize");
  978. var ar = clamp(max(w, h) / min(w, h), 0, 2);
  979. var fov = 60 + (ar - (4 / 3)) * 10 / (16 / 9 - 4 / 3);
  980. setprop("/sim/view/config/default-field-of-view-deg", fov);
  981. if (internal)
  982. setprop("/sim/current-view/config/default-field-of-view-deg", fov);
  983. }
  984. setlistener("/sim/startup/xsize", adjust_fov);
  985. setlistener("/sim/startup/ysize", adjust_fov, 1);
  986. ###############################################################################
  987. # view handler for "Searchlight Follow View"
  988. # mhab
  989. var searchlight_follow_view_handler = {
  990. view_name : "Searchlight Follow View",
  991. init : func {
  992. me.view_name = "Searchlight Follow View";
  993. me.view = view.views[view.indexof(me.view_name)];
  994. me.shown = 0;
  995. },
  996. start : func {
  997. if (!me.shown) {
  998. }
  999. me.shown = 1;
  1000. },
  1001. stop : func {
  1002. if (me.shown) {
  1003. }
  1004. me.shown = 0;
  1005. },
  1006. update : func {
  1007. var cur = props.globals.getNode("/sim/current-view");
  1008. var head = getprop("/sim/model/searchlight/heading-deg");
  1009. var elev = getprop("/sim/model/searchlight/elevation-deg");
  1010. var sx16 = getprop("/sim/model/ec130/searchlight");
  1011. var trak = getprop("/sim/model/ec130/searchlight_a800");
  1012. var stabi = getprop("/sim/model/searchlight/stabi-active");
  1013. # A800 is stowed in reverse direction
  1014. if ( trak ) { head=head+180; }
  1015. # sync view direction with searchlight
  1016. cur.getNode("heading-offset-deg").setValue(head);
  1017. cur.getNode("pitch-offset-deg").setValue(elev);
  1018. cur.getNode("roll-offset-deg").setValue(0.0);
  1019. # position view for SX16
  1020. if ( sx16 ) {
  1021. cur.getNode("x-offset-m").setValue(1.471);
  1022. cur.getNode("y-offset-m").setValue(-1.268);
  1023. cur.getNode("z-offset-m").setValue(-2.390);
  1024. }
  1025. # position view for A800
  1026. if ( trak ) {
  1027. cur.getNode("x-offset-m").setValue(-1.200);
  1028. cur.getNode("y-offset-m").setValue(-1.220);
  1029. cur.getNode("z-offset-m").setValue(-4.940);
  1030. }
  1031. return 0.0;
  1032. }
  1033. };
  1034. view.manager.register(view.indexof(searchlight_follow_view_handler.view_name),
  1035. searchlight_follow_view_handler);
  1036. ###############################################################################
  1037. # view handler for "Searchlight Watch View"
  1038. # mhab
  1039. var searchlight_watch_view_handler = {
  1040. view_name : "Searchlight Watch View",
  1041. init : func {
  1042. me.view_name = "Searchlight Watch View";
  1043. me.view = view.views[view.indexof(me.view_name)];
  1044. me.shown = 0;
  1045. },
  1046. start : func {
  1047. if (!me.shown) {
  1048. }
  1049. me.shown = 1;
  1050. },
  1051. stop : func {
  1052. if (me.shown) {
  1053. }
  1054. me.shown = 0;
  1055. },
  1056. update : func {
  1057. var cur = props.globals.getNode("/sim/current-view");
  1058. var sx16 = getprop("/sim/model/ec130/searchlight");
  1059. var trak = getprop("/sim/model/ec130/searchlight_a800");
  1060. # position view for SX16
  1061. if ( sx16 ) {
  1062. cur.getNode("x-offset-m").setValue(1.471);
  1063. cur.getNode("y-offset-m").setValue(-0.600);
  1064. cur.getNode("z-offset-m").setValue(-0.900);
  1065. }
  1066. # position view for A800
  1067. if ( trak ) {
  1068. cur.getNode("x-offset-m").setValue(-1.100);
  1069. cur.getNode("y-offset-m").setValue(-0.600);
  1070. cur.getNode("z-offset-m").setValue(-3.500);
  1071. }
  1072. return 0.0;
  1073. }
  1074. };
  1075. view.manager.register(view.indexof(searchlight_watch_view_handler.view_name),
  1076. searchlight_watch_view_handler);
  1077. ###############################################################################
  1078. # view handler for "Front Right Seat View"
  1079. # mhab
  1080. var front_right_view_handler = {
  1081. view_name : "Front Right Seat View",
  1082. init : func {
  1083. me.view_name = "Front Right Seat View";
  1084. me.view = view.views[view.indexof(me.view_name)];
  1085. me.shown = 0;
  1086. },
  1087. start : func {
  1088. if (!me.shown) {
  1089. }
  1090. me.shown = 1;
  1091. },
  1092. stop : func {
  1093. if (me.shown) {
  1094. }
  1095. me.shown = 0;
  1096. },
  1097. update : func {
  1098. var cur = props.globals.getNode("/sim/current-view");
  1099. var head = getprop("/sim/current-view/heading-offset-deg");
  1100. var seats = getprop("/sim/model/ec130/interior_passengers");
  1101. # shift view to the left for 5 seat config
  1102. if ( seats < 6 ) {
  1103. cur.getNode("x-offset-m").setValue(0.550);
  1104. cur.getNode("y-offset-m").setValue(0.050);
  1105. cur.getNode("z-offset-m").setValue(-3.930);
  1106. } else {
  1107. cur.getNode("x-offset-m").setValue(0.730);
  1108. cur.getNode("y-offset-m").setValue(0.050);
  1109. cur.getNode("z-offset-m").setValue(-3.930);
  1110. }
  1111. # handle limits
  1112. if ( (head > 140) and (head < 180) ) {
  1113. cur.getNode("goal-heading-offset-deg").setValue(140);
  1114. }
  1115. if ( (head > 180) and (head < 220) ) {
  1116. cur.getNode("goal-heading-offset-deg").setValue(220);
  1117. }
  1118. return 0.0;
  1119. }
  1120. };
  1121. view.manager.register(view.indexof(front_right_view_handler.view_name),
  1122. front_right_view_handler);
  1123. ###############################################################################
  1124. # view handler for "Patient View"
  1125. # mhab
  1126. var patient_view_handler = {
  1127. view_name : "Patient View",
  1128. init : func {
  1129. me.view_name = "Patient View";
  1130. me.view = view.views[view.indexof(me.view_name)];
  1131. me.shown = 0;
  1132. },
  1133. start : func {
  1134. if (!me.shown) {
  1135. }
  1136. me.shown = 1;
  1137. # set pitch from property tree
  1138. setprop("/sim/current-view/pitch-offset-deg",getprop("/sim/view[107]/config/pitch-offset-deg"));
  1139. },
  1140. stop : func {
  1141. if (me.shown) {
  1142. }
  1143. me.shown = 0;
  1144. },
  1145. update : func {
  1146. var cur = props.globals.getNode("/sim/current-view");
  1147. var head = getprop("/sim/current-view/heading-offset-deg");
  1148. var pitch = getprop("/sim/current-view/pitch-offset-deg");
  1149. var seats = getprop("/sim/model/ec130/interior_passengers");
  1150. var restpos = getprop("/controls/seat/stretcher/position-deg");
  1151. # adjust view to backrest position
  1152. if ( seats == 4 ) {
  1153. # up
  1154. y_off = -0.600 + 0.6*sin(restpos);
  1155. # back
  1156. z_off = -3.160 - 0.6*(1-cos(restpos));
  1157. cur.getNode("y-offset-m").setValue(y_off);
  1158. cur.getNode("z-offset-m").setValue(z_off);
  1159. # limit pitch for patient
  1160. if ( pitch < 0-restpos ) {
  1161. pitch = 0-restpos;
  1162. cur.getNode("pitch-offset-deg").setValue(pitch);
  1163. }
  1164. # remember view setting
  1165. setprop("/sim/view[107]/config/heading-offset-deg",head);
  1166. setprop("/sim/view[107]/config/pitch-offset-deg",pitch);
  1167. }
  1168. # handle limits
  1169. if ( (head > 140) and (head < 180) ) {
  1170. cur.getNode("goal-heading-offset-deg").setValue(140);
  1171. }
  1172. if ( (head > 180) and (head < 220) ) {
  1173. cur.getNode("goal-heading-offset-deg").setValue(220);
  1174. }
  1175. return 0.0;
  1176. }
  1177. };
  1178. view.manager.register(view.indexof(patient_view_handler.view_name),
  1179. patient_view_handler);
  1180. ###################################
  1181. # mhab
  1182. var set_pilot_view = func {
  1183. # if disabled switch to Co-Pilot view
  1184. if ( getprop("/sim/view[0]/enabled") ) {
  1185. setprop("sim/current-view/view-number", 0);
  1186. } else {
  1187. # Remark: as in current FG (3.4) there is no function to jump to a
  1188. # specific view this is copied from FG view.nas and it
  1189. # is a limited solution, it is not a full-qualified view change
  1190. # as it doesn't honor extensions in view changes which maybe
  1191. # implemented in view.nas (e.g. autohide HUD)
  1192. setprop("sim/current-view/view-number", view.indexof("Co-Pilot View"));
  1193. }
  1194. # And pop up a nice reminder
  1195. var popup=getprop("/sim/view-name-popup");
  1196. if(popup == 1 or popup==nil) gui.popupTip(getprop("/sim/current-view/name"));
  1197. }
  1198. ##############################################
  1199. # mhab merged from woolthread.nas
  1200. # Simple vibrating yawstring
  1201. var yawstring = func {
  1202. var airspeed = getprop("/velocities/airspeed-kt");
  1203. # mhab fix
  1204. if ( airspeed == nil ) airspeed=0;
  1205. var rpm = getprop("/rotors/main/rpm");
  1206. var severity = 0;
  1207. if ( (airspeed < 137) and (rpm >170)) {
  1208. severity = ( math.sin (math.pi*airspeed/137) * (rand()*12) ) ;
  1209. }
  1210. var position = getprop("/orientation/side-slip-deg") + severity ;
  1211. setprop("/instrumentation/yawstring",position);
  1212. settimer(yawstring,0);
  1213. }
  1214. # Start the yawstring ASAP
  1215. yawstring();
  1216. ##############################################
  1217. # mhab merged from lightmap.nas
  1218. #### this small script handles the intensity of the lightmap effect
  1219. call_lightmap = func {
  1220. TAXI = getprop("/systems/electrical/outputs/taxi-light") or 0;
  1221. BL = getprop("/systems/electrical/outputs/beacon") or 0;
  1222. LaL = getprop("/systems/electrical/outputs/landing-light") or 0;
  1223. SUN_ANGLE = getprop("/sim/time/sun-angle-rad");
  1224. setprop("/systems/electrical/outputs/taxi-light-itensity",(SUN_ANGLE * (TAXI * 0.0357)));
  1225. setprop("/systems/electrical/outputs/beacon-itensity",(SUN_ANGLE * (BL * 0.010625)));
  1226. setprop("/systems/electrical/outputs/landing-light-intensity",(SUN_ANGLE * (LaL * 0.0357)));
  1227. settimer(call_lightmap, 0.0);
  1228. }
  1229. init = func {
  1230. settimer(call_lightmap, 0.0);
  1231. }
  1232. init();
  1233. ###############################################
  1234. ## mhab merged from mousehandlerx.nas
  1235. #var MouseHandlerX = {
  1236. # new : func() {
  1237. # var obj = { parents : [ MouseHandlerX ] };
  1238. #
  1239. # obj.property = nil;
  1240. # obj.factor = 1.0;
  1241. #
  1242. # obj.YListenerId = setlistener( "devices/status/mice/mouse/accel-x",
  1243. # func(n) { obj.YListener(n); }, 1, 0 );
  1244. #
  1245. # return obj;
  1246. # },
  1247. #
  1248. # YListener : func(n) {
  1249. # me.property == nil and return;
  1250. # me.factor == 0 and return;
  1251. # n == nil and return;
  1252. # var v = n.getValue();
  1253. # v == nil and return;
  1254. # fgcommand("property-adjust", props.Node.new({
  1255. # "offset" : v,
  1256. # "factor" : me.factor,
  1257. # "property" : me.property
  1258. # }));
  1259. # },
  1260. #
  1261. # set : func( property = nil, factor = 1.0 ) {
  1262. # me.property = property;
  1263. # me.factor = factor;
  1264. # },
  1265. #
  1266. #};
  1267. #
  1268. #var mouseHandlerX = MouseHandlerX.new();
  1269. ##############################################
  1270. # mhab merged from mousehandlery.nas
  1271. var MouseHandlerY = {
  1272. new : func() {
  1273. var obj = { parents : [ MouseHandlerY ] };
  1274. obj.property = nil;
  1275. obj.factor = 1.0;
  1276. obj.YListenerId = setlistener( "devices/status/mice/mouse/accel-y",
  1277. func(n) { obj.YListener(n); }, 1, 0 );
  1278. return obj;
  1279. },
  1280. YListener : func(n) {
  1281. me.property == nil and return;
  1282. me.factor == 0 and return;
  1283. n == nil and return;
  1284. var v = n.getValue();
  1285. v == nil and return;
  1286. fgcommand("property-adjust", props.Node.new({
  1287. "offset" : v,
  1288. "factor" : me.factor,
  1289. "property" : me.property
  1290. }));
  1291. },
  1292. set : func( property = nil, factor = 1.0 ) {
  1293. me.property = property;
  1294. me.factor = factor;
  1295. },
  1296. };
  1297. var mouseHandlerY = MouseHandlerY.new();
  1298. ##############################################
  1299. # mhab merged from rotor.nas
  1300. # functions for main rotor handling
  1301. # mhab 20131023
  1302. #
  1303. # cycle wake strength limit
  1304. # if
  1305. # 0: off
  1306. # 1: low
  1307. # 2: medium
  1308. # 3: high
  1309. #
  1310. cycle_wakes = func () {
  1311. var p = getprop("/rotors/main/wakevisible");
  1312. if ( p < 3 ) {
  1313. p = p + 1;
  1314. } else {
  1315. p = 0;
  1316. }
  1317. setprop("/rotors/main/wakevisible", p);
  1318. setprop("/rotors/main/wake_flag_0",0);
  1319. setprop("/rotors/main/wake_flag_1",0);
  1320. setprop("/rotors/main/wake_flag_2",0);
  1321. setprop("/rotors/main/wake_flag_3",0);
  1322. if ( p == 0 ) {
  1323. setprop("/rotors/main/wake_flag_0",1);
  1324. gui.popupTip("Wake invisible");
  1325. }
  1326. if ( p == 1 ) {
  1327. setprop("/rotors/main/wake_flag_1",1);
  1328. gui.popupTip("Wake low");
  1329. }
  1330. if ( p == 2 ) {
  1331. setprop("/rotors/main/wake_flag_2",1);
  1332. gui.popupTip("Wake medium");
  1333. }
  1334. if ( p == 3 ) {
  1335. setprop("/rotors/main/wake_flag_3",1);
  1336. gui.popupTip("Wake heavy");
  1337. }
  1338. }
  1339. ##############################################
  1340. # mhab merged from rotorloads.nas
  1341. # rotorloads
  1342. # simulating the force of the rotor due to Rotor-RPM, blade-incidence, g-forces and airpressure
  1343. # To-Do: calculate forces for each control, add airpressure
  1344. # very, very, very simplified- engineers: please make me right!
  1345. var incidence = 0;
  1346. var rpm_norm = 0;
  1347. var run = func {
  1348. var incidence = props.globals.getNode("/rotors/main/incidence", 1);
  1349. var rpm_norm = props.globals.getNode("/rotors/main/rpm_norm", 1);
  1350. var rotor_load = props.globals.getNode("/rotors/main/rotor_load", 1);
  1351. var rrpm = props.globals.getValue("/rotors/main/rpm") or 0;
  1352. var incidence = props.globals.getValue("/rotors/main/incidence") or 0;
  1353. var rpm_norm = props.globals.getValue("/rotors/main/rpm_norm") or 0;
  1354. var g = getprop("/accelerations/pilot-g");
  1355. # mhab fix
  1356. if ( g == nil ) g=0;
  1357. var incidence1 =getprop("/rotors/main/blade/incidence-deg");
  1358. var incidence2 = getprop("/rotors/main/blade[1]/incidence-deg");
  1359. var incidence3 = getprop("/rotors/main/blade[2]/incidence-deg");
  1360. if (rrpm >0){
  1361. setprop("/rotors/main/rpm_norm", rrpm/386);
  1362. setprop("/rotors/main/incidence", (incidence1 + incidence2 + incidence2)/3);
  1363. }
  1364. if (rrpm >0){
  1365. force = rpm_norm * (incidence*2) * g/2;
  1366. rotor_load.setDoubleValue(force);
  1367. }else{
  1368. rotor_load.setDoubleValue(0);
  1369. }
  1370. settimer(run, 0.1);
  1371. }
  1372. run();
  1373. ##############################################
  1374. # mhab merged from savestate.nas
  1375. # added some settings, but they don't work if
  1376. # they are part of the livery specific xml file
  1377. ################
  1378. # saving states so it makes it all a bit more realistic
  1379. ################
  1380. var save_list = [ "/sim/model/fuel/tank[0]/level-gal_us",
  1381. "/engines/engine/oil-temperature-degc-filter",
  1382. "/sim/model/ec130/flightnumber",
  1383. # "/sim/model/ec130/antenna_left",
  1384. # "/sim/model/ec130/antenna_tail_front",
  1385. # "/sim/model/ec130/vor_2_roof",
  1386. # "/sim/model/ec130/adf_bottom",
  1387. # "/sim/model/ec130/adf_roof",
  1388. # "/sim/model/ec130/adf_roof_l",
  1389. # "/sim/model/ec130/VUHF",
  1390. # "/sim/model/ec130/VUHF_front",
  1391. # "/sim/model/ec130/antenna_flat_tail",
  1392. # "/sim/model/ec130/antenna_square_tail",
  1393. # "/sim/model/ec130/DME",
  1394. # "/sim/model/ec130/DME_small",
  1395. # "/sim/model/ec130/copilot_controls",
  1396. # "/sim/model/ec130/interior_passengers",
  1397. # "/sim/model/ec130/show_gsdi",
  1398. # "/sim/model/ec130/wirecutter",
  1399. # "/sim/model/ec130/mirror",
  1400. # "/sim/model/ec130/FLIR",
  1401. # "/sim/model/ec130/emerg_floats",
  1402. # "/sim/model/ec130/basket_left",
  1403. # "/sim/model/ec130/basket_right",
  1404. # "/sim/model/ec130/searchlight_a800",
  1405. # "/sim/model/ec130/searchlight",
  1406. # "/sim/model/ec130/searchlight_filter",
  1407. # "/sim/model/ec130/snowshoes",
  1408. # "/sim/model/ec130/hoist",
  1409. # "/sim/model/ec130/gear_strobe",
  1410. # "/sim/model/ec130/gear_light",
  1411. # "/sim/model/ec130/luggage_wide",
  1412. "/instrumentation/transponder/id-code",
  1413. "/instrumentation/comm[0]/volume-selected",
  1414. "/instrumentation/nav[0]/volume",
  1415. ];
  1416. aircraft.data.add(save_list);
  1417. # Load saved fuel level on sim initialization
  1418. var tank_0 = props.globals.getNode("/consumables/fuel/tank[0]/level-gal_us", 1);
  1419. var copy_0 = props.globals.getNode("/sim/model/fuel/tank[0]/level-gal_us", 1);
  1420. var update_fuel = func {
  1421. if (copy_0.getValue() != nil) {
  1422. tank_0.setValue(copy_0.getValue());
  1423. }
  1424. setlistener("/consumables/fuel/tank[0]/level-gal_us", func {
  1425. copy_0.setValue(tank_0.getValue());
  1426. });
  1427. }
  1428. var loadup = func{
  1429. var copy_0 = props.globals.getValue("/sim/model/fuel/tank[0]/level-gal_us") or 0;
  1430. var tank_0 = props.globals.getNode("/consumables/fuel/tank[0]/level-gal_us", 1);
  1431. tank_0.setValue(copy_0);
  1432. }
  1433. # Load saved fuel level on sim initialization
  1434. var load = setlistener("/sim/signals/fdm-initialized", func {
  1435. update_fuel();
  1436. loadup();
  1437. removelistener(load);
  1438. });
  1439. ##############################################
  1440. # mhab merged from weights.nas
  1441. ##external sores and weights##
  1442. var external_weights = func {
  1443. wirecutter = props.globals.getNode("/sim/model/ec130/external/wirecutter/weight-lb", 1);
  1444. mirror = props.globals.getNode("/sim/model/ec130/external/mirror/weight-lb", 1);
  1445. searchlight_a800 = props.globals.getNode("/sim/model/ec130/external/searchlight_a800/weight-lb", 1);
  1446. FLIR = props.globals.getNode("/sim/model/ec130/external/FLIR/weight-lb", 1);
  1447. searchlight = props.globals.getNode("/sim/model/ec130/external/searchlight/weight-lb", 1);
  1448. basket_left = props.globals.getNode("/sim/model/ec130/external/basket_left/weight-lb", 1);
  1449. basket_right = props.globals.getNode("/sim/model/ec130/external/basket_right/weight-lb", 1);
  1450. luggage_left_wide = props.globals.getNode("/sim/model/ec130/external/luggage_left_wide/weight-lb", 1);
  1451. luggage_right_wide = props.globals.getNode("/sim/model/ec130/external/luggage_right_wide/weight-lb", 1);
  1452. float_deflated_left = props.globals.getNode("/sim/model/ec130/external/float_deflated_left/weight-lb", 1);
  1453. float_deflated_right = props.globals.getNode("/sim/model/ec130/external/float_deflated_right/weight-lb", 1);
  1454. float_inflated_left = props.globals.getNode("/sim/model/ec130/external/float_inflated_left/weight-lb", 1);
  1455. float_inflated_right = props.globals.getNode("/sim/model/ec130/external/float_inflated_right/weight-lb", 1);
  1456. snowshoe_left = props.globals.getNode("/sim/model/ec130/external/snowshoe_left/weight-lb", 1);
  1457. snowshoe_right = props.globals.getNode("/sim/model/ec130/external/snowshoe_right/weight-lb", 1);
  1458. hoist = props.globals.getNode("/sim/model/ec130/external/hoist/weight-lb", 1);
  1459. if ( getprop("/sim/model/ec130/wirecutter") ){
  1460. wirecutter.setValue(10);
  1461. }else{
  1462. wirecutter.setValue(0);
  1463. }
  1464. if ( getprop("/sim/model/ec130/mirror") ){
  1465. mirror.setValue(10);
  1466. }else{
  1467. mirror.setValue(0);
  1468. }
  1469. if ( getprop("/sim/model/ec130/searchlight_a800") ){
  1470. searchlight_a800.setValue(60);
  1471. }else{
  1472. searchlight_a800.setValue(0);
  1473. }
  1474. if ( getprop("/sim/model/ec130/FLIR") ){
  1475. FLIR.setValue(40);
  1476. }else{
  1477. FLIR.setValue(0);
  1478. }
  1479. if ( getprop("/sim/model/ec130/searchlight") ){
  1480. searchlight.setValue(50);
  1481. }else{
  1482. searchlight.setValue(0);
  1483. }
  1484. if ( getprop("/sim/model/ec130/basket_left") ){
  1485. basket_left.setValue(65);
  1486. }else{
  1487. basket_left.setValue(0);
  1488. }
  1489. if ( getprop("/sim/model/ec130/basket_right") ){
  1490. basket_right.setValue(65);
  1491. }else{
  1492. basket_right.setValue(0);
  1493. }
  1494. if ( getprop("/sim/model/ec130/luggage_wide") ){
  1495. luggage_left_wide.setValue(22);
  1496. luggage_right_wide.setValue(22);
  1497. }else{
  1498. luggage_left_wide.setValue(0);
  1499. luggage_right_wide.setValue(0);
  1500. }
  1501. if ( getprop("/sim/model/ec130/emerg_floats") ){
  1502. float_deflated_left.setValue(67.285);
  1503. float_deflated_right.setValue(67.285);
  1504. }else{
  1505. float_deflated_left.setValue(0);
  1506. float_deflated_right.setValue(0);
  1507. }
  1508. # now the inflated floats- they keep their weight of course as with inflation no additional weight is added, but they influence the aerodynamics.
  1509. # So we set weight to zero, but YASim will increase drag #
  1510. if( getprop("/controls/gear/floats-inflat") ){
  1511. float_inflated_left.setValue(0);
  1512. float_inflated_right.setValue(0);
  1513. }else{
  1514. float_inflated_left.setValue(0);
  1515. float_inflated_right.setValue(0);
  1516. }
  1517. #mhab
  1518. if ( getprop("/sim/model/ec130/snowshoes") ){
  1519. snowshoe_left.setValue(10);
  1520. snowshoe_right.setValue(10);
  1521. }else{
  1522. snowshoe_left.setValue(0);
  1523. snowshoe_right.setValue(0);
  1524. }
  1525. #mhab
  1526. if ( getprop("/sim/model/ec130/hoist") ){
  1527. hoist.setValue(50);
  1528. }else{
  1529. hoist.setValue(0);
  1530. }
  1531. #mhab
  1532. # get sum weight of equipment
  1533. var weight_equipment=0;
  1534. weight_equipment=weight_equipment+getprop("/sim/model/ec130/external/wirecutter/weight-lb");
  1535. weight_equipment=weight_equipment+getprop("/sim/model/ec130/external/mirror/weight-lb");
  1536. weight_equipment=weight_equipment+getprop("/sim/model/ec130/external/searchlight_a800/weight-lb");
  1537. weight_equipment=weight_equipment+getprop("/sim/model/ec130/external/FLIR/weight-lb");
  1538. weight_equipment=weight_equipment+getprop("/sim/model/ec130/external/searchlight/weight-lb");
  1539. weight_equipment=weight_equipment+getprop("/sim/model/ec130/external/basket_left/weight-lb");
  1540. weight_equipment=weight_equipment+getprop("/sim/model/ec130/external/basket_right/weight-lb");
  1541. weight_equipment=weight_equipment+getprop("/sim/model/ec130/external/luggage_left_wide/weight-lb");
  1542. weight_equipment=weight_equipment+getprop("/sim/model/ec130/external/luggage_right_wide/weight-lb");
  1543. weight_equipment=weight_equipment+getprop("/sim/model/ec130/external/float_deflated_left/weight-lb");
  1544. weight_equipment=weight_equipment+getprop("/sim/model/ec130/external/float_deflated_right/weight-lb");
  1545. weight_equipment=weight_equipment+getprop("/sim/model/ec130/external/float_inflated_left/weight-lb");
  1546. weight_equipment=weight_equipment+getprop("/sim/model/ec130/external/float_inflated_right/weight-lb");
  1547. weight_equipment=weight_equipment+getprop("/sim/model/ec130/external/snowshoe_left/weight-lb");
  1548. weight_equipment=weight_equipment+getprop("/sim/model/ec130/external/snowshoe_right/weight-lb");
  1549. weight_equipment=weight_equipment+getprop("/sim/model/ec130/external/hoist/weight-lb");
  1550. setprop("/sim/weight[13]/weight-lb",weight_equipment);
  1551. # floats menu entries activate/deactivate
  1552. # cross-check menubar definition
  1553. if ( !getprop("/sim/model/ec130/emerg_floats") ) {
  1554. setprop("/sim/menubar/default/menu[10]/item[6]/enabled",0);
  1555. } else {
  1556. setprop("/sim/menubar/default/menu[10]/item[6]/enabled",1);
  1557. }
  1558. # mhab deactivated
  1559. # settimer(weights,0.1);
  1560. }
  1561. external_weights();
  1562. ##############################################
  1563. # mhab merged from dialog.nas
  1564. # dialogs
  1565. var options_dialog = gui.Dialog.new("/sim/gui/dialogs/ec130/options/dialog", "Aircraft/ec130/Dialogs/ec130-options-dialog.xml");
  1566. var config_dialog = gui.Dialog.new("/sim/gui/dialogs/ec130/config/dialog", "Aircraft/ec130/Dialogs/ec130-config-dialog.xml");
  1567. var antenna_config_dialog = gui.Dialog.new("/sim/gui/dialogs/ec130/antenna/dialog", "Aircraft/ec130/Dialogs/ec130-antenna-config-dialog.xml");
  1568. var help_config_dialog = gui.Dialog.new("/sim/gui/dialogs/ec130/help_config/dialog", "Aircraft/ec130/Dialogs/ec130-help-config-dialog.xml");
  1569. var model_info_dialog = gui.Dialog.new("/sim/gui/dialogs/ec130/model_info/dialog", "Aircraft/ec130/Dialogs/ec130-model-info-dialog.xml");
  1570. ##seats weights and views##
  1571. var set_seats = func {
  1572. if ( getprop("/sim/weight[0]/weight-lb") < 30 ) { setprop("/sim/weight[0]/weight-lb",30) }
  1573. if ( getprop("/sim/weight[1]/weight-lb") < 30 ) { setprop("/sim/weight[1]/weight-lb",30) }
  1574. if ( getprop("/sim/weight[2]/weight-lb") < 30 ) { setprop("/sim/weight[2]/weight-lb",30) }
  1575. if ( getprop("/sim/weight[3]/weight-lb") < 30 ) { setprop("/sim/weight[3]/weight-lb",30) }
  1576. if ( getprop("/sim/weight[4]/weight-lb") < 30 ) { setprop("/sim/weight[4]/weight-lb",30) }
  1577. if ( getprop("/sim/weight[5]/weight-lb") < 30 ) { setprop("/sim/weight[5]/weight-lb",30) }
  1578. if ( getprop("/sim/weight[6]/weight-lb") < 30 ) { setprop("/sim/weight[6]/weight-lb",30) }
  1579. if ( getprop("/sim/weight[7]/weight-lb") < 30 ) { setprop("/sim/weight[7]/weight-lb",30) }
  1580. var p = getprop("/sim/model/ec130/interior_passengers");
  1581. # pilot or co-pilot must be present (seat weight 30lbs)
  1582. if ( getprop("/sim/weight[0]/weight-lb") < 40 ) {
  1583. if ( getprop("/sim/weight[1]/weight-lb") < 40 ) {
  1584. setprop("/sim/weight[0]/weight-lb",180)
  1585. }
  1586. }
  1587. # set label for Rear Mid Right/EMS configuration
  1588. setprop("/sim/weight[6]/name", "Rear Mid Right");
  1589. # 5 seats
  1590. if ( p == 5 ) {
  1591. # disable weight
  1592. # front left seat
  1593. setprop("/sim/weight[2]/weight-lb",0);
  1594. }
  1595. # 6 seats
  1596. if ( p == 6 ) {
  1597. # set min weight if seats were activated from smaller configuration
  1598. if ( getprop("/sim/weight[2]/weight-lb") == 0 ) {
  1599. setprop("/sim/weight[2]/weight-lb",30);
  1600. }
  1601. if ( getprop("/sim/weight[7]/weight-lb") == 0 ) {
  1602. setprop("/sim/weight[7]/weight-lb",30);
  1603. }
  1604. }
  1605. # rescue config
  1606. if ( p == 4 ) {
  1607. # set weights
  1608. setprop("/sim/weight[2]/weight-lb",0);
  1609. setprop("/sim/weight[3]/weight-lb",30);
  1610. setprop("/sim/weight[7]/weight-lb",0);
  1611. # set label for Rear Mid Right/EMS configuration
  1612. setprop("/sim/weight[6]/name", "Patient");
  1613. if ( getprop("/sim/weight[6]/weight-lb") == 0 ) {
  1614. setprop("/sim/weight[6]/weight-lb",50);
  1615. }
  1616. }
  1617. # synchronize views with weight
  1618. set_views();
  1619. }
  1620. var set_views = func {
  1621. var p = getprop("/sim/model/ec130/interior_passengers");
  1622. # weights
  1623. var pilotw = getprop("/sim/weight[0]/weight-lb");
  1624. var copilotw= getprop("/sim/weight[1]/weight-lb");
  1625. var frontlw = getprop("/sim/weight[2]/weight-lb");
  1626. var frontrw = getprop("/sim/weight[3]/weight-lb");
  1627. var rearlw = getprop("/sim/weight[4]/weight-lb");
  1628. var rearmlw = getprop("/sim/weight[5]/weight-lb");
  1629. var rearmrw = getprop("/sim/weight[6]/weight-lb");
  1630. var rearrw = getprop("/sim/weight[7]/weight-lb");
  1631. # views
  1632. var pilotv = "sim/view[0]/enabled";
  1633. var copilotv= "sim/view[101]/enabled";
  1634. var frontlv = "sim/view[102]/enabled";
  1635. var frontrv = "sim/view[103]/enabled";
  1636. var rearlv = "sim/view[104]/enabled";
  1637. var rearmlv = "sim/view[105]/enabled";
  1638. var rearmrv = "sim/view[106]/enabled";
  1639. var patientv= "sim/view[107]/enabled";
  1640. var rearrv = "sim/view[108]/enabled";
  1641. if ( pilotw < 40 ){ setprop(pilotv,0) } else { setprop(pilotv,1) };
  1642. if ( copilotw < 40 ){ setprop(copilotv,0) } else { setprop(copilotv,1) };
  1643. if ( frontlw < 40 ){ setprop(frontlv,0) } else { setprop(frontlv,1) };
  1644. if ( frontrw < 40 ){ setprop(frontrv,0) } else { setprop(frontrv,1) };
  1645. if ( rearlw < 40 ){ setprop(rearlv,0) } else { setprop(rearlv,1) };
  1646. if ( rearmlw < 40 ){ setprop(rearmlv,0) } else { setprop(rearmlv,1) };
  1647. # rearmr and patient interchange
  1648. if ( rearmrw < 40 ) {
  1649. setprop(rearmrv,0);
  1650. setprop(patientv,0);
  1651. } else {
  1652. if ( p == 4 ) {
  1653. setprop(patientv,1);
  1654. setprop(rearmrv,0);
  1655. } else {
  1656. setprop(patientv,0);
  1657. setprop(rearmrv,1);
  1658. }
  1659. }
  1660. if ( rearrw < 40 ){ setprop(rearrv,0) } else { setprop(rearrv,1) };
  1661. # set patient view
  1662. set_patient_view();
  1663. # if current view was just disabled
  1664. # switch to previous internal view
  1665. var views = props.globals.getNode("/sim").getChildren("view");
  1666. foreach (var v; views) {
  1667. var i = v.getIndex();
  1668. vname = getprop("/sim/view[" ~ i ~ "]/name");
  1669. enabled = getprop("/sim/view[" ~ i ~ "]/enabled");
  1670. if ( vname == getprop("/sim/current-view/name") and !enabled ) {
  1671. # switch to previous view
  1672. # hopefully the previous view is internal and active
  1673. view.stepView(-1);
  1674. # if no internal aircraft view was left switch to Cockpit View
  1675. # or Co-Pilot View if Cockpit is disabled
  1676. if ( !getprop("/sim/current-view/internal") ) {
  1677. set_pilot_view();
  1678. }
  1679. }
  1680. }
  1681. }
  1682. var set_searchview = func {
  1683. var searchw = "sim/view[111]/enabled";
  1684. var searchv = "sim/view[112]/enabled";
  1685. setprop(searchw,0);
  1686. setprop(searchv,0);
  1687. if ( getprop("/sim/model/ec130/searchlight") or getprop("/sim/model/ec130/searchlight_a800") ) {
  1688. if ( getprop("/sim/view[111]/enabled_flag") ) setprop(searchw,1);
  1689. if ( getprop("/sim/view[112]/enabled_flag") ) setprop(searchv,1);
  1690. }
  1691. }
  1692. var set_patient_view = func {
  1693. var pv = -15;
  1694. if ( getprop("/sim/model/ec130/interior_passengers") == 4 ){
  1695. var po = getprop("/controls/seat/stretcher/position-deg");
  1696. if ( po != nil ) { pv= 90-po-15; }
  1697. }
  1698. setprop("/sim/view[107]/config/pitch-offset-deg",pv);
  1699. }
  1700. ##############################################
  1701. # mhab merged from systems.nas
  1702. ### some systems like hydraulics and engineoil, maingearboxoil etc...####
  1703. ###create oil pressure###
  1704. var oilpressure = func {
  1705. oilpres_low = props.globals.getNode("/engines/engine/oil-pressure-low", 1);
  1706. oilpres_norm = props.globals.getNode("/engines/engine/oil-pressure-norm", 1);
  1707. oilpres_bar = props.globals.getNode("/engines/engine/oil-pressure-bar", 1);
  1708. var rpm = props.globals.getValue("/engines/engine/rpm") or 0;
  1709. if ( rpm > 0 ) oilpres_low.setDoubleValue((15-22000/rpm)*0.0689);
  1710. if ( rpm > 0 ) oilpres_norm.setDoubleValue((60-22000/rpm)*0.0689);
  1711. settimer(oilpressure, 0);
  1712. }
  1713. oilpressure();
  1714. ##############
  1715. var oilpressurebar = func{
  1716. oilpres_bar = props.globals.getNode("/engines/engine/oil-pressure-bar", 1);
  1717. var rpm = props.globals.getValue("/engines/engine/rpm") or 0;
  1718. var oilpres_low = props.globals.getValue("/engines/engine/oil-pressure-low") or 0;
  1719. var oilpres_norm = props.globals.getValue("/engines/engine/oil-pressure-norm") or 0;
  1720. if ((rpm > 0) and (rpm < 23000)){
  1721. interpolate ("/engines/engine/oil-pressure-bar", oilpres_low, 1.5);
  1722. }elsif (rpm > 23000) {
  1723. interpolate ("/engines/engine/oil-pressure-bar", oilpres_norm, 2);
  1724. }
  1725. settimer(oilpressurebar, 0.1);
  1726. }
  1727. oilpressurebar();
  1728. ##################
  1729. var oiltemp = func{
  1730. var OAT = props.globals.getValue("/environment/temperature-degc") or 0;
  1731. var oilpres_bar = props.globals.getValue("/engines/engine/oil-pressure-bar-filter") or 0;
  1732. var rpm = props.globals.getValue("/engines/engine/rpm") or 0;
  1733. ot = props.globals.getNode("/engines/engine/oil-temperature-degc", 1);
  1734. if (oilpres_bar >1){
  1735. ot.setDoubleValue(((25-22000/rpm)*oilpres_bar)+OAT);
  1736. } else {
  1737. ot.setDoubleValue(OAT);
  1738. }
  1739. settimer( oiltemp, 0);
  1740. }
  1741. oiltemp();
  1742. #########################################
  1743. ###main gear box oil pressure###
  1744. var mgbp = func {
  1745. #create oilpressure#
  1746. mgb_oilpres_low = props.globals.getNode("/rotors/gear/mgb-oil-pressure-low", 1);
  1747. mgb_oilpres_norm = props.globals.getNode("/rotors/gear/mgb-oil-pressure-norm", 1);
  1748. mgb_oilpres_bar = props.globals.getNode("/rotors/gear/mgb-oil-pressure-bar", 1);
  1749. var rpm = props.globals.getValue("/rotors/main/rpm") or 0;
  1750. if ( rpm > 0 ) mgb_oilpres_low.setDoubleValue((15-230/rpm)*0.0689);
  1751. if ( rpm > 0 ) mgb_oilpres_norm.setDoubleValue((60-230/rpm)*0.0689);
  1752. settimer(mgbp, 0);
  1753. }
  1754. mgbp();
  1755. ##############
  1756. var mgbp_bar = func{
  1757. mgb_oilpres_bar = props.globals.getNode("/rotors/gear/mgb-oil-pressure-bar", 1);
  1758. var rpm = props.globals.getValue("/rotors/main/rpm") or 0;
  1759. mgb_oilpres_low = props.globals.getValue("/rotors/gear/mgb-oil-pressure-low") or 0;
  1760. mgb_oilpres_norm = props.globals.getValue("/rotors/gear/mgb-oil-pressure-norm") or 0;
  1761. if ((rpm > 0) and (rpm < 280)){
  1762. interpolate ("/rotors/gear/mgb-oil-pressure-bar",mgb_oilpres_low, 1.5);
  1763. }elsif (rpm > 280) {
  1764. interpolate ("/rotors/gear/mgb-oil-pressure-bar",mgb_oilpres_norm, 2);
  1765. }
  1766. settimer(mgbp_bar, 0.1);
  1767. }
  1768. mgbp_bar();
  1769. ##############################################
  1770. # mhab merged from flightcontrols.nas
  1771. # contains flightcontrol and hydraulics-system
  1772. #
  1773. # Force Trim Release#
  1774. ##############
  1775. # Due to hydraulic boost of the controls the pilot woulden't feel any force feedback on the controls.
  1776. # That's why there is a spring which produce artificial force feel. This force can be set to zero by pressing
  1777. # the FTR-button at each stick position by some clutches and electric motors. The clutches holds the
  1778. # cyclic-controls, and the spring is moved to a force free position.
  1779. #
  1780. # As FlightGear doesn't support Force Feedback, and anyway there is no good hardware for that, we cannot simulate
  1781. # this approach. We could use the already implemented AutoTrim but this isn't really suitable to helicopters and
  1782. # seems even wrong to me. See also data/nasal/aircraft.nas ->autotrim
  1783. #
  1784. # We use another approach: While pressing the FTR-button ("t-key"), the inputs from Joystick/Mouse are interrupted
  1785. # and keep the Cyclic position in the sim to its current state. Now the Joystick/Mouse can be moved into a new
  1786. # position (like centered or any other position liked). When the button is released, inputs flow again.
  1787. # Some helis, the EC130 as an option on demand, has a 4-way trim switch. This will move the controlls in small
  1788. # steps in the wished direction, so the heli is correctly trimmed it can be flown just with this little inputs.
  1789. #
  1790. # the EC130 here will only make use by FTR. Sorry, no money left for extra gadgets! ;-)#
  1791. # that's how to use it:
  1792. # (1) move the stick such that the heli is in an orientation that
  1793. # you want to trim for (forward flight, hover, ...)
  1794. # (2) press FTR button (f-key)and keep it pressed
  1795. # (3) move stick/yoke to neutral position (center)
  1796. # (4) release FTR button (f-key)
  1797. #
  1798. var cyclaileron =props.globals.getNode("/controls/flight/aileron", 1);
  1799. var cyclelevator =props.globals.getNode("/controls/flight/elevator", 1);
  1800. ftr_start = func {
  1801. cyclaileron.setAttribute("writable", 0);
  1802. cyclelevator.setAttribute("writable", 0);
  1803. }
  1804. ftr_stop = func {
  1805. cyclaileron.setAttribute("writable", 1);
  1806. cyclelevator.setAttribute("writable", 1);
  1807. }
  1808. ######
  1809. #Hydraulic system #
  1810. #system 1 driven by MGB (rotor-rpm) #
  1811. #system 2 driven by engine (n2) #
  1812. update_hydr = func{
  1813. var rpm = props.globals.getValue("/rotors/main/rpm") or 0;
  1814. var n2 = props.globals.getValue("/engines/engine/n2-rpm") or 0;
  1815. hpump1 = props.globals.getNode("/systems/hydraulics/pump-psi", 1);
  1816. hpump2 = props.globals.getNode("/systems/hydraulics[1]/pump-psi", 1);
  1817. servosp = props.globals.getNode("/systems/hydraulic_servos/servosp", 1);
  1818. var hpsi1 = rpm*2;
  1819. var hpsi2 = n2/40;
  1820. if (hpsi1>508)hpsi1 = 508;
  1821. if (hpsi2>508)hpsi2 = 508;
  1822. hpump1.setValue(hpsi1);
  1823. hpump2.setValue(hpsi2);
  1824. servosp.setValue((hpsi1 + hpsi2)/60);
  1825. settimer(update_hydr, 0.1);
  1826. }
  1827. init = func {
  1828. settimer(update_hydr, 0.0);
  1829. }
  1830. init();
  1831. #simulation interaction rotorload and cyclic#
  1832. var interaction = func{
  1833. rl = props.globals.getValue("/rotors/main/rotor_load") or 0;
  1834. servosp = props.globals.getValue("/systems/hydraulic_servos/servosp") or 0;
  1835. dst1aileron = props.globals.getNode("/controls/flight/aileron_dst1",1);
  1836. dst1elevator = props.globals.getNode("/controls/flight/elevator_dst1",1);
  1837. dst0aileron = props.globals.getNode("/controls/flight/aileron_dst0",1);
  1838. dst0elevator = props.globals.getNode("/controls/flight/elevator_dst0",1);
  1839. if (rl > servosp){
  1840. dst1aileron.setValue(1-(rl - 18) / (26 - 18));
  1841. dst1elevator.setValue(1-(rl - 18) / (26 - 18));
  1842. dst0aileron.setValue(-1-(rl - 18) / (26 - 18));
  1843. dst0elevator.setValue(-1-(rl - 18) / (26 - 18));
  1844. }else{
  1845. dst1aileron.setValue(1);
  1846. dst1elevator.setValue(1);
  1847. dst0aileron.setValue(-1);
  1848. dst0elevator.setValue(-1);
  1849. }
  1850. settimer(interaction, 0.1);
  1851. }
  1852. init = func {
  1853. settimer(interaction, 0.0);
  1854. }
  1855. init();
  1856. ##############
  1857. var emerg_floats = func {
  1858. EF= getprop("/sim/model/ec130/emerg_floats");
  1859. if (EF == "false"){
  1860. setprop("/controls/gear/floats-inflat", "false");
  1861. }
  1862. settimer(emerg_floats, 0.1);
  1863. }
  1864. emerg_floats();
  1865. ##############################################
  1866. # mhab merged from fadec.nas
  1867. ###FADEC###
  1868. #simple hack- needs some work to look more professionell#
  1869. ###Cycle of enginefuelpumps###
  1870. #simple hack#
  1871. var engfuelpumps = func {
  1872. fuelpump = props.globals.getNode("/controls/engines/engine/fuel-pump", 1);
  1873. flines_filled = props.globals.getNode("/controls/fuel/tank/fuellines_filled", 1);
  1874. fuelfilter = props.globals.getNode("/controls/fuel/tank/fuelfilter", 1);
  1875. var n1 = props.globals.getValue("/engines/engine/n1-pct") or 0;
  1876. var CUTOFF = props.globals.getValue("/controls/engines/engine/cutoff") or 0;
  1877. var fp = props.globals.getValue("/controls/engines/engine/fuel-pump") or 0;
  1878. fuelfilter.setValue(0);
  1879. if (n1 > 60){
  1880. fuelpump.setValue(1);
  1881. }else{
  1882. fuelpump.setValue(0);
  1883. }
  1884. if ((fp <1) and (CUTOFF==1)){
  1885. interpolate ("/controls/fuel/tank/fuellines_filled",0, 3);
  1886. }
  1887. settimer(engfuelpumps, 0.1);
  1888. }
  1889. engfuelpumps();
  1890. ###State of fuellines - if filled up engine can run - if not engine cuts off###
  1891. #simpel hack - known issue: boost-pump runs even without power
  1892. var boostpumps = func {
  1893. flines_filled = props.globals.getNode("/controls/fuel/tank/fuellines_filled", 1);
  1894. var boostpump = props.globals.getValue("/controls/fuel/tank/boost-pump") or 0;
  1895. var n1 = props.globals.getValue("/engines/engine/n1-pct") or 0;
  1896. var CUTOFF = props.globals.getValue("/controls/engines/engine/cutoff") or 0;
  1897. var VOLTS = props.globals.getValue("/systems/electrical/volts") or 0;
  1898. var bp_pwr = getprop("/systems/electrical/outputs/boost-pump");
  1899. if (n1 <60) {
  1900. if ((boostpump >0) and (bp_pwr >22)){
  1901. interpolate ("/controls/fuel/tank/fuellines_filled",1, 5);
  1902. }else{
  1903. interpolate ("/controls/fuel/tank/fuellines_filled",0, 3);
  1904. }
  1905. }
  1906. if (CUTOFF==1){
  1907. interpolate ("/controls/fuel/tank/fuellines_filled",0, 3);
  1908. }
  1909. settimer(boostpumps, 0.1);
  1910. }
  1911. boostpumps();
  1912. #####################################################
  1913. ###Engine Start###
  1914. ##starter cycle##
  1915. # var StartSelector
  1916. var start = func {
  1917. var ignition = props.globals.getNode("/controls/engines/engine/ignition", 1);
  1918. var starter = props.globals.getNode("/controls/engines/engine/starter", 1);
  1919. var fuelpump = props.globals.getNode("/controls/fuel/tank/boost-pump", 1);
  1920. var power = props.globals.getNode("/controls/engines/engine/power", 1);
  1921. var starting = props.globals.getNode("/controls/engines/engine/starting", 1);
  1922. var injection = props.globals.getNode("/controls/engines/engine/injection", 1);
  1923. var CUTOFF = props.globals.getValue("/controls/engines/engine/cutoff") or 0;
  1924. var n1 = props.globals.getValue("/engines/engine/n1-pct") or 0;
  1925. var VOLTS = props.globals.getValue("/systems/electrical/volts") or 0;
  1926. var SEL = props.globals.getValue("/controls/engines/engine/startselector") or 0;
  1927. if ((SEL == 1) and (n1 < 63)) {
  1928. if (VOLTS > 22){
  1929. starter.setValue (1);
  1930. }
  1931. }else{
  1932. starter.setValue (0);
  1933. }
  1934. ###ignition cycle###
  1935. if ((SEL == 1) and (n1 > 17) and (n1 < 63)) {
  1936. if (VOLTS > 22){
  1937. ignition.setValue (1);
  1938. }
  1939. }else{
  1940. ignition.setValue(0);
  1941. }
  1942. if ((n1 > 17) and (n1 < 63)) {
  1943. starting.setValue(1.0);
  1944. }
  1945. settimer(start, 0.2);
  1946. }
  1947. start();
  1948. ###fuel injection ###
  1949. var injection = {
  1950. init: func {
  1951. var injection = props.globals.getNode("/controls/engines/engine/injection", 1);
  1952. var power = props.globals.getNode("/controls/engines/engine/power", 1);
  1953. var flines_filled = props.globals.getValue("/controls/fuel/tank/fuellines_filled") or 0;
  1954. var n1 = props.globals.getValue("/engines/engine/n1-pct") or 0;
  1955. if (flines_filled >0.90) {
  1956. power.setValue (0.13);
  1957. }else{
  1958. power.setValue(0.0);
  1959. }
  1960. if ((n1 > 18) and (n1 < 63)) {
  1961. injection.setValue(1.0);
  1962. }
  1963. }
  1964. };
  1965. setlistener("/controls/engines/engine/starting", func {
  1966. injection.init();
  1967. });
  1968. ###idle ###
  1969. var idle= {
  1970. init: func {
  1971. var power = props.globals.getNode("/controls/engines/engine/power", 1);
  1972. var flines_filled = props.globals.getValue("/controls/fuel/tank/fuellines_filled") or 0;
  1973. var n1 = props.globals.getValue("/engines/engine/n1-pct") or 0;
  1974. var CUTOFF = props.globals.getValue("/controls/engines/engine/cutoff") or 0;
  1975. if (CUTOFF==0) {
  1976. power.setValue (0.71);
  1977. }
  1978. }
  1979. };
  1980. setlistener("/controls/engines/engine/injection", func {
  1981. idle.init();
  1982. });
  1983. ###flight###
  1984. var flight = func {
  1985. var flines_filled = props.globals.getValue("/controls/fuel/tank/fuellines_filled") or 0;
  1986. var n1 = props.globals.getValue("/engines/engine/n1-pct") or 0;
  1987. var power = props.globals.getNode("/controls/engines/engine/power", 1);
  1988. var SEL = props.globals.getValue("/controls/engines/engine/startselector") or 0;
  1989. var ebt = props.globals.getValue("/controls/engines/engine/ebcautest") or 0;
  1990. if ((n1 > 1) and (flines_filled <0.90)) {
  1991. power.setValue(0);
  1992. }
  1993. if ((n1 > 1) and (SEL == 0)) {
  1994. power.setValue(0);
  1995. }
  1996. settimer(flight, 0.2);
  1997. }
  1998. flight();
  1999. ##automatic variable main rotor speed system to reduce external noise = rotor-noise-signature reduction feature##
  2000. var avrs = func {
  2001. var n2function = props.globals.getNode("/controls/engines/power-trim", 1);
  2002. var trimvalue = props.globals.getValue("/controls/engines/power-trim") or 0;
  2003. #var catabtn = props.globals.getValue("/controls/rotor/cata") or 0;
  2004. var asp = props.globals.getValue("/instrumentation/airspeed-indicator/indicated-speed-kt") or 0;
  2005. # mhab added
  2006. var ebt = props.globals.getValue("/controls/engines/engine/ebcautest") or 0;
  2007. if ( getprop("/gear/gear[0]/wow") or getprop("/gear/gear[1]/wow")
  2008. or getprop("/gear/gear[2]/wow") or getprop("/gear/gear[3]/wow") )
  2009. { var ground = 1;
  2010. } else {
  2011. ground = 0;
  2012. }
  2013. if ( ground ) {
  2014. if ( ebt ) {
  2015. interpolate( n2function, 0.4, 2 );
  2016. } else {
  2017. interpolate( n2function, 0, 6 );
  2018. }
  2019. } else {
  2020. if ( (asp > 0) and (asp <= 20) ) {
  2021. interpolate( n2function, 0.20, 6 );
  2022. }
  2023. if ( (asp > 20) and (asp <= 40) ) {
  2024. interpolate( n2function, 0.10, 6 );
  2025. }
  2026. if ( (asp > 40) and (asp <= 70) ) {
  2027. interpolate( n2function, 0.0, 6 );
  2028. }
  2029. if ( (asp > 70) and (asp <= 120) ) {
  2030. interpolate( n2function, -0.10, 6 );
  2031. }
  2032. if ( (asp > 120) and (asp < 210) ) {
  2033. interpolate( n2function, -0.20, 6 );
  2034. }
  2035. }
  2036. settimer(avrs, 0);
  2037. }
  2038. avrs();
  2039. ###########################
  2040. # mhab added
  2041. #
  2042. var toggle_ebcautest = func () {
  2043. var ebt = getprop("/controls/engines/engine/ebcautest");
  2044. var rpm = getprop("/rotors/main/rpm");
  2045. if ( !ebt ) {
  2046. if ( rpm > 360 ) {
  2047. if ( getprop("/gear/gear[0]/wow") or getprop("/gear/gear[1]/wow")
  2048. or getprop("/gear/gear[2]/wow") or getprop("/gear/gear[3]/wow") )
  2049. {
  2050. setprop("/controls/engines/engine/ebcautest",1);
  2051. # deactivate governor so gov warnings go on
  2052. setprop("/controls/engines/engine/governor",0);
  2053. } else {
  2054. screen.log.write("ATTENTION EBCAU TEST only ground !!!");
  2055. }
  2056. } else {
  2057. screen.log.write("EBCAU TEST requires full powered engine !!!");
  2058. }
  2059. } else {
  2060. setprop("/controls/engines/engine/ebcautest",0);
  2061. # reactivate governor
  2062. setprop("/controls/engines/engine/governor",1);
  2063. }
  2064. }
  2065. ###########################
  2066. # mhab added
  2067. #
  2068. var adjust_twist_grip = func (delta) {
  2069. var p = getprop("/controls/engines/engine/power");
  2070. if ( delta > 0 ) {
  2071. delta=0.03;
  2072. p +=delta;
  2073. if ( p > 0.60 ) {
  2074. if ( p > 1 ) p = 1;
  2075. setprop("/controls/engines/engine/power", p);
  2076. if ( getprop("/controls/electric/external-power") ) {
  2077. settimer( func{ screen.log.write("Disconnect external power supply before Take-Off !!!"); },3);
  2078. }
  2079. } else {
  2080. setprop("/controls/engines/engine/power", 0.63);
  2081. }
  2082. } else {
  2083. delta=-0.03;
  2084. p +=delta;
  2085. if ( p > 0.59 ) {
  2086. if ( p < 0.63 ) p = 0.63;
  2087. setprop("/controls/engines/engine/power", p);
  2088. } else {
  2089. setprop("/controls/engines/engine/power", 0.63);
  2090. }
  2091. }
  2092. p = getprop("/controls/engines/engine/power")*100;
  2093. if ( p > 60 ) {
  2094. gui.popupTip(sprintf("Twist Grip %d%%", p));
  2095. }
  2096. return p;
  2097. }
  2098. ###########################
  2099. # mhab added
  2100. #
  2101. var adjust_inst1 = func (delta) {
  2102. var p = getprop("/controls/lighting/instrument-lights-norm");
  2103. p +=delta;
  2104. if ( p > 1 ) p = 1;
  2105. if ( p < 0 ) p = 0;
  2106. setprop("/controls/lighting/instrument-lights-norm", p);
  2107. return p*100;
  2108. }
  2109. ###########################
  2110. # mhab added
  2111. #
  2112. var adjust_inst2 = func (delta) {
  2113. var p = getprop("/controls/lighting/instrument-lights2-norm");
  2114. p +=delta;
  2115. if ( p > 1 ) p = 1;
  2116. if ( p < 0 ) p = 0;
  2117. setprop("/controls/lighting/instrument-lights2-norm", p);
  2118. return p*100;
  2119. }
  2120. ###########################
  2121. # mhab added
  2122. #
  2123. var adjust_vemd = func (delta) {
  2124. var p = getprop("/controls/lighting/instrument-lights-vemd-norm");
  2125. p +=delta;
  2126. if ( p > 1 ) p = 1;
  2127. if ( p < 0 ) p = 0;
  2128. setprop("/controls/lighting/instrument-lights-vemd-norm", p);
  2129. return p*100;
  2130. }
  2131. ###########################
  2132. # mhab added
  2133. #
  2134. var adjust_rpm = func (delta) {
  2135. var p = getprop("/controls/lighting/tach-light-norm");
  2136. p +=delta;
  2137. if ( p > 1 ) p = 1;
  2138. if ( p < 0 ) p = 0;
  2139. setprop("/controls/lighting/tach-light-norm", p);
  2140. return p*100;
  2141. }
  2142. ###########################
  2143. # mhab added
  2144. #
  2145. var adjust_heading = func (delta) {
  2146. var p = getprop("/instrumentation/kcs55/ki525/selected-heading-deg");
  2147. p +=delta;
  2148. if ( p > 360 ) p -= 360;
  2149. if ( p < 0 ) p += 360;
  2150. setprop("/instrumentation/kcs55/ki525/selected-heading-deg", p);
  2151. return p;
  2152. }
  2153. ###########################
  2154. # mhab added
  2155. var adjust_obs = func (delta) {
  2156. var p = getprop("/instrumentation/kcs55/ki525/selected-course-deg");
  2157. p +=delta;
  2158. if ( p > 360 ) p -= 360;
  2159. if ( p < 0 ) p += 360;
  2160. setprop("/instrumentation/kcs55/ki525/selected-course-deg", p);
  2161. return p;
  2162. }
  2163. ###########################
  2164. # mhab added
  2165. #
  2166. var adjust_horizon_offset = func (delta) {
  2167. var p = 0;
  2168. # only if horizob is active
  2169. if ( getprop("/instrumentation/attitude-indicator/serviceable") ) {
  2170. p = getprop("/instrumentation/attitude-indicator/horizon-offset-deg");
  2171. p +=delta;
  2172. setprop("/instrumentation/attitude-indicator/horizon-offset-deg", p);
  2173. return p;
  2174. }
  2175. }
  2176. ###########################
  2177. # mhab added
  2178. #
  2179. var adjust_altimeter = func (delta) {
  2180. var p = getprop("/instrumentation/altimeter/setting-inhg");
  2181. p +=delta;
  2182. if ( p > 31.0 ) p = 31.0;
  2183. if ( p < 27.50 ) p = 27.50;
  2184. setprop("/instrumentation/altimeter/setting-inhg", p);
  2185. return p;
  2186. }
  2187. ###########################
  2188. # mhab added
  2189. #
  2190. var adjust_stretcher = func (delta) {
  2191. p = 0;
  2192. # only do something if stretcher is available
  2193. if ( getprop("/sim/model/ec130/interior_passengers") == 4 ) {
  2194. var p = getprop("/controls/seat/stretcher/position-deg");
  2195. var po = getprop("/sim/view[107]/config/pitch-offset-deg");
  2196. p +=delta;
  2197. po -=delta;
  2198. if ( delta > 0 and p > 40.0 ) {
  2199. p = 40.0;
  2200. po +=delta;
  2201. }
  2202. if ( delta < 0 and p < 0.0 ) {
  2203. p = 0.0;
  2204. po +=delta;
  2205. }
  2206. setprop("/controls/seat/stretcher/position-deg", p);
  2207. # adjust view setting
  2208. setprop("/sim/view[107]/config/pitch-offset-deg",po);
  2209. if ( getprop("/sim/current-view/name") == "Patient View" ) {
  2210. setprop("/sim/current-view/pitch-offset-deg",po);
  2211. }
  2212. }
  2213. return p;
  2214. }
  2215. ###########################
  2216. # mhab added
  2217. #
  2218. var adjust_fuel = func (delta) {
  2219. if ( getprop("gear/gear[0]/wow") or getprop("gear/gear[1]/wow") or getprop("gear/gear[2]/wow") or getprop("gear/gear[3]/wow") ) {
  2220. var p = getprop("/consumables/fuel/tank/level-lbs");
  2221. var max= getprop("/limits/tank");
  2222. p +=delta;
  2223. if ( delta > 0 and p > max ) {
  2224. p = max;
  2225. }
  2226. if ( delta < 0 and p < 0.0 ) {
  2227. p = 0.0;
  2228. }
  2229. setprop("/consumables/fuel/tank/level-lbs", p);
  2230. } else {
  2231. screen.log.write("Fuel adjust only possible on ground !!!");
  2232. }
  2233. return p;
  2234. }
  2235. ###########################
  2236. # mhab added
  2237. #
  2238. var toggle_all_doors = func () {
  2239. doors.doorsystem.frontlexport();
  2240. doors.doorsystem.frontrexport();
  2241. doors.doorsystem.passengerlexport();
  2242. if ( getprop("/sim/model/variant") == "1" ) {
  2243. doors.doorsystem.luggagerexport();
  2244. } else {
  2245. doors.doorsystem.passengerrexport();
  2246. doors.doorsystem.basketrexport();
  2247. }
  2248. doors.doorsystem.doorbexport();
  2249. doors.doorsystem.basketlexport();
  2250. }
  2251. ###########################
  2252. # mhab added
  2253. #
  2254. var switch_startselector = func () {
  2255. var p = getprop("/controls/engines/engine/startselector");
  2256. var g = getprop("/controls/engines/engine/switchguard");
  2257. var r = getprop("/controls/rotor/brake");
  2258. var s = getprop("/sim/sound/click");
  2259. if (p == 0) {
  2260. if ( !r ) {
  2261. # rotorbrake inhibits starter
  2262. setprop("/controls/engines/engine/startselector", 1);
  2263. setprop("/sim/sound/click", !s);
  2264. } else {
  2265. screen.log.write("Rotorbrake is active !!!");
  2266. }
  2267. } else {
  2268. if ( !g ) {
  2269. setprop("/controls/engines/engine/startselector", 0);
  2270. setprop("/sim/sound/click", !s);
  2271. }
  2272. }
  2273. }
  2274. ###########################
  2275. # mhab added
  2276. #
  2277. var unlock_emergency = func () {
  2278. if ( getprop("/controls/electric/emergency-switch-locked") == 1 ) {
  2279. setprop("/controls/electric/emergency-switch-locked",0);
  2280. screen.log.write("Emergency Switch is UNLOCKED !!!");
  2281. screen.log.write("ATTENTION Emergency Switch CANNOT be RESET !!!");
  2282. } else {
  2283. screen.log.write("Emergency Switch is UNLOCKED !!!");
  2284. }
  2285. }
  2286. ###########################
  2287. # mhab added
  2288. #
  2289. var switch_emergency = func () {
  2290. if ( getprop("/controls/electric/emergency-switch-locked") == 0) {
  2291. setprop("/controls/electric/emergency-switch",1);
  2292. screen.log.write("Emergency Switch is SET !!! No RESET possible !!!");
  2293. inhibit_emergency();
  2294. } else {
  2295. if ( getprop("/controls/electric/emergency-switch") == 0 ) {
  2296. screen.log.write("Unlock Emergency Switch first !!!");
  2297. } else {
  2298. screen.log.write("Emergency Switch CANNOT be RESET !!!");
  2299. }
  2300. }
  2301. }
  2302. ###########################
  2303. # mhab added
  2304. #
  2305. var inhibit_emergency = func () {
  2306. # disable systems
  2307. # engine
  2308. setprop("/controls/engines/engine/cutoffguard",0);
  2309. setprop("/controls/engines/engine/cutoff",1);
  2310. setprop("/controls/engines/engine/cutoff-norm",1);
  2311. setprop("/controls/engines/engine/switchguard",0);
  2312. setprop("/controls/engines/engine/startselector", 0);
  2313. setprop("/controls/electric/engine[0]/generator",0);
  2314. setprop("/controls/fuel/tank/boost-pump",0);
  2315. # instruments
  2316. setprop("/controls/electric/horn",0);
  2317. setprop("/controls/electric/avionics-switch",0);
  2318. setprop("/controls/anti-ice/pitot-heat",0);
  2319. setprop("/instrumentation/attitude-indicator/serviceable",0);
  2320. setprop("/controls/electric/gyrocompass",0);
  2321. # lights
  2322. setprop("/controls/lighting/beacon",0);
  2323. setprop("/controls/lighting/strobe", 0);
  2324. setprop("/controls/lighting/nav-lights",0);
  2325. setprop("/controls/lighting/taxi-light",0);
  2326. setprop("/controls/lighting/landing-lights",0);
  2327. setprop("/controls/lighting/instrument-lights",0);
  2328. # keep on for emergency
  2329. #setprop("/controls/lighting/dome-light",0);
  2330. #setprop("/controls/lighting/instrument-lights2",0);
  2331. settimer(inhibit_emergency,0.1);
  2332. }
  2333. ###########################
  2334. # mhab added
  2335. #
  2336. var ELT_test = func () {
  2337. if ( !getprop("/ELT/test") ) {
  2338. setprop("/ELT/armed",0);
  2339. setprop("/ELT/test",1);
  2340. settimer(func { setprop("/ELT/test",0);},2);
  2341. }
  2342. }
  2343. ###########################
  2344. # mhab added
  2345. #
  2346. var toggle_rotorbrake = func () {
  2347. var l = getprop("/controls/rotor/brake-locked");
  2348. var b = getprop("/controls/rotor/brake");
  2349. if ( !l ) {
  2350. interpolate("/controls/rotor/brake",!b,1);
  2351. if ( getprop("/controls/rotor/brake") > 0.1 ) {
  2352. gui.popupTip("Rotorbrake opening ...",1);
  2353. } else {
  2354. gui.popupTip("Rotorbrake closing ...",1);
  2355. }
  2356. settimer(func { gui.popupTip("Rotorbrake " ~ (b ? "released !" : "engaged !"));},1.1);
  2357. } else {
  2358. screen.log.write("Rotorbrake is locked !!!");
  2359. }
  2360. }
  2361. ###########################
  2362. # mhab added
  2363. #
  2364. var toggle_cutoff = func () {
  2365. var l = getprop("/controls/engines/engine/cutoffguard");
  2366. var b = getprop("/controls/engines/engine/cutoff");
  2367. var n = getprop("/controls/engines/engine/cutoff-norm");
  2368. if ( !l ) {
  2369. interpolate("/controls/engines/engine/cutoff-norm",!b,1);
  2370. interpolate("/controls/engines/engine/cutoff",!b,1);
  2371. if ( getprop("/controls/engines/engine/cutoff-norm") > 0.1 ) {
  2372. gui.popupTip("Cutoff opening ...",1);
  2373. } else {
  2374. gui.popupTip("Cutoff closing ...",1);
  2375. }
  2376. settimer(func { gui.popupTip("Cutoff " ~ (b ? "inactive !" : "active !"));},1.1);
  2377. } else {
  2378. screen.log.write("Cutoff is guarded, unlock first !!!");
  2379. }
  2380. }
  2381. ###########################
  2382. # mhab added
  2383. #
  2384. # used in:
  2385. # - config dialog (view property not toggled)
  2386. # - pick animation (with view property toggled)
  2387. ###########################
  2388. var toggle_copilot_controls = func (n) {
  2389. if ( getprop("gear/gear[0]/wow") or getprop("gear/gear[1]/wow") or getprop("gear/gear[2]/wow") or getprop("gear/gear[3]/wow") ) {
  2390. if ( n > 0 ) {
  2391. setprop("/sim/model/ec130/copilot_controls", !getprop("/sim/model/ec130/copilot_controls"));
  2392. }
  2393. # if Pilot is not there Co-Pilot ( and i.e. his controls) must
  2394. if ( getprop("/sim/weight[0]/weight-lb") < 40 ) {
  2395. setprop("/sim/model/ec130/copilot_controls",1);
  2396. screen.log.write("One Pilot must be available !!!");
  2397. }
  2398. ec130.set_seats();
  2399. } else {
  2400. screen.log.write("Only possible on ground !!!");
  2401. }
  2402. }
  2403. ###########################
  2404. # mhab added
  2405. #
  2406. # used in:
  2407. # - config dialog (view property not toggled)
  2408. # - pick animations (with view property toggled)
  2409. ###########################
  2410. var toggle_view = func(n) {
  2411. if ( getprop("gear/gear[0]/wow") or getprop("gear/gear[1]/wow") or getprop("gear/gear[2]/wow") or getprop("gear/gear[3]/wow") ) {
  2412. # negativ n means don't toggle property
  2413. if ( n < 0 ) {
  2414. n=n*-1;
  2415. # -1 means view 0 (pilot view)
  2416. if (n == 1) n=0;
  2417. } else {
  2418. setprop("/sim/view[" ~ n ~ "]/enabled", !getprop("/sim/view[" ~ n ~ "]/enabled"));
  2419. }
  2420. if ( n == 0 ) {
  2421. if ( getprop("/sim/view[0]/enabled") ) {
  2422. setprop("/sim/weight[0]/weight-lb",180);
  2423. } else {
  2424. setprop("/sim/weight[0]/weight-lb",0);
  2425. # if pilot is not there co-pilot must
  2426. setprop("/sim/weight[1]/weight-lb",180);
  2427. setprop("/sim/model/ec130/copilot_controls",1);
  2428. }
  2429. } else if (n == 101) {
  2430. if ( getprop("/sim/view[101]/enabled") ) {
  2431. setprop("/sim/weight[1]/weight-lb",180);
  2432. } else {
  2433. setprop("/sim/weight[1]/weight-lb",0);
  2434. # if co-Pilot is not there pilot must
  2435. setprop("/sim/weight[0]/weight-lb",180);
  2436. }
  2437. } else if (n == 102) {
  2438. if ( getprop("/sim/view[102]/enabled") ) {
  2439. setprop("/sim/weight[2]/weight-lb",180);
  2440. } else {
  2441. setprop("/sim/weight[2]/weight-lb",0);
  2442. }
  2443. } else if (n == 103) {
  2444. if ( getprop("/sim/view[103]/enabled") ) {
  2445. setprop("/sim/weight[3]/weight-lb",180);
  2446. } else {
  2447. setprop("/sim/weight[3]/weight-lb",0);
  2448. }
  2449. } else if (n == 104) {
  2450. if ( getprop("/sim/view[104]/enabled") ) {
  2451. setprop("/sim/weight[4]/weight-lb",180);
  2452. } else {
  2453. setprop("/sim/weight[4]/weight-lb",0);
  2454. }
  2455. } else if (n == 105) {
  2456. if ( getprop("/sim/view[105]/enabled") ) {
  2457. setprop("/sim/weight[5]/weight-lb",180);
  2458. } else {
  2459. setprop("/sim/weight[5]/weight-lb",0);
  2460. }
  2461. } else if (n == 106) {
  2462. if ( getprop("/sim/view[106]/enabled") ) {
  2463. setprop("/sim/weight[6]/weight-lb",180);
  2464. } else {
  2465. setprop("/sim/weight[6]/weight-lb",0);
  2466. }
  2467. } else if (n == 107) {
  2468. if ( getprop("/sim/view[107]/enabled") ) {
  2469. setprop("/sim/weight[6]/weight-lb",180);
  2470. } else {
  2471. setprop("/sim/weight[6]/weight-lb",0);
  2472. }
  2473. } else if (n == 108) {
  2474. if ( getprop("/sim/view[108]/enabled") ) {
  2475. setprop("/sim/weight[7]/weight-lb",180);
  2476. } else {
  2477. setprop("/sim/weight[7]/weight-lb",0);
  2478. }
  2479. }
  2480. ec130.set_seats();
  2481. } else {
  2482. screen.log.write("Only possible on ground !!!");
  2483. }
  2484. }
  2485. ###########################
  2486. # mhab added
  2487. #
  2488. # This function can add/remove luggage step by step.
  2489. #
  2490. # Luggage Concept:
  2491. #
  2492. # For some predefined weights a special luggage handling is implemented.
  2493. # The following weights are possible to use:
  2494. # weight 8 ... Luggage Left
  2495. # weight 9 ... Luggage Right
  2496. # weight 10 ... Luggage Back
  2497. # weight 11 ... Basket Left
  2498. # weight 12 ... Basket Right
  2499. #
  2500. # There may be several pieces of luggage with differing weights defined
  2501. # for each compartment.
  2502. #
  2503. # The compartment is specified by the weight number (wn) as defined
  2504. # for the aircraft.
  2505. #
  2506. # The upper limit of each compartment is defined by "/sim/weight[wn]/max-lb"
  2507. # The weight of each piece of luggage is defined by "/sim/weight[wn]/luggage[n]/weight-lb"
  2508. #
  2509. # The max number of pieces may be less than the max weight would allow.
  2510. # If the weight is changed through the configuration dialog it can only be
  2511. # changed in steps related to available luggage.
  2512. #
  2513. # Wide luggage boxes:
  2514. # Wide luggage boxes can take more luggage than the regular ones.
  2515. # This dependency is marked in weight/luggage definition ("wide" flag).
  2516. # wide: 0 ... not with wide boxes
  2517. # 1 ... with wide boxes (default)
  2518. # 2 ... only with wide boxes
  2519. #
  2520. # EMS (rescue) configuration:
  2521. # In EMS configuration the right luggagebox is used for special equipment.
  2522. # In order to control the use of luggage in EMS config the "ems" flag
  2523. # in weight/luggage definition is used.
  2524. # ems: 0 ... not with EMS configuration
  2525. # 1 ... with EMS (default)
  2526. # 2 ... only with EMS
  2527. ###########################
  2528. var handle_luggage = func(n,wn) {
  2529. # only handle selected weight positions
  2530. if ( wn<8 or wn>12 ) {
  2531. screen.log.write(sprintf("Weight %i not usable for luggage handling !",wn));
  2532. return;
  2533. }
  2534. # not really necessary here, because doors are not operable off ground
  2535. # still here to be sure
  2536. if ( !getprop("gear/gear[0]/wow") and !getprop("gear/gear[1]/wow") and !getprop("gear/gear[2]/wow") and !getprop("gear/gear[3]/wow") ) {
  2537. screen.log.write("Only possible on ground !!!");
  2538. return;
  2539. }
  2540. n = n > 0 ? 1 : -1;
  2541. var cnt = getprop("/sim/weight[" ~ wn ~ "]/luggage-cnt");
  2542. var wgt = getprop("/sim/weight[" ~ wn ~ "]/weight-lb");
  2543. var wgt_max = getprop("/sim/weight[" ~ wn ~ "]/max-lb");
  2544. var wid = getprop("/sim/model/ec130/luggage_wide");
  2545. var ems = getprop("/sim/model/ec130/interior_passengers");
  2546. var luggage = props.globals.getNode("/sim/weight[" ~ wn ~ "]").getChildren("luggage");
  2547. ems = ems > 4 ? 0 : 1;
  2548. var wid_use = 0;
  2549. var ems_use = 0;
  2550. var cnt_ori = cnt;
  2551. var lmax_ems = 0;
  2552. cnt_idx = n > 0 ? cnt : cnt-1;
  2553. cnt+=n;
  2554. if ( cnt >= 0 ) {
  2555. # get maximum luggage count in ems config
  2556. if ( ems ) {
  2557. for(var i=0; i< size(luggage); i+=1) {
  2558. ems_use = getprop("/sim/weight[" ~ wn ~ "]/luggage[" ~ i ~ "]/ems");
  2559. if ( ems_use == nil ) ems_use=1;
  2560. if ( ems_use > 0) lmax_ems+=1;
  2561. }
  2562. }
  2563. for(var i=cnt_idx; i< size(luggage); i+=1) {
  2564. if ( ems and cnt > lmax_ems ) break;
  2565. wgt_diff = getprop("/sim/weight[" ~ wn ~ "]/luggage[" ~ i ~ "]/weight-lb");
  2566. wid_use = getprop("/sim/weight[" ~ wn ~ "]/luggage[" ~ i ~ "]/wide");
  2567. ems_use = getprop("/sim/weight[" ~ wn ~ "]/luggage[" ~ i ~ "]/ems");
  2568. if ( wid_use == nil ) wid_use=1;
  2569. if ( ems_use == nil ) ems_use=1;
  2570. # no more luggage available or usable
  2571. if ( ( wgt_diff == nil ) or
  2572. ( wid and wid_use == 0) or
  2573. (!wid and wid_use == 2) or
  2574. ( ems and ems_use == 0) or
  2575. (!ems and ems_use == 2) ) {
  2576. continue;
  2577. }
  2578. wgt_new=wgt+wgt_diff*n;
  2579. if ( wgt_new > wgt_max ) {
  2580. wgt_new=wgt;
  2581. cnt=cnt-1;
  2582. screen.log.write("Weight limit exceeded !");
  2583. }
  2584. if ( wgt_new < 0 ) wgt_new=0;
  2585. setprop("/sim/weight[" ~ wn ~ "]/weight-lb",wgt_new);
  2586. setprop("/sim/weight[" ~ wn ~ "]/luggage-cnt",cnt);
  2587. if ( ems ) setprop("/sim/weight[" ~ wn ~ "]/luggage-cnt-ems",cnt);
  2588. break;
  2589. }
  2590. } else {
  2591. setprop("/sim/weight[" ~ wn ~ "]/weight-lb",0);
  2592. setprop("/sim/weight[" ~ wn ~ "]/luggage-cnt",0);
  2593. }
  2594. cnt = getprop("/sim/weight[" ~ wn ~ "]/luggage-cnt");
  2595. if ( cnt == cnt_ori ) {
  2596. if ( cnt > 0 ) {
  2597. screen.log.write("No (more) usable luggage defined !");
  2598. } else {
  2599. screen.log.write("All luggage removed !");
  2600. }
  2601. }
  2602. }
  2603. ###########################
  2604. # mhab added
  2605. #
  2606. # This function fills up pieces of luggage until the weight is reached
  2607. # and readjusts the weight according to available luggage if necessary
  2608. #
  2609. # Luggage Concept: see above comment for function handle_luggage()
  2610. #
  2611. ###########################
  2612. var set_luggage = func(wn) {
  2613. # only handle selected weight positions
  2614. if ( wn<8 or wn>12 ) {
  2615. screen.log.write(sprintf("Weight %i not usable for luggage handling !",wn));
  2616. return;
  2617. }
  2618. if ( wn == 11 ) {
  2619. if ( !getprop("/sim/model/ec130/basket_left") ) {
  2620. # reset basket left
  2621. setprop("/sim/weight[" ~ wn ~ "]/luggage-cnt",0);
  2622. setprop("/sim/weight[" ~ wn ~ "]/weight-lb",0);
  2623. setprop("/sim/model/ec130/doors/basketl/position-norm",0);
  2624. return;
  2625. }
  2626. }
  2627. if ( wn == 12 ) {
  2628. if ( !getprop("/sim/model/ec130/basket_right") ) {
  2629. # reset basket right
  2630. setprop("/sim/weight[" ~ wn ~ "]/luggage-cnt",0);
  2631. setprop("/sim/weight[" ~ wn ~ "]/weight-lb",0);
  2632. setprop("/sim/model/ec130/doors/basketr/position-norm",0);
  2633. return;
  2634. }
  2635. }
  2636. var wgt = getprop("/sim/weight[" ~ wn ~ "]/weight-lb");
  2637. var wgt_max = getprop("/sim/weight[" ~ wn ~ "]/max-lb");
  2638. var wid = getprop("/sim/model/ec130/luggage_wide");
  2639. var ems = getprop("/sim/model/ec130/interior_passengers");
  2640. ems = ems > 4 ? 0 : 1;
  2641. var lcnt = 0;
  2642. var wgt_sum = 0;
  2643. var wgt_cur = 0;
  2644. var wid_use = 0;
  2645. var luggage = props.globals.getNode("/sim/weight[" ~ wn ~ "]").getChildren("luggage");
  2646. for(var i=0; i<size(luggage); i+=1) {
  2647. wgt_cur = luggage[i].getValue("weight-lb");
  2648. wid_use = luggage[i].getValue("wide");
  2649. ems_use = luggage[i].getValue("ems");
  2650. if ( wid_use == nil ) wid_use=1;
  2651. if ( ems_use == nil ) ems_use=1;
  2652. if ( !(( wgt_cur == nil ) or
  2653. ( wid and wid_use == 0) or
  2654. (!wid and wid_use == 2) or
  2655. ( ems and ems_use == 0) or
  2656. (!ems and ems_use == 2) ) ) {
  2657. lcnt+=1;
  2658. # add up weight
  2659. wgt_sum+=wgt_cur;
  2660. if ( wgt_sum > wgt or wgt_sum > wgt_max ) {
  2661. wgt_sum-=wgt_cur;
  2662. lcnt-=1;
  2663. break;
  2664. }
  2665. }
  2666. }
  2667. # set luggage count and weight
  2668. setprop("/sim/weight[" ~ wn ~ "]/luggage-cnt",lcnt);
  2669. setprop("/sim/weight[" ~ wn ~ "]/weight-lb",wgt_sum);
  2670. if ( size(luggage) == 0 and lcnt == 0 ) {
  2671. screen.log.write("No luggage usable !");
  2672. }
  2673. }
  2674. ###########################
  2675. # mhab added
  2676. #
  2677. var set_luggage_all = func() {
  2678. ec130.set_luggage(8);
  2679. ec130.set_luggage(9);
  2680. ec130.set_luggage(10);
  2681. ec130.set_luggage(11);
  2682. ec130.set_luggage(12);
  2683. }
  2684. ###########################
  2685. # mhab added
  2686. #
  2687. var aircraft_init = func() {
  2688. ec130.set_seats();
  2689. ec130.set_luggage_all();
  2690. ec130.external_weights();
  2691. }
  2692. ##############################################
  2693. # main() ============================================================
  2694. var delta_time = props.globals.getNode("/sim/time/delta-sec", 1);
  2695. var hi_heading = props.globals.getNode("/instrumentation/heading-indicator/indicated-heading-deg", 1);
  2696. var vertspeed = props.globals.initNode("/velocities/vertical-speed-fps");
  2697. var gross_weight_lb = props.globals.initNode("/fdm/yasim/gross-weight-lbs");
  2698. var gross_weight_kg = props.globals.initNode("/sim/model/gross-weight-kg");
  2699. props.globals.getNode("/instrumentation/adf/rotation-deg", 1).alias(hi_heading);
  2700. var main_loop = func {
  2701. props.globals.removeChild("autopilot");
  2702. if (replay)
  2703. setprop("/position/gear-agl-m", getprop("/position/altitude-agl-ft") * 0.3 - 1.2);
  2704. # mhab fix
  2705. #vert_speed_fpm.setDoubleValue(vertspeed.getValue() * 60);
  2706. var vspeed=vertspeed.getValue();
  2707. if ( vspeed == nil ) vspeed=0;
  2708. vert_speed_fpm.setDoubleValue(vspeed * 60);
  2709. gross_weight_kg.setDoubleValue(gross_weight_lb.getValue() or 0 * LB2KG);
  2710. var dt = delta_time.getValue();
  2711. update_torque(dt);
  2712. update_stall(dt);
  2713. update_slide();
  2714. update_absorber();
  2715. fuel.update(dt);
  2716. engines.update(dt);
  2717. vibration.update(dt);
  2718. settimer(main_loop, 0);
  2719. }
  2720. var replay = 0;
  2721. var crashed = 0;
  2722. setlistener("/sim/signals/fdm-initialized", func {
  2723. gui.menuEnable("autopilot", 1);
  2724. init_rotoranim();
  2725. vibration.init();
  2726. engines.init();
  2727. fuel.init();
  2728. mouse.init();
  2729. # mhab
  2730. setprop("/sim/model/sound/volume", 1.0);
  2731. collective.setDoubleValue(1);
  2732. setlistener("/sim/signals/reinit", func(n) {
  2733. n.getBoolValue() and return;
  2734. cprint("32;1", "reinit");
  2735. procedure.reset();
  2736. collective.setDoubleValue(1);
  2737. aircraft.livery.rescan();
  2738. # reconfigure is undefined
  2739. # reconfigure();
  2740. crashed = 0;
  2741. });
  2742. setlistener("/sim/crashed", func(n) {
  2743. cprint("31;1", "crashed ", n.getValue());
  2744. engines.engine[0].timer.stop();
  2745. engines.engine[1].timer.stop();
  2746. if (n.getBoolValue())
  2747. crash(crashed = 1);
  2748. # mhab start smoke and fire gradually
  2749. settimer(func { setprop("/sim/smoke/enabled",1); }, 5);
  2750. settimer(func { setprop("/sim/smoke/part-per-sec",8); }, 5);
  2751. settimer(func { setprop("/sim/smoke/life-sec",2); }, 5);
  2752. settimer(func { setprop("/sim/smoke/part-per-sec",12); }, 7);
  2753. settimer(func { setprop("/sim/smoke/life-sec",4); }, 7);
  2754. settimer(func { setprop("/sim/smoke/part-per-sec",25); }, 15);
  2755. settimer(func { setprop("/sim/smoke/life-sec",6.5); }, 15);
  2756. settimer(func { setprop("/sim/fire/enabled",1); }, 15);
  2757. settimer(func { setprop("/sim/fire/part-per-sec",8); }, 5);
  2758. settimer(func { setprop("/sim/fire/life-sec",0.5); }, 5);
  2759. settimer(func { setprop("/sim/fire/part-per-sec",12); }, 10);
  2760. settimer(func { setprop("/sim/fire/life-sec",1); }, 10);
  2761. settimer(func { setprop("/sim/fire/part-per-sec",25); }, 15);
  2762. settimer(func { setprop("/sim/fire/life-sec",2); }, 15);
  2763. });
  2764. setlistener("/sim/freeze/replay-state", func(n) {
  2765. replay = n.getValue();
  2766. cprint("33;1", replay ? "replay" : "pause");
  2767. if (crashed)
  2768. crash(!n.getBoolValue())
  2769. });
  2770. main_loop();
  2771. if (devel and quickstart)
  2772. engines.quickstart();
  2773. # activate sound after a delay to avoid
  2774. # "crushing" sound samples in cockpit at startup
  2775. settimer(func { setprop("/sim/sound/enabled",1); }, 3);
  2776. });