2 # NASAL instruments for TU-154B
3 # Yurik V. Nikiforoff, yurik.nsk@gmail.com
9 ######################################################################
11 # Utility classes and functions.
14 # Before anything else change random seed.
18 # Chase() works like interpolate(), but tracks value changes, supports
19 # wraparound, and allows cancellation.
22 deactivate: func(src) {
23 var m = Chase._active[src];
27 new: func(src, dst, delay, wrap=nil) {
36 Chase.deactivate(src);
37 Chase._active[src] = m;
38 m.t = maketimer(0, m, Chase._update);
43 return (Chase._active[me.src] == me);
46 Chase._active[me.src] = nil;
51 var passed = ts - me.ts;
52 var dv = (num(me.dst) == nil ? getprop(me.dst) : me.dst);
53 if (me.left > passed) {
54 var sv = getprop(me.src);
58 var w = (me.wrap != nil
59 and abs(delta) > (me.wrap[1] - me.wrap[0]) / 2.0);
62 delta -= me.wrap[1] - me.wrap[0];
64 delta += me.wrap[1] - me.wrap[0];
66 var nsv = sv + delta * passed / me.left;
69 nsv += (nsv < me.wrap[0] ? me.wrap[1] : 0);
71 nsv -= (nsv >= me.wrap[1] ? me.wrap[1] : 0);
83 # Smooth property re-aliasing.
84 var realias = func(src, dst, delay, wrap=nil) {
88 var obj = props.globals.getNode(src, 1);
91 if (v != nil and delay > 0) {
93 var c = Chase.new(src, dst, delay, wrap);
104 Chase.deactivate(src);
112 var range_wrap = func(val, min, max) {
121 ######################################################################
127 # Both left and right PNPs are instances of the same pnp.xml model
128 # parameterized with corresponding properties, and behave identically.
129 # Each PNP has five modes of operation: normal (no indication), NVU
130 # (NV indication), VOR1 and VOR2 (both have VOR indication), and SP
131 # (SP indication). Left PNP mode is selected with ABSU mode buttons
132 # (Reset and Heading buttons correspond to normal mode, Landing button
133 # corresponds to SP mode, and the rest button correspondence is
134 # one-to-one). Right PNP mode is selected with the dedicated switch
137 # In all modes of PNP operation left handle sets heading (yellow
138 # rotating marks) and right handle sets course in degrees (shown with
139 # digit wheels in the top right corner of PNP). In all modes but NVU
140 # course needle also points to the dialed course. In NVU mode course
141 # needle points to current NVU course from active V-140 set.
143 # Course deflection needle in VOR1 or VOR2 mode shows offset in
144 # degrees of the VOR radial selected on corresponding KURS-MP up to 10
145 # degrees at full scale. In SP mode it shows offset in degrees of the
146 # ILS-LOC radial (again, up to 10 degrees; ILS frequency is set in
147 # left KURS-MP set). In NVU mode the needle shows Z offset of NVU
148 # course in km up to 4 km at full scale (that is, negated Z value from
149 # active NVU counter clipped to 4 km). In normal mode (or when
150 # there's no VOR or ILS-LOC in range) the needle is not deflected and
151 # course blanker is shown.
153 # Glideslope deflection needle in SP mode shows offset in degrees to
154 # the ILS-GS up to 0.7 degrees at full scale (ILS frequency is set in
155 # left KURS-MP set). In other modes (or when there's no ILS-GS in
156 # range) the needle is not deflected and glideslope blanker is shown.
158 # Note that VOR1 and SP modes are mutually exclusive: when you tune
159 # left KURS-MP to VOR then PNP in SP mode will be blanked on both
160 # channels. Likewise, when you tune left KURS-MP to ILS then PNP in
161 # VOR1 mode will be blanked on both channels. Also note that tuning
162 # right KURS-MP to ILS will result in VOR2 mode blanked on both
165 # When /tu154/instrumentation/distance-to-pnp is set to true distance
166 # digit wheels show abs(S) from active NVU block.
171 # With setlistener() we track changes to all properties that determine
172 # PNP mode and blankers (but not needle input values). When any such
173 # change occurs we recompute PNP mode, set blankers accordingly, and
174 # alias() PNP needle properties to relevant inputs so that needle
175 # value updates happen implicitly after that. This way we track only
176 # infrequent changes (like button presses or switch toggling), but do
177 # not have to recompute needle values every frame.
180 var pnp_mode_update = func(i, mode) {
181 var plane = "/tu154/instrumentation/pnp["~i~"]/plane-dialed";
184 var distance = getprop("/tu154/instrumentation/pnp["~i~"]/distance");
185 var blank_course = 1;
188 if (mode == 1 and getprop("fdm/jsbsim/instrumentation/nvu/active")) { # NVU
189 plane = "fdm/jsbsim/instrumentation/nvu/ZPU-active";
190 defl_course = "fdm/jsbsim/instrumentation/nvu/Z-deflection";
192 } else if (mode == 2 and !getprop("instrumentation/nav[0]/nav-loc")) { #VOR1
193 if (getprop("instrumentation/nav[0]/in-range")) {
195 "instrumentation/nav[0]/heading-needle-deflection-norm";
198 } else if (mode == 3 and !getprop("instrumentation/nav[1]/nav-loc")) { #VOR2
199 if (getprop("instrumentation/nav[1]/in-range")) {
201 "instrumentation/nav[1]/heading-needle-deflection-norm";
204 } else if (mode == 4 and getprop("instrumentation/nav[0]/nav-loc")) { # SP
205 if (getprop("instrumentation/nav[0]/in-range")) {
207 "instrumentation/nav[0]/heading-needle-deflection-norm";
210 if (getprop("instrumentation/nav[0]/gs-in-range")) {
211 defl_gs = "instrumentation/nav[0]/gs-needle-deflection-norm";
215 if (getprop("tu154/instrumentation/distance-to-pnp")
216 and getprop("fdm/jsbsim/instrumentation/nvu/active")) {
217 distance = "fdm/jsbsim/instrumentation/nvu/S-active";
220 setprop("tu154/instrumentation/pnp["~i~"]/mode", mode);
221 realias("/tu154/instrumentation/pnp["~i~"]/plane-deg", plane, 0.5,
223 realias("/tu154/instrumentation/pnp["~i~"]/defl-course", defl_course, 0.5);
224 realias("/tu154/instrumentation/pnp["~i~"]/defl-gs", defl_gs, 0.5);
225 realias("/tu154/instrumentation/pnp["~i~"]/distance", distance, 0.5);
226 setprop("tu154/instrumentation/pnp["~i~"]/blank-course", blank_course);
227 setprop("tu154/instrumentation/pnp["~i~"]/blank-gs", blank_gs);
228 setprop("tu154/instrumentation/pnp["~i~"]/blank-dist", blank_dist);
231 # PNP mode for first pilot.
232 var pnp0_mode_update = func {
233 var sel = getprop("fdm/jsbsim/ap/roll-selector") or 0;
234 if (!getprop("instrumentation/heading-indicator[0]/serviceable")
235 or !getprop("tu154/systems/absu/serviceable"))
238 var mode = 0; # Disabled or Stab or ZK (sel == 0 or sel == 1 or sel == 2)
239 if (sel == 3) { # VOR
241 if (getprop("tu154/instrumentation/pn-5/az-2"))
243 } else if (sel == 4) { # NVU
245 } else if (sel == 5) { # SP
247 } else if (sel != -1) {
248 if (getprop("tu154/switches/pn-5-navigac") == 0
249 and getprop("tu154/switches/pn-5-posadk") == 1
250 and getprop("instrumentation/nav[0]/nav-loc")
251 and (getprop("instrumentation/nav[0]/in-range")
252 or getprop("instrumentation/nav[0]/gs-in-range")))
255 pnp_mode_update(0, mode);
258 # PNP mode for second pilot.
259 var pnp1_mode_update = func {
260 var sel = getprop("tu154/switches/pn-6-selector") or 0;
261 if (!getprop("instrumentation/heading-indicator[1]/serviceable"))
263 pnp_mode_update(1, sel);
266 var pnp_both_mode_update = func {
271 setlistener("tu154/systems/absu/serviceable", pnp0_mode_update, 0, 0);
272 setlistener("tu154/switches/pn-5-navigac", pnp0_mode_update);
273 setlistener("tu154/switches/pn-5-posadk", pnp0_mode_update);
274 setlistener("fdm/jsbsim/ap/roll-selector", pnp0_mode_update);
275 setlistener("instrumentation/heading-indicator[0]/serviceable",
276 pnp0_mode_update, 1, 0);
278 setlistener("tu154/switches/pn-6-selector", pnp1_mode_update);
279 setlistener("instrumentation/heading-indicator[1]/serviceable",
280 pnp1_mode_update, 1, 0);
282 setlistener("fdm/jsbsim/instrumentation/nvu/active", pnp_both_mode_update, 0, 0);
283 setlistener("tu154/instrumentation/distance-to-pnp", pnp_both_mode_update);
284 setlistener("instrumentation/nav[0]/nav-loc", pnp_both_mode_update, 0, 0);
285 setlistener("instrumentation/nav[1]/nav-loc", pnp_both_mode_update, 0, 0);
286 setlistener("instrumentation/nav[0]/in-range", pnp_both_mode_update, 0, 0);
287 setlistener("instrumentation/nav[1]/in-range", pnp_both_mode_update, 0, 0);
288 setlistener("instrumentation/nav[0]/gs-in-range", pnp_both_mode_update, 0, 0);
291 ######################################################################
296 # Smooth DME updates.
297 var dme_distance = func(i) {
298 var distance = getprop("instrumentation/dme["~i~"]/indicated-distance-nm");
299 # We ignore exact zero distance because it signifies out of range
300 # condition, and we want to keep last value in this case. Within DME
301 # proximity exact zero distance is highly unlikely, and close to zero
302 # update will be enough.
304 distance = int(distance * 18.52) * 100;
305 interpolate("tu154/instrumentation/dme["~i~"]/distance", distance, 0.2);
308 setlistener("instrumentation/dme[0]/indicated-distance-nm",
309 func { dme_distance(0) }, 0, 0);
310 setlistener("instrumentation/dme[1]/indicated-distance-nm",
311 func { dme_distance(1) }, 0, 0);
312 setlistener("instrumentation/dme[2]/indicated-distance-nm",
313 func { dme_distance(2) }, 0, 0);
316 # Added by Yurik dec 2013
317 setprop("instrumentation/dme[0]/frequencies/selected-mhz",
318 getprop("instrumentation/nav[0]/frequencies/selected-mhz") );
320 setprop("instrumentation/dme[1]/frequencies/selected-mhz",
321 getprop("instrumentation/nav[1]/frequencies/selected-mhz") );
323 ######################################################################
329 # Note that DME cannel in VOR-DME and ILS-DME operates in the same way
330 # so IDR-1 works with both.
333 var idr_mode_update = func(i, selector) {
334 var sel = getprop(selector);
335 if (int(sel) != sel) # The switch is in transition.
337 var ni = (sel ? 3 - sel : 0); # 2 -> 1, 1 -> 2, 0 -> 0
338 var distance = getprop("/tu154/instrumentation/idr-1["~i~"]/distance");
340 if (getprop("instrumentation/dme["~ni~"]/in-range")) {
341 distance = "tu154/instrumentation/dme["~ni~"]/distance";
344 realias("/tu154/instrumentation/idr-1["~i~"]/distance", distance, 0.5);
345 setprop("tu154/instrumentation/idr-1["~i~"]/blank", blank);
348 var idr0_mode_update = func {
349 idr_mode_update(0, "tu154/switches/capt-idr-selector");
352 var idr1_mode_update = func {
353 idr_mode_update(1, "tu154/switches/copilot-idr-selector");
356 var idr_both_mode_update = func {
361 setlistener("tu154/switches/capt-idr-selector", idr0_mode_update, 1);
363 setlistener("tu154/switches/copilot-idr-selector", idr1_mode_update, 1);
365 setlistener("instrumentation/dme[0]/in-range", idr_both_mode_update, 0, 0);
366 setlistener("instrumentation/dme[1]/in-range", idr_both_mode_update, 0, 0);
367 setlistener("instrumentation/dme[2]/in-range", idr_both_mode_update, 0, 0);
370 ######################################################################
375 var rv_altitude_update = func {
376 var alt_m = getprop("position/altitude-agl-ft") * 0.3048;
377 settimer(rv_altitude_update, (alt_m < 1200 ? 0.1 : (alt_m - 900) / 300));
379 var pitch_deg = getprop("orientation/pitch-deg");
380 var roll_deg = getprop("orientation/roll-deg");
381 if (-90 < pitch_deg and pitch_deg < 90
382 and -90 < roll_deg and roll_deg < 90) {
383 var beam_rad = math.acos(math.cos(pitch_deg / 57.3)
384 * math.cos(roll_deg / 57.3));
385 if (beam_rad > 0.262) { # > 15 degrees
387 alt_m /= math.cos(beam_rad);
397 setprop("fdm/jsbsim/instrumentation/indicated-altitude-m", alt_m);
399 rv_altitude_update();
401 var rv_mode_update = func(i, toggled) {
402 # Temporal hack to wait electrical initialization.
403 if (getprop("tu154/switches/main-battery") == nil) {
404 settimer(func { rv_mode_update(i, 1) }, 0.5);
409 var ac_obj = electrical.AC3x200_bus_1L;
410 var volts = "tu154/systems/electrical/buses/AC3x200-bus-1L/volts";
412 var ac_obj = electrical.AC3x200_bus_3R;
413 var volts = "tu154/systems/electrical/buses/AC3x200-bus-3L/volts";
415 volts = getprop(volts) or 0;
416 var powered = (volts > 150.0);
417 var altitude = "tu154/instrumentation/rv-5m["~i~"]/altitude";
418 var switch = "RV-5-"~(i + 1);
421 if (powered and getprop("tu154/switches/"~switch)) {
423 ac_obj.add_output(switch, 10.0);
424 realias(altitude, 850, 3);
427 "fdm/jsbsim/instrumentation/indicated-altitude-m", 3);
428 settimer(func { rv_mode_update(i, 0) }, 3);
429 }, 15); # Up to 2 minutes in reality.
431 warn = (getprop(altitude) <=
432 getprop("tu154/instrumentation/rv-5m["~i~"]/dialed"));
434 var agl = getprop("position/altitude-agl-ft");
435 if (agl < 4000) { # < ~1200m
436 settimer(func { rv_mode_update(i, 0) }, 0.1);
438 # FIXME: RV should be switched off, but for now we have
439 # to track power state.
440 settimer(func { rv_mode_update(i, 0) }, 0.5);
445 ac_obj.rm_output(switch);
446 realias(altitude, 0, 3);
448 settimer(func { rv_mode_update(i, 1) }, 0.5);
451 setprop("tu154/instrumentation/rv-5m["~i~"]/warn", warn);
452 setprop("tu154/instrumentation/rv-5m["~i~"]/blank", blank);
455 rv_mode_update(0, 1);
456 rv_mode_update(1, 1);
459 ######################################################################
464 var iku_vor_bearing = func(i) {
465 setprop("tu154/instrumentation/nav["~i~"]/bearing-deg",
466 getprop("instrumentation/nav["~i~"]/radials/reciprocal-radial-deg")
467 - getprop("fdm/jsbsim/instrumentation/bgmk-"~(i+1)));
469 var iku_vor_bearing_timer = [maketimer(0.1, func { iku_vor_bearing(0) }),
470 maketimer(0.1, func { iku_vor_bearing(1) })];
472 var iku_mode_update = func(i, b) {
473 var sel = getprop("tu154/instrumentation/iku-1["~i~"]/mode-"~b);
477 if (getprop("instrumentation/nav["~j~"]/in-range")
478 and !getprop("instrumentation/nav["~j~"]/nav-loc")) {
479 iku_vor_bearing_timer[j].start();
480 bearing = "tu154/instrumentation/nav["~j~"]/bearing-deg";
482 iku_vor_bearing_timer[j].stop();
485 iku_vor_bearing_timer[j].stop();
486 if (getprop("instrumentation/adf["~j~"]/in-range"))
487 bearing = "instrumentation/adf["~j~"]/indicated-bearing-deg";
490 interpolate("tu154/instrumentation/iku-1["~i~"]/trans-"~b, sel, 0.1);
491 realias("tu154/instrumentation/iku-1["~i~"]/heading-"~b, bearing, 0.5,
495 var iku0_mode1_update = func {
496 iku_mode_update(0, 1);
499 var iku0_mode2_update = func {
500 iku_mode_update(0, 2);
503 var iku1_mode1_update = func {
504 iku_mode_update(1, 1);
507 var iku1_mode2_update = func {
508 iku_mode_update(1, 2);
511 var iku_both_mode1_update = func {
516 var iku_both_mode2_update = func {
521 setlistener("instrumentation/adf[0]/in-range", iku_both_mode1_update, 0, 0);
522 setlistener("instrumentation/nav[0]/in-range", iku_both_mode1_update, 0, 0);
523 setlistener("instrumentation/nav[0]/nav-loc", iku_both_mode1_update, 0, 0);
524 setlistener("instrumentation/adf[1]/in-range", iku_both_mode2_update, 0, 0);
525 setlistener("instrumentation/nav[1]/in-range", iku_both_mode2_update, 0, 0);
526 setlistener("instrumentation/nav[1]/nav-loc", iku_both_mode2_update, 0, 0);
527 setlistener("tu154/instrumentation/iku-1[0]/mode-1", iku0_mode1_update, 1);
528 setlistener("tu154/instrumentation/iku-1[0]/mode-2", iku0_mode2_update, 1);
529 setlistener("tu154/instrumentation/iku-1[1]/mode-1", iku1_mode1_update, 1);
530 setlistener("tu154/instrumentation/iku-1[1]/mode-2", iku1_mode2_update, 1);
533 ######################################################################
538 var ushdb_mode_update = func(b) {
539 var sel = getprop("tu154/switches/ushdb-sel-"~b);
540 if (int(sel) != sel) # The switch is in transition.
545 if (getprop("instrumentation/nav["~j~"]/in-range")
546 and !getprop("instrumentation/nav["~j~"]/nav-loc"))
548 "instrumentation/nav["~j~"]/radials/reciprocal-radial-deg";
550 if (getprop("instrumentation/adf["~j~"]/in-range"))
551 bearing = "instrumentation/adf["~j~"]/indicated-bearing-deg";
554 realias("tu154/instrumentation/ushdb/heading-deg-"~b, bearing, 0.5,
558 var ushdb_mode1_update = func {
559 ushdb_mode_update(1);
562 var ushdb_mode2_update = func {
563 ushdb_mode_update(2);
566 setlistener("instrumentation/adf[0]/in-range", ushdb_mode1_update, 0, 0);
567 setlistener("instrumentation/nav[0]/in-range", ushdb_mode1_update, 0, 0);
568 setlistener("instrumentation/nav[0]/nav-loc", ushdb_mode1_update, 0, 0);
569 setlistener("instrumentation/adf[1]/in-range", ushdb_mode2_update, 0, 0);
570 setlistener("instrumentation/nav[1]/in-range", ushdb_mode2_update, 0, 0);
571 setlistener("instrumentation/nav[1]/nav-loc", ushdb_mode2_update, 0, 0);
572 setlistener("tu154/switches/ushdb-sel-1", ushdb_mode1_update, 1);
573 setlistener("tu154/switches/ushdb-sel-2", ushdb_mode2_update, 1);
576 ######################################################################
581 var uvid_inhg = func(i) {
582 var inhgX100 = getprop("tu154/instrumentation/altimeter["~i~"]/inhgX100");
583 setprop("instrumentation/altimeter["~i~"]/setting-inhg", inhgX100 / 100.0);
586 setprop("tu154/instrumentation/altimeter[0]/mmhg", inhgX100 * 0.254);
588 if (getprop("tu154/instrumentation/altimeters-sync-inhg")) {
589 setprop("tu154/instrumentation/altimeter["~(1-i)~"]/inhgX100",
594 setlistener("tu154/instrumentation/altimeter[0]/inhgX100",
595 func { uvid_inhg(0) }, 1, 0);
596 setlistener("tu154/instrumentation/altimeter[1]/inhgX100",
597 func { uvid_inhg(1) }, 1, 0);
600 ######################################################################
604 # Implementation note:
606 # instrumentation/nav doesn't export true radial value, only twisted
607 # one. Instead of computing true azimuth in Nasal we remember twist
608 # value (which is zero for RSBN but non-zero for VOR) and alias to
609 # twisted radial. rsbn_corr() is sill called every 0.1 second, but
610 # only when correction is enabled.
613 var rsbn_corr = func {
614 var twist = getprop("tu154/instrumentation/rsbn/twist");
615 var ds = (getprop("fdm/jsbsim/instrumentation/nvu/S-active")
616 - getprop("fdm/jsbsim/instrumentation/nvu/Spm-active"));
617 var dz = (getprop("fdm/jsbsim/instrumentation/nvu/Z-active")
618 - getprop("fdm/jsbsim/instrumentation/nvu/Zpm-active"));
619 if (!getprop("instrumentation/nav[2]/nav-loc")
620 and getprop("instrumentation/nav[2]/in-range")
621 and getprop("instrumentation/dme[2]/in-range")) {
622 setprop("tu154/systems/electrical/indicators/nvu-correction-on", 1);
624 var radial = getprop("tu154/instrumentation/rsbn/radial") + twist;
625 var distance = getprop("tu154/instrumentation/rsbn/distance");
626 var uk = (getprop("tu154/instrumentation/b-8m/outer")
627 + getprop("tu154/instrumentation/b-8m/inner") / 10);
628 var angle_rad = (radial - uk) / 57.295779;
629 var deltaS = distance * math.cos(angle_rad) - ds;
630 var deltaZ = distance * math.sin(angle_rad) - dz;
632 var Sb = getprop("fdm/jsbsim/instrumentation/nvu/S-base-active");
633 var Zb = getprop("fdm/jsbsim/instrumentation/nvu/Z-base-active");
634 interpolate("fdm/jsbsim/instrumentation/nvu/S-base-active", Sb + deltaS,
635 (abs(deltaS) + 40000) / 40000);
636 interpolate("fdm/jsbsim/instrumentation/nvu/Z-base-active", Zb + deltaZ,
637 (abs(deltaZ) + 40000) / 40000);
639 setprop("tu154/systems/electrical/indicators/nvu-correction-on", 0);
641 var tks = getprop("fdm/jsbsim/instrumentation/tks-consumers") or 0;
643 (getprop("fdm/jsbsim/instrumentation/nvu/ZPU-active")
644 - getprop("instrumentation/heading-indicator["~tks~"]/offset-deg"));
645 var deg = (ds or dz ? math.atan2(-dz, -ds) * 57.3 : 0);
646 var radial = range_wrap(deg - zpu_true - twist, 0, 360);
647 var distance = math.sqrt(ds * ds + dz * dz);
648 distance = int(distance / 100) * 100;
650 setprop("tu154/instrumentation/rsbn/radial-auto", radial);
651 if (getprop("tu154/instrumentation/rsbn/distance-target") != distance) {
652 setprop("tu154/instrumentation/rsbn/distance-target", distance);
653 interpolate("tu154/instrumentation/rsbn/distance-auto", distance,
658 var rsbn_corr_timer = maketimer(0.1, rsbn_corr);
660 var ppda_mode_update = func {
661 var radial = getprop("tu154/instrumentation/rsbn/radial");
662 var distance = getprop("tu154/instrumentation/rsbn/distance");
663 var nav_in_range = 1;
664 var dme_in_range = 1;
667 rsbn_corr_timer.stop();
668 setprop("tu154/systems/electrical/indicators/nvu-correction-on", 0);
669 if (getprop("tu154/instrumentation/rsbn/serviceable")) {
670 if (!getprop("instrumentation/nav[2]/nav-loc")) {
671 nav_in_range = getprop("instrumentation/nav[2]/in-range");
672 dme_in_range = getprop("instrumentation/dme[2]/in-range");
675 radial = "instrumentation/nav[2]/radials/actual-deg";
676 twist = getprop("instrumentation/nav[2]/radials/target-radial-deg");
679 distance = "tu154/instrumentation/dme[2]/distance";
681 if (getprop("fdm/jsbsim/instrumentation/nvu/active")
682 and getprop("tu154/switches/v-51-corr") == 1) {
684 radial = "tu154/instrumentation/rsbn/radial-auto";
686 distance = "tu154/instrumentation/rsbn/distance-auto";
687 rsbn_corr_timer.start();
691 interpolate("tu154/instrumentation/rsbn/twist", twist, 0.5);
692 realias("/tu154/instrumentation/rsbn/radial", radial, 0.5, [0, 360]);
693 realias("/tu154/instrumentation/rsbn/distance", distance, 0.5);
694 setprop("tu154/systems/electrical/indicators/azimuth-avton", !nav_in_range);
695 setprop("tu154/systems/electrical/indicators/range-avton", !dme_in_range);
698 setlistener("tu154/instrumentation/rsbn/serviceable", ppda_mode_update, 1, 0);
699 setlistener("instrumentation/nav[2]/nav-loc", ppda_mode_update, 0, 0);
700 setlistener("instrumentation/nav[2]/in-range", ppda_mode_update, 0, 0);
701 setlistener("instrumentation/dme[2]/in-range", ppda_mode_update, 0, 0);
702 setlistener("fdm/jsbsim/instrumentation/nvu/active", ppda_mode_update, 0, 0);
703 setlistener("tu154/switches/v-51-corr", ppda_mode_update, 0, 0);
706 ######################################################################
711 var usvp_mode_update = func {
712 var target = "fdm/jsbsim/instrumentation/svs/TAS-fps";
713 if (getprop("tu154/switches/usvp-selector"))
714 target = "fdm/jsbsim/instrumentation/nvu/GS-fps";
716 var mode_out = getprop("fdm/jsbsim/instrumentation/nvu/mode-out");
717 setprop("fdm/jsbsim/instrumentation/nvu/mode-in", mode_out);
718 realias("tu154/instrumentation/usvp/speed-fps", target, 0.5);
722 and getprop("fdm/jsbsim/instrumentation/nvu/source") == 2
723 and getprop("fdm/jsbsim/instrumentation/diss/sensitivity") > 0);
724 setprop("tu154/systems/electrical/indicators/memory-diss",
725 (diss_memory ? 1 : 0));
728 setlistener("tu154/switches/usvp-selector", usvp_mode_update, 1, 0);
729 setlistener("fdm/jsbsim/instrumentation/nvu/mode-out", usvp_mode_update, 0, 0);
730 setlistener("fdm/jsbsim/instrumentation/nvu/source", usvp_mode_update, 0, 0);
731 setlistener("fdm/jsbsim/instrumentation/diss/sensitivity", usvp_mode_update,
733 setlistener("fdm/jsbsim/instrumentation/svs/serviceable", usvp_mode_update,
736 setlistener("tu154/systems/svs/powered", func {
737 setprop("fdm/jsbsim/instrumentation/svs/serviceable",
738 getprop("tu154/systems/svs/powered"));
741 var diss_sensitivity_update = func {
742 var diss_terrain = getprop("tu154/switches/DISS-surface");
743 var lat = getprop("position/latitude-deg");
744 var lon = getprop("position/longitude-deg");
745 # Probe terrain below aircraft and in ~6 km vicinity.
746 var info = geodinfo(lat, lon);
747 var above_ground = (info != nil and info[1] != nil and info[1].solid);
748 for (var i = 0; i < 3 and !above_ground; i += 1) {
749 info = geodinfo(lat + 0.1 * (rand() - 0.5), lon + 0.1 * (rand() - 0.5));
750 above_ground = (info != nil and info[1] != nil and info[1].solid);
752 var sensitivity = 1; # Threshold is >= 0.2
755 sensitivity = rand() * 0.5; # >= 0.2 with probability 0.6.
757 # Beaufort scale 1 corresponds to 3 kts wind, and this
758 # corresponds to wave amplitude of 1.06.
759 var wave_amp = getprop("environment/wave/amp");
760 sensitivity = (wave_amp - 1) * 3.3333;
762 sensitivity *= rand() * 0.2857; # >= 0.2 with probability 0.3.
764 setprop("fdm/jsbsim/instrumentation/diss/sensitivity", sensitivity or 0.001);
766 var diss_sensitivity_update_timer = maketimer(60, diss_sensitivity_update);
768 setlistener("tu154/switches/DISS-surface", func {
769 if (getprop("tu154/instrumentation/diss/powered"))
770 diss_sensitivity_update_timer.restart(60);
773 setlistener("tu154/instrumentation/diss/powered", func {
774 var powered = getprop("tu154/instrumentation/diss/powered");
776 diss_sensitivity_update_timer.start();
777 electrical.AC3x200_bus_1L.add_output("DISS", 25);
779 diss_sensitivity_update_timer.stop();
780 setprop("fdm/jsbsim/instrumentation/diss/sensitivity", 0);
781 electrical.AC3x200_bus_1L.rm_output("DISS");
786 ######################################################################
790 # Implementation: the basic idea is simple: in Systems/nvu.xml we
791 # compute S,Z-active and S,Z-inactive, and here we play with aliases
792 # to swap active and inactive NVU blocks. Smooth movement of digit
793 # wheels is implemented in Systems/property-filters.xml.
796 var nvu_swap_alias = func(active, name) {
797 var inactive = 3 - active;
798 var src = "tu154/systems/nvu/"~name;
799 var dst = "fdm/jsbsim/instrumentation/nvu/"~name;
800 var av = getprop(dst~"-active");
801 var iv = getprop(dst~"-inactive");
802 setprop(dst~"-active", iv);
803 setprop(dst~"-inactive", av);
804 realias(src~"-"~active, dst~"-active", 0);
805 realias(src~"-"~inactive, dst~"-inactive", 0);
806 if (name == "S" or name == "Z") {
807 var I = getprop("fdm/jsbsim/instrumentation/nvu/"~name~"-integrator");
808 setprop("fdm/jsbsim/instrumentation/nvu/"~name~"-base-active", iv - I);
812 nvu_swap_alias(1, "S");
813 nvu_swap_alias(1, "Z");
814 nvu_swap_alias(1, "Spm");
815 nvu_swap_alias(1, "Zpm");
816 nvu_swap_alias(1, "ZPU");
818 var nvu_enable = func {
819 var powered = getprop("tu154/systems/nvu/powered");
820 setprop("fdm/jsbsim/instrumentation/nvu/active", powered);
822 electrical.AC3x200_bus_1L.add_output("NVU", 150);
824 electrical.AC3x200_bus_1L.rm_output("NVU");
827 setlistener("tu154/systems/nvu/powered", nvu_enable, 0, 0);
829 var nvu_virtual_navigator_load = func(li, lin) {
830 var active = getprop("fdm/jsbsim/instrumentation/nvu/active") or 1;
831 var inactive = 3 - active;
833 var route = props.globals.getNode("tu154/systems/nvu-calc/route", 1);
835 var leg = route.getChild("leg", li);
837 var values = leg.getValues();
838 msg = sprintf("Virtual navigator: on leg %s - %s (%.1f km)",
839 values.from, values.to, -values.S);
841 var beacon = route.getChild("beacon", li);
843 var b = beacon.getValues();
844 setprop("fdm/jsbsim/instrumentation/nvu/Spm-active", b.S * 1000);
845 setprop("fdm/jsbsim/instrumentation/nvu/Zpm-active", b.Z * 1000);
846 var UK_outer = int(b.UK / 10) * 10;
847 var UK_inner = (b.UK - UK_outer) * 10;
848 realias("tu154/instrumentation/b-8m/outer", UK_outer, 3);
849 realias("tu154/instrumentation/b-8m/inner", UK_inner, 3);
850 msg ~= sprintf(", beacon %s (%s %.2f mhz)", b.name, b.ident, b.freq);
854 var leg2 = route.getChild("leg", lin);
856 var values = leg2.getValues();
857 var ZPU = int(values.ZPU * 10 + 0.5) / 10;
858 setprop("fdm/jsbsim/instrumentation/nvu/Spm-inactive", values.S * 1000);
859 setprop("fdm/jsbsim/instrumentation/nvu/Zpm-inactive", 0);
860 setprop("fdm/jsbsim/instrumentation/nvu/ZPU-inactive", ZPU);
862 msg ~= " - last leg";
863 if (getprop("tu154/switches/v-51-selector-2") > 0) {
864 setprop("tu154/switches/v-51-selector-2", 0);
865 msg ~= ", disabling LUR";
873 var nvu_set_integrator = func(name, i, val) {
874 var I = getprop("fdm/jsbsim/instrumentation/nvu/"~name~"-integrator");
875 setprop("fdm/jsbsim/instrumentation/nvu/"~name~"-base-active", val - I);
878 var nvu_calculator_load = func {
879 var active = getprop("fdm/jsbsim/instrumentation/nvu/active");
883 var route = props.globals.getNode("tu154/systems/nvu-calc/route", 1);
884 var lin = getprop("tu154/systems/nvu/leg-next");
885 var leg = route.getChild("leg", lin);
889 if (getprop("fdm/jsbsim/instrumentation/nvu/stopped")) {
890 var values = leg.getValues();
891 var ZPU = int(values.ZPU * 10 + 0.5) / 10;
892 nvu_set_integrator("S", active, values.S * 1000);
893 nvu_set_integrator("Z", active, 0);
894 setprop("fdm/jsbsim/instrumentation/nvu/ZPU-active", ZPU);
895 setprop("tu154/systems/nvu/leg", lin);
897 setprop("tu154/systems/nvu/leg-next", lin);
900 nvu_virtual_navigator_load(getprop("tu154/systems/nvu/leg"), lin);
903 var nvu_zpu_adjust_sign = 0;
904 var nvu_zpu_adjust = func(vi, sign) {
905 var active = getprop("fdm/jsbsim/instrumentation/nvu/active");
909 var ZPU = getprop("tu154/systems/nvu/ZPU-"~vi);
910 var step = getprop("tu154/instrumentation/v-140/adjust-step-"~vi);
912 ZPU = getprop("tu154/systems/nvu/ZPU-"~vi~"-smooth");
913 if (nvu_zpu_adjust_sign > 0)
914 ZPU = math.ceil(ZPU * 10 + 0.025) / 10;
916 ZPU = math.floor(ZPU * 10 + 0.025) / 10;
918 ZPU = range_wrap(int((ZPU + sign * step + 360) * 10 + 0.5) / 10, 0, 360);
920 setprop("tu154/systems/nvu/ZPU-"~vi, ZPU);
922 nvu_zpu_adjust_sign = sign;
925 var nvu_distance_adjust = func(sign) {
926 var active = getprop("fdm/jsbsim/instrumentation/nvu/active");
930 var sel = getprop("tu154/switches/v-51-selector-1");
946 var prop = "fdm/jsbsim/instrumentation/nvu/"~name;
947 var v = getprop(prop);
949 var speed = (getprop("tu154/instrumentation/v-51/adjust-speed")
950 / getprop("tu154/instrumentation/v-51/scale"));
951 interpolate(prop, v + sign * speed * 610, 610);
953 interpolate(prop, v, 0);
957 var nvu_next_leg = func {
958 var active = getprop("fdm/jsbsim/instrumentation/nvu/active");
962 var active = 3 - active;
964 setprop("fdm/jsbsim/instrumentation/nvu/active", active);
966 nvu_swap_alias(active, "S");
967 nvu_swap_alias(active, "Z");
968 nvu_swap_alias(active, "Spm");
969 nvu_swap_alias(active, "Zpm");
970 nvu_swap_alias(active, "ZPU");
972 var lin = getprop("tu154/systems/nvu/leg-next");
973 setprop("tu154/systems/nvu/leg", lin);
974 setprop("tu154/systems/nvu/leg-next", lin + 1);
975 if (getprop("tu154/systems/nvu-calc/virtual-navigator")) {
976 nvu_virtual_navigator_load(lin, lin + 1);
980 setlistener("tu154/switches/v-51-selector-2", func {
981 var sel = getprop("tu154/switches/v-51-selector-2");
986 var nvu_fork_apply = func {
987 if (getprop("/tu154/systems/nvu-calc/fork-only-route"))
990 var fork = getprop("tu154/systems/nvu-calc/fork") or 0;
991 if (!getprop("tu154/systems/nvu-calc/fork-applied"))
994 var val = getprop("instrumentation/heading-indicator[0]/offset-deg");
995 setprop("instrumentation/heading-indicator[0]/offset-deg",
996 range_wrap(val + fork, 0, 360));
998 val = getprop("instrumentation/heading-indicator[1]/offset-deg");
999 setprop("instrumentation/heading-indicator[1]/offset-deg",
1000 range_wrap(val + fork, 0, 360));
1002 val = getprop("fdm/jsbsim/instrumentation/nvu/ZPU-active");
1003 val = range_wrap(val + fork, 0, 360);
1004 setprop("fdm/jsbsim/instrumentation/nvu/ZPU-active", val);
1006 val = getprop("fdm/jsbsim/instrumentation/nvu/ZPU-inactive");
1007 val = range_wrap(val + fork, 0, 360);
1008 setprop("fdm/jsbsim/instrumentation/nvu/ZPU-inactive", val);
1010 var mode = getprop("fdm/jsbsim/instrumentation/nvu/mode-out");
1011 if (mode == 3 or mode == 0) {
1012 val = getprop("fdm/jsbsim/instrumentation/nvu/wind-azimuth-svs");
1013 val = range_wrap(val + fork, 0, 360);
1014 setprop("fdm/jsbsim/instrumentation/nvu/wind-azimuth-svs", val);
1018 setlistener("tu154/systems/nvu-calc/fork-applied", nvu_fork_apply, 0, 0);
1020 var nvu_lur_vicinity = func {
1021 var sel = getprop("tu154/switches/v-51-selector-2");
1022 var active = (getprop("fdm/jsbsim/instrumentation/nvu/active")
1023 and getprop("fdm/jsbsim/instrumentation/nvu/LUR-vicinity-out")
1025 var S = getprop("fdm/jsbsim/instrumentation/nvu/S-active");
1026 var LUR = sel * 5000;
1027 if (!active or (-LUR <= S and S <= LUR)) {
1028 setprop("tu154/systems/electrical/indicators/change-waypoint", 0);
1032 setprop("tu154/systems/electrical/indicators/change-waypoint", 1);
1033 settimer(nvu_lur_vicinity, 0);
1037 setlistener("fdm/jsbsim/instrumentation/nvu/LUR-vicinity-out", func {
1038 if (getprop("fdm/jsbsim/instrumentation/nvu/LUR-vicinity-out"))
1043 ######################################################################
1048 var nvu_wind_mode_update = func {
1049 var target = "diss";
1050 var mode = getprop("fdm/jsbsim/instrumentation/nvu/mode-out");
1051 if (mode == 3 or mode == 0) {
1052 setprop("fdm/jsbsim/instrumentation/nvu/wind-speed-svs",
1053 getprop("tu154/systems/nvu/wind-speed"));
1054 setprop("fdm/jsbsim/instrumentation/nvu/wind-azimuth-svs",
1055 getprop("tu154/systems/nvu/wind-azimuth"));
1059 realias("tu154/systems/nvu/wind-speed",
1060 "fdm/jsbsim/instrumentation/nvu/wind-speed-"~target, 0);
1061 realias("tu154/systems/nvu/wind-azimuth",
1062 "fdm/jsbsim/instrumentation/nvu/wind-azimuth-"~target, 0);
1065 setlistener("fdm/jsbsim/instrumentation/nvu/mode-out", nvu_wind_mode_update,
1068 var nvu_wind_adjust_sign = 0;
1069 var nvu_wind_adjust = func(which, sign) {
1070 var mode = getprop("fdm/jsbsim/instrumentation/nvu/mode-out");
1072 and (mode != 0 or !getprop("fdm/jsbsim/instrumentation/nvu/active")))
1075 var step = getprop("tu154/instrumentation/v-57/"~which~"-adjust-step");
1077 var v = getprop("fdm/jsbsim/instrumentation/nvu/wind-"~which~"-svs");
1079 v = getprop("tu154/systems/nvu/wind-"~which~"-smooth");
1080 if (nvu_wind_adjust_sign > 0)
1081 v = math.ceil(v * 4 + 0.0625) / 4;
1083 v = math.floor(v * 4 + 0.0625) / 4;
1086 if (which == "speed") {
1093 setprop("fdm/jsbsim/instrumentation/nvu/wind-"~which~"-svs", v);
1095 nvu_wind_adjust_sign = sign;
1099 ######################################################################
1102 if( getprop( "tu154/switches/SVS-power" ) == 1.0 )
1103 electrical.AC3x200_bus_1L.add_output( "SVS", 10.0);
1104 else electrical.AC3x200_bus_1L.rm_output( "SVS" );
1107 setlistener("tu154/switches/SVS-power", svs_power, 0, 0);
1110 uvid15_power = func{
1111 if( getprop( "tu154/switches/UVID" ) == 1.0 )
1112 electrical.AC3x200_bus_1L.add_output( "UVID-15", 10.0);
1113 else electrical.AC3x200_bus_1L.rm_output( "UVID-15" );
1116 setlistener("tu154/switches/UVID", uvid15_power, 0, 0 );
1121 var skawk_handler = func{
1122 var digit_1 = getprop( "tu154/instrumentation/skawk/handle-1" );
1123 var digit_2 = getprop( "tu154/instrumentation/skawk/handle-2" );
1124 var digit_3 = getprop( "tu154/instrumentation/skawk/handle-3" );
1125 var digit_4 = getprop( "tu154/instrumentation/skawk/handle-4" );
1126 var mode_handle = getprop("tu154/instrumentation/skawk/handle-5" );
1129 if( mode_handle == 0 ) mode = 4; # A mode
1130 if( mode_handle == 2 ) mode = 5; # C mode
1131 if( mode_handle == 1 ) mode = 1; # Standby mode (B)
1132 if( mode_handle == 3 ) mode = 3; # Ground mode (D)
1134 setprop("instrumentation/transponder/inputs/knob-mode", mode );
1135 setprop("instrumentation/transponder/inputs/digit[3]", digit_1 );
1136 setprop("instrumentation/transponder/inputs/digit[2]", digit_2 );
1137 setprop("instrumentation/transponder/inputs/digit[1]", digit_3 );
1138 setprop("instrumentation/transponder/inputs/digit", digit_4 );
1141 # Load defaults at startup
1142 var skawk_init = func{
1143 setprop( "tu154/instrumentation/skawk/handle-1", getprop( "instrumentation/transponder/inputs/digit[3]" ) );
1144 setprop( "tu154/instrumentation/skawk/handle-2", getprop( "instrumentation/transponder/inputs/digit[2]" ) );
1145 setprop( "tu154/instrumentation/skawk/handle-3", getprop( "instrumentation/transponder/inputs/digit[1]" ) );
1146 setprop( "tu154/instrumentation/skawk/handle-4", getprop( "instrumentation/transponder/inputs/digit" ) );
1147 setprop( "tu154/instrumentation/skawk/handle-5", 1 );
1148 setprop( "instrumentation/transponder/inputs/knob-mode", 1 );
1150 setlistener("tu154/instrumentation/skawk/handle-1", skawk_handler,0,0 );
1151 setlistener("tu154/instrumentation/skawk/handle-2", skawk_handler,0,0 );
1152 setlistener("tu154/instrumentation/skawk/handle-3", skawk_handler,0,0 );
1153 setlistener("tu154/instrumentation/skawk/handle-4", skawk_handler,0,0 );
1154 setlistener("tu154/instrumentation/skawk/handle-5", skawk_handler,0,0 );
1157 # We use transponder for FG 2.10 and newest
1159 if( getprop( "instrumentation/transponder/inputs/digit" ) != nil ) skawk_init();
1165 settimer( bkk_handler, 0.5 );
1166 var param = getprop("tu154/instrumentation/bkk/serviceable");
1167 if( param == nil ) return;
1170 setprop("tu154/instrumentation/bkk/mgv-1-failure", 1.0);
1171 setprop("tu154/instrumentation/bkk/mgv-2-failure", 1.0);
1172 setprop("tu154/instrumentation/bkk/mgv-contr-failure", 1.0);
1174 var lamp_pwr = getprop("tu154/systems/electrical/buses/DC27-bus-L/volts");
1175 if( lamp_pwr == nil ) lamp_pwr = 0.0;
1176 if( lamp_pwr > 0 ) lamp_pwr = 1.0;
1177 setprop("tu154/systems/electrical/indicators/contr-gyro", lamp_pwr );
1178 setprop("tu154/systems/electrical/indicators/mgvk-failure", lamp_pwr);
1183 var mgv_1_pitch = getprop("instrumentation/attitude-indicator[0]/indicated-pitch-deg");
1184 if( mgv_1_pitch == nil ) return;
1185 var mgv_1_roll = getprop("instrumentation/attitude-indicator[0]/indicated-roll-deg");
1186 if( mgv_1_roll == nil ) return;
1187 var mgv_2_pitch = getprop("instrumentation/attitude-indicator[1]/indicated-pitch-deg");
1188 if( mgv_2_pitch == nil ) return;
1189 var mgv_2_roll = getprop("instrumentation/attitude-indicator[1]/indicated-roll-deg");
1190 if( mgv_2_roll == nil ) return;
1191 var mgv_c_pitch = getprop("instrumentation/attitude-indicator[2]/indicated-pitch-deg");
1192 if( mgv_c_pitch == nil ) return;
1193 var mgv_c_roll = getprop("instrumentation/attitude-indicator[2]/indicated-roll-deg");
1194 if( mgv_c_roll == nil ) return;
1195 var delta = getprop("tu154/instrumentation/bkk/delta-deg");
1198 if( delta < abs( mgv_1_pitch - mgv_c_pitch ) )
1199 setprop("tu154/instrumentation/bkk/mgv-1-failure", 1);
1200 if( delta < abs( mgv_1_roll - mgv_c_roll ) )
1201 setprop("tu154/instrumentation/bkk/mgv-1-failure", 1);
1204 if( delta < abs( mgv_2_pitch - mgv_c_pitch ) )
1205 setprop("tu154/instrumentation/bkk/mgv-2-failure", 1);
1206 if( delta < abs( mgv_2_roll - mgv_c_roll ) )
1207 setprop("tu154/instrumentation/bkk/mgv-2-failure", 1);
1210 if( getprop("tu154/instrumentation/bkk/mgv-1-failure" ) == 1 ){
1211 if( getprop("tu154/instrumentation/bkk/mgv-2-failure" ) == 1 )
1213 setprop("tu154/instrumentation/bkk/mgv-contr-failure", 1);
1214 setprop("tu154/systems/electrical/indicators/contr-gyro", 1);
1215 setprop("tu154/systems/electrical/indicators/mgvk-failure", 1);
1220 var ias = getprop( "instrumentation/airspeed-indicator/indicated-speed-kt" );
1221 if( ias == nil ) ias = 0.0;
1222 ias = ias * 1.852; # to kmh
1223 var alt = getprop( "instrumentation/altimeter/indicated-altitude-ft" );
1224 if( alt == nil ) alt = 0.0;
1225 alt = alt * 0.3048; # to m
1227 if( getprop( "tu154/switches/pn-5-posadk" ) == 1 ){
1228 if( alt >= 250.0 ) limit = 33.0;
1229 if( alt < 250.0 ) limit = 15.0;
1232 if( ias > 340.0 ) limit = 33.0;
1233 if( alt < 280.0 ) limit = 15.0;
1237 if( getprop("tu154/instrumentation/bkk/mgv-1-failure" == 0 ) ){
1238 if( abs( mgv_1_roll ) > limit ){
1239 if( mgv_1_roll < 0 ){
1240 setprop("tu154/systems/electrical/indicators/left-bank", 1); }
1241 else { setprop("tu154/systems/electrical/indicators/right-bank", 1); }
1243 if( abs( mgv_1_roll ) < limit ) {
1244 if( mgv_1_roll < 0 ){
1245 setprop("tu154/systems/electrical/indicators/left-bank", 0); }
1246 else { setprop("tu154/systems/electrical/indicators/right-bank", 0); }
1250 if( getprop("tu154/instrumentation/bkk/mgv-2-failure" ) == 0 )
1251 if( abs( mgv_2_roll ) > limit ){
1252 if( mgv_2_roll < 0 ){
1253 setprop("tu154/systems/electrical/indicators/left-bank", 1); }
1254 else { setprop("tu154/systems/electrical/indicators/right-bank", 1); }
1256 if( abs( mgv_1_roll ) < limit ) {
1257 if( mgv_2_roll < 0 ){
1258 setprop("tu154/systems/electrical/indicators/left-bank", 0); }
1259 else { setprop("tu154/systems/electrical/indicators/right-bank", 0); }
1268 var param = getprop("tu154/systems/mgv/one");
1269 if( param == nil ) return;
1270 param = param + 0.1;
1271 if( param >= 6.0 ) param = 6.0;
1272 setprop("tu154/systems/mgv/one", param);
1274 param = getprop("tu154/systems/mgv/two");
1275 if( param == nil ) return;
1276 param = param + 0.1;
1277 if( param >= 6.0 ) param = 6.0;
1278 setprop("tu154/systems/mgv/two", param);
1280 param = getprop("tu154/systems/mgv/contr");
1281 if( param == nil ) return;
1282 param = param + 0.1;
1283 if( param >= 6.0 ) param = 6.0;
1284 setprop("tu154/systems/mgv/contr", param);
1288 bkk_shutdown = func{
1291 # setprop( "instrumentation/attitude-indicator[0]/serviceable", 0 );
1292 setprop("tu154/systems/mgv/one", 0.0);
1293 #setprop( "instrumentation/attitude-indicator[0]/internal-pitch-deg",-rand()*30.0 );
1294 #setprop( "instrumentation/attitude-indicator[0]/internal-roll-deg", -rand()*15.0 );
1298 # setprop( "instrumentation/attitude-indicator[1]/serviceable", 0 );
1299 setprop("tu154/systems/mgv/two", 0.0);
1300 #setprop( "instrumentation/attitude-indicator[1]/internal-pitch-deg",-rand()*30.0 );
1301 #setprop( "instrumentation/attitude-indicator[1]/internal-roll-deg", -rand()*15.0 );
1305 setprop( "instrumentation/attitude-indicator[2]/serviceable", 0 );
1306 setprop("tu154/systems/mgv/contr", 0.0);
1307 #setprop( "instrumentation/attitude-indicator[2]/internal-pitch-deg",-rand()*30.0 );
1308 #setprop( "instrumentation/attitude-indicator[2]/internal-roll-deg", -rand()*15.0 );
1312 setprop( "instrumentation/attitude-indicator[3]/serviceable", 0 );
1313 #setprop( "instrumentation/attitude-indicator[3]/internal-pitch-deg",-rand()*30.0 );
1314 #setprop( "instrumentation/attitude-indicator[3]/internal-roll-deg", -rand()*15.0 );
1321 bkk_reset = func(i) {
1322 setprop("tu154/instrumentation/bkk/mgv-"~i~"-failure", 0);
1323 setprop("tu154/instrumentation/bkk/mgv-contr-failure", 0);
1324 setprop("tu154/systems/electrical/indicators/contr-gyro", 0);
1325 setprop("tu154/systems/electrical/indicators/mgvk-failure", 0);
1334 if( getprop( "tu154/switches/BKK-power" ) == 1.0 )
1335 electrical.AC3x200_bus_1L.add_output( "BKK", 25.0);
1336 else electrical.AC3x200_bus_1L.rm_output( "BKK" );
1339 setlistener("tu154/switches/BKK-power", bkk_power,0,0);
1343 if( getprop( "tu154/switches/AGR" ) == 1.0 )
1344 electrical.AC3x200_bus_1L.add_output( "AGR", 10.0);
1345 else electrical.AC3x200_bus_1L.rm_output( "AGR" );
1347 # MGV-1 power support
1349 if( getprop( "tu154/switches/PKP-left" ) == 1.0 )
1350 electrical.AC3x200_bus_1L.add_output( "MGV-1", 10.0);
1351 else electrical.AC3x200_bus_1L.rm_output( "MGV-1" );
1353 # MGV-2 power support
1355 if( getprop( "tu154/switches/PKP-right" ) == 1.0 )
1356 electrical.AC3x200_bus_3R.add_output( "MGV-2", 10.0);
1357 else electrical.AC3x200_bus_3R.rm_output( "MGV-2" );
1359 # MGV contr power support
1361 if( getprop( "tu154/switches/MGV-contr" ) == 1.0 )
1362 electrical.AC3x200_bus_3R.add_output( "MGV-contr", 10.0);
1363 else electrical.AC3x200_bus_3R.rm_output( "MGV-contr" );
1366 setlistener("tu154/switches/AGR", agr_power,0,0);
1367 setlistener("tu154/switches/PKP-left", mgv_1_power,0,0);
1368 setlistener("tu154/switches/PKP-right", mgv_2_power,0,0);
1369 setlistener("tu154/switches/MGV-contr", mgv_c_power,0,0);
1372 # ************************* TKS staff ***********************************
1374 # auto corrector for GA-3 and BGMK
1375 var tks_corr = func{
1376 var mk1 = getprop("fdm/jsbsim/instrumentation/km-5-1");
1377 if( mk1 == nil ) return;
1378 var mk2 = getprop("fdm/jsbsim/instrumentation/km-5-2");
1379 if( mk2 == nil ) return;
1380 help.tks(); # show help string
1381 if( getprop("tu154/switches/pu-11-gpk") == 1 ) { # GA-3 correction
1383 var gpk_1 = getprop("fdm/jsbsim/instrumentation/ga3-corrected-1");
1384 var gpk_2 = getprop("fdm/jsbsim/instrumentation/ga3-corrected-2");
1385 if( gpk_1 == nil ) return;
1386 if( gpk_2 == nil ) return;
1387 if( getprop("tu154/switches/pu-11-corr") == 0 ) # kontr
1389 if( getprop("instrumentation/heading-indicator[1]/serviceable" ) != 1 ) return;
1390 var delta = gpk_2 - mk2;
1391 if( abs( delta ) < 0.5 ) return; # not adjust small values
1392 if( delta > 360.0 ) delta = delta - 360.0; # bias control
1393 if( delta < 0.0 ) delta = delta + 360.0;
1394 if( delta > 180 ) delta = 0.5; else delta = -0.5;# find short way
1395 var offset = getprop("instrumentation/heading-indicator[1]/offset-deg");
1396 if( offset == nil ) return;
1397 setprop("instrumentation/heading-indicator[1]/offset-deg", offset+delta );
1401 if( getprop("instrumentation/heading-indicator[0]/serviceable" ) != 1 ) return;
1402 var delta = gpk_1 - mk1;
1403 if( abs( delta ) < 1.0 ) return; # not adjust small values
1404 if( delta > 360.0 ) delta = delta - 360.0; # bias control
1405 if( delta < 0.0 ) delta = delta + 360.0;
1406 if( delta > 180 ) delta = 0.5; else delta = -0.5;# find short way
1407 var offset = getprop("instrumentation/heading-indicator[0]/offset-deg");
1408 if( offset == nil ) return;
1409 setprop("instrumentation/heading-indicator[0]/offset-deg", offset+delta );
1412 } # end GA-3 correction
1413 if( getprop("tu154/switches/pu-11-gpk") == 0 ) { # BGMK correction
1415 if( getprop("tu154/switches/pu-11-corr") == 0 ) # BGMK-2
1417 setprop("fdm/jsbsim/instrumentation/bgmk-corrector-2",1);
1420 setprop("fdm/jsbsim/instrumentation/bgmk-corrector-1",1);
1422 } # end BGMK correction
1425 # manually adjust gyro heading - GA-3 only
1427 if( getprop("tu154/switches/pu-11-gpk") != 0 ) return;
1428 help.tks(); # show help string
1430 if( getprop("tu154/switches/pu-11-corr") == 0 ) # kontr
1432 if( getprop("instrumentation/heading-indicator[1]/serviceable" ) != 1 ) return;
1433 if( arg[0] == 1 ) # to right
1435 var offset = getprop("instrumentation/heading-indicator[1]/offset-deg");
1436 if( offset == nil ) return;
1437 setprop("instrumentation/heading-indicator[1]/offset-deg", offset+delta );
1441 var offset = getprop("instrumentation/heading-indicator[1]/offset-deg");
1442 if( offset == nil ) return;
1443 setprop("instrumentation/heading-indicator[1]/offset-deg", offset-delta );
1448 if( getprop("instrumentation/heading-indicator[0]/serviceable" ) != 1 ) return;
1449 if( arg[0] == 1 ) # to right
1451 var offset = getprop("instrumentation/heading-indicator[0]/offset-deg");
1452 if( offset == nil ) return;
1453 setprop("instrumentation/heading-indicator[0]/offset-deg", offset+delta );
1457 var offset = getprop("instrumentation/heading-indicator[0]/offset-deg");
1458 if( offset == nil ) return;
1459 setprop("instrumentation/heading-indicator[0]/offset-deg", offset-delta );
1469 if( getprop( "tu154/switches/TKC-power-1" ) == 1.0 )
1470 electrical.AC3x200_bus_1L.add_output( "GA3-1", 10.0);
1471 else electrical.AC3x200_bus_1L.rm_output( "GA3-1" );
1475 if( getprop( "tu154/switches/TKC-BGMK-1" ) == 1.0 )
1476 electrical.AC3x200_bus_1L.add_output( "BGMK-1", 10.0);
1477 else electrical.AC3x200_bus_1L.rm_output( "BGMK-1" );
1481 if( getprop( "tu154/switches/TKC-power-2" ) == 1.0 )
1482 electrical.AC3x200_bus_3R.add_output( "GA3-2", 10.0);
1483 else electrical.AC3x200_bus_3R.rm_output( "GA3-2" );
1487 if( getprop( "tu154/switches/TKC-BGMK-2" ) == 1.0 )
1488 electrical.AC3x200_bus_3R.add_output( "BGMK-2", 10.0);
1489 else electrical.AC3x200_bus_3R.rm_output( "BGMK-2" );
1493 setlistener( "tu154/switches/TKC-power-1", tks_power_1 ,0,0);
1494 setlistener( "tu154/switches/TKC-power-2", tks_power_2 ,0,0);
1495 setlistener( "tu154/switches/TKC-BGMK-1", tks_bgmk_1 ,0,0);
1496 setlistener( "tu154/switches/TKC-BGMK-2", tks_bgmk_2 ,0,0);
1499 # Azimuthal error for gyroscope
1501 var last_point = geo.Coord.new();
1502 var current_point = geo.Coord.new();
1505 last_point = geo.aircraft_position();
1506 current_point = last_point;
1507 setprop("/fdm/jsbsim/instrumentation/az-err", 0.0 );
1509 # Azimuth error handler
1510 var tks_az_handler = func{
1511 settimer(tks_az_handler, 60.0 );
1512 current_point = geo.aircraft_position();
1513 if( last_point.distance_to( current_point ) < 1000.0 ) return; # skip small distance
1515 az_err = getprop("/fdm/jsbsim/instrumentation/az-err" );
1516 var zipu = last_point.course_to( current_point );
1517 var ozipu = current_point.course_to( last_point );
1518 az_err += zipu - (ozipu - 180.0);
1519 if( az_err > 180.0 ) az_err -= 360.0;
1520 if( -180.0 > az_err ) az_err += 360.0;
1521 setprop("/fdm/jsbsim/instrumentation/az-err", az_err );
1522 last_point = current_point;
1525 settimer(tks_az_handler, 60.0 );
1528 # ************************* End TKS staff ***********************************
1530 # KURS-MP frequency support
1532 var kursmp_sync = func{
1533 var frequency = 0.0;
1535 if( arg[0] == 0 ) # proceed captain panel
1537 var freq_hi = getprop("tu154/instrumentation/kurs-mp-1/digit-f-hi");
1538 if( freq_hi == nil ) return;
1539 var freq_low = getprop("tu154/instrumentation/kurs-mp-1/digit-f-low");
1540 if( freq_low == nil ) return;
1541 frequency = freq_hi + freq_low/100.0;
1542 setprop("instrumentation/nav[0]/frequencies/selected-mhz", frequency );
1544 var hdg_ones = getprop("tu154/instrumentation/kurs-mp-1/digit-h-ones");
1545 if( hdg_ones == nil ) return;
1546 var hdg_dec = getprop("tu154/instrumentation/kurs-mp-1/digit-h-dec");
1547 if( hdg_dec == nil ) return;
1548 var hdg_hund = getprop("tu154/instrumentation/kurs-mp-1/digit-h-hund");
1549 if( hdg_hund == nil ) return;
1550 heading = hdg_hund * 100 + hdg_dec * 10 + hdg_ones;
1551 if( heading > 359.0 ) {
1553 setprop("tu154/instrumentation/kurs-mp-1/digit-h-hund", 0.0 );
1554 setprop("tu154/instrumentation/kurs-mp-1/digit-h-dec", 0.0 );
1555 setprop("tu154/instrumentation/kurs-mp-1/digit-h-ones", 0.0 );
1557 setprop("instrumentation/nav[0]/radials/selected-deg", heading );
1560 if( arg[0] == 1 ) # co-pilot
1562 var freq_hi = getprop("tu154/instrumentation/kurs-mp-2/digit-f-hi");
1563 if( freq_hi == nil ) return;
1564 var freq_low = getprop("tu154/instrumentation/kurs-mp-2/digit-f-low");
1565 if( freq_low == nil ) return;
1566 frequency = freq_hi + freq_low/100.0;
1567 setprop("instrumentation/nav[1]/frequencies/selected-mhz", frequency );
1569 var hdg_ones = getprop("tu154/instrumentation/kurs-mp-2/digit-h-ones");
1570 if( hdg_ones == nil ) return;
1571 var hdg_dec = getprop("tu154/instrumentation/kurs-mp-2/digit-h-dec");
1572 if( hdg_dec == nil ) return;
1573 var hdg_hund = getprop("tu154/instrumentation/kurs-mp-2/digit-h-hund");
1574 if( hdg_hund == nil ) return;
1575 heading = hdg_hund * 100 + hdg_dec * 10 + hdg_ones;
1576 if( heading > 359.0 ) {
1578 setprop("tu154/instrumentation/kurs-mp-2/digit-h-hund", 0.0 );
1579 setprop("tu154/instrumentation/kurs-mp-2/digit-h-dec", 0.0 );
1580 setprop("tu154/instrumentation/kurs-mp-2/digit-h-ones", 0.0 );
1582 setprop("instrumentation/nav[1]/radials/selected-deg", heading );
1586 # initialize KURS-MP frequencies & headings
1587 var kursmp_init = func{
1588 var freq = getprop("instrumentation/nav[0]/frequencies/selected-mhz");
1589 if( freq == nil ) { settimer( kursmp_init, 1.0 ); return; } # try until success
1590 setprop("tu154/instrumentation/kurs-mp-1/digit-f-hi", int(freq) );
1591 setprop("tu154/instrumentation/kurs-mp-1/digit-f-low", (freq - int(freq) ) * 100 );
1592 var hdg = getprop("instrumentation/nav[0]/radials/selected-deg");
1593 if( hdg == nil ) { settimer( kursmp_init, 1.0 ); return; }
1594 setprop("tu154/instrumentation/kurs-mp-1/digit-h-hund", int(hdg/100) );
1595 setprop("tu154/instrumentation/kurs-mp-1/digit-h-dec", int( (hdg/10.0)-int(hdg/100.0 )*10.0) );
1596 setprop("tu154/instrumentation/kurs-mp-1/digit-h-ones", int(hdg-int(hdg/10.0 )*10.0) );
1598 freq = getprop("instrumentation/nav[1]/frequencies/selected-mhz");
1599 if( freq == nil ) { settimer( kursmp_init, 1.0 ); return; } # try until success
1600 setprop("tu154/instrumentation/kurs-mp-2/digit-f-hi", int(freq) );
1601 setprop("tu154/instrumentation/kurs-mp-2/digit-f-low", (freq - int(freq) ) * 100 );
1602 hdg = getprop("instrumentation/nav[1]/radials/selected-deg");
1603 if( hdg == nil ) { settimer( kursmp_init, 1.0 ); return; }
1604 setprop("tu154/instrumentation/kurs-mp-2/digit-h-hund", int( hdg/100) );
1605 setprop("tu154/instrumentation/kurs-mp-2/digit-h-dec",int( ( hdg / 10.0 )-int( hdg / 100.0 ) * 10.0 ) );
1606 setprop("tu154/instrumentation/kurs-mp-2/digit-h-ones", int( hdg-int( hdg/10.0 )* 10.0 ) );
1610 var kursmp_watchdog_1 = func{
1611 #settimer( kursmp_watchdog_1, 0.5 );
1612 if( getprop("instrumentation/nav[0]/in-range" ) == 1 ) return;
1613 if( getprop("tu154/instrumentation/pn-5/gliss" ) == 1.0 ) absu.absu_reset();
1614 if( getprop("tu154/instrumentation/pn-5/az-1" ) == 1.0 ) absu.absu_reset();
1615 if( getprop("tu154/instrumentation/pn-5/zahod" ) == 1.0 ) absu.absu_reset();
1618 var kursmp_watchdog_2 = func{
1619 #settimer( kursmp_watchdog_2, 0.5 );
1620 if( getprop("instrumentation/nav[1]/in-range" ) == 1 ) return;
1621 if( getprop("tu154/instrumentation/pn-5/az-2" ) == 1.0 ) absu.absu_reset();
1624 setlistener( "instrumentation/nav[0]/in-range", kursmp_watchdog_1, 0,0 );
1625 setlistener( "instrumentation/nav[1]/in-range", kursmp_watchdog_2, 0,0 );
1627 var kursmp_power_1 = func{
1628 if( getprop( "tu154/switches/KURS-MP-1" ) == 1.0 )
1629 electrical.AC3x200_bus_1L.add_output( "KURS-MP-1", 20.0);
1630 else electrical.AC3x200_bus_1L.rm_output( "KURS-MP-1" );
1633 var kursmp_power_2 = func{
1634 if( getprop( "tu154/switches/KURS-MP-2" ) == 1.0 )
1635 electrical.AC3x200_bus_3R.add_output( "KURS-MP-2", 20.0);
1636 else electrical.AC3x200_bus_3R.rm_output( "KURS-MP-2" );
1639 setlistener( "tu154/switches/KURS-MP-1", kursmp_power_1 ,0,0);
1640 setlistener( "tu154/switches/KURS-MP-2", kursmp_power_2 ,0,0);
1641 #kursmp_watchdog_1();
1642 #kursmp_watchdog_2();
1645 # ******************************** end KURS-MP *******************************
1649 var rsbn_set_f_1 = func{
1650 var handle = getprop("tu154/instrumentation/rsbn/handle-1");
1651 if( handle == nil ) handle = 0.0;
1653 if( getprop("tu154/instrumentation/rsbn/mode") == 0)
1655 handle = handle + step;
1656 if( handle > 4.0 ) handle = 4.0;
1657 if( handle < 0.0 ) handle = 0.0;
1658 setprop("tu154/instrumentation/rsbn/handle-1", handle );
1663 handle = handle + step/2.5;
1664 if( handle > 4.0 ) handle = 4.0;
1665 if( handle < 0.0 ) handle = 0.0;
1666 setprop("tu154/instrumentation/rsbn/handle-1", handle );
1667 var freq = getprop("tu154/instrumentation/rsbn/frequency" );
1668 if( freq == nil ) freq = 108.0;
1669 var khz = freq - int( freq );
1670 setprop("tu154/instrumentation/rsbn/frequency", 108.0 + handle*2.5 + khz );
1671 setprop("instrumentation/nav[2]/frequencies/selected-mhz", 108.0 + handle*2.5 + khz );
1676 var rsbn_set_f_2 = func{
1677 var handle = getprop("tu154/instrumentation/rsbn/handle-2");
1678 if( handle == nil ) handle = 0.0;
1680 if( getprop("tu154/instrumentation/rsbn/mode") == 0)
1682 handle = handle + step;
1683 if( handle > 9.0 ) handle = 9.0;
1684 if( handle < 0.0 ) handle = 0.0;
1685 setprop("tu154/instrumentation/rsbn/handle-2", handle );
1690 handle = handle + step/20.0;
1691 if( handle > 9.0 ) handle = 9.0;
1692 if( handle < 0.0 ) handle = 0.0;
1693 var freq = getprop("tu154/instrumentation/rsbn/frequency" );
1694 if( freq == nil ) freq = 108.0;
1695 setprop("tu154/instrumentation/rsbn/handle-2", handle );
1696 setprop("tu154/instrumentation/rsbn/frequency", int(freq) + handle/10.0 );
1697 setprop("instrumentation/nav[2]/frequencies/selected-mhz", int(freq) + handle/10.0 );
1702 var rsbn_set_mode = func{
1705 setprop("tu154/instrumentation/rsbn/mode", 0 );
1706 var handle = getprop("tu154/instrumentation/rsbn/handle-1");
1707 if( handle == nil ) handle = 0.0;
1708 handle = int( handle );
1709 setprop("tu154/instrumentation/rsbn/handle-1", handle );
1710 handle = getprop("tu154/instrumentation/rsbn/handle-2");
1711 if( handle == nil ) handle = 0.0;
1712 handle = int( handle );
1713 setprop("tu154/instrumentation/rsbn/handle-2", handle );
1716 setprop("tu154/instrumentation/rsbn/mode", 1 );
1724 var rsbn_chan_to_f = func{
1725 var handle_1 = getprop("tu154/instrumentation/rsbn/handle-1");
1726 var handle_2 = getprop("tu154/instrumentation/rsbn/handle-2");
1727 if( handle_1 == nil ) handle_1 = 0.0;
1728 if( handle_2 == nil ) handle_2 = 0.0;
1730 var channel = handle_1 * 10 + handle_2;
1731 if( channel < 1.0 ) channel = 1.0;
1732 if( channel > 40.0 ) channel = 40.0;
1734 var freq = 959.95 + channel * 0.05;
1735 setprop("tu154/instrumentation/rsbn/frequency", freq );
1736 setprop("instrumentation/nav[2]/frequencies/selected-mhz", freq );
1740 var rsbn_power = func{
1743 if( getprop("instrumentation/nav[2]/powered") == 1 )
1747 electrical.AC3x200_bus_1L.add_output( "RSBN", 50.0);
1748 setprop("instrumentation/nav[2]/power-btn", 1 );
1749 setprop("instrumentation/dme[2]/serviceable", 1 );
1750 setprop("tu154/instrumentation/rsbn/serviceable", 1 );
1754 electrical.AC3x200_bus_1L.rm_output( "RSBN" );
1755 # setprop("instrumentation/nav[2]/serviceable", 0 );
1756 setprop("instrumentation/dme[2]/serviceable", 0 );
1757 setprop("instrumentation/nav[2]/power-btn", 0 );
1758 setprop("tu154/instrumentation/rsbn/serviceable", 0 );
1759 setprop("instrumentation/nav[2]/powered", 0 );
1763 var rsbn_pwr_watchdog = func{
1764 if( getprop("instrumentation/nav[2]/powered" ) != 1 ) # power off
1766 # setprop("instrumentation/nav[2]/serviceable", 0 );
1767 setprop("instrumentation/dme[2]/serviceable", 0 );
1768 setprop("instrumentation/nav[2]/power-btn", 0 );
1769 # setprop("tu154/systems/electrical/indicators/range-avton", 0 );
1770 # setprop("tu154/systems/electrical/indicators/azimuth-avton", 0 );
1771 setprop("tu154/instrumentation/rsbn/serviceable", 0 );
1775 if( getprop( "tu154/switches/RSBN-power" ) == 1.0 )
1777 setprop("instrumentation/nav[2]/power-btn", 1 );
1778 setprop("instrumentation/dme[2]/serviceable", 1 );
1779 setprop("tu154/instrumentation/rsbn/serviceable", 1 );
1783 if( getprop( "tu154/switches/RSBN-power" ) != 1.0 )
1785 setprop("tu154/instrumentation/rsbn/serviceable", 0 );
1786 setprop("instrumentation/nav[2]/power-btn", 0 );
1787 setprop("instrumentation/dme[2]/serviceable", 0 );
1792 setlistener("instrumentation/nav[2]/powered", rsbn_pwr_watchdog, 0,0 );
1798 ark_1_2_handler = func {
1799 var ones = getprop("tu154/instrumentation/ark-15[0]/digit-2-1");
1800 if( ones == nil ) ones = 0.0;
1801 var dec = getprop("tu154/instrumentation/ark-15[0]/digit-2-2");
1802 if( dec == nil ) dec = 0.0;
1803 var hund = getprop("tu154/instrumentation/ark-15[0]/digit-2-3");
1804 if( hund == nil ) hund = 0.0;
1805 var freq = hund * 100 + dec * 10 + ones;
1806 if( getprop("tu154/switches/adf-1-selector") == 1 )
1807 setprop("instrumentation/adf[0]/frequencies/selected-khz", freq );
1810 ark_1_1_handler = func {
1811 var ones = getprop("tu154/instrumentation/ark-15[0]/digit-1-1");
1812 if( ones == nil ) ones = 0.0;
1813 var dec = getprop("tu154/instrumentation/ark-15[0]/digit-1-2");
1814 if( dec == nil ) dec = 0.0;
1815 var hund = getprop("tu154/instrumentation/ark-15[0]/digit-1-3");
1816 if( hund == nil ) hund = 0.0;
1817 var freq = hund * 100 + dec * 10 + ones;
1818 if( getprop("tu154/switches/adf-1-selector") == 0 )
1819 setprop("instrumentation/adf[0]/frequencies/selected-khz", freq );
1822 ark_2_2_handler = func {
1823 var ones = getprop("tu154/instrumentation/ark-15[1]/digit-2-1");
1824 if( ones == nil ) ones = 0.0;
1825 var dec = getprop("tu154/instrumentation/ark-15[1]/digit-2-2");
1826 if( dec == nil ) dec = 0.0;
1827 var hund = getprop("tu154/instrumentation/ark-15[1]/digit-2-3");
1828 if( hund == nil ) hund = 0.0;
1829 var freq = hund * 100 + dec * 10 + ones;
1830 if( getprop("tu154/switches/adf-2-selector") == 1 )
1831 setprop("instrumentation/adf[1]/frequencies/selected-khz", freq );
1834 ark_2_1_handler = func {
1835 var ones = getprop("tu154/instrumentation/ark-15[1]/digit-1-1");
1836 if( ones == nil ) ones = 0.0;
1837 var dec = getprop("tu154/instrumentation/ark-15[1]/digit-1-2");
1838 if( dec == nil ) dec = 0.0;
1839 var hund = getprop("tu154/instrumentation/ark-15[1]/digit-1-3");
1840 if( hund == nil ) hund = 0.0;
1841 var freq = hund * 100 + dec * 10 + ones;
1842 if( getprop("tu154/switches/adf-2-selector") == 0 )
1843 setprop("instrumentation/adf[1]/frequencies/selected-khz", freq );
1848 if( getprop("tu154/instrumentation/ark-15[0]/powered") == 1 )
1850 if( getprop("tu154/switches/adf-power-1")==1 )
1852 electrical.AC3x200_bus_1L.add_output( "ARK-15-1", 20.0);
1853 setprop("instrumentation/adf[0]/serviceable", 1 );
1856 electrical.AC3x200_bus_1L.rm_output( "ARK-15-1" );
1857 setprop("instrumentation/adf[0]/serviceable", 0 );
1861 electrical.AC3x200_bus_1L.rm_output( "ARK-15-1" );
1862 setprop("instrumentation/adf[0]/serviceable", 0 );
1867 if( getprop("tu154/instrumentation/ark-15[1]/powered") == 1 )
1869 if( getprop("tu154/switches/adf-power-2")==1 )
1871 electrical.AC3x200_bus_3R.add_output( "ARK-15-2", 20.0);
1872 setprop("instrumentation/adf[1]/serviceable", 1 );
1875 electrical.AC3x200_bus_3R.rm_output( "ARK-15-2" );
1876 setprop("instrumentation/adf[1]/serviceable", 0 );
1880 electrical.AC3x200_bus_3R.rm_output( "ARK-15-2" );
1881 setprop("instrumentation/adf[1]/serviceable", 0 );
1887 # read selected and standby ADF frequencies and copy it to ARK
1889 var freq = getprop("instrumentation/adf[0]/frequencies/selected-khz");
1890 if( freq == nil ) freq = 0.0;
1891 setprop("tu154/instrumentation/ark-15[0]/digit-1-3",
1892 int( (freq/100.0) - int( freq/1000.0 )*10.0 ) );
1893 setprop("tu154/instrumentation/ark-15[0]/digit-1-2",
1894 int( (freq/10.0) - int( freq/100.0 )*10.0 ) );
1895 setprop("tu154/instrumentation/ark-15[0]/digit-1-1",
1896 int( freq - int( freq/10.0 )*10.0 ) );
1898 freq = getprop("instrumentation/adf[0]/frequencies/standby-khz");
1899 if( freq == nil ) freq = 0.0;
1900 setprop("tu154/instrumentation/ark-15[0]/digit-2-3",
1901 int( (freq/100.0) - int( freq/1000.0 )*10.0 ) );
1902 setprop("tu154/instrumentation/ark-15[0]/digit-2-2",
1903 int( (freq/10.0) - int( freq/100.0 )*10.0 ) );
1904 setprop("tu154/instrumentation/ark-15[0]/digit-2-1",
1905 int( freq - int( freq/10.0 )*10.0 ) );
1907 freq = getprop("instrumentation/adf[1]/frequencies/selected-khz");
1908 if( freq == nil ) freq = 0.0;
1909 setprop("tu154/instrumentation/ark-15[1]/digit-1-3",
1910 int( (freq/100.0) - int( freq/1000.0 )*10.0 ) );
1911 setprop("tu154/instrumentation/ark-15[1]/digit-1-2",
1912 int( (freq/10.0) - int( freq/100.0 )*10.0 ) );
1913 setprop("tu154/instrumentation/ark-15[1]/digit-1-1",
1914 int( freq - int( freq/10.0 )*10.0 ) );
1916 freq = getprop("instrumentation/adf[1]/frequencies/standby-khz");
1917 if( freq == nil ) freq = 0.0;
1918 setprop("tu154/instrumentation/ark-15[1]/digit-2-3",
1919 int( (freq/100.0) - int( freq/1000.0 )*10.0 ) );
1920 setprop("tu154/instrumentation/ark-15[1]/digit-2-2",
1921 int( (freq/10.0) - int( freq/100.0 )*10.0 ) );
1922 setprop("tu154/instrumentation/ark-15[1]/digit-2-1",
1923 int( freq - int( freq/10.0 )*10.0 ) );
1929 setlistener("tu154/switches/adf-power-1", ark_1_power ,0,0);
1930 setlistener("tu154/switches/adf-power-2", ark_2_power ,0,0);
1932 setlistener( "tu154/instrumentation/ark-15[0]/powered", ark_1_power ,0,0);
1933 setlistener( "tu154/instrumentation/ark-15[1]/powered", ark_2_power ,0,0);
1936 setlistener( "tu154/switches/adf-1-selector", ark_1_1_handler ,0,0);
1937 setlistener( "tu154/switches/adf-1-selector", ark_1_2_handler ,0,0);
1939 setlistener( "tu154/switches/adf-2-selector", ark_2_1_handler ,0,0);
1940 setlistener( "tu154/switches/adf-2-selector", ark_2_2_handler ,0,0);
1942 setlistener( "tu154/instrumentation/ark-15[0]/digit-1-1", ark_1_1_handler ,0,0);
1943 setlistener( "tu154/instrumentation/ark-15[0]/digit-1-2", ark_1_1_handler ,0,0);
1944 setlistener( "tu154/instrumentation/ark-15[0]/digit-1-3", ark_1_1_handler ,0,0);
1946 setlistener( "tu154/instrumentation/ark-15[0]/digit-2-1", ark_1_2_handler ,0,0);
1947 setlistener( "tu154/instrumentation/ark-15[0]/digit-2-2", ark_1_2_handler ,0,0);
1948 setlistener( "tu154/instrumentation/ark-15[0]/digit-2-3", ark_1_2_handler ,0,0);
1950 setlistener( "tu154/instrumentation/ark-15[1]/digit-1-1", ark_2_1_handler ,0,0);
1951 setlistener( "tu154/instrumentation/ark-15[1]/digit-1-2", ark_2_1_handler ,0,0);
1952 setlistener( "tu154/instrumentation/ark-15[1]/digit-1-3", ark_2_1_handler ,0,0);
1954 setlistener( "tu154/instrumentation/ark-15[1]/digit-2-1", ark_2_2_handler ,0,0);
1955 setlistener( "tu154/instrumentation/ark-15[1]/digit-2-2", ark_2_2_handler ,0,0);
1956 setlistener( "tu154/instrumentation/ark-15[1]/digit-2-3", ark_2_2_handler ,0,0);
1959 # AUASP (UAP-12) power support
1961 if( getprop("tu154/switches/AUASP")==1 )
1963 electrical.AC3x200_bus_1L.add_output( "AUASP", 10.0);
1964 setprop("tu154/instrumentation/uap-12/powered", 1 );
1967 electrical.AC3x200_bus_1L.rm_output( "AUASP" );
1968 setprop("tu154/instrumentation/uap-12/powered", 0 );
1971 setlistener("tu154/switches/AUASP", auasp_power, 0,0 );
1974 settimer(uap_handler, 0.0);
1975 if( getprop("tu154/instrumentation/uap-12/powered") == 0.0 ) return;
1976 var n_norm = getprop("fdm/jsbsim/instrumentation/n-norm");
1977 var n_max = getprop("tu154/instrumentation/uap-12/accelerate-max");
1978 var n_min = getprop("tu154/instrumentation/uap-12/accelerate-min");
1979 if( n_norm == nil ) n_norm = -1.0;
1980 if( n_max == nil ) n_max = -1.0;
1981 if( n_min == nil ) n_min = -1.0;
1982 if( n_norm >= n_max ) setprop("tu154/instrumentation/uap-12/accelerate-max", n_norm);
1983 if( n_norm <= n_min ) setprop("tu154/instrumentation/uap-12/accelerate-min", n_norm);
1990 if( getprop("tu154/switches/EUP")==1 )
1992 electrical.AC3x200_bus_1L.add_output( "EUP", 5.0);
1993 setprop("instrumentation/turn-indicator/serviceable", 1 );
1996 electrical.AC3x200_bus_1L.rm_output( "EUP" );
1997 setprop("instrumentation/turn-indicator/serviceable", 0 );
2000 setlistener("tu154/switches/EUP", eup_power, 0,0 );
2003 # electrical system update for PNK
2005 var update_electrical = func{
2006 var dc12 = getprop( "tu154/systems/electrical/buses/DC27-bus-L/volts" );
2007 if( dc12 == nil ) return;
2009 if( getprop( "tu154/switches/comm-power-1" ) == 1.0 )
2010 setprop("instrumentation/comm[0]/serviceable", 1 );
2011 else setprop("instrumentation/comm[0]/serviceable", 0 );
2013 if( getprop( "tu154/switches/comm-power-2" ) == 1.0 )
2014 setprop("instrumentation/comm[1]/serviceable", 1 );
2015 else setprop("instrumentation/comm[1]/serviceable", 0 );
2018 setprop("instrumentation/comm[0]/serviceable", 0 );
2019 setprop("instrumentation/comm[1]/serviceable", 0 );
2022 var ac200 = getprop( "tu154/systems/electrical/buses/AC3x200-bus-1L/volts" );
2023 if( ac200 == nil ) return; # system not ready yet
2025 { # 200 V 400 Hz Line 1 Power OK
2026 setprop("tu154/instrumentation/ark-15[0]/powered", 1 );
2027 setprop("instrumentation/dme[0]/serviceable",
2028 (getprop("tu154/switches/dme-1-power") == 1));
2029 setprop("instrumentation/nav[2]/powered", 1 );
2030 setprop("instrumentation/dme[2]/serviceable", 1 );
2031 setprop("tu154/systems/nvu/powered",
2032 (getprop("tu154/switches/v-51-power") ? 1 : 0));
2034 if( getprop( "tu154/switches/KURS-MP-1" ) == 1.0 )
2036 setprop("instrumentation/nav[0]/power-btn", 1 );
2037 setprop("instrumentation/nav[0]/serviceable", 1 );
2038 setprop("instrumentation/marker-beacon[0]/power-btn", 1 );
2039 setprop("instrumentation/marker-beacon[0]/serviceable", 1 );
2042 setprop("instrumentation/nav[0]/power-btn", 0 );
2043 setprop("instrumentation/nav[0]/serviceable", 0 );
2044 setprop("instrumentation/marker-beacon[0]/power-btn", 0 );
2045 setprop("instrumentation/marker-beacon[0]/serviceable", 0 );
2048 if( getprop( "tu154/switches/TKC-power-1" ) == 1.0 )
2049 setprop("instrumentation/heading-indicator[0]/serviceable", 1 );
2050 else setprop("instrumentation/heading-indicator[0]/serviceable", 0 );
2053 if( getprop( "tu154/switches/TKC-BGMK-1" ) == 1.0 )
2054 setprop("fdm/jsbsim/instrumentation/bgmk-failure-1", 0 );
2055 else setprop("fdm/jsbsim/instrumentation/bgmk-failure-1", 1 );
2057 if( getprop( "tu154/switches/BKK-power" ) == 1.0 )
2058 setprop("tu154/instrumentation/bkk/serviceable", 1 );
2059 else setprop("tu154/instrumentation/bkk/serviceable", 0 );
2062 if( getprop( "tu154/switches/DISS-power" ) == 1.0 )
2063 setprop("tu154/instrumentation/diss/powered", 1 );
2064 else setprop("tu154/instrumentation/diss/powered", 0 );
2067 if( getprop( "tu154/switches/SVS-power" ) == 1.0 )
2068 setprop("tu154/systems/svs/powered", 1 );
2069 else setprop("tu154/systems/svs/powered", 0 );
2072 if( getprop( "tu154/switches/UVID" ) == 1.0 )
2073 setprop("tu154/instrumentation/altimeter[1]/powered", 1 );
2074 else setprop("tu154/instrumentation/altimeter[1]/powered", 0 );
2077 if( getprop( "tu154/switches/AGR" ) == 1.0 )
2079 setprop("instrumentation/attitude-indicator[3]/serviceable", 1 );
2080 setprop("instrumentation/attitude-indicator[3]/caged-flag", 0 );
2083 setprop("instrumentation/attitude-indicator[3]/serviceable", 0 );
2084 setprop("instrumentation/attitude-indicator[3]/caged-flag", 1 );
2088 if( getprop( "tu154/switches/PKP-left" ) == 1.0 )
2089 setprop("instrumentation/attitude-indicator[0]/serviceable", 1 );
2090 else { bkk_shutdown(0); }
2092 if( getprop("tu154/switches/AUASP")==1 )
2093 setprop("tu154/instrumentation/uap-12/powered", 1 );
2094 else setprop("tu154/instrumentation/uap-12/powered", 0 );
2096 if( getprop("tu154/switches/EUP")==1 )
2097 setprop("instrumentation/turn-indicator/serviceable", 1 );
2098 else setprop("instrumentation/turn-indicator/serviceable", 0 );
2105 # turn off all consumers if bus has gone
2107 setprop("tu154/instrumentation/ark-15[0]/powered", 0 );
2108 setprop("instrumentation/dme[0]/serviceable", 0 );
2109 setprop("instrumentation/nav[2]/powered", 0 );
2110 setprop("instrumentation/dme[2]/serviceable", 0 );
2111 setprop("tu154/systems/nvu/powered", 0.0 );
2112 setprop("instrumentation/nav[0]/power-btn", 0 );
2113 setprop("instrumentation/nav[0]/serviceable", 0 );
2114 setprop("instrumentation/heading-indicator[0]/serviceable", 0 );
2115 setprop("fdm/jsbsim/instrumentation/bgmk-failure-1", 1 );
2116 setprop("tu154/instrumentation/bkk/serviceable", 0 );
2117 setprop("tu154/instrumentation/diss/powered", 0 );
2118 setprop("tu154/systems/svs/powered", 0 );
2119 setprop("tu154/instrumentation/altimeter[1]/powered", 0 );
2120 setprop("instrumentation/attitude-indicator[3]/caged-flag", 1 );
2121 setprop("tu154/instrumentation/uap-12/powered", 0 );
2122 setprop("instrumentation/turn-indicator/serviceable", 0 );
2123 setprop("instrumentation/marker-beacon[0]/power-btn", 0 );
2124 setprop("instrumentation/marker-beacon[0]/serviceable", 0 );
2130 ac200 = getprop( "tu154/systems/electrical/buses/AC3x200-bus-3L/volts" );
2131 if( ac200 == nil ) return; # system not ready yet
2133 { # 200 V 400 Hz Line 3 Power OK
2134 setprop("tu154/instrumentation/ark-15[1]/powered", 1 );
2135 setprop("instrumentation/dme[1]/serviceable",
2136 (getprop("tu154/switches/dme-2-power") == 1));
2138 if( getprop( "tu154/switches/KURS-MP-2" ) == 1.0 )
2140 setprop("instrumentation/nav[1]/power-btn", 1 );
2141 setprop("instrumentation/nav[1]/serviceable", 1 );
2144 setprop("instrumentation/nav[1]/power-btn", 0 );
2145 setprop("instrumentation/nav[1]/serviceable", 0 );
2148 if( getprop( "tu154/switches/TKC-power-2" ) == 1.0 )
2149 setprop("instrumentation/heading-indicator[1]/serviceable", 1 );
2150 else setprop("instrumentation/heading-indicator[1]/serviceable", 0 );
2153 if( getprop( "tu154/switches/TKC-BGMK-2" ) == 1.0 )
2154 setprop("fdm/jsbsim/instrumentation/bgmk-failure-2", 0 );
2155 else setprop("fdm/jsbsim/instrumentation/bgmk-failure-2", 1 );
2158 if( getprop( "tu154/switches/SAU-STU" ) == 1.0 )
2161 setprop("tu154/instrumentation/pn-6/serviceable", 1 );
2164 setprop("tu154/systems/absu/serviceable", 0 );
2165 setprop("tu154/instrumentation/pn-6/serviceable", 0 );
2168 if( getprop( "tu154/switches/PKP-right" ) == 1.0 )
2169 setprop("instrumentation/attitude-indicator[1]/serviceable", 1 );
2170 else { bkk_shutdown(1); }
2172 if( getprop( "tu154/switches/MGV-contr" ) == 1.0 )
2173 setprop("instrumentation/attitude-indicator[2]/serviceable", 1 );
2174 else { bkk_shutdown(2); }
2180 setprop("tu154/instrumentation/ark-15[1]/powered", 0 );
2181 setprop("instrumentation/dme[1]/serviceable", 0 );
2182 setprop("instrumentation/nav[1]/power-btn", 0 );
2183 setprop("instrumentation/nav[1]/serviceable", 0 );
2184 setprop("instrumentation/heading-indicator[1]/serviceable", 0 );
2185 setprop("fdm/jsbsim/instrumentation/bgmk-failure-2", 1 );
2186 setprop("tu154/systems/absu/serviceable", 0 );
2187 setprop("tu154/instrumentation/pn-6/serviceable", 0 );
2196 update_electrical();
2198 # It's shoul be at different place...
2199 # Gear animation support
2200 # for animation only
2201 gear_handler = func{
2202 settimer(gear_handler, 0.0);
2203 var rot = getprop("orientation/pitch-deg");
2204 if( rot == nil ) return;
2205 var offset = getprop("tu154/gear/offset");
2206 if( offset == nil ) offset = 0.0;
2207 var gain = getprop("tu154/gear/gain");
2208 if( gain == nil ) gain = 1.0;
2210 var pressure = getprop("gear/gear[1]/compression-norm");
2211 if( pressure == nil ) return;
2212 if( pressure < 0.1 )setprop("tu154/gear/rotation-left-deg", 8.5 );
2213 else setprop("tu154/gear/rotation-left-deg", rot );
2214 setprop("tu154/gear/compression-left-m", pressure*gain+offset );
2216 pressure = getprop("gear/gear[2]/compression-norm");
2217 if( pressure == nil ) return;
2218 if( pressure < 0.1 ) setprop("tu154/gear/rotation-right-deg", 8.5 );
2219 else setprop("tu154/gear/rotation-right-deg", rot );
2220 setprop("tu154/gear/compression-right-m", pressure*gain+offset );
2226 # Set random gyro deviation
2227 setprop("instrumentation/heading-indicator[0]/offset-deg", 359.0 * rand() );
2228 setprop("instrumentation/heading-indicator[1]/offset-deg", 359.0 * rand() );
2230 setprop("instrumentation/attitude-indicator[0]/internal-pitch-deg",
2231 -70 + 140 * rand());
2232 setprop("instrumentation/attitude-indicator[0]/internal-roll-deg",
2233 -70 + 140 * rand());
2234 setprop("instrumentation/attitude-indicator[1]/internal-pitch-deg",
2235 -70 + 140 * rand());
2236 setprop("instrumentation/attitude-indicator[1]/internal-roll-deg",
2237 -70 + 140 * rand());
2238 setprop("instrumentation/attitude-indicator[2]/internal-pitch-deg",
2239 -70 + 140 * rand());
2240 setprop("instrumentation/attitude-indicator[2]/internal-roll-deg",
2241 -70 + 140 * rand());
2243 #save sound volume and deny sound for startup
2245 var vol = getprop("/sim/sound/volume");
2246 setprop("tu154/volume", vol);
2247 setprop("/sim/sound/volume", 0.0);
2248 print("PNK started");