57 static const unsigned n_altitude_callouts = 12;
72 : _value(0), ncd(
true) {}
74 inline T get ()
const { assert(! ncd);
return _value; }
75 inline T *get_pointer () {
return &_value; }
76 inline void set (T value) { ncd =
false; _value = value; }
77 inline void unset () { ncd =
true; }
79 inline void set (
const Parameter<T> *parameter)
84 set(parameter->get());
87 inline void set (
const Parameter<double> *parameter,
double factor)
92 set(parameter->get() * factor);
107 inline Sample (T _value)
108 : timestamp(
globals->get_sim_time_sec()), value(_value) {}
123 : start_time(0.0), running(
false) {}
125 inline void start () { running =
true; start_time =
globals->get_sim_time_sec(); }
126 inline void stop () { running =
false; }
127 inline double elapsed ()
const { assert(running);
return globals->get_sim_time_sec() - start_time; }
128 inline double start_or_elapsed ()
151 SGPropertyNode_ptr ai_caged;
152 SGPropertyNode_ptr ai_roll;
153 SGPropertyNode_ptr ai_serviceable;
154 SGPropertyNode_ptr altimeter_altitude;
155 SGPropertyNode_ptr altimeter_serviceable;
157 SGPropertyNode_ptr altitude_agl;
158 SGPropertyNode_ptr altitude_gear_agl;
159 SGPropertyNode_ptr altitude_radar_agl;
160 SGPropertyNode_ptr orientation_roll;
161 SGPropertyNode_ptr asi_serviceable;
162 SGPropertyNode_ptr asi_speed;
163 SGPropertyNode_ptr autopilot_heading_lock;
164 SGPropertyNode_ptr flaps;
165 SGPropertyNode_ptr gear_down;
169 SGPropertyNode_ptr nav0_cdi_serviceable;
170 SGPropertyNode_ptr nav0_gs_distance;
171 SGPropertyNode_ptr nav0_gs_needle_deflection;
172 SGPropertyNode_ptr nav0_gs_serviceable;
173 SGPropertyNode_ptr nav0_has_gs;
174 SGPropertyNode_ptr nav0_heading_needle_deflection;
175 SGPropertyNode_ptr nav0_in_range;
176 SGPropertyNode_ptr nav0_nav_loc;
177 SGPropertyNode_ptr nav0_serviceable;
178 SGPropertyNode_ptr power;
179 SGPropertyNode_ptr replay_state;
180 SGPropertyNode_ptr vs;
181 } external_properties;
183 inline PropertiesHandler (
MK_VIII *device)
206 Timer power_loss_timer;
207 Timer abnormal_timer;
208 Timer low_surge_timer;
209 Timer high_surge_timer;
210 Timer very_high_surge_timer;
212 bool handle_abnormal_voltage (
bool abnormal,
214 double max_duration);
220 inline PowerHandler (
MK_VIII *device)
221 : mk(device), serviceable(
false), powered(
false) {}
223 void bind (SGPropertyNode *node);
238 int last_replay_state;
239 Timer reposition_timer;
252 inline SystemHandler (
MK_VIII *device)
253 : mk(device), boot_delay(0.0), last_replay_state(0), state(STATE_OFF) {}
264 class ConfigurationModule
270 CATEGORY_AIRCRAFT_MODE_TYPE_SELECT,
271 CATEGORY_AIR_DATA_INPUT_SELECT,
272 CATEGORY_POSITION_INPUT_SELECT,
273 CATEGORY_ALTITUDE_CALLOUTS,
274 CATEGORY_AUDIO_MENU_SELECT,
275 CATEGORY_TERRAIN_DISPLAY_SELECT,
276 CATEGORY_OPTIONS_SELECT_GROUP_1,
277 CATEGORY_RADIO_ALTITUDE_INPUT_SELECT,
278 CATEGORY_NAVIGATION_INPUT_SELECT,
279 CATEGORY_ATTITUDE_INPUT_SELECT,
280 CATEGORY_HEADING_INPUT_SELECT,
281 CATEGORY_WINDSHEAR_INPUT_SELECT,
282 CATEGORY_INPUT_OUTPUT_DISCRETE_TYPE_SELECT,
283 CATEGORY_AUDIO_OUTPUT_LEVEL,
284 CATEGORY_UNDEFINED_INPUT_SELECT_1,
285 CATEGORY_UNDEFINED_INPUT_SELECT_2,
286 CATEGORY_UNDEFINED_INPUT_SELECT_3,
293 STATE_INVALID_DATABASE,
294 STATE_INVALID_AIRCRAFT_TYPE
299 int effective_categories[N_CATEGORIES];
301 ConfigurationModule (
MK_VIII *device);
304 void bind (SGPropertyNode *node);
309 int categories[N_CATEGORIES];
311 bool read_aircraft_mode_type_select (
int value);
312 bool read_air_data_input_select (
int value);
313 bool read_position_input_select (
int value);
314 bool read_altitude_callouts (
int value);
315 bool read_audio_menu_select (
int value);
316 bool read_terrain_display_select (
int value);
317 bool read_options_select_group_1 (
int value);
318 bool read_radio_altitude_input_select (
int value);
319 bool read_navigation_input_select (
int value);
320 bool read_attitude_input_select (
int value);
321 bool read_heading_input_select (
int value);
322 bool read_windshear_input_select (
int value);
323 bool read_input_output_discrete_type_select (
int value);
324 bool read_audio_output_level (
int value);
325 bool read_undefined_input_select (
int value);
327 static bool m6_t2_is_bank_angle (Parameter<double> *agl,
330 static bool m6_t4_is_bank_angle (Parameter<double> *agl,
349 static const unsigned int fault_inops[];
351 bool has_faults (
unsigned int inop);
358 FAULT_ALL_MODES_INHIBIT,
361 FAULT_MOMENTARY_FLAP_OVERRIDE_INVALID,
362 FAULT_SELF_TEST_INVALID,
363 FAULT_GLIDESLOPE_CANCEL_INVALID,
364 FAULT_STEEP_APPROACH_INVALID,
366 FAULT_TA_TCF_INHIBIT,
367 FAULT_MODES14_INPUTS_INVALID,
368 FAULT_MODE5_INPUTS_INVALID,
369 FAULT_MODE6_INPUTS_INVALID,
370 FAULT_BANK_ANGLE_INPUTS_INVALID,
371 FAULT_TCF_INPUTS_INVALID,
377 inline FaultHandler(
MK_VIII *device) :
378 mk(device), faults(0) {
383 void set_fault(Fault fault);
384 void unset_fault(Fault fault);
386 bool has_faults()
const;
569 void bind (SGPropertyNode *node);
579 class TerrainClearanceFilter
581 typedef std::deque< Sample<double> > samples_type;
582 samples_type samples;
587 inline TerrainClearanceFilter ()
588 : value(0.0), last_update(-1.0) {}
590 double update (
double agl);
598 TerrainClearanceFilter terrain_clearance_filter;
603 Timer audio_inhibit_fault_timer;
604 Timer landing_gear_fault_timer;
605 Timer flaps_down_fault_timer;
606 Timer momentary_flap_override_fault_timer;
607 Timer self_test_fault_timer;
608 Timer glideslope_cancel_fault_timer;
609 Timer steep_approach_fault_timer;
610 Timer gpws_inhibit_fault_timer;
611 Timer ta_tcf_inhibit_fault_timer;
613 bool last_landing_gear;
614 bool last_real_flaps_down;
616 typedef std::deque< Sample< Parameter<double> > > altitude_samples_type;
617 altitude_samples_type altitude_samples;
624 void update_terrain_clearance ();
625 void reset_terrain_clearance ();
627 void handle_input_fault (
bool test, FaultHandler::Fault fault);
628 void handle_input_fault (
bool test,
631 FaultHandler::Fault fault);
633 void tie_input (SGPropertyNode *node,
637 void tie_input (SGPropertyNode *node,
639 Parameter<double> *input,
641 void tie_output (SGPropertyNode *node,
644 void tie_output (SGPropertyNode *node,
715 class SelfTestHandler
728 ACTION_SLEEP = 1 << 0,
729 ACTION_VOICE = 1 << 1,
730 ACTION_DISCRETE_ON_OFF = 1 << 2,
737 double sleep_duration;
745 double button_press_timestamp;
746 IOHandler::Outputs saved_outputs;
749 bool _was_here (
int position);
751 Action sleep (
double duration);
752 Action play (VoicePlayer::Voice *voice);
753 Action discrete_on (
bool *discrete,
double duration);
754 Action discrete_on_off (
bool *discrete,
double duration);
755 Action discrete_on_off (
bool *discrete, VoicePlayer::Voice *voice);
774 inline SelfTestHandler (
MK_VIII *device)
775 : mk(device), button_pressed(false), state(STATE_NONE) {}
777 inline void power_off () { stop(); }
778 inline void set_inop () { stop(); }
779 void handle_button_event (
bool value);
791 unsigned int old_alerts;
792 unsigned int voice_alerts;
793 unsigned int repeated_alerts;
794 VoicePlayer::Voice *altitude_callout_voice;
797 inline bool has_alerts (
unsigned int test)
const {
return (alerts & test) != 0; }
798 inline bool has_old_alerts (
unsigned int test)
const {
return (old_alerts & test) != 0; }
799 inline bool must_play_voice (
unsigned int test)
const {
return ! has_old_alerts(test) || (repeated_alerts & test) != 0; }
800 bool select_voice_alerts (
unsigned int test);
805 ALERT_MODE1_PULL_UP = 1 << 0,
806 ALERT_MODE1_SINK_RATE = 1 << 1,
808 ALERT_MODE2A_PREFACE = 1 << 2,
809 ALERT_MODE2B_PREFACE = 1 << 3,
810 ALERT_MODE2A = 1 << 4,
811 ALERT_MODE2B = 1 << 5,
812 ALERT_MODE2B_LANDING_MODE = 1 << 6,
813 ALERT_MODE2A_ALTITUDE_GAIN = 1 << 7,
814 ALERT_MODE2A_ALTITUDE_GAIN_TERRAIN_CLOSING = 1 << 8,
816 ALERT_MODE3 = 1 << 9,
818 ALERT_MODE4_TOO_LOW_FLAPS = 1 << 10,
819 ALERT_MODE4_TOO_LOW_GEAR = 1 << 11,
820 ALERT_MODE4AB_TOO_LOW_TERRAIN = 1 << 12,
821 ALERT_MODE4C_TOO_LOW_TERRAIN = 1 << 13,
823 ALERT_MODE5_SOFT = 1 << 14,
824 ALERT_MODE5_HARD = 1 << 15,
826 ALERT_MODE6_MINIMUMS = 1 << 16,
828 ALERT_MODE6_ALTITUDE_CALLOUT = 1 << 17,
829 ALERT_MODE6_LOW_BANK_ANGLE_1 = 1 << 18,
830 ALERT_MODE6_HIGH_BANK_ANGLE_1 = 1 << 19,
831 ALERT_MODE6_LOW_BANK_ANGLE_2 = 1 << 20,
832 ALERT_MODE6_HIGH_BANK_ANGLE_2 = 1 << 21,
833 ALERT_MODE6_LOW_BANK_ANGLE_3 = 1 << 22,
834 ALERT_MODE6_HIGH_BANK_ANGLE_3 = 1 << 23,
836 ALERT_TCF_TOO_LOW_TERRAIN = 1 << 24,
838 ALERT_MODE6_MINIMUMS_100 = 1 << 28,
839 ALERT_MODE6_RETARD = 1 << 29,
844 ALERT_FLAG_REPEAT = 1 << 0
849 inline AlertHandler (
MK_VIII *device)
856 void set_alerts (
unsigned int _alerts,
857 unsigned int flags = 0,
858 VoicePlayer::Voice *_altitude_callout_voice = NULL);
859 void unset_alerts (
unsigned int _alerts);
861 inline void repeat_alert (
unsigned int alert) { set_alerts(alert, ALERT_FLAG_REPEAT); }
862 inline void set_altitude_callout_alert (VoicePlayer::Voice *voice) { set_alerts(ALERT_MODE6_ALTITUDE_CALLOUT, 0, voice); }
873 Timer potentially_airborne_timer;
875 void update_ground ();
876 void enter_ground ();
877 void leave_ground ();
879 void update_takeoff ();
880 void enter_takeoff ();
881 void leave_takeoff ();
887 inline StateHandler (
MK_VIII *device)
888 : mk(device), ground(true), takeoff(true) {}
890 void post_reposition ();
903 Timer sink_rate_timer;
905 double sink_rate_tti;
907 double get_pull_up_bias ();
910 double get_sink_rate_bias ();
911 bool is_sink_rate ();
912 double get_sink_rate_tti ();
914 void update_pull_up ();
915 void update_sink_rate ();
933 inline Mode1Handler (
MK_VIII *device)
934 : mk(device), sink_rate_tti(0.0) {}
950 class ClosureRateFilter
966 inline PassFilter (
double _a0,
double _a1,
double _b1)
967 : a0(_a0), a1(_a1), b1(_b1), last_input(0.0), last_output(0.0) {}
969 inline double filter (
double input)
971 last_output = a0 * input + a1 * last_input + b1 * last_output;
991 Parameter<double> last_ra;
992 Parameter<double> last_ba;
993 PassFilter ra_filter;
994 PassFilter ba_filter;
996 double limit_radio_altitude_rate (
double r);
999 Parameter<double> output;
1001 inline ClosureRateFilter (
MK_VIII *device)
1003 ra_filter(0.05, 0, 0.95),
1004 ba_filter(0.93, -0.93, 0.86) {}
1016 ClosureRateFilter closure_rate_filter;
1018 Timer takeoff_timer;
1019 Timer pull_up_timer;
1021 double a_start_time;
1022 Timer a_altitude_gain_timer;
1023 double a_altitude_gain_alt;
1025 void check_pull_up (
unsigned int preface_alert,
unsigned int alert);
1027 bool b_conditions ();
1044 inline Mode2Handler (
MK_VIII *device)
1045 : mk(device), closure_rate_filter(device) {}
1049 void leave_ground ();
1050 void enter_takeoff ();
1063 bool has_descent_alt;
1067 double max_alt_loss (
double _bias);
1068 double get_bias (
double initial_bias,
double alt_loss);
1069 bool is (
double *alt_loss);
1081 inline Mode3Handler (
MK_VIII *device)
1082 : mk(device), armed(false), has_descent_alt(false) {}
1084 void enter_takeoff ();
1116 inline Mode4Handler (
MK_VIII *device)
1117 : mk(device),ab_bias(0.0),ab_expanded_bias(0.0),c_bias(0.0) {}
1119 double get_upper_agl (
const EnvelopesConfiguration *c);
1126 double ab_expanded_bias;
1129 const EnvelopesConfiguration *get_ab_envelope ();
1130 double get_bias (
double initial_bias,
double min_agl);
1131 void handle_alert (
unsigned int alert,
double min_agl,
double *bias);
1134 void update_ab_expanded ();
1152 bool is_soft (
double bias);
1154 double get_soft_bias (
double initial_bias);
1156 void update_hard (
bool is);
1157 void update_soft (
bool is);
1160 inline Mode5Handler (
MK_VIII *device)
1161 : mk(device), soft_bias(0.0) {}
1176 ALTITUDE_CALLOUT_2500,
1177 ALTITUDE_CALLOUT_1000,
1178 ALTITUDE_CALLOUT_500,
1179 ALTITUDE_CALLOUT_400,
1180 ALTITUDE_CALLOUT_300,
1181 ALTITUDE_CALLOUT_200,
1182 ALTITUDE_CALLOUT_100,
1183 ALTITUDE_CALLOUT_50,
1184 ALTITUDE_CALLOUT_40,
1185 ALTITUDE_CALLOUT_30,
1186 ALTITUDE_CALLOUT_20,
1190 typedef bool (*BankAnglePredicate) (Parameter<double> *agl,
1191 double abs_roll_deg,
1196 bool retard_enabled;
1197 bool minimums_above_100_enabled;
1198 bool minimums_enabled;
1199 bool smart_500_enabled;
1200 VoicePlayer::Voice *above_field_voice;
1202 unsigned int altitude_callouts_enabled;
1203 bool bank_angle_enabled;
1204 BankAnglePredicate is_bank_angle;
1207 static const int altitude_callout_definitions[];
1209 inline Mode6Handler (
MK_VIII *device)
1214 void enter_takeoff ();
1215 void leave_takeoff ();
1216 void set_volume (
float volume);
1217 bool altitude_callouts_enabled ();
1223 bool last_decision_height;
1224 bool last_decision_height_100;
1225 Parameter<double> last_radio_altitude;
1226 Parameter<double> last_altitude_above_field;
1228 bool altitude_callouts_issued[n_altitude_callouts];
1229 bool minimums_issued;
1230 bool minimums_above_100_issued;
1231 bool above_field_issued;
1232 bool throttle_retarded;
1235 Parameter<bool> has_runway;
1242 void reset_minimums ();
1243 void reset_altitude_callouts ();
1244 bool is_playing_altitude_callout ();
1245 bool is_near_minimums (
double callout);
1246 bool is_outside_band (
double elevation,
double callout);
1247 bool inhibit_smart_500 ();
1249 void update_minimums ();
1250 void update_altitude_callouts ();
1252 bool test_runway (
const FGRunway *_runway);
1253 bool test_airport (
const FGAirport *airport);
1254 void update_runway ();
1256 void get_altitude_above_field (Parameter<double> *parameter);
1257 void update_above_field_callout ();
1259 bool is_bank_angle (
double abs_roll_angle,
double bias);
1260 bool is_high_bank_angle ();
1261 unsigned int get_bank_angle_alerts ();
1262 void update_bank_angle ();
1264 class AirportFilter :
public FGAirport::AirportFilter
1267 AirportFilter(Mode6Handler *s)
1270 virtual bool passAirport(FGAirport *a)
const;
1295 static const double k;
1305 double half_width_m;
1307 SGVec3d bias_points[2];
1312 double initial_value;
1314 void update_runway ();
1316 bool is_inside_edge_triangle (RunwayEdge *edge);
1317 bool is_inside_bias_area ();
1322 class AirportFilter :
public FGAirport::AirportFilter
1325 AirportFilter(
MK_VIII *device)
1328 virtual bool passAirport(FGAirport *a)
const;
1339 inline TCFHandler (
MK_VIII *device)
1352 PowerHandler power_handler;
1353 SystemHandler system_handler;
1354 ConfigurationModule configuration_module;
1355 FaultHandler fault_handler;
1358 SelfTestHandler self_test_handler;
1359 AlertHandler alert_handler;
1360 StateHandler state_handler;
1361 Mode1Handler mode1_handler;
1362 Mode2Handler mode2_handler;
1363 Mode3Handler mode3_handler;
1364 Mode4Handler mode4_handler;
1365 Mode5Handler mode5_handler;
1366 Mode6Handler mode6_handler;
1367 TCFHandler tcf_handler;
1375 MK_VIII (SGPropertyNode *node);
1378 void bind()
override;
1379 void init()
override;
1381 void update(
double dt)
override;