bk117 (1).nas 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. # Melchior FRANZ, < mfranz # aon : at >
  2. if (!contains(globals, "cprint"))
  3. var cprint = func nil;
  4. var devel = !!getprop("devel");
  5. var quickstart = !!getprop("quickstart");
  6. var sin = func(a) math.sin(a * D2R);
  7. var cos = func(a) math.cos(a * D2R);
  8. var pow = func(v, w) math.exp(math.ln(v) * w);
  9. var npow = func(v, w) v ? math.exp(math.ln(abs(v)) * w) * (v < 0 ? -1 : 1) : 0;
  10. var clamp = func(v, min = 0, max = 1) v < min ? min : v > max ? max : v;
  11. var normatan = func(x, slope = 1) math.atan2(x, slope) * 2 / math.pi;
  12. var bell = func(x, spread = 2) pow(math.e, -(x * x) / spread);
  13. var max = func(a, b) a > b ? a : b;
  14. var min = func(a, b) a < b ? a : b;
  15. # liveries =========================================================
  16. aircraft.livery.init("Aircraft/ec145/Models/liveries");
  17. #retractable landinglight================================================
  18. var landinglight = aircraft.door.new("/controls/landinglight", 2);
  19. #doors=========================
  20. leftFrontDoor = aircraft.door.new( "/sim/model/bk117/door-positions/leftFrontDoor", 4, 0 );
  21. rightFrontDoor = aircraft.door.new( "/sim/model/bk117/door-positions/rightFrontDoor", 4, 0 );
  22. leftBackDoor = aircraft.door.new( "/sim/model/bk117/door-positions/leftBackDoor", 4, 0 );
  23. rightBackDoor = aircraft.door.new( "/sim/model/bk117/door-positions/rightBackDoor", 4, 0 );
  24. leftRearDoor = aircraft.door.new( "/sim/model/bk117/door-positions/leftRearDoor", 4, 0 );
  25. rightRearDoor = aircraft.door.new( "/sim/model/bk117/door-positions/rightRearDoor", 4, 0 );
  26. # timers ============================================================
  27. aircraft.timer.new("/sim/time/hobbs/helicopter", nil).start();
  28. var elapsedN = props.globals.getNode("/sim/time/elapsed-sec", 1);
  29. # strobes ===========================================================
  30. var strobe_switch = props.globals.initNode("controls/lighting/strobe", 1, "BOOL");
  31. aircraft.light.new("sim/model/bk117/lighting/strobe-top", [0.05, 1.00], strobe_switch);
  32. aircraft.light.new("sim/model/bk117/lighting/strobe-bottom", [0.05, 1.03], strobe_switch);
  33. # beacons ===========================================================
  34. var beacon_switch = props.globals.initNode("controls/lighting/beacon", 1, "BOOL");
  35. aircraft.light.new("sim/model/bk117/lighting/beacon-top", [0.62, 0.62], beacon_switch);
  36. aircraft.light.new("sim/model/bk117/lighting/beacon-bottom", [0.63, 0.63], beacon_switch);
  37. # nav lights ========================================================
  38. var nav_light_switch = props.globals.initNode("controls/lighting/nav-lights", 1, "BOOL");
  39. var visibility = props.globals.getNode("environment/visibility-m", 1);
  40. var sun_angle = props.globals.getNode("sim/time/sun-angle-rad", 1);
  41. var nav_lights = props.globals.getNode("sim/model/bk117/lighting/nav-lights", 1);
  42. var nav_light_loop = func {
  43. if (nav_light_switch.getValue())
  44. nav_lights.setValue( visibility.getValue() < 5000 or sun_angle.getValue() > 1.4);
  45. else
  46. nav_lights.setValue(0);
  47. settimer(nav_light_loop, 3);
  48. }
  49. nav_light_loop();
  50. # init propulsion and load the XML definition for turbines and gearbox:
  51. io.include("propulsion.nas");
  52. var propulsion = Propulsion.new();
  53. # make a fuel system with 3 tanks, the Tank class is defined in propulsion.nas:
  54. var fuel = {
  55. main: Tank.new(0),
  56. # by litzi: ec145 needs two supply tanks, one per engine
  57. supply: [ Tank.new(1), Tank.new(2) ],
  58. init: func {
  59. # init the 3 tanks
  60. me.main.init();
  61. me.supply[0].init();
  62. me.supply[1].init();
  63. var fuel = props.globals.getNode("/consumables/fuel");
  64. me.pump_capacity = 10 * L2GAL / 60; # same pumps for transfer and supply
  65. me.total_galN = fuel.getNode("total-fuel-gals", 1);
  66. me.total_lbN = fuel.getNode("total-fuel-lbs", 1);
  67. me.total_normN = fuel.getNode("total-fuel-norm", 1);
  68. # transfer pumps electrical supply
  69. var elec = props.globals.getNode("/systems/electrical/outputs/");
  70. # transfer pumps (feed supply tanks from main tank) have more than 23V power?
  71. setlistener(elec.getNode("fuelpump-fwd",1), func(n) {me.trans1 = (n.getValue() or 0)>23;} , 1);
  72. setlistener(elec.getNode("fuelpump-aft",1), func(n) {me.trans2 = (n.getValue() or 0)>23;} , 1);
  73. setlistener("/sim/freeze/fuel", func(n) me.freeze = n.getBoolValue(), 1);
  74. me.capacity = me.main.capacity + me.supply[0].capacity + me.supply[1].capacity;
  75. me.warntime = 0;
  76. me.update(0);
  77. print("fuel system ... initialized");
  78. },
  79. update: func(dt) {
  80. foreach (a; me.supply) {
  81. var free = a.capacity - a.level();
  82. if (free > 0) {
  83. var trans_flow = (me.trans1 + me.trans2) * me.pump_capacity;
  84. a.consume( -me.main.consume(min(trans_flow * dt, free)));
  85. }
  86. }
  87. var level = me.main.level() + me.supply[0].level() + me.supply[1].level();;
  88. me.total_galN.setValue(level);
  89. me.total_lbN.setValue(level * GAL2LB);
  90. me.total_normN.setValue(level / me.capacity);
  91. },
  92. level: func(eng) {
  93. return me.supply[eng].level();
  94. },
  95. consume: func(eng, amount) {
  96. return me.freeze ? 0 : me.supply[eng].consume(amount);
  97. },
  98. };
  99. var fuel_pump_prime = {
  100. p: ["/controls/fuel/tank[1]/prime-pump", "/controls/fuel/tank[2]/prime-pump"],
  101. on: func(n) {
  102. setprop(me.p[n], 1);
  103. },
  104. off: func(n) {
  105. setprop(me.p[n], 0);
  106. },
  107. get: func(n) {
  108. return( getprop(me.p[n]) );
  109. }
  110. };
  111. ###this is the bit we need###
  112. var fuel_pump_xfer = {
  113. p: ["/controls/switches/fuel/transfer-pump[0]", "/controls/switches/fuel/transfer-pump[1]"],
  114. on: func(n) {
  115. setprop(me.p[n], 1); },
  116. off: func(n) {
  117. setprop(me.p[n], 0); },
  118. get: func(n) {
  119. return( getprop(me.p[n]) ); }
  120. };
  121. ###create fuel endurance in sec###
  122. var endu = "/consumables/fuel/endurance-sec";
  123. var ff = ["/engines/engine[0]/fuel-flow_pph",
  124. "/engines/engine[1]/fuel-flow_pph"];
  125. var fuelendurance = func () {
  126. var ffx = (getprop(ff[0]) or 0) + (getprop(ff[1]) or 0); #pound/h
  127. if (ffx > 0) {
  128. # max. 10h indication
  129. var ss = min( getprop("/consumables/fuel/total-fuel-lbs")/ffx*3600, 36000);
  130. interpolate(endu, ss, 10);
  131. } else {
  132. setprop(endu, 0);
  133. }
  134. };
  135. var vert_speed_fpm = props.globals.initNode("/velocities/vertical-speed-fpm");
  136. if (devel) {
  137. setprop("/instrumentation/altimeter/setting-inhg", getprop("/environment/pressure-inhg"));
  138. setprop("/controls/fuel/tank[1]/prime-pump",1);
  139. setprop("/controls/fuel/tank[2]/prime-pump",1);
  140. setlistener("/sim/signals/fdm-initialized", func {
  141. settimer(func {
  142. screen.property_display.x = 10;
  143. screen.property_display.y = 500;
  144. screen.property_display.format = "%.3g";
  145. screen.property_display.add(
  146. "/controls/engines/engine/throttle",
  147. propulsion.rotor_rpm,
  148. "/consumables/fuel/total-fuel-gals",
  149. "L",
  150. propulsion.engine[0].runningOut,
  151. propulsion.engine[0].starterOut,
  152. propulsion.engine[0].powerOut,
  153. propulsion.engine[0].freewheelOut,
  154. "/controls/engines/engine[0]/power",
  155. propulsion.engine[0].maxRelTrqOut,
  156. propulsion.engine[0].n1pct,
  157. propulsion.engine[0].n2pct,
  158. propulsion.engine[0].outOfFuelOut,
  159. "R",
  160. propulsion.engine[1].runningOut,
  161. propulsion.engine[1].starterOut,
  162. propulsion.engine[1].powerOut,
  163. propulsion.engine[1].freewheelOut,
  164. "/controls/engines/engine[1]/power",
  165. propulsion.engine[1].maxRelTrqOut,
  166. propulsion.engine[1].n1pct,
  167. propulsion.engine[1].n2pct,
  168. propulsion.engine[1].outOfFuelOut,
  169. "X",
  170. "/sim/model/gross-weight-kg",
  171. "/sim/systems/electrical/battery/charge-amph",
  172. "/position/altitude-ft",
  173. "/position/altitude-agl-ft",
  174. "/instrumentation/altimeter/indicated-altitude-ft",
  175. "/environment/temperature-degc",
  176. "/velocities/airspeed-kt",
  177. vert_speed_fpm
  178. );
  179. }, 1);
  180. });
  181. }
  182. var mouse = {
  183. init: func {
  184. me.x = me.y = nil;
  185. me.savex = nil;
  186. me.savey = nil;
  187. setlistener("/sim/startup/xsize", func(n) me.centerx = int(n.getValue()) / 2, 1);
  188. setlistener("/sim/startup/ysize", func(n) me.centery = int(n.getValue()) / 2, 1);
  189. setlistener("/devices/status/mice/mouse/mode", func(n) me.mode = n.getValue(), 1);
  190. setlistener("/devices/status/mice/mouse/button[1]", func(n) {
  191. me.mmb = n.getValue();
  192. if (me.mode)
  193. return;
  194. if (me.mmb) {
  195. me.savex = me.x;
  196. me.savey = me.y;
  197. gui.setCursor(me.centerx, me.centery, "none");
  198. } else {
  199. gui.setCursor(me.savex, me.savey, "pointer");
  200. }
  201. }, 1);
  202. setlistener("/devices/status/mice/mouse/x", func(n) me.x = n.getValue(), 1);
  203. setlistener("/devices/status/mice/mouse/y", func(n) me.update( me.y = n.getValue() ), 1);
  204. },
  205. update: func {
  206. if (me.mode or !me.mmb)
  207. return;
  208. if (var dy = -me.y + me.centery)
  209. #engines.adjust_power(dy * 0.005);
  210. gui.setCursor(me.centerx, me.centery);
  211. },
  212. };
  213. var startup = func {
  214. if (procedure.stage < 0) {
  215. procedure.step = 1;
  216. procedure.next();
  217. }
  218. };
  219. var shutdown = func {
  220. if (procedure.stage > 0) {
  221. procedure.step = -1;
  222. procedure.next();
  223. }
  224. };
  225. var procedure = {
  226. stage: -999,
  227. step: nil,
  228. loopid: 0,
  229. reset: func {
  230. me.loopid += 1;
  231. me.stage = -999;
  232. step = nil;
  233. propulsion.init();
  234. },
  235. next: func(delay = 0) {
  236. if (crashed)
  237. return;
  238. if (me.stage < 0 and me.step > 0 or me.stage > 0 and me.step < 0)
  239. me.stage = 0;
  240. settimer(func { me.stage += me.step; me.process(me.loopid) }, delay * !quickstart);
  241. # interpolate(startup_proc,startup_proc.getPath()+delay,delay);
  242. },
  243. process: func(id) {
  244. # the model-specific startup processes are defined in enginecontrol-h145.nas and enginecontrol-ec145-nas
  245. }
  246. };
  247. # blade vibration absorber pendulum
  248. var pendulum = props.globals.getNode("/sim/model/bk117/absorber-angle-deg", 1);
  249. var update_absorber = func {
  250. pendulum.setValue( 90 * clamp(abs( propulsion.rotor_rpm.getValue() ) / 90));
  251. };
  252. var vibration = { # and noise ...
  253. init: func {
  254. me.lonN = props.globals.initNode("/rotors/main/vibration/longitudinal");
  255. me.latN = props.globals.initNode("/rotors/main/vibration/lateral");
  256. me.soundN = props.globals.initNode("/sim/sound/vibration");
  257. me.airspeedN = props.globals.getNode("/velocities/airspeed-kt");
  258. me.vertspeedN = props.globals.getNode("/velocities/vertical-speed-fps");
  259. me.groundspeedN = props.globals.getNode("/velocities/groundspeed-kt");
  260. me.speeddownN = props.globals.getNode("/velocities/speed-down-fps");
  261. me.angleN = props.globals.initNode("/velocities/descent-angle-deg");
  262. me.dir = 0;
  263. },
  264. update: func(dt) {
  265. var airspeed = me.airspeedN.getValue();
  266. if (airspeed > 145) { # overspeed vibration
  267. var frequency = 2000 + 500 * rand();
  268. var v = 0.49 + 0.5 * normatan(airspeed - 160, 10);
  269. var intensity = v;
  270. var noise = v * internal;
  271. } elsif (airspeed > 30) { # Blade Vortex Interaction (BVI) 8 deg, 65 kts max?
  272. var frequency = propulsion.rotor_rpm.getValue() * 4 * 60;
  273. var down = me.speeddownN.getValue() * FT2M;
  274. var level = me.groundspeedN.getValue() * NM2M / 3600;
  275. me.angleN.setValue(var angle = math.atan2(down, level) * R2D);
  276. var speed = math.sqrt(level * level + down * down) * MPS2KT;
  277. angle = bell(angle - 9, 13);
  278. speed = bell(speed - 65, 450);
  279. var v = angle * speed;
  280. var intensity = v * 0.10;
  281. var noise = v * (1 - internal * 0.4);
  282. } else { # hover
  283. var rpm = propulsion.rotor_rpm.getValue();
  284. var frequency = rpm * 4 * 60;
  285. var coll = bell(propulsion.collective.getValue(), 0.5);
  286. var ias = bell(airspeed, 600);
  287. var vert = bell(me.vertspeedN.getValue() * 0.5, 400);
  288. var rpm = 0.477 + 0.5 * normatan(rpm - 350, 30) * 1.025;
  289. var v = coll * ias * vert * rpm;
  290. var intensity = v * 0.10;
  291. var noise = v * (1 - internal * 0.4);
  292. }
  293. me.dir += dt * frequency;
  294. me.lonN.setValue(cos(me.dir) * intensity);
  295. me.latN.setValue(sin(me.dir) * intensity);
  296. me.soundN.setValue(noise);
  297. },
  298. };
  299. # sound =============================================================
  300. # stall sound
  301. var stall = props.globals.getNode("rotors/main/stall", 1);
  302. var stall_filtered = props.globals.getNode("rotors/main/stall-filtered", 1);
  303. var stall_val = 0;
  304. stall.setValue(0);
  305. var update_stall = func(dt) {
  306. var s = getprop(stall.getPath());
  307. if (s < stall_val) {
  308. var f = dt / (0.3 + dt);
  309. stall_val = s * f + stall_val * (1 - f);
  310. } else {
  311. stall_val = s;
  312. }
  313. var c = propulsion.collective.getValue();
  314. stall_filtered.setValue(stall_val + 0.006 * (1 - c));
  315. }
  316. # skid slide sound
  317. var Skid = {
  318. new: func(n) {
  319. var m = { parents: [Skid] };
  320. var soundN = props.globals.getNode("sim/model/bk117/sound", 1).getChild("slide", n, 1);
  321. var gearN = props.globals.getNode("gear", 1).getChild("gear", n, 1);
  322. m.compressionN = gearN.getNode("compression-norm", 1);
  323. m.rollspeedN = gearN.getNode("rollspeed-ms", 1);
  324. m.frictionN = gearN.getNode("ground-friction-factor", 1);
  325. m.wowN = gearN.getNode("wow", 1);
  326. m.volumeN = soundN.getNode("volume", 1);
  327. m.pitchN = soundN.getNode("pitch", 1);
  328. m.compressionN.setValue(0);
  329. m.rollspeedN.setValue(0);
  330. m.frictionN.setValue(0);
  331. m.volumeN.setValue(0);
  332. m.pitchN.setValue(0);
  333. m.wowN.setValue(1);
  334. m.self = n;
  335. return m;
  336. },
  337. update: func {
  338. me.wow = me.wowN.getValue();
  339. if (me.wow < 0.5)
  340. return me.volumeN.setValue(0);
  341. var rollspeed = abs(me.rollspeedN.getValue() );
  342. me.pitchN.setValue(rollspeed * 0.6);
  343. var s = normatan(20 * rollspeed);
  344. var f = clamp((me.frictionN.getValue() - 0.5) * 2);
  345. var c = clamp(me.compressionN.getValue() * 2);
  346. var vol = s * f * c;
  347. me.volumeN.setValue(vol > 0.1 ? vol : 0);
  348. }
  349. };
  350. var skids = [];
  351. for (var i = 0; i < 4; i += 1)
  352. append(skids, Skid.new(i));
  353. #var antislide = props.globals.initNode("/gear/antislide");
  354. var update_slide = func {
  355. var wow = 0;
  356. foreach (var s; skids) {
  357. s.update();
  358. wow += s.wow;
  359. }
  360. #antislide.getPath(),wow > 0 ? 1 - rotor_rpm.getPath() / 10 : 0);
  361. }
  362. var internal = 1;
  363. setlistener("sim/current-view/view-number", func {
  364. internal = getprop("sim/current-view/internal");
  365. }, 1);
  366. # crash handler =====================================================
  367. var crash = func {
  368. if (arg[0]) {
  369. # crash
  370. setprop("sim/model/bk117/tail-angle-deg", 35);
  371. setprop("sim/model/bk117/shadow", 0);
  372. setprop("sim/model/bk117/doors/door[0]/position-norm", 0.2);
  373. setprop("sim/model/bk117/doors/door[1]/position-norm", 0.9);
  374. setprop("sim/model/bk117/doors/door[2]/position-norm", 0.2);
  375. setprop("sim/model/bk117/doors/door[3]/position-norm", 0.6);
  376. setprop("sim/model/bk117/doors/door[4]/position-norm", 0.1);
  377. setprop("sim/model/bk117/doors/door[5]/position-norm", 0.05);
  378. setprop("rotors/main/rpm", 0);
  379. setprop("rotors/main/blade[0]/flap-deg", -60);
  380. setprop("rotors/main/blade[1]/flap-deg", -50);
  381. setprop("rotors/main/blade[2]/flap-deg", -40);
  382. setprop("rotors/main/blade[3]/flap-deg", -30);
  383. setprop("rotors/main/blade[0]/incidence-deg", -30);
  384. setprop("rotors/main/blade[1]/incidence-deg", -20);
  385. setprop("rotors/main/blade[2]/incidence-deg", -50);
  386. setprop("rotors/main/blade[3]/incidence-deg", -55);
  387. setprop("rotors/tail/rpm", 0);
  388. strobe_switch.setValue(0);
  389. beacon_switch.setValue(0);
  390. nav_light_switch.setValue(0);
  391. propulsion.engine[0].n2pct.setValue(0);
  392. propulsion.engine[1].n2pct.setValue(0);
  393. #torque_pct.setValue(torque_val = 0);
  394. stall_filtered.setValue(stall_val = 0);
  395. } else {
  396. # uncrash (for replay)
  397. setprop("sim/model/bk117/tail-angle-deg", 0);
  398. setprop("sim/model/bk117/shadow", 1);
  399. doors.reset();
  400. setprop("rotors/tail/rpm", 2219);
  401. setprop("rotors/main/rpm", 442);
  402. for (i = 0; i < 4; i += 1) {
  403. setprop("rotors/main/blade[" ~ i ~ "]/flap-deg", 0);
  404. setprop("rotors/main/blade[" ~ i ~ "]/incidence-deg", 0);
  405. }
  406. strobe_switch.setValue(1);
  407. beacon_switch.setValue(1);
  408. propulsion.engine[0].n2pct.setValue(100);
  409. propulsion.engine[1].n2pct.setValue(100);
  410. }
  411. }
  412. # "manual" rotor animation for flight data recorder replay ============
  413. var rotor_step = props.globals.getNode("sim/model/bk117/rotor-step-deg");
  414. var blade1_pos = props.globals.getNode("rotors/main/blade[0]/position-deg", 1);
  415. var blade2_pos = props.globals.getNode("rotors/main/blade[1]/position-deg", 1);
  416. var blade3_pos = props.globals.getNode("rotors/main/blade[2]/position-deg", 1);
  417. var blade4_pos = props.globals.getNode("rotors/main/blade[3]/position-deg", 1);
  418. var rotorangle = 0;
  419. var rotoranim_loop = func {
  420. var i = rotor_step.getValue();
  421. if (i >= 0.0) {
  422. blade1_pos.setValue(rotorangle);
  423. blade2_pos.setValue(rotorangle + 90);
  424. blade3_pos.setValue(rotorangle + 180);
  425. blade4_pos.setValue(rotorangle + 270);
  426. rotorangle += i;
  427. settimer(rotoranim_loop, 0.1);
  428. }
  429. }
  430. var init_rotoranim = func {
  431. if (rotor_step.getValue() >= 0.0)
  432. settimer(rotoranim_loop, 0.1);
  433. }
  434. # view management ===================================================
  435. var flap_mode = 0;
  436. var down_time = 0;
  437. controls.flapsDown = func(v) {
  438. if (!flap_mode) {
  439. if (v < 0) {
  440. down_time = elapsedN.getValue();
  441. flap_mode = 1;
  442. dynamic_view.lookat(
  443. 5, # heading left
  444. -20, # pitch up
  445. 0, # roll right
  446. 0.2, # right
  447. 0.6, # up
  448. 0.85, # back
  449. 0.2, # time
  450. 55, # field of view
  451. );
  452. } elsif (v > 0) {
  453. flap_mode = 2;
  454. gui.popupTip("AUTOTRIM", 1e10);
  455. aircraft.autotrim.start();
  456. }
  457. } else {
  458. if (flap_mode == 1) {
  459. if (elapsedN.getValue() < down_time + 0.2)
  460. return;
  461. dynamic_view.resume();
  462. } elsif (flap_mode == 2) {
  463. aircraft.autotrim.stop();
  464. gui.popdown();
  465. }
  466. flap_mode = 0;
  467. }
  468. }
  469. # register function that may set me.heading_offset, me.pitch_offset, me.roll_offset,
  470. # me.x_offset, me.y_offset, me.z_offset, and me.fov_offset
  471. #
  472. dynamic_view.register(func {
  473. var lowspeed = 1 - normatan(me.speedN.getValue() / 50);
  474. var r = sin(me.roll) * cos(me.pitch);
  475. me.heading_offset = # heading change due to
  476. (me.roll < 0 ? -50 : -30) * r * abs(r); # roll left/right
  477. me.pitch_offset = # pitch change due to
  478. (me.pitch < 0 ? -50 : -50) * sin(me.pitch) * lowspeed # pitch down/up
  479. + 15 * sin(me.roll) * sin(me.roll); # roll
  480. me.roll_offset = # roll change due to
  481. -15 * r * lowspeed; # roll
  482. });
  483. # main() ============================================================
  484. var delta_time = props.globals.getNode("/sim/time/delta-sec", 1);
  485. var hi_heading = props.globals.getNode("/instrumentation/heading-indicator/indicated-heading-deg", 1);
  486. var vertspeed = props.globals.initNode("/velocities/vertical-speed-fps");
  487. var gross_weight_lb = props.globals.initNode("/yasim/gross-weight-lbs");
  488. var gross_weight_kg = props.globals.initNode("/sim/model/gross-weight-kg");
  489. props.globals.getNode("/instrumentation/adf/rotation-deg", 1).alias(hi_heading);
  490. var main_loop = func {
  491. props.globals.removeChild("autopilot");
  492. if (replay)
  493. setprop("/position/gear-agl-m", getprop("/position/altitude-agl-ft") * 0.3 - 1.2);
  494. vert_speed_fpm.setValue( vertspeed.getValue() * 60 );
  495. #gross_weight_kg.getPath(),gross_weight_lb.getPath() * LB2KG);
  496. var dt = delta_time.getValue();
  497. fuel.update(dt);
  498. propulsion.update(dt);
  499. update_stall(dt);
  500. vibration.update(dt);
  501. settimer(main_loop, 0);
  502. }
  503. var aux_loop = func {
  504. update_slide();
  505. #update_volume();
  506. update_absorber();
  507. fuelendurance();
  508. settimer(aux_loop, 0.1);
  509. }
  510. var replay = 0;
  511. var crashed = 0;
  512. setlistener("/sim/signals/fdm-initialized", func {
  513. gui.menuEnable("autopilot", 1);
  514. #init_rotoranim();
  515. vibration.init();
  516. mouse.init();
  517. fuel.init();
  518. propulsion.init(); # this inits all other engine related stuff
  519. #init_weapons();
  520. #setlistener("/sim/model/livery/file", reconfigure, 1);
  521. propulsion.collective.setValue(1);
  522. setlistener("/sim/signals/reinit", func(n) {
  523. n.getBoolValue() and return;
  524. cprint("32;1", "reinit");
  525. procedure.reset();
  526. collective.setValue(1);
  527. aircraft.livery.rescan();
  528. reconfigure();
  529. crashed = 0;
  530. });
  531. setlistener("sim/crashed", func(n) {
  532. cprint("31;1", "crashed ", n.getValue());
  533. propulsion.engine[0].timer.stop();
  534. propulsion.engine[1].timer.stop();
  535. if (n.getBoolValue()) crash(crashed = 1);
  536. });
  537. setlistener("/sim/freeze/replay-state", func(n) {
  538. replay = n.getValue();
  539. cprint("33;1", (replay) ? "replay" : "pause" );
  540. if (crashed) crash(!getprop(n.getPath()));
  541. });
  542. main_loop();
  543. aux_loop();
  544. if (devel and quickstart)
  545. propulsion.quickstart();
  546. });