Add hydraulic system, tidy pneumatic system
[fg:toms-fgdata.git] / Aircraft / Hurricane / Nasal / hurricane.nas
1 # $Id$
2
3 # ==================================== timer stuff ===========================================
4
5 # set the update period
6
7 UPDATE_PERIOD = 0.3;
8
9 # set the timer for the selected function
10
11 registerTimer = func {
12         
13         settimer(arg[0], UPDATE_PERIOD);
14
15 } # end function 
16
17 # =============================== end timer stuff ===========================================
18
19 # =============================== Boost Controller stuff======================================
20
21 BOOST_CONTROL_AUTHORITY = 0.99; # How much can it move the throttle?
22 #BOOST_CONTROL_RANGE = 1;         When does it start to engage? (psig)
23 BOOST_CONTROL_LIMIT_RATED = 11.9;       # Maximum MP (psig)
24 BOOST_CONTROL_LIMIT_COMBAT = 18;    # Combat limit (5 mins)
25
26 boost_control = props.globals.getNode("/controls/engines/engine/boost-control", 1);
27 boost_pressure = props.globals.getNode("/engines/engine/boost-gauge-inhg", 1);
28 boost_pressure_psi = props.globals.getNode("/engines/engine/boost-gauge-psi", 1);
29 boost_control_damp = props.globals.getNode("/controls/engines/engine/boost-control-damp", 1);
30 boost_control_range = props.globals.getNode("/controls/engines/engine/boost-control-range", 1);
31 boost_control_cutout = props.globals.getNode("/controls/engines/engine/boost-control-cutout", 1);
32 mp_inhg = props.globals.getNode("/engines/engine/mp-inhg", 1);
33
34 boost_control.setDoubleValue(1); 
35 boost_pressure.setDoubleValue(0); 
36 boost_pressure_psi.setDoubleValue(0); 
37 boost_control_damp.setDoubleValue(0.015); 
38 boost_control_range.setDoubleValue(0.5); 
39 boost_control_cutout.setBoolValue(0); 
40 mp_inhg.setDoubleValue(0);
41
42
43 damp = 0;
44
45 toggleBoost = func{
46         b = getprop("controls/engines/engine/boost");
47
48         if (b == 1) {
49             b = 0.79; }
50         else  {
51             b = 1;
52                 }
53
54    setprop("controls/engines/engine/boost",b);
55 #  print("b: " , b );
56
57 } # end function toggleBoost
58
59 toggleCutout = func{
60         var c = boost_control_cutout.getValue();
61         
62         c = !c;
63         boost_control_cutout.setBoolValue(c);
64                         
65 #       print("c: " , c );
66         
67 } # end function toggleCutout
68
69 updateBoostControl = func {
70                 var n = boost_control_damp.getValue(); 
71                 var BOOST_CONTROL_RANGE = boost_control_range.getValue();
72                 var mp = (mp_inhg.getValue() * 0.491154077497) - 14.6959487755 ;
73                 var cutout = boost_control_cutout.getValue();
74                 var val = 0;
75                 
76                 if(! cutout){           
77                         val = (mp - BOOST_CONTROL_LIMIT_RATED) / BOOST_CONTROL_RANGE;
78                 } else {
79                         val = (mp - BOOST_CONTROL_LIMIT_COMBAT) / BOOST_CONTROL_RANGE;
80                 }       
81                         
82                 var in = val;
83                         
84                 if (val < 0  ) {
85                                 val = 0;                             # Can't increase throttle
86                 } elsif (val < -BOOST_CONTROL_AUTHORITY) {
87                                 val = -BOOST_CONTROL_AUTHORITY        # limit by authority
88                 } else {
89                                 val = -val;
90                 }
91                         
92                 damp = (val * n) + (damp * (1 - n)); # apply low pass filter
93           
94 #  print(sprintf("mp=%0.5f, in=%0.5f, raw=%0.5f, out=%0.5f", mp, in, val, damp));
95                                 boost_pressure_psi.setDoubleValue(mp);
96                 boost_control.setDoubleValue(damp);
97                                 boost_control_cutout.setBoolValue(cutout);
98                 settimer(updateBoostControl, 0.1);
99 }
100
101 updateBoostControl();
102
103
104 # ======================================= end Boost Controller f ============================
105
106
107
108 # =============================== set the aircraft type =====================================
109
110 spitfireIIa = 0;
111
112 type = getprop("sim/aircraft");
113
114 if (type == "spitfireIIa") {spitfireIIa = 1;}
115
116 print ("type: " , type );
117 # ============================= Coffman starter stuff =======================================
118
119
120 nowN       = props.globals.getNode("/sim/time/elapsed-sec", 1);
121 starterN   = props.globals.getNode("controls/engines/engine/starter", 1);
122 primerN    = props.globals.getNode("controls/engines/engine/primer", 1);
123 cartridgeN = props.globals.getNode("controls/engines/engine/coffman-starter/index");
124 LastStartTime = 0;
125 LastCartridge = -1;
126 Start = 0;              # stopCof needs this, too
127
128
129 indexCof = func{
130         pull=arg[0];
131         if(pull) {
132 #        i = getprop("controls/engines/engine/coffman-starter/index");
133                 i = cartridgeN.getValue();
134                 i = i - 1;
135                 if (i == -1) {
136                         i = 5;
137                 }
138                 setprop("controls/engines/engine/coffman-starter/index",i);
139                 setprop("controls/engines/engine/coffman-starter/index-pull-norm",1)
140         }else{
141                 setprop("controls/engines/engine/coffman-starter/index-pull-norm",0)
142                 }
143
144 } # end function
145
146
147 startCof = func{
148         Start = arg[0];
149         max_run = 4;
150         
151         if (Start) {
152                 LastStartTime = nowN.getValue();
153                 if (!starterN.getValue()) {                     # not started yet: do it now
154                         setprop("controls/engines/engine/coffman-starter/starter-push-norm", 1);
155                         
156                         ready = !hurricane.spitfireIIa;         # seafires are always ready
157
158                         if (!ready) {                                           # must be a spitfire
159                                 LastCartridge = cartridgeN.getValue();
160                                 j = "controls/engines/engine/coffman-starter/cartridge[" ~ LastCartridge ~ "]";
161                                 if (ready = getprop(j)) {
162                                         setprop(j, 0);
163 #                                       print("max run: " , max_run);
164                                         settimer(func {             # nameless out-of-gas watcher
165                                                                 starterN.setValue(0);
166                                                                 primerN.setValue(0);
167                                                                 print ("starter stopping, out of gas!"); 
168                                                                 }, max_run)};
169                         }
170
171                         if (ready) {
172                                 primerMixture(primerN.getValue());
173                                 starterN.setValue(1);
174 #                               print ("starter running!", primerN.getValue());
175                         }
176                 }
177         } else{
178                 settimer(stopCof, 0.2);
179         }
180 } # end function
181
182
183 stopCof = func {
184
185         min_run = 1.0;
186         if (!Start and starterN.getValue()) {
187                 if (nowN.getValue() - LastStartTime < min_run) {
188                         settimer(stopCof, 0.2);                 # too soon; let's try again later
189 #                       print ("too soon! min run: " , min_run);
190
191         } else {
192                         primerN.setValue(0);
193                         starterN.setValue(0);
194                         setprop("controls/engines/engine/coffman-starter/starter-push-norm", 0);
195 #                       print ("starter stopping!");
196                 }
197         }
198 } # end function
199
200 # ============================ end Coffman starter stuff =====================================
201
202 # ================================= priming pump stuff =======================================
203
204 pumpPrimer = func{
205         
206         push = arg[0];
207         
208         if (push){
209                 pump = getprop("controls/engines/engine/primer") + 1;
210                 setprop("controls/engines/engine/primer", pump);
211                 setprop("controls/engines/engine/primer-pump",1);
212                 }
213         else
214                 {
215                 setprop("controls/engines/engine/primer-pump",0);
216         }
217
218 } # end function
219
220 primerMixture = func{
221         
222         mixture = 0;
223         primer = arg[0];
224         
225         if(primer >3 and primer <7) {
226                 mixture = 1;
227         }
228         
229         return mixture;
230            
231 } # end function
232
233 # ================================== end priming pump stuff =================================
234
235 # ================================= magneto stuff ===========================================
236
237 setMagnetos = func{     # set the magneto value according to the switch positions
238
239         right = getprop("controls/engines/engine/mag-switch-right");
240         left = getprop("controls/engines/engine/mag-switch-left");
241         if (left and right){                                 # both
242                 setprop("controls/engines/engine/magnetos",3); 
243                 }
244                 elsif (left and !right) {                         # left
245                         setprop("controls/engines/engine/magnetos",1)
246                 }
247                 elsif (!left and right) {                         # right
248                         setprop("controls/engines/engine/magnetos",2)
249                 }
250         else{    
251                 setprop("controls/engines/engine/magnetos",0); # none
252                 }
253         
254 } # end function
255
256 setleftMagswitch = func{
257         
258         left = arg[0];
259         setprop("controls/engines/engine/mag-switch-left",left);
260         hurricane.setMagnetos();
261
262 } # end function
263
264
265 setrightMagswitch = func{
266         
267         right = arg[0];
268         setprop("controls/engines/engine/mag-switch-right",right);
269         hurricane.setMagnetos();
270
271 } # end function
272
273
274 toggleleftMagswitch = func{
275         
276         left = getprop("controls/engines/engine/mag-switch-left");
277         left = !left;
278         setprop("controls/engines/engine/mag-switch-left",left);
279         hurricane.setMagnetos();
280
281 } # end function
282
283 togglerightMagswitch = func{
284         
285         right = getprop("controls/engines/engine/mag-switch-right");
286         right = !right;
287         setprop("controls/engines/engine/mag-switch-right",right);
288         hurricane.setMagnetos();
289
290 } # end function
291
292 # =============================== end magneto stuff =========================================
293
294 # ====================================== door and canopy stuff ==============================
295
296 openDoor = func{ # open the door if canopy is open
297         
298         dooropen = arg[0];
299         canopyopen = getprop("gear/canopy/position-norm");
300         if (canopyopen) {
301                 setprop("controls/flight/door-position-norm",dooropen)
302         }
303         
304 } # end function
305
306 toggleDoor = func{ # toggle the door if canopy is open
307         
308         dooropen = getprop("controls/flight/door-position-norm");
309         canopyopen = getprop("gear/canopy/position-norm");
310         if (canopyopen) {
311                 dooropen = !dooropen;
312                 setprop("controls/flight/door-position-norm",dooropen);
313         }
314         
315 } # end function
316
317 openCanopy = func{ # open the canopy if door is closed
318         
319         canopyopen = arg[0];
320         dooropen = getprop("controls/flight/door-position-norm");
321         if (!dooropen) {
322                 setprop("controls/flight/canopy-slide",canopyopen)
323         }
324
325 } # end function
326
327 # ==================================== end door and canopy ===================================
328
329 # ======================================== Cutoff ============================================
330
331 pullCutoff = func{
332
333         pull=arg[0];
334         mixturelever = getprop("controls/engines/engine/mixture-lever");
335         
336         if(pull) {
337                 setprop("controls/engines/engine/cutoff-pull-norm",1);
338                 setprop("controls/engines/engine/cutoff",0);
339                 #setprop("controls/engines/engine/mixture",0);
340                 if (getprop("engines/engine/rpm") < 100) {setprop("engines/engine/running",0)}
341         }else{
342                 setprop("controls/engines/engine/cutoff-pull-norm",0);
343                 setprop("controls/engines/engine/cutoff",1);
344                 #setprop("controls/engines/engine/mixture",mixturelever)
345                 }
346
347 } # end function
348
349 # =================================== end Cutoff ============================================
350
351
352
353 # ======================================= fuel tank stuff ===================================
354
355 # fuel gauge
356
357 setTankContents=func{
358
359         tank=getprop("controls/switches/fuel-gauge-sel");
360         contents=getprop("consumables/fuel/tank[" ~ tank ~ "]/level-gal_us");
361         setprop("instrumentation/fuel/contents-gal_us",contents);
362 #       print("contents: " , contents, " tank: " , tank);
363         registerTimer(setTankContents);
364         
365 }#end func
366
367 registerTimer(setTankContents);
368
369 # operate fuel cocks
370
371 openCock=func{
372
373         cock=getprop("controls/engines/engine/fuel-cock/lever");
374    
375         if (cock < 2){
376                 cock = cock +1;
377                 setprop("controls/engines/engine/fuel-cock/lever",cock);
378                 adjustCock()
379                 }
380                 
381 }#end func
382
383 closeCock=func{
384
385         cock=getprop("controls/engines/engine/fuel-cock/lever");
386    
387         if (cock > 0){
388                 cock = cock - 1;
389                 setprop("controls/engines/engine/fuel-cock/lever",cock);
390                 adjustCock()
391                 }
392                 
393 }#end func
394
395
396 # adjust fuel cocks
397
398 adjustCock=func{
399
400         lever=getprop("controls/engines/engine/fuel-cock/lever");
401         
402         if (lever == 0){
403                 setprop("consumables/fuel/tank[0]/selected",0);
404                 setprop("consumables/fuel/tank[1]/selected",0);
405                 setprop("consumables/fuel/tank[2]/selected",0);
406                 }
407                 elsif (lever == 1){
408                 setprop("consumables/fuel/tank[0]/selected",1);
409                 setprop("consumables/fuel/tank[1]/selected",1);
410                 setprop("consumables/fuel/tank[2]/selected",0);
411                 }
412                 else {
413                 setprop("consumables/fuel/tank[0]/selected",0);
414                 setprop("consumables/fuel/tank[1]/selected",0);
415                 setprop("consumables/fuel/tank[2]/selected",1);
416         }
417         
418 }#end func
419
420 # ========================== end fuel stuff ======================================
421
422
423 # =========================== hydraulic stuff =========================================
424
425 #controls.gearDown = func(x) { if (x) { hydraulicLever(-1, -x) } }
426 #controls.flapsDown = func(x) { if (x) { hydraulicLever(1, -x) } }
427
428 #hydraulicLever = func{             #sets the lever up-down, right-left or neutral
429
430 #       right = arg[0]; 
431 #       up = arg[1];
432 #       lever=[0,1];
433 #       
434 #       print("input: ", right, " ", up);
435 #       
436 #       lever[0]= getprop("controls/hydraulic/lever[0]"); #right/left
437 #       lever[1]= getprop("controls/hydraulic/lever[1]"); #up/down
438 #       
439 #       print ("lever in: ", lever[0],lever[1]);
440 #               
441 #       if ( lever[0] == 0 or lever[0] == right) {     #
442 #               if (up == 1  and lever[1] < 1){
443 #                       lever[1] = lever[1] + 1;
444 #               }
445 #               elsif ( up == -1  and lever[1] > -1){
446 #                       lever[1] = lever[1] - 1;
447 #               }
448 #               elsif (up == 0) {
449 #                       lever[1] = 0;
450 #               }
451 #               
452 #               if (lever[1] == 0) {
453 #                       lever[0] = 0;
454 #               } else {
455 #                       lever[0] = right;
456 #               }
457 #       }
458 #       
459 #       print ("lever out: ", lever[0],lever[1]);
460 #       
461 #       setprop("controls/hydraulic/lever[1]",lever[1]);
462 #       setprop("controls/hydraulic/lever[0]",lever[0]);
463 #       
464 #       if (lever[0] == 1 and lever[1] == -1) 
465 #               { registerTimer (flapBlowin)}   # run the timer 
466 #               
467 #       if (lever[0] == -1 and lever[1] != 0) 
468 #               { registerTimer (wheelsMove)}   # run the timer                    
469 #               
470 #} # end function 
471
472 flapBlowin = func{
473         flap = 0;
474         lever=[0,1];
475         lever[0] = getprop("controls/hydraulic/lever[0]");
476         lever[1] = getprop("controls/hydraulic/lever[1]");
477         airspeed = getprop("velocities/airspeed-kt");
478         flap_pos = getprop("surface-positions/flap-pos-norm");
479
480 #    print("lever: " , lever[1] , " airspeed (kts): " , airspeed , " flap pos: " , flap_pos);
481         
482         if (lever[0] == 1){
483          if (lever[1] == -1 and airspeed < 105) { 
484                 setprop("controls/flight/flaps" , flap_pos + 0.05);    # increase the flap
485                 return registerTimer(flapBlowin);                      # run the timer                
486                 }
487                 elsif (lever[1] == -1 and airspeed >= 110 and airspeed <= 120) {
488                         flap = -0.08*airspeed + 9.4;
489                         if(flap_pos < flap)
490                                 {
491                                 setprop("controls/flight/flaps" , flap_pos + 0.05); # flap partially blown in 
492                                 } 
493                         return registerTimer(flapBlowin);                    # run the timer                        
494                 }
495                 elsif (lever[1] == -1 and airspeed > 120) {
496                         flap = 0.2;
497                         if(flap_pos < flap)
498                                 {
499                                 setprop("controls/flight/flaps" , flap_pos + 0.05); # flap partially blown in 
500                                 } 
501                         return registerTimer(flapBlowin);                  # run timer
502                 }                    
503         if ( lever[1] == 1) {
504                         setprop("controls/flight/flaps" , flap_pos - 0.05);
505                 return registerTimer(flapBlowin); 
506                 }
507         }
508          
509         if (flap_pos != 0 and airspeed < 110){
510                         return registerTimer(flapBlowin);
511                 }
512                 elsif( flap_pos != 0 and airspeed >= 110 and airspeed <= 120) {
513                         flap = -0.08 * airspeed + 9.4;
514                         if (flap_pos > flap){
515 #               print("flap: " , "flap 1");
516                                 setprop("controls/flight/flaps", flap);                 # flap partially blown in
517                         }  
518                         return registerTimer(flapBlowin);
519                 }
520                 elsif (flap_pos != 0 and airspeed > 120) {
521                         flap = 0.2;
522                         if (flap_pos > flap){
523 #               print("flap: " , "flap 2");
524                                 setprop("controls/flight/flaps", flap);       # flap blown in                                         
525                         }
526 #                       print("flap: " , "flap 2");
527                         return registerTimer(flapBlowin);                  # run the timer
528                 }                    
529         else
530                 {                    # stop flap movement, don't run the timer                    
531                 return;
532                 }   
533 } # end function
534
535 wheelsMove = func{
536                 
537         lever=[0,1];
538         lever[0] = getprop("controls/hydraulic/lever[0]");
539         lever[1] = getprop("controls/hydraulic/lever[1]");
540         wheel_pos = getprop("gear/gear[1]/position-norm[0]");
541         
542         
543         if (lever[0] == -1){
544          if (lever[1] == -1 ) {
545 #           print("levers1: " ,lever[0], lever[1] , " wheel pos: " , wheel_pos); 
546                         setprop("controls/hydraulic/wheels" , wheel_pos + 0.05);     # lower wheels
547                         return registerTimer(wheelsMove);                            # run the timer                
548                 }
549          elsif ( lever[1] == 1) {
550 #               print("levers2: " ,lever[0], lever[1] , " wheel pos: " , wheel_pos);
551                 setprop("controls/hydraulic/wheels" , wheel_pos - 0.05); # raise wheels
552                 return registerTimer(wheelsMove); 
553                 }
554         else
555                 {                    # stop wheel movement, don't run the timer                    
556                 return;
557                 }
558         }   
559 } # end function  
560
561 # =============================== end flap stuff =========================================
562
563 # =========================== gear warning stuff =========================================
564
565 toggleGearWarn = func{                                         # toggle the gear warning
566
567         cancel = getprop("sim/alarms/gear-warn");
568         cancel = !cancel;
569 #   print("cancel :", cancel);
570         setprop("sim/alarms/gear-warn",cancel);
571         if (cancel) {registerTimer(resetWarn)}                    # run the timer
572                 
573 } # end function 
574
575 resetWarn = func{
576
577         throttle = getprop("controls/engines/engine/throttle");
578         gearwarn = getprop("sim/alarms/gear-warn");
579 #   print("throttle " , throttle , " gearwarn: " , gearwarn);
580         if (gearwarn and throttle >= 0.25 ) { 
581                 setprop("sim/alarms/gear-warn",0);                    # reset the gear warning
582                 }
583                 else
584                 {
585                 return registerTimer(resetWarn);                      # run the timer                
586                 }
587                 
588 } # end function 
589
590
591 # =========================== end gear warning stuff =========================================
592
593 # =============================== -ve g cutoff stuff =========================================
594
595 negGCutoff = func{
596
597         g = getprop("accelerations/pilot-g");
598         if (g == nil) { g = 0 };
599         mixture = getprop("controls/engines/engine/mixture-lever");
600         if (spitfireIIa) {
601                 if (g > 0.75) {
602                                 return  mixture;                    # mixture set by lever
603                         }
604                         elsif (g <= 0.75 and g >= 0)  {            # mixture set by - ve g
605                                 mixture = g * 4/3;
606                         }
607                         else  {                                    # mixture set by - ve g
608                                 mixture = 0;
609                 }
610         } 
611                 
612 #    print("g: " , g , " mixture: " , mixture);
613         
614         return mixture;
615
616 } # end function 
617
618 # =============================== end -ve g cutoff ===========================================
619
620 # =============================== Pilot G stuff======================================
621
622 pilot_g = props.globals.getNode("accelerations/pilot-g", 1);
623 timeratio = props.globals.getNode("accelerations/timeratio", 1);
624 pilot_g_damped = props.globals.getNode("accelerations/pilot-g-damped", 1);
625
626 pilot_g.setDoubleValue(0);
627 pilot_g_damped.setDoubleValue(0); 
628 timeratio.setDoubleValue(0.03); 
629
630 g_damp = 0;
631
632 updatePilotG = func {
633                 var n = timeratio.getValue(); 
634                 var g = pilot_g.getValue() ;
635                 #if (g == nil) { g = 0; }
636                 g_damp = ( g * n) + (g_damp * (1 - n));
637                 
638                 pilot_g_damped.setDoubleValue(g_damp);
639
640 # print(sprintf("pilot_g_damped in=%0.5f, out=%0.5f", g, g_damp));
641                 
642                 settimer(updatePilotG, 0.1);
643
644 } #end updatePilotG()
645
646 updatePilotG();
647
648 # headshake - this is a modification of the original work by Josh Babcock
649
650 # Define some stuff with global scope
651
652 xConfigNode = '';
653 yConfigNode = '';
654 zConfigNode = '';
655
656 xAccelNode = '';
657 yAccelNode = '';
658 zAccelNode = '';
659
660 var xDivergence_damp = 0;
661 var yDivergence_damp = 0;
662 var zDivergence_damp = 0;
663
664 var last_xDivergence = 0;
665 var last_yDivergence = 0;
666 var last_zDivergence = 0;
667
668 # Make sure that some vital data exists and set some default values
669 enabledNode = props.globals.getNode("/sim/headshake/enabled", 1);
670 enabledNode.setBoolValue(1);
671
672 xMaxNode = props.globals.getNode("/sim/headshake/x-max-m",1);
673 xMaxNode.setDoubleValue( 0.025 );
674
675 xMinNode = props.globals.getNode("/sim/headshake/x-min-m",1);
676 xMinNode.setDoubleValue( -0.05 );
677         
678 yMaxNode = props.globals.getNode("/sim/headshake/y-max-m",1);
679 yMaxNode.setDoubleValue( 0.025 );
680
681 yMinNode = props.globals.getNode("/sim/headshake/y-min-m",1);
682 yMinNode.setDoubleValue( -0.025 );
683         
684 zMaxNode = props.globals.getNode("/sim/headshake/z-max-m",1);
685 zMaxNode.setDoubleValue( 0.025 );
686
687 zMinNode = props.globals.getNode("/sim/headshake/z-min-m",1);
688 zMinNode.setDoubleValue( -0.05 );
689
690 view_number_Node = props.globals.getNode("/sim/current-view/view-number",1);
691 view_number_Node.setDoubleValue( 0 );
692
693 time_ratio_Node = props.globals.getNode("/sim/headshake/time-ratio",1);
694 time_ratio_Node.setDoubleValue( 0.003 );
695
696 seat_vertical_adjust_Node = props.globals.getNode("/controls/seat/vertical-adjust",1);
697 seat_vertical_adjust_Node.setDoubleValue( 0 );
698
699 xThresholdNode = props.globals.getNode("/sim/headshake/x-threshold-m",1);
700 xThresholdNode.setDoubleValue( 0.02 );
701
702 yThresholdNode = props.globals.getNode("/sim/headshake/y-threshold-m",1);
703 yThresholdNode.setDoubleValue( 0.02 );
704
705 zThresholdNode = props.globals.getNode("/sim/headshake/z-threshold-m",1);
706 zThresholdNode.setDoubleValue( 0.02 );
707
708 # We will use these later
709 xConfigNode = props.globals.getNode("/sim/view/config/z-offset-m");
710 yConfigNode = props.globals.getNode("/sim/view/config/x-offset-m");
711 zConfigNode = props.globals.getNode("/sim/view/config/y-offset-m");
712         
713 xAccelNode = props.globals.getNode("/accelerations/pilot/x-accel-fps_sec",1);
714 xAccelNode.setDoubleValue( 0 );
715 yAccelNode = props.globals.getNode("/accelerations/pilot/y-accel-fps_sec",1);
716 yAccelNode.setDoubleValue( 0 );
717 zAccelNode = props.globals.getNode("/accelerations/pilot/z-accel-fps_sec",1);
718 zAccelNode.setDoubleValue(-32 );
719    
720
721 headShake = func {
722
723         # First, we don't shake outside the vehicle. Inside, we boogie down.
724         # There are two coordinate systems here, one used for accelerations, and one used for the viewpoint.
725         # We will be using the one for accelerations.
726         var enabled = enabledNode.getValue();
727         var view_number= view_number_Node.getValue();
728         var n = timeratio.getValue(); 
729         var seat_vertical_adjust = seat_vertical_adjust_Node.getValue();
730         
731
732         if ( (enabled) and ( view_number == 0)) {
733         
734         var xConfig = xConfigNode.getValue();
735                 var yConfig = yConfigNode.getValue();
736                 var zConfig = zConfigNode.getValue();
737
738                 var xMax = xMaxNode.getValue();
739                 var xMin = xMinNode.getValue();
740                 var yMax = yMaxNode.getValue();
741                 var yMin = yMinNode.getValue();
742                 var zMax = zMaxNode.getValue();
743                 var zMin = zMinNode.getValue();
744
745         #work in G, not fps/s
746                 var xAccel = xAccelNode.getValue()/32;
747                 var yAccel = yAccelNode.getValue()/32;
748                 var zAccel = (zAccelNode.getValue() + 32)/32; # We aren't counting gravity
749  
750         var xThreshold =  xThresholdNode.getValue();
751         var yThreshold =  yThresholdNode.getValue();
752         var zThreshold =  zThresholdNode.getValue();
753                 
754                 # Set viewpoint divergence and clamp
755                 # Note that each dimension has it's own special ratio and +X is clamped at 1cm
756                 # to simulate a headrest.
757
758         #y = -0.0005x3 - 0.005x2 - 0.0089x - 0.0045
759         # -0.0004x3 + 0.0042x2 - 0.0084x + 0.0048
760         # -0.0004x3 - 0.0042x2 - 0.0084x - 0.0048
761                 if (xAccel < -5 ) {
762                 xDivergence = -0.03;
763         } elsif ((xAccel < -0.5) and (xAccel >= -5)) {
764                         xDivergence = ((( -0.0005 * xAccel ) - ( 0.0036 )) * xAccel - ( 0.001 )) * xAccel - 0.0004;
765                 } elsif ((xAccel > 1) and (xAccel <= 6)) {
766                                 xDivergence = ((( -0.0004 * xAccel ) + ( 0.0031 )) * xAccel - ( 0.0016 )) * xAccel + 0.0002;
767         } elsif (xAccel > 5) {
768                 xDivergence = 0.02;
769         } else {
770                 xDivergence = 0;
771                 }
772
773 #       These equations shape the output and convet from G number to divergence left/right in meters
774 #       y = -0.0005x3 - 0.0036x2 + 0.0001x + 0.0004
775 #       y = -0.013x3 + 0.125x2 - 0.1202x + 0.0272
776                 
777         if (yAccel < -5 ) {
778                 yDivergence = -0.03;
779         } elsif ((yAccel < -0.5) and (yAccel >= -5)) {
780                         yDivergence = ((( -0.005 * yAccel ) - ( 0.0036 )) * yAccel - (  0.0001 )) * yAccel - 0.0004;
781                 } elsif ((yAccel > 0.5) and (yAccel <= 5)) {
782                         yDivergence = ((( -0.013 * yAccel ) + ( 0.125 )) * yAccel - (  0.1202 )) * yAccel + 0.0272;
783                 } elsif (yAccel > 5) {
784                 yDivergence = 0.03;
785         }else {
786                 yDivergence = 0;
787         }
788
789 #        setprop("/sim/current-view/x-offset-m", (yConfig + yDivergence));      
790 # y = -0.0005x3 - 0.0036x2 + 0.0001x + 0.0004
791 # y = -0.0004x3 + 0.0031x2 - 0.0016x + 0.0002
792         if (zAccel < -5 ) {
793                 zDivergence = -0.03;
794         } elsif ((zAccel < -0.5) and (zAccel >= -5)) {
795                         zDivergence = ((( -0.0005 * zAccel ) - ( 0.0036 )) * zAccel - ( 0.001 )) * zAccel - 0.0004;
796                 } elsif ((zAccel > 0.5) and (zAccel <= 5)) {
797                                 zDivergence = ((( -0.0004 * zAccel ) + ( 0.0031 )) * zAccel - ( 0.0016 )) * zAccel + 0.0002;
798         } elsif (zAccel > 5) {
799                 zDivergence = 0.02;
800         } else {
801                 zDivergence = 0;
802                 }
803                 # 
804            
805         xDivergence_total = (xDivergence * 0.75) + (zDivergence * 0.25);
806
807                 if (xDivergence_total > xMax){xDivergence_total = xMax;}
808                 if (xDivergence_total < xMin){xDivergence_total = xMin;}
809         
810         if (abs(last_xDivergence - xDivergence_total) <= xThreshold){
811                         xDivergence_damp = ( xDivergence_total * n) + ( xDivergence_damp * (1 - n));
812         #       print ("x low pass");
813         } else {
814                 xDivergence_damp = xDivergence_total;
815         #       print ("x high pass");
816         }
817                 
818         last_xDivergence = xDivergence_damp;
819
820 # print (sprintf("x-G=%0.5fx, total=%0.5f, x div damped=%0.5f",xAccel, xDivergence_total, xDivergence_damp));   
821
822         yDivergence_total = yDivergence;
823                 if (yDivergence_total >= yMax){yDivergence_total = yMax;}
824                 if (yDivergence_total <= yMin){yDivergence_total = yMin;}
825
826         if (abs(last_yDivergence - yDivergence_total) <= yThreshold){
827                 yDivergence_damp = ( yDivergence_total * n) + ( yDivergence_damp * (1 - n));
828                 #       print ("y low pass");
829         } else {
830                 yDivergence_damp = yDivergence_total;
831         #       print ("y high pass");
832         }
833
834         last_yDivergence = yDivergence_damp;
835
836 #print (sprintf("y=%0.5f, y total=%0.5f, y min=%0.5f, y div damped=%0.5f",yDivergence, yDivergence_total, yMin , yDivergence_damp));
837         
838         zDivergence_total =  (xDivergence * 0.25 ) + (zDivergence * 0.75);
839
840         if (zDivergence_total >= zMax){zDivergence_total = zMax;}
841                 if (zDivergence_total <= zMin){zDivergence_total = zMin;}
842            
843         if (abs(last_zDivergence - zDivergence_total) <= zThreshold){ 
844                         zDivergence_damp = ( zDivergence_total * n) + ( zDivergence_damp * (1 - n));
845         #print ("z low pass");
846         } else {
847                 zDivergence_damp = zDivergence_total;
848         #print ("z high pass");
849         }
850         
851
852 #       last_zDivergence = zDivergence_damp;
853
854 #print (sprintf("z-G=%0.5f, z total=%0.5f, z div damped=%0.5f",zAccel, zDivergence_total,zDivergence_damp));
855
856         setprop("/sim/current-view/z-offset-m", xConfig + xDivergence_damp );
857                 setprop("/sim/current-view/x-offset-m", yConfig + yDivergence_damp );
858         setprop("/sim/current-view/y-offset-m", zConfig + zDivergence_damp + seat_vertical_adjust );
859         }
860         settimer(headShake,0 );
861
862 }
863
864 headShake();
865
866 # ======================================= end Pilot G stuff ============================
867
868 # ================================== Steering ==========================================
869
870 aircraft.steering.init();
871
872
873 # ==================================  Engine Hobbs Meter ================================
874
875 var hobbs_engine = aircraft.timer.new("sim/time/hobbs/engine[0]", 60, 0);
876 var engine_running_Node = props.globals.initNode("engines/engine[0]/running", 1, "BOOL");
877
878 hobbs_engine.reset();
879
880 updateHobbs = func{
881         var running = engine_running_Node.getValue();
882
883         if(running){
884                 hobbs_engine.start();
885         } else {
886                 hobbs_engine.stop();
887         }
888
889         settimer(updateHobbs,0)
890 }
891
892 updateHobbs();
893
894 # ================================== End Engine Hobbs Meter ================================
895
896 # ==================================  Tyresmoke /Spray ================================
897 var run_tyresmoke0 = 0;
898 var run_tyresmoke1 = 0;
899 var run_tyresmoke2 = 0;
900
901 var tyresmoke_0 = aircraft.tyresmoke.new(0);
902 var tyresmoke_1 = aircraft.tyresmoke.new(1);
903 var tyresmoke_2 = aircraft.tyresmoke.new(2);
904
905 # =============================== listeners ===============================
906 #
907
908 setlistener( "controls/lighting/nav-lights", func {
909         var nav_lights_node = props.globals.getNode("controls/lighting/nav-lights", 1);
910         var generic_node = props.globals.getNode("sim/multiplay/generic/int[0]", 1);
911         generic_node.setIntValue(nav_lights_node.getValue());
912         print("nav_lights ", nav_lights_node.getValue(), "generic_node ", generic_node.getValue());
913         }
914 ); 
915
916 setlistener("gear/gear[0]/position-norm", func {
917         var gear = getprop("gear/gear[0]/position-norm");
918         
919         if (gear == 1 ){
920                 run_tyresmoke0 = 1;
921         }else{
922                 run_tyresmoke0 = 0;
923         }
924
925         },
926         1,
927         0);
928
929 setlistener("gear/gear[1]/position-norm", func {
930         var gear = getprop("gear/gear[1]/position-norm");
931         
932         if (gear == 1 ){
933                 run_tyresmoke1 = 1;
934         }else{
935                 run_tyresmoke1 = 0;
936         }
937
938         },
939         1,
940         0);
941
942 setlistener("gear/gear[2]/position-norm", func {
943         var gear = getprop("gear/gear[2]/position-norm");
944         
945         if (gear == 1 ){
946                 run_tyresmoke2 = 1;
947         }else{
948                 run_tyresmoke2 = 0;
949         }
950
951         },
952         1,
953         0);
954
955 #============================ Tyre Smoke ===================================
956
957 var tyresmoke = func {
958
959 #print ("run_tyresmoke ",run_tyresmoke0,run_tyresmoke1,run_tyresmoke2);
960
961         if (run_tyresmoke0)
962                 tyresmoke_0.update();
963
964         if (run_tyresmoke1)
965                 tyresmoke_1.update();
966
967         if (run_tyresmoke2)
968                 tyresmoke_2.update();
969
970         settimer(tyresmoke, 0);
971 }# end tyresmoke
972
973 # == fire it up ===
974
975 tyresmoke();
976
977 #============================ Rain ===================================
978
979 aircraft.rain.init();
980
981 var rain = func {
982         var running = engine_running_Node.getValue();
983         aircraft.rain.update();
984 #       print("running ", running);
985
986         if(running){
987                 setprop("sim/model/rain/flow-threshold-kt", 0);
988         } else {
989                 setprop("sim/model/rain/flow-threshold-kt", 15);
990         }
991         
992         settimer(rain, 0);
993 }
994
995 # == fire it up ===
996 rain()
997
998 # end 
999