### # Not Yet Implemented: just draw a warnig box during 3 seconds var nyi = func (x) { gui.popupTip(x ~ ': not yet implemented', 3) } ### # print message in terminal var msg = func (str) { print('ZKV1000 >> ', str) } ### # print message in popup var msg_popup = func (str...) { gui.popupTip("ZKV1000\n" ~ str, 3) } ### # just do nothing var void = func { } ### # returns decimal part arg var frac = func (x) { return (x - int(x)) } ### # rounds regarding proximity # e.g.: # round(1540, 300) gives 1500 # round(2370, 400) gives 2400 var round = func (x, m = 1) { var v = x / m; if (frac(v) >= 0.5) v += 1; return (int(v) * m); } ### # rounds regarless proximity # e.g.: # round_bis(1540, 300) gives 1500 # round_bis(2370, 400) gives 2000 var round_bis = func (x, m) { var r = round(x, m); if (r > x) r -= m; return r; } var alt = vs = vs_abs = ias = tas = pitch = roll = agl = stall = rpm = 0; var getData = func { alt = math.abs(getprop('/instrumentation/altimeter/indicated-altitude-ft')); vs = getprop('/velocities/vertical-speed-fps') * 60; ias = getprop('/instrumentation/airspeed-indicator/indicated-speed-kt'); pitch = getprop('/orientation/pitch-deg'); roll = getprop('/orientation/pitch-deg'); agl = getprop('/position/altitude-agl-ft'); stall = getprop('/sim/alarms/stall-warning'); gear = getprop('/controls/gears/gear'); } ### # returns DMS coordinates # d is decimal longitude or latitude # c should be one of E, W, S or N # inspired from FG source: $FGSRC/src/Main/fg_props.cxx var DMS = func (d, c) { var deg = min = sec = 0.0; d = abs(d); deg = d + 0.05 / 3600; min = (deg - int(deg)) * 60; sec = (min - int(min)) * 60 - 0.049; return sprintf('%d %02d %04.1f %s', int(deg), int(min), abs(sec), c); } var timeUTC = func { setprop('/instrumentation/zkv1000/infos/time', sprintf('UTC %02i%02i%02i', getprop('/sim/time/utc/hour'), getprop('/sim/time/utc/minute'), getprop('/sim/time/utc/second'))); } var timeLCL = func { var utc_hour = getprop('/sim/time/utc/hour') + (getprop('/sim/time/local-offset') / 3600); if (utc_hour > 23) utc_hour -= 24; if (utc_hour < 0) utc_hour += 24; setprop('/instrumentation/zkv1000/infos/time', sprintf('LCL %02i%02i%02i', utc_hour, getprop('/sim/time/utc/minute'), getprop('/sim/time/utc/second'))); } var timeRL = func { setprop('/instrumentation/zkv1000/infos/time', sprintf('RL %02i%02i%02i', getprop('/sim/time/real/hour'), getprop('/sim/time/real/minute'), getprop('/sim/time/real/second'))); } # returns time + d (is seconds) formated HH:MM:SS var HMS = func (hh, mm, ss, d = 0) { ss += d; if (ss > 59) { ss -= 60; mm += 1; if (mm > 59) { mm = 0; hh += 1; } } elsif (ss < 0) { if (mm > 0) { ss += 60; mm -= 1; } elsif (mm == 0 and hh > 0) { ss += 60; mm = 59; hh -= 1; } elsif (mm == 0 and hh == 0) ss = 0; } return sprintf('%02i:%02i:%02i', hh, mm, ss); } ### # Loads a fligtplan (route) from a XML file # replaces existing route by the new one var loadFPLfromFile = func (file) { afcs.getNode('route').removeChildren(); fgcommand('loadxml', props.Node.new({ 'filename': file, 'targetnode': afcs.getNode('route').getPath()}) ); FPLtoRouteManager(); msg('route loaded from ' ~ file); } var wipeRoute = func { var command = props.globals.getNode('/instrumentation/gps/command'); var v = getprop('/autopilot/route-manager/route/num'); setprop('/autopilot/route-manager/active', 0); setprop('/instrumentation/gps/scratch/index', 0); while (v) { v -= 1; command.setValue('route-delete'); } } var FPLtoRouteManager = func { wipeRoute(); lockSearches(); var scratch = props.globals.getNode('/instrumentation/gps/scratch'); var command = scratch.getNode('../command'); foreach (var waypoint; afcs.getNode('route').getChildren()) { scratch.getNode('index').setIntValue(-1); searchNearestNavaid(waypoint.getNode('type').getValue(), 1, waypoint.getPath()); command.setValue('route-insert-after'); } unlockSearches(); } #### # Search nav facilities var searchNearestNavaid = func (type, quantity = 1, path = nil) { getprop('/instrumentation/zkv1000/searches-locked') or return; scratch = props.globals.getNode('/instrumentation/gps/scratch/'); scratch.getNode('max-results', 1).setIntValue(quantity); var lat = lon = -9999; if (path != nil) { if (props.globals.getNode(path) != nil) { lon = getprop(path ~ '/longitude-deg'); lat = getprop(path ~ '/latitude-deg'); } } scratch.getNode('longitude-deg', 1).setDoubleValue(lon); scratch.getNode('latitude-deg', 1).setDoubleValue(lat); scratch.getNode('type').setValue(type); setprop('/instrumentation/gps/command', 'nearest'); } var lockSearches = func (v = 1) { props.globals.getNode('/instrumentation/zkv1000/searches-locked', 1).setBoolValue(v); } var unlockSearches = func { lockSearches(0); } #var dialog = func { # var d = gui.Widget.new(); # d.set({'name': 'ZKV1000 text entry interface', # 'layout': 'vbox', # 'default-padding' : 0}); # d.addChild('text'). #} var computeAltitudeDiff = void; var computeAirspeedDiff = void; var FLCcomputation = void; var checkRollAcquisition = void; var checkPitchAcquisition = void; var checkTrafficProximity = void; var manageLandingGears = void; var checkAbnormalAttitude = void; var applyFilter = void;