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