2016-11-05 03:39:28 +00:00
|
|
|
##########################################################################
|
|
|
|
# GPWS nasal wrapper
|
|
|
|
# 2010, Thorsten Brehm
|
|
|
|
#
|
|
|
|
# For more documentation see http://wiki.flightgear.org/index.php/GPWS
|
|
|
|
##########################################################################
|
|
|
|
|
|
|
|
##########################################################################
|
|
|
|
# Configuration settings
|
|
|
|
##########################################################################
|
|
|
|
# Minimum landing flap position
|
2017-02-23 11:27:44 +00:00
|
|
|
# A320 normal flaps for landing full
|
|
|
|
var gpws_min_landing_flaps = 0.1;
|
2016-11-05 03:39:28 +00:00
|
|
|
|
|
|
|
##############################################
|
|
|
|
# GPWS specific class
|
|
|
|
# ie: var Gpws = GPWS.new("instrumentation/mk-viii");
|
|
|
|
##############################################
|
|
|
|
var GPWS =
|
|
|
|
{
|
|
|
|
new : func(prop1)
|
|
|
|
{
|
|
|
|
m = { parents : [GPWS]};
|
|
|
|
|
|
|
|
m.gpws = props.globals.getNode(prop1);
|
|
|
|
m.self_test = m.gpws.getNode("inputs/discretes/self-test");
|
2017-02-23 11:27:44 +00:00
|
|
|
m.flap_override = m.gpws.getNode("inputs/discretes/momentary-flap-override"); #allows flap 3 ldg if overhead switch is enabled
|
2016-11-05 03:39:28 +00:00
|
|
|
m.gs_inhibit = m.gpws.getNode("inputs/discretes/glideslope-inhibit");
|
|
|
|
m.gpws_inhibit = m.gpws.getNode("inputs/discretes/gpws-inhibit");
|
|
|
|
m.terrain_inhibit = m.gpws.getNode("inputs/discretes/ta-tcf-inhibit");
|
|
|
|
m.landing_gear = m.gpws.getNode("inputs/discretes/landing-gear");
|
|
|
|
m.landing_flaps = m.gpws.getNode("inputs/discretes/landing-flaps");
|
|
|
|
|
|
|
|
# mk-viii doesn't provide gear-override input. Emulate it...
|
|
|
|
m.gear_override = m.gpws.initNode("inputs/discretes/gear-override",0,"BOOL");
|
|
|
|
|
|
|
|
m.last_gear_state = 0;
|
|
|
|
|
|
|
|
# add listener to gear
|
|
|
|
setlistener("controls/gear/gear-down", func { Gpws.update_gear_state() } );
|
|
|
|
|
2017-02-23 11:27:44 +00:00
|
|
|
# GPWS provides two TCWs (Time Critical Warnings) to the PFD: not enabled for A320
|
2016-11-05 03:39:28 +00:00
|
|
|
# "PULL UP" and "WINDSHEAR" alerts (windshears not supported here...)
|
|
|
|
m.tcw_out = m.gpws.initNode("outputs/warning","","STRING");
|
|
|
|
m.tcw_out.setValue("");
|
|
|
|
m.logic_discretes = m.gpws.getNode("outputs/arinc429/egpwc-logic-discretes");
|
|
|
|
settimer(gpws_input_feeder,0);
|
|
|
|
|
|
|
|
return m;
|
|
|
|
},
|
|
|
|
|
2017-02-23 11:27:44 +00:00
|
|
|
#### self-test buttons ####
|
|
|
|
# above ND dimmer on A320, currently not modelled. NOT GPWS switches on OHP
|
2016-11-05 03:39:28 +00:00
|
|
|
clicked_selftest : func
|
|
|
|
{
|
|
|
|
if (!me.self_test.getBoolValue())
|
|
|
|
{
|
|
|
|
# simulate a long button press (>> 5 seconds)
|
|
|
|
me.self_test.setBoolValue(1);
|
|
|
|
settimer(func { Gpws.release_selftest_button() },9);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
# clicked again => release button early...
|
|
|
|
me.release_selftest_button();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
press_selftest_button : func
|
|
|
|
{
|
|
|
|
me.self_test.setBoolValue(1);
|
|
|
|
},
|
|
|
|
release_selftest_button : func
|
|
|
|
{
|
|
|
|
me.self_test.setBoolValue(0);
|
|
|
|
},
|
|
|
|
|
|
|
|
#### flap-override button ####
|
2017-02-23 11:27:44 +00:00
|
|
|
# allow FLAP 3 ldg
|
2016-11-05 03:39:28 +00:00
|
|
|
clicked_flap_override : func
|
|
|
|
{
|
|
|
|
if (!me.flap_override.getBoolValue())
|
|
|
|
{
|
|
|
|
# simulate a short button press
|
|
|
|
me.flap_override.setBoolValue(1);
|
|
|
|
settimer(func {Gpws.release_button_flap_override() },0.5);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
release_button_flap_override : func
|
|
|
|
{
|
|
|
|
me.flap_override.setBoolValue(0);
|
|
|
|
},
|
|
|
|
|
|
|
|
#### gear-override button ####
|
|
|
|
clicked_gear_override : func
|
|
|
|
{
|
|
|
|
# toggle
|
|
|
|
me.gear_override.setBoolValue(!me.gear_override.getBoolValue());
|
|
|
|
me.update_gear_state();
|
|
|
|
},
|
|
|
|
|
|
|
|
#### glide-slope button ####
|
|
|
|
clicked_gs_override : func
|
|
|
|
{
|
|
|
|
# toggle g/s inhibit.
|
|
|
|
me.gs_inhibit.setBoolValue(!me.gs_inhibit.getBoolValue());
|
|
|
|
},
|
|
|
|
disable_gs_override : func
|
|
|
|
{
|
|
|
|
me.gs_inhibit.setBoolValue(0);
|
|
|
|
},
|
|
|
|
|
|
|
|
#### gpws inhibit button ####
|
|
|
|
clicked_gpws_inhibit : func
|
|
|
|
{
|
|
|
|
# toggle
|
|
|
|
me.gpws_inhibit.setBoolValue(!me.gpws_inhibit.getBoolValue());
|
|
|
|
},
|
|
|
|
|
|
|
|
#### terrain inhibit button ####
|
|
|
|
clicked_terrain_inhibit : func
|
|
|
|
{
|
|
|
|
# toggle
|
|
|
|
me.terrain_inhibit.setBoolValue(!me.terrain_inhibit.getBoolValue());
|
|
|
|
},
|
|
|
|
|
|
|
|
#### decode alerts to time critical warnings ####
|
|
|
|
tcw_feeder : func
|
|
|
|
{
|
|
|
|
var tcwmsg="";
|
|
|
|
var alerts = me.logic_discretes.getValue();
|
|
|
|
if (gpws_test_bit(alerts,0x100000)) # bit 20="MODE1_PULL_UP"
|
|
|
|
tcwmsg="PULL UP";
|
|
|
|
me.tcw_out.setValue(tcwmsg);
|
|
|
|
},
|
|
|
|
|
|
|
|
#### custom input feeders ####
|
|
|
|
update_gear_state : func()
|
|
|
|
{
|
|
|
|
# Simulate gear override button using a custom landing gear feeder.
|
|
|
|
# Default mk-viii gear feeder is disabled in <plane>-set.xml
|
|
|
|
var gear_state = getprop("controls/gear/gear-down");
|
|
|
|
|
|
|
|
me.landing_gear.setBoolValue(gear_state or me.gear_override.getBoolValue());
|
|
|
|
|
|
|
|
if ((me.last_gear_state)and(!gear_state))
|
|
|
|
{
|
|
|
|
# g/s override is cancelled when retracting landing gear...
|
|
|
|
me.disable_gs_override();
|
|
|
|
}
|
|
|
|
me.last_gear_state = gear_state;
|
|
|
|
},
|
|
|
|
update_flap_state : func()
|
|
|
|
{
|
|
|
|
# Feeder to configure custom "minimum landing flap position".
|
|
|
|
# Default mk-viii flap feeder is disabled in <plane>-set.xml
|
|
|
|
var flap_position = getprop("controls/flight/flaps");
|
|
|
|
|
|
|
|
me.landing_flaps.setBoolValue(flap_position < gpws_min_landing_flaps);
|
|
|
|
},
|
|
|
|
update_height : func()
|
|
|
|
{
|
|
|
|
radio_alt = getprop("position/gear-agl-ft");
|
|
|
|
# "glide-slope warning inhibited" is disabled below 50 feet
|
|
|
|
if ((radio_alt < 50.0)or(radio_alt > 1000.0))
|
|
|
|
me.disable_gs_override();
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
##############################################
|
|
|
|
# helper
|
|
|
|
##############################################
|
|
|
|
var gpws_test_bit = func(value,bitValue)
|
|
|
|
{
|
|
|
|
if (bitValue>1) value=int(value/bitValue);
|
|
|
|
# test if LSB set
|
|
|
|
return (value!=int(value/2)*2);
|
|
|
|
}
|
|
|
|
|
|
|
|
##############################################
|
|
|
|
# timer callbacks
|
|
|
|
##############################################
|
|
|
|
var gpws_input_feeder = func
|
|
|
|
{
|
|
|
|
Gpws.tcw_feeder();
|
|
|
|
Gpws.update_flap_state();
|
|
|
|
Gpws.update_height();
|
|
|
|
settimer(gpws_input_feeder,0.3);
|
|
|
|
}
|
|
|
|
|
|
|
|
##############################################
|
|
|
|
# main
|
|
|
|
##############################################
|
|
|
|
var Gpws = GPWS.new("instrumentation/mk-viii");
|
|
|
|
|