1 ###############################################################################
3 ## Nasal for DR400-dauphin
6 ## Clément de l'Hamaide - PAF Team - http://equipe-flightgear.forumactif.com
7 ## This file is licensed under the GPL license version 2 or later.
9 ###############################################################################
11 # Do terrain modelling ourselves.
12 setprop("sim/fdm/surface/override-level", 1);
15 #####################################
17 #####################################
19 foreach( var config; props.globals.getNode("/sim/model/config").getChildren() ) {
20 aircraft.data.add(config);
23 #####################################
25 #####################################
27 var config_dlg = gui.Dialog.new("/sim/gui/dialogs/config/dialog", getprop("/sim/aircraft-dir")~"/Dialogs/config.xml");
29 #####################################
31 #####################################
33 var canopy = aircraft.door.new("controls/canopy", 3);
35 ###############################################
36 #Fuel Management (+ Daniel Dubreuil, March 2013)
37 ###############################################
39 setprop("controls/fuel/selected-tank",-1);
40 setprop("/engines/engine/fuel-pressure-psi",0);
41 props.globals.initNode("consumables/fuel/tank[0]/selected",0,"BOOL");
42 props.globals.initNode("consumables/fuel/tank[1]/selected",0,"BOOL");
43 props.globals.initNode("consumables/fuel/tank[2]/selected",0,"BOOL");
44 props.globals.initNode("consumables/fuel/fuel-low",0,"INT");
46 #Feeding tank (to engine)
48 setlistener("controls/fuel/selected-tank", func() {
49 var sel_tank = getprop("controls/fuel/selected-tank");
52 setprop("consumables/fuel/tank[0]/selected",1);
53 setprop("fdm/jsbsim/propulsion/tank[0]/priority", 1);
56 setprop("consumables/fuel/tank[0]/selected",0);
57 setprop("fdm/jsbsim/propulsion/tank[0]/priority", 0);
60 setprop("consumables/fuel/tank[1]/selected",1);
61 setprop("fdm/jsbsim/propulsion/tank[1]/priority", 1);
64 setprop("consumables/fuel/tank[1]/selected",0);
65 setprop("fdm/jsbsim/propulsion/tank[1]/priority", 0);
68 setprop("consumables/fuel/tank[2]/selected",1);
69 setprop("fdm/jsbsim/propulsion/tank[2]/priority", 1);
72 setprop("consumables/fuel/tank[2]/selected",0);
73 setprop("fdm/jsbsim/propulsion/tank[2]/priority", 0);
79 var engine_run = getprop("/engines/engine/running");
80 var pump_on = (getprop("/systems/electrical/outputs/fuel-pump") > 20) ? 1 : 0;
81 var fuel_level_0 = getprop("consumables/fuel/tank[0]/level-lbs");
82 var fuel_level_1 = getprop("consumables/fuel/tank[1]/level-lbs");
83 var fuel_level_2 = getprop("consumables/fuel/tank[2]/level-lbs");
84 var tank_selector0 = getprop("consumables/fuel/tank[0]/selected");
85 var tank_selector1 = getprop("consumables/fuel/tank[1]/selected");
86 var tank_selector2 = getprop("consumables/fuel/tank[2]/selected");
88 #Fuel level low (15.43 lbs = 10 liters) in the selected tank
89 # two warning thresholds: light then sound
91 if ((fuel_level_0 < 15.43 and tank_selector0) or (fuel_level_1 < 15.43 and tank_selector1) or (fuel_level_2 < 15.43 and tank_selector2))
92 if ((fuel_level_0 < 1.5 and tank_selector0) or (fuel_level_1 < 5 and tank_selector1) or (fuel_level_2 < 1.5 and tank_selector2))
93 setprop("consumables/fuel/fuel-low",2);
95 setprop("consumables/fuel/fuel-low",1);
97 setprop("consumables/fuel/fuel-low",0);
101 if ((fuel_level_0 > 0.1 and tank_selector0) or (fuel_level_1 > 0.1 and tank_selector1) or (fuel_level_2 > 0.1 and tank_selector2))
103 interpolate("/engines/engine/fuel-pressure-psi", 4, 1); #300 mbar
106 interpolate("/engines/engine/fuel-pressure-psi", 4, 1); #300 mbar
108 interpolate("/engines/engine/fuel-pressure-psi", 0, 1);
110 interpolate("/engines/engine/fuel-pressure-psi", 0, 1);
112 #Engine does not start if no fuel pressure
114 if(getprop("/engines/engine/fuel-pressure-psi") > 1){
116 setprop("fdm/jsbsim/propulsion/tank[0]/priority", 1);
118 setprop("fdm/jsbsim/propulsion/tank[0]/priority", 0);
120 setprop("fdm/jsbsim/propulsion/tank[1]/priority", 1);
122 setprop("fdm/jsbsim/propulsion/tank[1]/priority", 0);
124 setprop("fdm/jsbsim/propulsion/tank[2]/priority", 1);
126 setprop("fdm/jsbsim/propulsion/tank[2]/priority", 0);
129 setprop("fdm/jsbsim/propulsion/tank[0]/priority", 0);
130 setprop("fdm/jsbsim/propulsion/tank[1]/priority", 0);
131 setprop("fdm/jsbsim/propulsion/tank[2]/priority", 0);
135 ##########################################
137 ##########################################
139 props.globals.initNode("/instrumentation/horameter/elapsed-time", 0, "INT");
140 props.globals.initNode("/instrumentation/chrono/elapsed-time", 0, "INT");
142 var chrono = aircraft.timer.new("/instrumentation/chrono/elapsed-time", 1);
143 var horameter = aircraft.timer.new("/instrumentation/horameter/elapsed-time", 1, 1);
145 setlistener("/instrumentation/horameter/running", func(running){
146 if(running.getBoolValue()){
154 var floor = func(v) v < 0.0 ? -int(-v) - 1 : int(v);
156 var formatedTime = "";
161 var timeFormat = func{
163 elapsedTime = getprop("/instrumentation/chrono/elapsed-time");
165 hrs = floor(elapsedTime/3600);
166 min = floor(elapsedTime/60);
169 formatedTime = sprintf("%02d:%02d:%02d", hrs, min-(60*hrs), sec-(60*min));
170 setprop("/instrumentation/chrono/formated-time", formatedTime);
174 ##############################################
175 ############### ENGINE SYSTEM ################
176 ##############################################
178 #Engine sensors class
179 # ie: var Eng = Engine.new(engine number);
182 m = { parents : [Engine]};
183 m.air_temp = props.globals.initNode("environment/temperature-degc");
184 m.oat = m.air_temp.getValue() or 0;
185 m.eng = props.globals.initNode("engines/engine["~eng_num~"]");
188 m.mp = m.eng.initNode("mp-inhg");
189 m.cutoff = props.globals.initNode("controls/engines/engine["~eng_num~"]/cutoff");
190 m.mixture = props.globals.initNode("engines/engine["~eng_num~"]/mixture");
191 m.mixture_lever = props.globals.initNode("controls/engines/engine["~eng_num~"]/mixture",1,"DOUBLE");
192 m.rpm = m.eng.initNode("rpm",1);
193 m.oil_temp = m.eng.initNode("oil-temp-c",m.oat,"DOUBLE");
194 m.cyl_temp = m.eng.initNode("cyl-temp",m.oat,"DOUBLE");
195 m.carb_heat = m.eng.initNode("carb-heat",0,"DOUBLE");
196 m.carb_temp = m.eng.initNode("carb-temp-degc",m.oat,"DOUBLE");
197 m.oil_psi = m.eng.initNode("oil-pressure-psi",0.0,"DOUBLE");
198 m.fuel_psi = m.eng.initNode("fuel-psi-norm",0,"DOUBLE");
199 m.fuel_out = m.eng.initNode("out-of-fuel",0,"BOOL");
200 m.fuel_switch = props.globals.initNode("controls/fuel/switch-position",-1,"INT");
201 m.hpump = props.globals.initNode("systems/hydraulics/pump-psi["~eng_num~"]",0,"DOUBLE");
202 m.Lrunning = setlistener("engines/engine["~eng_num~"]/running",func (rn){m.running=rn.getValue()},0,0);
206 update : func(eng_num){
207 var rpm = me.rpm.getValue();
208 var mp = me.mp.getValue();
209 var OT = me.oil_temp.getValue();
210 var mx = me.mixture_lever.getValue();
211 var ctemp = me.air_temp.getValue();
212 var cyltemp = me.cyl_temp.getValue();
213 var cheat = me.carb_heat.getValue();
214 var cooling = (getprop("velocities/airspeed-kt") * 0.1) *2;
215 ###################################
216 ######### OIL TEMPERATURE #########
217 ###################################
219 var tgt = me.ot_target + mp;
222 if(OT < tgt) OT += rpm * 0.00001;
223 if(OT > tgt) OT -= cooling * 0.001;
225 if(OT > me.air_temp.getValue()) OT-=0.001;
227 me.oil_temp.setValue(OT);
228 ###################################
229 ##### CARBURATOR TEMPERATURE ######
230 ###################################
231 var et0 = getprop("/environment/temperature-degc");
232 # var cbt = et0 + 0.85 * mp; #carb temperature
233 if(props.globals.getNode("systems/electrical/outputs/carb-heat").getValue() > 24){
235 if(cheat > 15) cheat = 15;
236 setprop("engines/engine["~eng_num~"]/carb-heat", cheat);
240 if(cheat < 0) cheat = 0;
241 setprop("engines/engine["~eng_num~"]/carb-heat", cheat);
244 ctemp = (rpm * 0.0029);
245 me.carb_temp.setValue(et0 - ctemp + cheat);
246 ######################################
247 ############ PROP FRICTION ###########
248 ######################################
249 if(!getprop("/fdm/jsbsim/propulsion/engine/set-running") and
250 getprop("/systems/electrical/outputs/starter") < 8) {
251 setprop("/fdm/jsbsim/propulsion/engine/friction-hp", 20);
253 setprop("/fdm/jsbsim/propulsion/engine/friction-hp", 0);
258 EngineMain = Engine.new(0);
260 ##########################################
261 # Mixture/Throttle controlled by mouse
262 ##########################################
271 var mouse_accel=func{
272 msx=getprop("devices/status/mice/mouse/x") or 0;
276 msy=getprop("devices/status/mice/mouse/y") or 0;
280 # settimer(mouse_accel, 0);
283 var set_levers = func(type,num,min,max){
286 if(type == "throttle"){
287 ctrl = ["controls/engines/engine[0]/throttle","controls/engines/engine[1]/throttle"];
288 cpld = "controls/throttle-coupled";
289 }elsif(type == "prop"){
290 ctrl = ["controls/engines/engine[0]/propeller-pitch","controls/engines/engine[1]/propeller-pitch"];
291 cpld = "controls/prop-coupled";
292 }elsif(type == "mixture"){
293 ctrl = ["controls/engines/engine[0]/mixture","controls/engines/engine[1]/mixture"];
294 cpld ="controls/mixture-coupled";
297 var amnt =mousey* getprop("controls/movement-scale");
298 var ttl = getprop(ctrl[num]) + amnt;
299 if(ttl > max) ttl = max;
301 setprop(ctrl[num],ttl);
302 if(getprop(cpld))setprop(ctrl[1-num],ttl);
305 ##########################################
307 ##########################################
309 var terrain_survol = func {
310 var lat = getprop("/position/latitude-deg");
311 var lon = getprop("/position/longitude-deg");
313 var info = geodinfo(lat, lon);
316 if (info[1].solid !=nil){
317 setprop("/environment/terrain-type",info[1].solid);
318 if( !getprop("sim/freeze/replay-state") and
320 ((getprop("/gear/gear[0]/compression-norm") > 0.12) or
321 (getprop("/gear/gear[1]/compression-norm") > 0.12) or
322 (getprop("/gear/gear[2]/compression-norm") > 0.12))){
323 setprop("sim/messages/copilot", "You are on water ! Press \"p\" to continue");
324 if(!getprop("sim/freeze/clock"))
325 setprop("sim/freeze/clock", 1);
326 if(!getprop("sim/freeze/master"))
327 setprop("sim/freeze/master", 1);
328 if(!getprop("sim/freeze/clock"))
329 setprop("sim/crashed", 1);
332 if(getprop("sim/freeze/clock"))
333 setprop("sim/freeze/clock", 0);
334 if(getprop("sim/freeze/master"))
335 setprop("sim/freeze/master", 0);
336 if(getprop("sim/freeze/clock"))
337 setprop("sim/crashed", 0);
344 ##############################################
345 ######### AUTOSTART / AUTOSHUTDOWN ###########
346 ##############################################
348 setlistener("/sim/model/start-idling", func(idle){
349 var run= idle.getBoolValue();
358 setprop("controls/fuel/selected-tank", 1);
360 settimer( func { FuelValve(180); }, 0.3);
361 setprop("controls/fuel/tank/boost-pump", 1);
362 setprop("controls/engines/engine[0]/master-alt",1);
363 setprop("/controls/engines/engine[0]/magnetos",3);
364 setprop("controls/engines/engine[0]/mixture",1);
365 setprop("/controls/gear/brake-parking",0);
366 setprop("/controls/lighting/instruments-norm",1);
367 setprop("/instrumentation/comm[0]/power-btn",1);
368 setprop("/instrumentation/comm[0]/volume",1);
369 setprop("/instrumentation/nav[0]/power-btn",1);
370 setprop("/instrumentation/nav[0]/volume",1);
371 setprop("/instrumentation/adf[0]/power-btn",1);
372 setprop("/instrumentation/adf[0]/volume",1);
373 setprop("/instrumentation/adf[0]/volume-norm",1);
374 setprop("controls/electric/battery-switch",1);
375 setprop("controls/switches/master-avionics",1);
376 # setprop("sim/messages/copilot", "Now press \"s\" to start engine");
377 gui.popupTip("Now press \"s\" to start engine", 8);
381 setprop("controls/fuel/selected-tank", -1);
383 setprop("controls/engines/engine[0]/master-alt",0);
384 setprop("/controls/engines/engine[0]/magnetos",0);
385 setprop("controls/engines/engine[0]/mixture",1);
386 setprop("/engines/engine[0]/rpm",0);
387 setprop("/engines/engine[0]/running",0);
388 setprop("/controls/gear/brake-parking",1);
389 setprop("/controls/lighting/instruments-norm",0);
390 setprop("/instrumentation/comm[0]/power-btn",0);
391 setprop("/instrumentation/comm[0]/volume",0);
392 setprop("/instrumentation/nav[0]/power-btn",0);
393 setprop("/instrumentation/nav[0]/volume",0);
394 setprop("/instrumentation/adf[0]/power-btn",0);
395 setprop("/instrumentation/adf[0]/volume",0);
396 setprop("/instrumentation/adf[0]/volume-norm",0);
397 setprop("controls/electric/battery-switch",0);
398 setprop("controls/switches/master-avionics",0);
399 setprop("controls/fuel/tank/boost-pump", 0);
400 #setprop("sim/messages/copilot", "Engine is stopped");
401 gui.popupTip("Engine is stopped");
405 ############################################
406 # ELT System from Cessna337
407 # Authors: Pavel Cueto, with A LOT of collaboration from Thorsten and AndersG
408 # Adaptation by Clément de l'Hamaide and Daniel Dubreuil for DR400-dauphin
409 ############################################
412 var lat = getprop("/position/latitude-string");
413 var lon = getprop("/position/longitude-string");
414 var aircraft = getprop("/sim/description");
415 var callsign = getprop("/sim/multiplay/callsign");
417 if(getprop("/sim/damaged")){
418 if(getprop("/instrumentation/elt/armed")) {
419 var help_string = "" ~ aircraft ~ " " ~ callsign ~ " DAMAGED, requesting SAR service";
420 screen.log.write(help_string);
424 if(getprop("/sim/crashed")){
425 if(getprop("/instrumentation/elt/armed")) {
426 var help_string = "ELT AutoMessage: " ~ aircraft ~ " " ~ callsign ~ " at " ~lat~" LAT "~lon~" LON, *** CRASHED ***";
427 setprop("/sim/multiplay/chat", help_string);
428 setprop("/sim/freeze/clock", 1);
429 setprop("/sim/freeze/master", 1);
430 setprop("/sim/crashed", 0);
431 screen.log.write("Press p to resume");
438 setlistener("/instrumentation/elt/on", func(n) {
439 if(n.getBoolValue()){
440 var lat = getprop("/position/latitude-string");
441 var lon = getprop("/position/longitude-string");
442 var aircraft = getprop("/sim/description");
443 var callsign = getprop("/sim/multiplay/callsign");
444 var help_string = "ELT AutoMessage: " ~ aircraft ~ " " ~ callsign ~ " at " ~lat~" LAT "~lon~" LON, MAYDAY, MAYDAY, MAYDAY";
445 setprop("/sim/multiplay/chat", help_string);
449 setlistener("/instrumentation/elt/test", func(n) {
450 if(n.getBoolValue()){
451 var lat = getprop("/position/latitude-string");
452 var lon = getprop("/position/longitude-string");
453 var aircraft = getprop("/sim/description");
454 var callsign = getprop("/sim/multiplay/callsign");
455 var help_string = "Testing ELT: " ~ aircraft ~ " " ~ callsign ~ " at " ~lat~" LAT "~lon~" LON";
456 screen.log.write(help_string);
460 ############################################
461 # Global loop function
462 # If you need to run nasal as loop, add it in this function
463 ############################################
464 global_system = func{
466 if(getprop("/systems/electrical/outputs/starter") > 18){
467 setprop("/controls/engines/engine[0]/starter",1);
469 setprop("/controls/engines/engine[0]/starter",0);
472 if(getprop("/systems/electrical/outputs/master-avionics") > 6){
473 setprop("/instrumentation/attitude-indicator/spin",10);
475 setprop("/instrumentation/attitude-indicator/spin",0);
482 EngineMain.update(0);
483 if(getprop("/sim/model/config/breakable-gears")){
487 settimer(global_system, 0);
492 ############################################
494 ############################################
495 var timeOfNegatifG = 0;
496 upsideDown_system = func{
497 if(getprop("/sim/mode/config/simulate-g-force")){
498 if(getprop("fdm/jsbsim/accelerations/Nz") < -0.5){
500 if(timeOfNegatifG > 4){
501 setprop("controls/fuel/tank/boost-pump", 0);
502 setprop("engines/engine/fuel-pressure-psi", 0);
509 settimer(upsideDown_system, 1);
513 ############################################
515 ############################################
517 setlistener("fdm/jsbsim/systems/crash-detect/over-g-failure", func(n){
518 if(getprop("/sim/model/config/simulate-g-force") and n.getBoolValue()){
519 if (!getprop("/sim/crashed")){
520 setprop("/sim/crashed", 1);
525 setlistener("fdm/jsbsim/systems/crash-detect/crashed", func(n){
526 if(getprop("/sim/model/config/enable-crash") and n.getBoolValue()){
527 if (!getprop("/sim/crashed")){
528 setprop("/sim/crashed", 1);
534 var firstEngineStartup = setlistener("/engines/engine/running", func(val) {
535 if( val.getBoolValue() ) {
536 setprop("/engines/engine/has-been-started-at-least-once", 1);
537 removelistener(firstEngineStartup);
541 ##########################################
542 # SetListerner must be at the end of this file
543 ##########################################
544 setlistener("/sim/signals/fdm-initialized", func{
545 setprop("/environment/terrain-type",1);
546 setprop("/environment/terrain-load-resistance",1e+30);
547 setprop("/environment/terrain-friction-factor",1.05);
548 setprop("/environment/terrain-bumpiness",0);
549 setprop("/environment/terrain-rolling-friction",0.02);
550 setprop("/instrumentation/nav[0]/power-btn",0); #force OFF
551 setprop("/instrumentation/nav[1]/power-btn",0); #force OFF
552 setprop("/instrumentation/adf[0]/power-btn",0);
553 setprop("/instrumentation/adf[0]/volume",0);
554 setprop("/instrumentation/adf[0]/volume-norm",0);
555 setprop("/controls/lighting/nav-lights", 0);
556 setprop("/controls/lighting/landing-lights", 0);
557 setprop("/controls/electric/battery-switch", 0);
560 var nasalInit = setlistener("/sim/signals/fdm-initialized", func{
563 print('Emergency Locator Transmitter (ELT) loaded');
565 setlistener("controls/engines/engine[0]/throttle", func(throttle){
566 interpolate("controls/engines/engine[0]/throttle-hand", 0.2, 0.5);
567 setprop("controls/engines/engine[0]/throttle-hand", throttle.getValue()-0.06);
568 settimer(func { interpolate("controls/engines/engine[0]/throttle-hand", 0, 0.4); }, 3);
571 settimer(global_system, 2);
572 settimer(upsideDown_system, 2);
573 removelistener(nasalInit);