Indicate these models want to use their own terrein handling code, until they switch...
[fg:toms-fgdata.git] / Aircraft / DR400 / Nasal / dr400.nas
1 ###############################################################################
2 ##
3 ##  Nasal for DR400
4 ##
5 ##  Clément de l'Hamaide - PAF Team
6 ##  This file is licensed under the GPL license version 2 or later.
7 ##
8 ## Updated for GIT : Helijah April 2013
9 ##
10 ###############################################################################
11
12 # Do terrain modelling ourselves.
13 setprop("sim/fdm/surface/override-level", 1);
14
15
16 #####################################
17 # Dialogs (please comment the version)
18 #####################################
19
20 var checklists_dialog = gui.Dialog.new("/sim/gui/dialogs/dr400/checklists/dialog", getprop("/sim/aircraft-dir")~"/Dialogs/checklist/checklists.xml");
21 var config_dlg = gui.Dialog.new("/sim/gui/dialogs/config/dialog", getprop("/sim/aircraft-dir")~"/Dialogs/config.xml");
22 fgcommand("loadxml", props.Node.new({filename: getprop("/sim/aircraft-dir")~"/Dialogs/checklist/checklists-text.xml", targetnode: "/sim/gui/dialogs/dr400/checklists-list"}));
23
24 #####################################
25 #Fuel pressure
26 #####################################
27
28 var Fuel_press=func {
29   var fuel_level = getprop("consumables/fuel/tank/level-lbs");
30   var engine_run = getprop("/engines/engine/running");
31   var tank_selector = getprop("controls/fuel/tank/to_engine");
32   var pump_on = (getprop("/systems/electrical/outputs/fuel-pump") > 20) ? 1 : 0;
33
34   if (fuel_level > 0.1) {
35     if (tank_selector==1){
36       if (pump_on==1){
37           interpolate("/engines/engine/fuel-pressure-psi", 4, 1); #300 mbar
38       }else{
39         if(engine_run==1){
40           interpolate("/engines/engine/fuel-pressure-psi", 4, 1); #300 mbar
41         }else{
42           interpolate("/engines/engine/fuel-pressure-psi", 0, 1);
43         }
44       }
45     }else{
46       interpolate("/engines/engine/fuel-pressure-psi", 0, 1);
47     }
48   }else{
49     interpolate("/engines/engine/fuel-pressure-psi", 0, 1);
50   }
51
52   #if(getprop("/engines/engine/fuel-pressure-psi") < 0.5){
53   #  setprop("fdm/jsbsim/propulsion/tank/priority", 0);
54   #}else{
55   #  setprop("fdm/jsbsim/propulsion/tank/priority", 1);
56   #}
57 #  settimer(Fuel_press,0);
58 }
59
60 ##############################################
61 ############### ENGINE SYSTEM ################
62 ##############################################
63
64 #Engine sensors class 
65 # ie: var Eng = Engine.new(engine number);
66 var Engine = {
67     new : func(eng_num){
68         m =               { parents : [Engine]};
69         m.air_temp =      props.globals.initNode("environment/temperature-degc");
70         m.oat =           m.air_temp.getValue() or 0;
71         m.eng =           props.globals.initNode("engines/engine["~eng_num~"]");
72         m.running =       0;
73         m.ot_target =     90;
74         m.mp =            m.eng.initNode("mp-inhg");
75         m.cutoff =        props.globals.initNode("controls/engines/engine["~eng_num~"]/cutoff");
76         m.mixture =       props.globals.initNode("engines/engine["~eng_num~"]/mixture");
77         m.mixture_lever = props.globals.initNode("controls/engines/engine["~eng_num~"]/mixture",1,"DOUBLE");
78         m.rpm =           m.eng.initNode("rpm",1);
79         m.oil_temp =      m.eng.initNode("oil-temp-c",m.oat,"DOUBLE");
80         m.cyl_temp =      m.eng.initNode("cyl-temp",m.oat,"DOUBLE");
81         m.carb_heat =     m.eng.initNode("carb-heat",0,"DOUBLE");
82         m.carb_temp =     m.eng.initNode("carb-temp-degc",m.oat,"DOUBLE");
83         m.oil_psi =       m.eng.initNode("oil-pressure-psi",0.0,"DOUBLE");
84         m.fuel_psi =      m.eng.initNode("fuel-psi-norm",0,"DOUBLE");
85         m.fuel_out =      m.eng.initNode("out-of-fuel",0,"BOOL");
86         m.fuel_switch =   props.globals.initNode("controls/fuel/switch-position",-1,"INT");
87         m.hpump =         props.globals.initNode("systems/hydraulics/pump-psi["~eng_num~"]",0,"DOUBLE");
88         m.Lrunning =      setlistener("engines/engine["~eng_num~"]/running",func (rn){m.running=rn.getValue()},0,0);
89         return m;
90     },
91 #### update ####
92     update : func(eng_num){
93         var rpm =     me.rpm.getValue();
94         var mp =      me.mp.getValue();
95         var OT =      me.oil_temp.getValue();
96         var mx =      me.mixture_lever.getValue();
97         var ctemp =   me.air_temp.getValue();
98         var cyltemp = me.cyl_temp.getValue();
99         var cheat =   me.carb_heat.getValue();
100         var cooling = (getprop("velocities/airspeed-kt") * 0.1) *2;
101         ###################################
102         ######### OIL TEMPERATURE #########
103         ###################################
104         cooling += (mx * 5);
105         var tgt  = me.ot_target + mp;
106         var tgt -= cooling;
107         if(me.running){
108                 if(OT < tgt) OT += rpm * 0.00001;
109                 if(OT > tgt) OT -= cooling * 0.001;
110                 }else{
111                 if(OT > me.air_temp.getValue()) OT-=0.001; 
112         }
113         me.oil_temp.setValue(OT);
114         ###################################
115         ##### CARBURATOR TEMPERATURE ######
116         ###################################
117         var et0 = getprop("/environment/temperature-degc");
118         # var cbt = et0 + 0.85 * mp; #carb temperature
119         if(props.globals.getNode("systems/electrical/outputs/carb-heat").getValue() > 24){
120           cheat += 0.01;
121           if(cheat > 15) cheat = 15;
122           setprop("engines/engine["~eng_num~"]/carb-heat", cheat);
123           # cbt += cheat;
124         }else{
125           cheat -= 0.05;
126           if(cheat < 0) cheat = 0;
127           setprop("engines/engine["~eng_num~"]/carb-heat", cheat);
128           # cbt += cheat;
129         }
130         ctemp = (rpm * 0.0029);
131         me.carb_temp.setValue(et0 - ctemp + cheat);
132     },
133 };
134
135 EngineMain = Engine.new(0);
136
137 ##########################################
138 # Mixture/Throttle controlled by mouse
139 ##########################################
140
141 var mousex =0;
142 var msx = 0;
143 var msxa = 0;
144 var mousey = 0;
145 var msy = 0;
146 var msya=0;
147
148 var mouse_accel=func{
149   msx=getprop("devices/status/mice/mouse/x") or 0;
150   mousex=msx-msxa;
151   mousex*=0.5;
152   msxa=msx;
153   msy=getprop("devices/status/mice/mouse/y") or 0;
154   mousey=msya-msy;
155   mousey*=0.5;
156   msya=msy;
157 #  settimer(mouse_accel, 0);
158 }
159
160 var set_levers = func(type,num,min,max){
161   var ctrl=[];
162   var cpld=-1;
163   if(type == "throttle"){
164     ctrl = ["controls/engines/engine[0]/throttle","controls/engines/engine[1]/throttle"];
165     cpld = "controls/throttle-coupled";
166   }elsif(type == "prop"){
167     ctrl = ["controls/engines/engine[0]/propeller-pitch","controls/engines/engine[1]/propeller-pitch"];
168     cpld = "controls/prop-coupled";
169   }elsif(type == "mixture"){
170     ctrl = ["controls/engines/engine[0]/mixture","controls/engines/engine[1]/mixture"];
171     cpld ="controls/mixture-coupled";
172   }
173
174   var amnt =mousey* getprop("controls/movement-scale");
175   var ttl = getprop(ctrl[num]) + amnt;
176   if(ttl > max) ttl = max;
177   if(ttl<min)ttl=min;
178   setprop(ctrl[num],ttl);
179   if(getprop(cpld))setprop(ctrl[1-num],ttl);
180 }
181
182 ##########################################
183 # Ground Detection
184 ##########################################
185
186 var terrain_survol = func {
187   var lat = getprop("/position/latitude-deg");
188   var lon = getprop("/position/longitude-deg");
189
190   var info = geodinfo(lat, lon);
191   if (info != nil) {
192     if (info[1] != nil){
193       if (info[1].solid !=nil)
194         setprop("/environment/terrain-type",info[1].solid);
195       if (info[1].load_resistance !=nil)
196         setprop("/environment/terrain-load-resistance",info[1].load_resistance);
197       if (info[1].friction_factor !=nil)
198         setprop("/environment/terrain-friction-factor",info[1].friction_factor);
199       if (info[1].bumpiness !=nil)
200         setprop("/environment/terrain-bumpiness",info[1].bumpiness);
201       if (info[1].rolling_friction !=nil)
202         setprop("/environment/terrain-rolling-friction",info[1].rolling_friction);
203       if (info[1].names !=nil)
204         setprop("/environment/terrain-names",info[1].names[0]);
205     }         
206   }else{
207     setprop("/environment/terrain",1);
208     setprop("/environment/terrain-load-resistance",1e+30);
209     setprop("/environment/terrain-friction-factor",1.05);
210     setprop("/environment/terrain-bumpiness",0);
211     setprop("/environment/terrain-rolling-friction",0.02);
212   }
213
214   if(!getprop("sim/freeze/replay-state") and !getprop("/environment/terrain-type") and getprop("/position/gear-agl-m") < 0.5){
215     setprop("sim/messages/copilot", "You are on water !");
216     setprop("sim/freeze/clock", 1);
217     setprop("sim/freeze/master", 1);
218     setprop("sim/crashed", 1);
219   }
220 #  settimer(terrain_survol, 0);
221 }
222
223 ##############################################
224 ######### AUTOSTART / AUTOSHUTDOWN ###########
225 ##############################################
226
227 setlistener("/sim/model/start-idling", func(idle){
228     var run= idle.getBoolValue();
229     if(run){
230     Startup();
231     }else{
232     Shutdown();
233     }
234 },0,0);
235
236 var Startup = func{
237   setprop("controls/fuel/tank/to_engine", 1);
238   setprop("controls/fuel/tank/boost-pump", 1);
239   setprop("controls/engines/engine[0]/master-alt",1);
240   setprop("/controls/engines/engine[0]/magnetos",3);
241   setprop("controls/engines/engine[0]/mixture",1);
242   setprop("/controls/gear/brake-parking",1);
243   setprop("/controls/lighting/instruments-norm",1);
244   setprop("/instrumentation/comm[0]/power-btn",1);
245   setprop("/instrumentation/comm[0]/volume",1);
246   setprop("/instrumentation/nav[0]/power-btn",1);  
247   setprop("/instrumentation/nav[0]/volume",1);
248   setprop("/instrumentation/adf[0]/power-btn",1);
249   setprop("/instrumentation/adf[0]/volume",1);
250   setprop("/instrumentation/adf[0]/volume-norm",1);
251   setprop("controls/electric/battery-switch",1);
252   setprop("sim/messages/copilot", "Now press \"s\" to start engine");
253 }
254
255 var Shutdown = func{
256   setprop("controls/fuel/tank/to_engine", 0);
257   setprop("controls/engines/engine[0]/master-alt",0);
258   setprop("/controls/engines/engine[0]/magnetos",0);
259   setprop("controls/engines/engine[0]/mixture",1);
260   setprop("/engines/engine[0]/rpm",0);
261   setprop("/engines/engine[0]/running",0);
262   setprop("/controls/gear/brake-parking",1);
263   setprop("/controls/lighting/instruments-norm",0);
264   setprop("/instrumentation/comm[0]/power-btn",0);
265   setprop("/instrumentation/comm[0]/volume",0);
266   setprop("/instrumentation/nav[0]/power-btn",0);
267   setprop("/instrumentation/nav[0]/volume",0);
268   setprop("/instrumentation/adf[0]/power-btn",0);
269   setprop("/instrumentation/adf[0]/volume",0);
270   setprop("/instrumentation/adf[0]/volume-norm",0);
271   setprop("controls/electric/battery-switch",0);
272   setprop("controls/fuel/tank/boost-pump", 0);
273   setprop("sim/messages/copilot", "Engine is stopped");
274 }
275
276
277 ############################################
278 # ELT System from Cessna337
279 # Authors: Pavel Cueto, with A LOT of collaboration from Thorsten and AndersG
280 # Adaptation by Clément de l'Hamaide and Daniel Dubreuil for DR400 or regent
281 ############################################
282
283 var eltmsg = func {
284   var lat = getprop("/position/latitude-string");
285   var lon = getprop("/position/longitude-string");
286   var aircraft = getprop("/sim/description");
287   var callsign = getprop("/sim/multiplay/callsign");
288
289   if(getprop("/sim/damaged")){
290      if(getprop("/instrumentation/elt/armed")) {
291         var help_string = "" ~ aircraft ~ " " ~ callsign ~ "  DAMAGED, requesting SAR service";
292         screen.log.write(help_string);
293       }
294     }
295   ;
296   
297     if(getprop("/sim/crashed")){
298       if(getprop("/instrumentation/elt/armed")) {
299         var help_string = "ELT AutoMessage: " ~ aircraft ~ " " ~ callsign ~ " at " ~lat~" LAT "~lon~" LON, *** CRASHED ***";
300         setprop("/sim/multiplay/chat", help_string);
301         setprop("/sim/freeze/clock", 1);
302         setprop("/sim/freeze/master", 1);
303         screen.log.write("Press p to resume");
304       }
305     }
306   ;
307
308   settimer(eltmsg, 0);  
309 };
310
311   setlistener("/instrumentation/elt/on", func(n) {
312     if(n.getBoolValue()){
313        var lat = getprop("/position/latitude-string");
314        var lon = getprop("/position/longitude-string");
315        var aircraft = getprop("/sim/description");
316        var callsign = getprop("/sim/multiplay/callsign");
317        var help_string = "ELT AutoMessage: " ~ aircraft ~ " " ~ callsign ~ " at " ~lat~" LAT "~lon~" LON, MAYDAY, MAYDAY, MAYDAY";
318        setprop("/sim/multiplay/chat", help_string);
319       }
320     }
321   );
322   
323  setlistener("/instrumentation/elt/test", func(n) {
324     if(n.getBoolValue()){
325        var lat = getprop("/position/latitude-string");
326        var lon = getprop("/position/longitude-string");
327        var aircraft = getprop("/sim/description");
328        var callsign = getprop("/sim/multiplay/callsign");
329        var help_string = "Testing ELT: " ~ aircraft ~ " " ~ callsign ~ " at " ~lat~" LAT "~lon~" LON";
330        screen.log.write(help_string);
331       }
332     }
333   );
334
335 ############################################
336 # Global loop function
337 # If you need to run nasal as loop, add it in this function
338 ############################################
339 global_system = func{
340
341   if(getprop("/systems/electrical/outputs/starter") > 18){
342     setprop("/controls/engines/engine[0]/starter",1);
343   }else{
344     setprop("/controls/engines/engine[0]/starter",0);
345   }
346
347   if(getprop("/systems/electrical/volts") > 6){
348     setprop("/instrumentation/attitude-indicator/spin",10);
349   }else{
350     setprop("/instrumentation/attitude-indicator/spin",0);
351   }
352
353   Fuel_press();
354   mouse_accel();
355   terrain_survol();
356   EngineMain.update(0);
357
358   settimer(global_system, 0);
359
360 }
361
362 ##########################################
363 # SetListerner must be at the end of this file
364 ##########################################
365 setlistener("/sim/signals/fdm-initialized", func{
366   setprop("/environment/terrain-type",1);
367   setprop("/environment/terrain-load-resistance",1e+30);
368   setprop("/environment/terrain-friction-factor",1.05);
369   setprop("/environment/terrain-bumpiness",0);
370   setprop("/environment/terrain-rolling-friction",0.02);
371   setprop("/instrumentation/nav[0]/power-btn",0); #force OFF
372   setprop("/instrumentation/adf[0]/power-btn",0);
373   setprop("/instrumentation/adf[0]/volume",0);
374   setprop("/instrumentation/adf[0]/volume-norm",0);
375   setprop("/controls/lighting/nav-lights", 0);
376   setprop("/controls/lighting/landing-lights", 0);
377   setprop("/controls/electric/battery-switch", 0);
378 });
379
380 var nasalInit = setlistener("/sim/signals/fdm-initialized", func{
381
382   settimer(eltmsg, 2);
383   print('Emergency Locator Transmitter (ELT) loaded');
384
385   setlistener("controls/engines/engine[0]/throttle", func(throttle){
386     interpolate("controls/engines/engine[0]/throttle-hand", 0.2, 0.5);
387     setprop("controls/engines/engine[0]/throttle-hand", throttle.getValue()-0.06);
388     settimer(func { interpolate("controls/engines/engine[0]/throttle-hand", 0, 0.4); }, 3);
389   });
390
391   settimer(global_system, 2);
392   removelistener(nasalInit);
393 });