1 // bfi.cxx - Big Friendly Interface implementation
3 // Written by David Megginson, started February, 2000.
5 // Copyright (C) 2000 David Megginson - david@megginson.com
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #if defined( FG_HAVE_NATIVE_SGI_COMPILERS )
29 # include <iostream.h>
34 #include <simgear/constants.h>
35 #include <simgear/debug/logstream.hxx>
36 #include <simgear/math/fg_types.hxx>
38 #include <Aircraft/aircraft.hxx>
39 #include <FDM/UIUCModel/uiuc_aircraftdir.h>
40 #include <Controls/controls.hxx>
41 #include <Autopilot/newauto.hxx>
42 #include <Scenery/scenery.hxx>
43 #include <Time/fg_time.hxx>
44 #include <Time/light.hxx>
45 #include <Cockpit/radiostack.hxx>
46 #ifndef FG_OLD_WEATHER
47 # include <WeatherCM/FGLocalWeatherDatabase.h>
49 # include <Weather/weather.hxx>
52 #include "options.hxx"
54 #include "fg_init.hxx"
56 FG_USING_NAMESPACE(std);
58 // FIXME: these are not part of the
59 // published interface!!!
60 // extern fgAPDataPtr APDataGlobal;
61 // extern void fgAPAltitudeSet (double new_altitude);
62 // extern void fgAPHeadingSet (double new_heading);
69 ////////////////////////////////////////////////////////////////////////
71 ////////////////////////////////////////////////////////////////////////
73 bool FGBFI::_needReinit = false;
77 ////////////////////////////////////////////////////////////////////////
79 ////////////////////////////////////////////////////////////////////////
83 * Reinitialize FGFS if required.
85 * Some changes (especially those in aircraft position) require that
86 * FGFS be reinitialized afterwards. Rather than reinitialize after
87 * every change, the setter methods simply set a flag so that there
88 * can be a single reinit at the end of the frame.
100 * Reinitialize FGFS to use the new BFI settings.
105 // Save the state of everything
106 // that's going to get clobbered
107 // when we reinit the subsystems.
109 cout << "BFI: start reinit\n";
111 // TODO: add more AP stuff
112 double elevator = getElevator();
113 double aileron = getAileron();
114 double rudder = getRudder();
115 double throttle = getThrottle();
116 double elevator_trim = getElevatorTrim();
117 double flaps = getFlaps();
118 double brake = getBrake();
119 bool apHeadingLock = getAPHeadingLock();
120 double apHeadingMag = getAPHeadingMag();
121 bool apAltitudeLock = getAPAltitudeLock();
122 double apAltitude = getAPAltitude();
123 const string &targetAirport = getTargetAirport();
124 bool gpsLock = getGPSLock();
125 double gpsLatitude = getGPSTargetLatitude();
126 double gpsLongitude = getGPSTargetLongitude();
128 fgReInitSubsystems();
129 // solarSystemRebuild();
130 cur_light_params.Update();
132 // Restore all of the old states.
133 setElevator(elevator);
136 setThrottle(throttle);
137 setElevatorTrim(elevator_trim);
140 setAPHeadingLock(apHeadingLock);
141 setAPHeadingMag(apHeadingMag);
142 setAPAltitudeLock(apAltitudeLock);
143 setAPAltitude(apAltitude);
144 setTargetAirport(targetAirport);
146 setGPSTargetLatitude(gpsLatitude);
147 setGPSTargetLongitude(gpsLongitude);
151 cout << "BFI: end reinit\n";
156 ////////////////////////////////////////////////////////////////////////
158 ////////////////////////////////////////////////////////////////////////
162 * Return the flight model as an integer.
164 * TODO: use a string instead.
167 FGBFI::getFlightModel ()
169 return current_options.get_flight_model();
174 * Return the current aircraft as a string.
177 FGBFI::getAircraft ()
179 return current_options.get_aircraft();
184 * Return the current aircraft directory (UIUC) as a string.
187 FGBFI::getAircraftDir ()
194 * Set the flight model as an integer.
196 * TODO: use a string instead.
199 FGBFI::setFlightModel (int model)
201 current_options.set_flight_model(model);
207 * Set the current aircraft.
210 FGBFI::setAircraft (const string &aircraft)
212 current_options.set_aircraft(aircraft);
218 * Set the current aircraft directory (UIUC).
221 FGBFI::setAircraftDir (const string &dir)
229 * Return the current Zulu time.
234 // FIXME: inefficient
235 return mktime(FGTime::cur_time_params->getGmt());
240 * Set the current Zulu time.
243 FGBFI::setTimeGMT (time_t time)
245 // FIXME: need to update lighting
247 current_options.set_time_offset(time);
248 current_options.set_time_offset_type(fgOPTIONS::FG_TIME_GMT_ABSOLUTE);
249 FGTime::cur_time_params->init( cur_fdm_state->get_Longitude(),
250 cur_fdm_state->get_Latitude() );
251 FGTime::cur_time_params->update( cur_fdm_state->get_Longitude(),
252 cur_fdm_state->get_Latitude(),
253 cur_fdm_state->get_Altitude()
260 * Return true if the HUD is visible.
263 FGBFI::getHUDVisible ()
265 return current_options.get_hud_status();
270 * Ensure that the HUD is visible or hidden.
273 FGBFI::setHUDVisible (bool visible)
275 current_options.set_hud_status(visible);
280 * Return true if the 2D panel is visible.
283 FGBFI::getPanelVisible ()
285 return current_options.get_panel_status();
290 * Ensure that the 2D panel is visible or hidden.
293 FGBFI::setPanelVisible (bool visible)
295 if (current_options.get_panel_status() != visible) {
296 current_options.toggle_panel();
302 ////////////////////////////////////////////////////////////////////////
304 ////////////////////////////////////////////////////////////////////////
308 * Return the current latitude in degrees (negative for south).
311 FGBFI::getLatitude ()
313 return current_aircraft.fdm_state->get_Latitude() * RAD_TO_DEG;
318 * Set the current latitude in degrees (negative for south).
321 FGBFI::setLatitude (double latitude)
323 current_options.set_lat(latitude);
329 * Return the current longitude in degrees (negative for west).
332 FGBFI::getLongitude ()
334 return current_aircraft.fdm_state->get_Longitude() * RAD_TO_DEG;
339 * Set the current longitude in degrees (negative for west).
342 FGBFI::setLongitude (double longitude)
344 current_options.set_lon(longitude);
350 * Return the current altitude in feet.
353 FGBFI::getAltitude ()
355 return current_aircraft.fdm_state->get_Altitude();
361 * Return the current altitude in above the terrain.
366 return current_aircraft.fdm_state->get_Altitude()
367 - scenery.cur_elev * METER_TO_FEET;
372 * Set the current altitude in feet.
375 FGBFI::setAltitude (double altitude)
377 current_options.set_altitude(altitude * FEET_TO_METER);
383 ////////////////////////////////////////////////////////////////////////
385 ////////////////////////////////////////////////////////////////////////
389 * Return the current heading in degrees.
394 return current_aircraft.fdm_state->get_Psi() * RAD_TO_DEG;
399 * Return the current heading in degrees.
402 FGBFI::getHeadingMag ()
404 return current_aircraft.fdm_state->get_Psi() * RAD_TO_DEG - getMagVar();
409 * Set the current heading in degrees.
412 FGBFI::setHeading (double heading)
414 current_options.set_heading(heading);
420 * Return the current pitch in degrees.
425 return current_aircraft.fdm_state->get_Theta() * RAD_TO_DEG;
430 * Set the current pitch in degrees.
433 FGBFI::setPitch (double pitch)
436 current_options.set_pitch(pitch);
442 * Return the current roll in degrees.
447 return current_aircraft.fdm_state->get_Phi() * RAD_TO_DEG;
452 * Set the current roll in degrees.
455 FGBFI::setRoll (double roll)
457 current_options.set_roll(roll);
463 ////////////////////////////////////////////////////////////////////////
465 ////////////////////////////////////////////////////////////////////////
469 * Return the current airspeed in knots.
472 FGBFI::getAirspeed ()
474 // FIXME: should we add speed-up?
475 return current_aircraft.fdm_state->get_V_calibrated_kts();
480 * Return the current sideslip (FIXME: units unknown).
483 FGBFI::getSideSlip ()
485 return current_aircraft.fdm_state->get_Beta();
490 * Return the current climb rate in feet/minute
493 FGBFI::getVerticalSpeed ()
495 // What about meters?
496 return current_aircraft.fdm_state->get_Climb_Rate() * 60.0;
501 * Get the current north velocity (units??).
504 FGBFI::getSpeedNorth ()
506 return current_aircraft.fdm_state->get_V_north();
511 * Set the current north velocity (units??).
514 FGBFI::setSpeedNorth (double speed)
516 current_options.set_uBody(speed);
522 * Get the current east velocity (units??).
525 FGBFI::getSpeedEast ()
527 return current_aircraft.fdm_state->get_V_east();
532 * Set the current east velocity (units??).
535 FGBFI::setSpeedEast (double speed)
537 current_options.set_vBody(speed);
543 * Get the current down velocity (units??).
546 FGBFI::getSpeedDown ()
548 return current_aircraft.fdm_state->get_V_down();
553 * Set the current down velocity (units??).
556 FGBFI::setSpeedDown (double speed)
558 current_options.set_wBody(speed);
564 ////////////////////////////////////////////////////////////////////////
566 ////////////////////////////////////////////////////////////////////////
570 * Get the throttle setting, from 0.0 (none) to 1.0 (full).
573 FGBFI::getThrottle ()
575 // FIXME: add throttle selector
576 return controls.get_throttle(0);
581 * Set the throttle, from 0.0 (none) to 1.0 (full).
584 FGBFI::setThrottle (double throttle)
586 // FIXME: allow throttle selection
588 controls.set_throttle(0, throttle);
593 * Get the flaps setting, from 0.0 (none) to 1.0 (full).
598 return controls.get_flaps();
603 * Set the flaps, from 0.0 (none) to 1.0 (full).
606 FGBFI::setFlaps (double flaps)
609 controls.set_flaps(flaps);
614 * Get the aileron, from -1.0 (left) to 1.0 (right).
619 return controls.get_aileron();
624 * Set the aileron, from -1.0 (left) to 1.0 (right).
627 FGBFI::setAileron (double aileron)
630 controls.set_aileron(aileron);
635 * Get the rudder setting, from -1.0 (left) to 1.0 (right).
640 return controls.get_rudder();
645 * Set the rudder, from -1.0 (left) to 1.0 (right).
648 FGBFI::setRudder (double rudder)
651 controls.set_rudder(rudder);
656 * Get the elevator setting, from -1.0 (down) to 1.0 (up).
659 FGBFI::getElevator ()
661 return controls.get_elevator();
666 * Set the elevator, from -1.0 (down) to 1.0 (up).
669 FGBFI::setElevator (double elevator)
672 controls.set_elevator(elevator);
677 * Get the elevator trim, from -1.0 (down) to 1.0 (up).
680 FGBFI::getElevatorTrim ()
682 return controls.get_elevator_trim();
687 * Set the elevator trim, from -1.0 (down) to 1.0 (up).
690 FGBFI::setElevatorTrim (double trim)
693 controls.set_elevator_trim(trim);
698 * Get the brake setting, from 0.0 (none) to 1.0 (full).
703 // FIXME: add brake selector
704 return controls.get_brake(0);
709 * Set the brake, from 0.0 (none) to 1.0 (full).
712 FGBFI::setBrake (double brake)
715 // FIXME: allow brake selection
716 controls.set_brake(0, brake);
721 ////////////////////////////////////////////////////////////////////////
723 ////////////////////////////////////////////////////////////////////////
727 * Get the autopilot altitude lock (true=on).
730 FGBFI::getAPAltitudeLock ()
732 return current_autopilot->get_AltitudeEnabled();
737 * Set the autopilot altitude lock (true=on).
740 FGBFI::setAPAltitudeLock (bool lock)
742 current_autopilot->set_AltitudeMode(FGAutopilot::FG_ALTITUDE_LOCK);
743 current_autopilot->set_AltitudeEnabled(lock);
748 * Get the autopilot target altitude in feet.
751 FGBFI::getAPAltitude ()
753 return current_autopilot->get_TargetAltitude() * METER_TO_FEET;
758 * Set the autopilot target altitude in feet.
761 FGBFI::setAPAltitude (double altitude)
763 current_autopilot->set_TargetAltitude( altitude );
768 * Get the autopilot heading lock (true=on).
771 FGBFI::getAPHeadingLock ()
774 (current_autopilot->get_HeadingEnabled() &&
775 current_autopilot->get_HeadingMode() == FGAutopilot::FG_HEADING_LOCK);
780 * Set the autopilot heading lock (true=on).
783 FGBFI::setAPHeadingLock (bool lock)
786 // We need to do this so that
787 // it's possible to lock onto a
788 // heading other than the current
790 double heading = getAPHeadingMag();
791 current_autopilot->set_HeadingMode(FGAutopilot::FG_HEADING_LOCK);
792 current_autopilot->set_HeadingEnabled(true);
793 setAPHeadingMag(heading);
794 } else if (current_autopilot->get_HeadingMode() ==
795 FGAutopilot::FG_HEADING_LOCK) {
796 current_autopilot->set_HeadingEnabled(false);
802 * Get the autopilot target heading in degrees.
805 FGBFI::getAPHeadingMag ()
807 return current_autopilot->get_TargetHeading() - getMagVar();
812 * Set the autopilot target heading in degrees.
815 FGBFI::setAPHeadingMag (double heading)
817 current_autopilot->set_TargetHeading( heading + getMagVar() );
822 * Return true if the autopilot is locked to NAV1.
825 FGBFI::getAPNAV1Lock ()
828 (current_autopilot->get_HeadingEnabled() &&
829 current_autopilot->get_HeadingMode() == FGAutopilot::FG_HEADING_NAV1);
834 * Set the autopilot NAV1 lock.
837 FGBFI::setAPNAV1Lock (bool lock)
840 current_autopilot->set_HeadingMode(FGAutopilot::FG_HEADING_NAV1);
841 current_autopilot->set_HeadingEnabled(true);
842 } else if (current_autopilot->get_HeadingMode() ==
843 FGAutopilot::FG_HEADING_NAV1) {
844 current_autopilot->set_HeadingEnabled(false);
850 ////////////////////////////////////////////////////////////////////////
852 ////////////////////////////////////////////////////////////////////////
855 FGBFI::getNAV1Freq ()
857 return current_radiostack->get_nav1_freq();
861 FGBFI::getNAV1AltFreq ()
863 return current_radiostack->get_nav1_alt_freq();
867 FGBFI::getNAV1Radial ()
869 return current_radiostack->get_nav1_radial();
873 FGBFI::getNAV1SelRadial ()
875 return current_radiostack->get_nav1_sel_radial();
879 FGBFI::getNAV1DistDME ()
881 return current_radiostack->get_nav1_dme_dist();
885 FGBFI::getNAV1InRange ()
887 return current_radiostack->get_nav1_inrange();
891 FGBFI::getNAV1DMEInRange ()
893 return (current_radiostack->get_nav1_inrange() &&
894 current_radiostack->get_nav1_has_dme());
898 FGBFI::getNAV2Freq ()
900 return current_radiostack->get_nav2_freq();
904 FGBFI::getNAV2AltFreq ()
906 return current_radiostack->get_nav2_alt_freq();
910 FGBFI::getNAV2Radial ()
912 return current_radiostack->get_nav2_radial();
916 FGBFI::getNAV2SelRadial ()
918 return current_radiostack->get_nav2_sel_radial();
922 FGBFI::getNAV2DistDME ()
924 return current_radiostack->get_nav2_dme_dist();
928 FGBFI::getNAV2InRange ()
930 return current_radiostack->get_nav2_inrange();
934 FGBFI::getNAV2DMEInRange ()
936 return (current_radiostack->get_nav2_inrange() &&
937 current_radiostack->get_nav2_has_dme());
943 return current_radiostack->get_adf_freq();
947 FGBFI::getADFAltFreq ()
949 return current_radiostack->get_adf_alt_freq();
953 FGBFI::getADFRotation ()
955 return current_radiostack->get_adf_rotation();
959 FGBFI::setNAV1Freq (double freq)
961 current_radiostack->set_nav1_freq(freq);
965 FGBFI::setNAV1AltFreq (double freq)
967 current_radiostack->set_nav1_alt_freq(freq);
971 FGBFI::setNAV1SelRadial (double radial)
973 current_radiostack->set_nav1_sel_radial(radial);
977 FGBFI::setNAV2Freq (double freq)
979 current_radiostack->set_nav2_freq(freq);
983 FGBFI::setNAV2AltFreq (double freq)
985 current_radiostack->set_nav2_alt_freq(freq);
989 FGBFI::setNAV2SelRadial (double radial)
991 current_radiostack->set_nav2_sel_radial(radial);
995 FGBFI::setADFFreq (double freq)
997 current_radiostack->set_adf_freq(freq);
1001 FGBFI::setADFAltFreq (double freq)
1003 current_radiostack->set_adf_alt_freq(freq);
1007 FGBFI::setADFRotation (double rot)
1009 current_radiostack->set_adf_rotation(rot);
1014 ////////////////////////////////////////////////////////////////////////
1016 ////////////////////////////////////////////////////////////////////////
1020 * Get the autopilot GPS lock (true=on).
1023 FGBFI::getGPSLock ()
1025 return (current_autopilot->get_HeadingEnabled() &&
1026 (current_autopilot->get_HeadingMode() ==
1027 FGAutopilot::FG_HEADING_WAYPOINT ));
1032 * Set the autopilot GPS lock (true=on).
1035 FGBFI::setGPSLock (bool lock)
1038 current_autopilot->set_HeadingMode(FGAutopilot::FG_HEADING_WAYPOINT);
1039 current_autopilot->set_HeadingEnabled(true);
1040 } else if (current_autopilot->get_HeadingMode() ==
1041 FGAutopilot::FG_HEADING_WAYPOINT) {
1042 current_autopilot->set_HeadingEnabled(false);
1048 * Get the GPS target airport code.
1051 FGBFI::getTargetAirport ()
1053 return current_options.get_airport_id();
1058 * Set the GPS target airport code.
1061 FGBFI::setTargetAirport (const string &airportId)
1063 current_options.set_airport_id(airportId);
1068 * Get the GPS target latitude in degrees (negative for south).
1071 FGBFI::getGPSTargetLatitude ()
1073 return current_autopilot->get_TargetLatitude();
1078 * Set the GPS target latitude in degrees (negative for south).
1081 FGBFI::setGPSTargetLatitude (double latitude)
1083 current_autopilot->set_TargetLatitude( latitude );
1088 * Get the GPS target longitude in degrees (negative for west).
1091 FGBFI::getGPSTargetLongitude ()
1093 return current_autopilot->get_TargetLongitude();
1098 * Set the GPS target longitude in degrees (negative for west).
1101 FGBFI::setGPSTargetLongitude (double longitude)
1103 current_autopilot->set_TargetLongitude( longitude );
1108 ////////////////////////////////////////////////////////////////////////
1110 ////////////////////////////////////////////////////////////////////////
1114 * Get the current visible (units??).
1117 FGBFI::getVisibility ()
1119 #ifndef FG_OLD_WEATHER
1120 return WeatherDatabase->getWeatherVisibility();
1122 return current_weather.get_visibility();
1128 * Check whether clouds are enabled.
1133 return current_options.get_clouds();
1138 * Check the height of the clouds ASL (units?).
1141 FGBFI::getCloudsASL ()
1143 return current_options.get_clouds_asl();
1148 * Set the current visibility (units??).
1151 FGBFI::setVisibility (double visibility)
1153 #ifndef FG_OLD_WEATHER
1154 WeatherDatabase->setWeatherVisibility(visibility);
1156 current_weather.set_visibility(visibility);
1162 * Switch clouds on or off.
1165 FGBFI::setClouds (bool clouds)
1167 current_options.set_clouds(clouds);
1173 * Set the cloud height.
1176 FGBFI::setCloudsASL (double cloudsASL)
1178 current_options.set_clouds_asl(cloudsASL);
1184 ////////////////////////////////////////////////////////////////////////
1186 ////////////////////////////////////////////////////////////////////////
1189 * Return the magnetic variation
1194 return FGTime::cur_time_params->getMagVar() * RAD_TO_DEG;
1199 * Return the magnetic variation
1204 return FGTime::cur_time_params->getMagDip() * RAD_TO_DEG;