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 setHeading(getHeading());
112 setPitch(getPitch());
114 setSpeedNorth(getSpeedNorth());
115 setSpeedEast(getSpeedEast());
116 setSpeedDown(getSpeedDown());
117 setLatitude(getLatitude());
118 setLongitude(getLongitude());
119 setAltitude(getAltitude());
120 setTargetAirport("");
121 // TODO: add more AP stuff
122 double elevator = getElevator();
123 double aileron = getAileron();
124 double rudder = getRudder();
125 double throttle = getThrottle();
126 double elevator_trim = getElevatorTrim();
127 double flaps = getFlaps();
128 double brake = getBrake();
129 bool apHeadingLock = getAPHeadingLock();
130 double apHeadingMag = getAPHeadingMag();
131 bool apAltitudeLock = getAPAltitudeLock();
132 double apAltitude = getAPAltitude();
133 const string &targetAirport = getTargetAirport();
134 bool gpsLock = getGPSLock();
135 double gpsLatitude = getGPSTargetLatitude();
136 double gpsLongitude = getGPSTargetLongitude();
138 fgReInitSubsystems();
139 // solarSystemRebuild();
140 cur_light_params.Update();
142 // Restore all of the old states.
143 setElevator(elevator);
146 setThrottle(throttle);
147 setElevatorTrim(elevator_trim);
150 setAPHeadingLock(apHeadingLock);
151 setAPHeadingMag(apHeadingMag);
152 setAPAltitudeLock(apAltitudeLock);
153 setAPAltitude(apAltitude);
154 setTargetAirport(targetAirport);
156 setGPSTargetLatitude(gpsLatitude);
157 setGPSTargetLongitude(gpsLongitude);
161 cout << "BFI: end reinit\n";
166 ////////////////////////////////////////////////////////////////////////
168 ////////////////////////////////////////////////////////////////////////
172 * Return the flight model as an integer.
174 * TODO: use a string instead.
177 FGBFI::getFlightModel ()
179 return current_options.get_flight_model();
184 * Return the current aircraft as a string.
187 FGBFI::getAircraft ()
189 return current_options.get_aircraft();
194 * Return the current aircraft directory (UIUC) as a string.
197 FGBFI::getAircraftDir ()
204 * Set the flight model as an integer.
206 * TODO: use a string instead.
209 FGBFI::setFlightModel (int model)
211 current_options.set_flight_model(model);
217 * Set the current aircraft.
220 FGBFI::setAircraft (const string &aircraft)
222 current_options.set_aircraft(aircraft);
228 * Set the current aircraft directory (UIUC).
231 FGBFI::setAircraftDir (const string &dir)
239 * Return the current Zulu time.
244 // FIXME: inefficient
245 return mktime(FGTime::cur_time_params->getGmt());
250 * Set the current Zulu time.
253 FGBFI::setTimeGMT (time_t time)
255 // FIXME: need to update lighting
257 current_options.set_time_offset(time);
258 current_options.set_time_offset_type(fgOPTIONS::FG_TIME_GMT_ABSOLUTE);
259 FGTime::cur_time_params->init( cur_fdm_state->get_Longitude(),
260 cur_fdm_state->get_Latitude() );
261 FGTime::cur_time_params->update( cur_fdm_state->get_Longitude(),
262 cur_fdm_state->get_Latitude(),
263 cur_fdm_state->get_Altitude()
270 * Return true if the HUD is visible.
273 FGBFI::getHUDVisible ()
275 return current_options.get_hud_status();
280 * Ensure that the HUD is visible or hidden.
283 FGBFI::setHUDVisible (bool visible)
285 current_options.set_hud_status(visible);
290 * Return true if the 2D panel is visible.
293 FGBFI::getPanelVisible ()
295 return current_options.get_panel_status();
300 * Ensure that the 2D panel is visible or hidden.
303 FGBFI::setPanelVisible (bool visible)
305 if (current_options.get_panel_status() != visible) {
306 current_options.toggle_panel();
312 ////////////////////////////////////////////////////////////////////////
314 ////////////////////////////////////////////////////////////////////////
318 * Return the current latitude in degrees (negative for south).
321 FGBFI::getLatitude ()
323 return current_aircraft.fdm_state->get_Latitude() * RAD_TO_DEG;
328 * Set the current latitude in degrees (negative for south).
331 FGBFI::setLatitude (double latitude)
333 current_options.set_lat(latitude);
339 * Return the current longitude in degrees (negative for west).
342 FGBFI::getLongitude ()
344 return current_aircraft.fdm_state->get_Longitude() * RAD_TO_DEG;
349 * Set the current longitude in degrees (negative for west).
352 FGBFI::setLongitude (double longitude)
354 current_options.set_lon(longitude);
360 * Return the current altitude in feet.
363 FGBFI::getAltitude ()
365 return current_aircraft.fdm_state->get_Altitude();
371 * Return the current altitude in above the terrain.
376 return current_aircraft.fdm_state->get_Altitude()
377 - scenery.cur_elev * METER_TO_FEET;
382 * Set the current altitude in feet.
385 FGBFI::setAltitude (double altitude)
387 current_options.set_altitude(altitude * FEET_TO_METER);
393 ////////////////////////////////////////////////////////////////////////
395 ////////////////////////////////////////////////////////////////////////
399 * Return the current heading in degrees.
404 return current_aircraft.fdm_state->get_Psi() * RAD_TO_DEG;
409 * Return the current heading in degrees.
412 FGBFI::getHeadingMag ()
414 return current_aircraft.fdm_state->get_Psi() * RAD_TO_DEG - getMagVar();
419 * Set the current heading in degrees.
422 FGBFI::setHeading (double heading)
424 current_options.set_heading(heading);
430 * Return the current pitch in degrees.
435 return current_aircraft.fdm_state->get_Theta() * RAD_TO_DEG;
440 * Set the current pitch in degrees.
443 FGBFI::setPitch (double pitch)
446 current_options.set_pitch(pitch);
452 * Return the current roll in degrees.
457 return current_aircraft.fdm_state->get_Phi() * RAD_TO_DEG;
462 * Set the current roll in degrees.
465 FGBFI::setRoll (double roll)
467 current_options.set_roll(roll);
473 ////////////////////////////////////////////////////////////////////////
475 ////////////////////////////////////////////////////////////////////////
479 * Return the current airspeed in knots.
482 FGBFI::getAirspeed ()
484 // FIXME: should we add speed-up?
485 return current_aircraft.fdm_state->get_V_calibrated_kts();
490 * Return the current sideslip (FIXME: units unknown).
493 FGBFI::getSideSlip ()
495 return current_aircraft.fdm_state->get_Beta();
500 * Return the current climb rate in feet/minute
503 FGBFI::getVerticalSpeed ()
505 // What about meters?
506 return current_aircraft.fdm_state->get_Climb_Rate() * 60.0;
511 * Get the current north velocity (units??).
514 FGBFI::getSpeedNorth ()
516 return current_aircraft.fdm_state->get_V_north();
521 * Set the current north velocity (units??).
524 FGBFI::setSpeedNorth (double speed)
526 current_options.set_uBody(speed);
532 * Get the current east velocity (units??).
535 FGBFI::getSpeedEast ()
537 return current_aircraft.fdm_state->get_V_east();
542 * Set the current east velocity (units??).
545 FGBFI::setSpeedEast (double speed)
547 current_options.set_vBody(speed);
553 * Get the current down velocity (units??).
556 FGBFI::getSpeedDown ()
558 return current_aircraft.fdm_state->get_V_down();
563 * Set the current down velocity (units??).
566 FGBFI::setSpeedDown (double speed)
568 current_options.set_wBody(speed);
574 ////////////////////////////////////////////////////////////////////////
576 ////////////////////////////////////////////////////////////////////////
580 * Get the throttle setting, from 0.0 (none) to 1.0 (full).
583 FGBFI::getThrottle ()
585 // FIXME: add throttle selector
586 return controls.get_throttle(0);
591 * Set the throttle, from 0.0 (none) to 1.0 (full).
594 FGBFI::setThrottle (double throttle)
596 // FIXME: allow throttle selection
598 controls.set_throttle(0, throttle);
603 * Get the flaps setting, from 0.0 (none) to 1.0 (full).
608 return controls.get_flaps();
613 * Set the flaps, from 0.0 (none) to 1.0 (full).
616 FGBFI::setFlaps (double flaps)
619 controls.set_flaps(flaps);
624 * Get the aileron, from -1.0 (left) to 1.0 (right).
629 return controls.get_aileron();
634 * Set the aileron, from -1.0 (left) to 1.0 (right).
637 FGBFI::setAileron (double aileron)
640 controls.set_aileron(aileron);
645 * Get the rudder setting, from -1.0 (left) to 1.0 (right).
650 return controls.get_rudder();
655 * Set the rudder, from -1.0 (left) to 1.0 (right).
658 FGBFI::setRudder (double rudder)
661 controls.set_rudder(rudder);
666 * Get the elevator setting, from -1.0 (down) to 1.0 (up).
669 FGBFI::getElevator ()
671 return controls.get_elevator();
676 * Set the elevator, from -1.0 (down) to 1.0 (up).
679 FGBFI::setElevator (double elevator)
682 controls.set_elevator(elevator);
687 * Get the elevator trim, from -1.0 (down) to 1.0 (up).
690 FGBFI::getElevatorTrim ()
692 return controls.get_elevator_trim();
697 * Set the elevator trim, from -1.0 (down) to 1.0 (up).
700 FGBFI::setElevatorTrim (double trim)
703 controls.set_elevator_trim(trim);
708 * Get the brake setting, from 0.0 (none) to 1.0 (full).
713 // FIXME: add brake selector
714 return controls.get_brake(0);
719 * Set the brake, from 0.0 (none) to 1.0 (full).
722 FGBFI::setBrake (double brake)
725 // FIXME: allow brake selection
726 controls.set_brake(0, brake);
731 ////////////////////////////////////////////////////////////////////////
733 ////////////////////////////////////////////////////////////////////////
737 * Get the autopilot altitude lock (true=on).
740 FGBFI::getAPAltitudeLock ()
742 return current_autopilot->get_AltitudeEnabled();
747 * Set the autopilot altitude lock (true=on).
750 FGBFI::setAPAltitudeLock (bool lock)
752 current_autopilot->set_AltitudeMode(FGAutopilot::FG_ALTITUDE_LOCK);
753 current_autopilot->set_AltitudeEnabled(lock);
758 * Get the autopilot target altitude in feet.
761 FGBFI::getAPAltitude ()
763 return current_autopilot->get_TargetAltitude() * METER_TO_FEET;
768 * Set the autopilot target altitude in feet.
771 FGBFI::setAPAltitude (double altitude)
773 current_autopilot->set_TargetAltitude( altitude );
778 * Get the autopilot heading lock (true=on).
781 FGBFI::getAPHeadingLock ()
784 (current_autopilot->get_HeadingEnabled() &&
785 current_autopilot->get_HeadingMode() == FGAutopilot::FG_HEADING_LOCK);
790 * Set the autopilot heading lock (true=on).
793 FGBFI::setAPHeadingLock (bool lock)
796 // We need to do this so that
797 // it's possible to lock onto a
798 // heading other than the current
800 double heading = getAPHeadingMag();
801 current_autopilot->set_HeadingMode(FGAutopilot::FG_HEADING_LOCK);
802 current_autopilot->set_HeadingEnabled(true);
803 setAPHeadingMag(heading);
804 } else if (current_autopilot->get_HeadingMode() ==
805 FGAutopilot::FG_HEADING_LOCK) {
806 current_autopilot->set_HeadingEnabled(false);
812 * Get the autopilot target heading in degrees.
815 FGBFI::getAPHeadingMag ()
817 return current_autopilot->get_TargetHeading() - getMagVar();
822 * Set the autopilot target heading in degrees.
825 FGBFI::setAPHeadingMag (double heading)
827 current_autopilot->set_TargetHeading( heading + getMagVar() );
832 * Return true if the autopilot is locked to NAV1.
835 FGBFI::getAPNAV1Lock ()
838 (current_autopilot->get_HeadingEnabled() &&
839 current_autopilot->get_HeadingMode() == FGAutopilot::FG_HEADING_NAV1);
844 * Set the autopilot NAV1 lock.
847 FGBFI::setAPNAV1Lock (bool lock)
850 current_autopilot->set_HeadingMode(FGAutopilot::FG_HEADING_NAV1);
851 current_autopilot->set_HeadingEnabled(true);
852 } else if (current_autopilot->get_HeadingMode() ==
853 FGAutopilot::FG_HEADING_NAV1) {
854 current_autopilot->set_HeadingEnabled(false);
860 ////////////////////////////////////////////////////////////////////////
862 ////////////////////////////////////////////////////////////////////////
865 FGBFI::getNAV1Freq ()
867 return current_radiostack->get_nav1_freq();
871 FGBFI::getNAV1AltFreq ()
873 return current_radiostack->get_nav1_alt_freq();
877 FGBFI::getNAV1Radial ()
879 return current_radiostack->get_nav1_radial();
883 FGBFI::getNAV1SelRadial ()
885 return current_radiostack->get_nav1_sel_radial();
889 FGBFI::getNAV1DistDME ()
891 return current_radiostack->get_nav1_dme_dist();
895 FGBFI::getNAV1InRange ()
897 return current_radiostack->get_nav1_inrange();
901 FGBFI::getNAV1DMEInRange ()
903 return (current_radiostack->get_nav1_inrange() &&
904 current_radiostack->get_nav1_has_dme());
908 FGBFI::getNAV2Freq ()
910 return current_radiostack->get_nav2_freq();
914 FGBFI::getNAV2AltFreq ()
916 return current_radiostack->get_nav2_alt_freq();
920 FGBFI::getNAV2Radial ()
922 return current_radiostack->get_nav2_radial();
926 FGBFI::getNAV2SelRadial ()
928 return current_radiostack->get_nav2_sel_radial();
932 FGBFI::getNAV2DistDME ()
934 return current_radiostack->get_nav2_dme_dist();
938 FGBFI::getNAV2InRange ()
940 return current_radiostack->get_nav2_inrange();
944 FGBFI::getNAV2DMEInRange ()
946 return (current_radiostack->get_nav2_inrange() &&
947 current_radiostack->get_nav2_has_dme());
953 return current_radiostack->get_adf_freq();
957 FGBFI::getADFAltFreq ()
959 return current_radiostack->get_adf_alt_freq();
963 FGBFI::getADFRotation ()
965 return current_radiostack->get_adf_rotation();
969 FGBFI::setNAV1Freq (double freq)
971 current_radiostack->set_nav1_freq(freq);
975 FGBFI::setNAV1AltFreq (double freq)
977 current_radiostack->set_nav1_alt_freq(freq);
981 FGBFI::setNAV1SelRadial (double radial)
983 current_radiostack->set_nav1_sel_radial(radial);
987 FGBFI::setNAV2Freq (double freq)
989 current_radiostack->set_nav2_freq(freq);
993 FGBFI::setNAV2AltFreq (double freq)
995 current_radiostack->set_nav2_alt_freq(freq);
999 FGBFI::setNAV2SelRadial (double radial)
1001 current_radiostack->set_nav2_sel_radial(radial);
1005 FGBFI::setADFFreq (double freq)
1007 current_radiostack->set_adf_freq(freq);
1011 FGBFI::setADFAltFreq (double freq)
1013 current_radiostack->set_adf_alt_freq(freq);
1017 FGBFI::setADFRotation (double rot)
1019 current_radiostack->set_adf_rotation(rot);
1024 ////////////////////////////////////////////////////////////////////////
1026 ////////////////////////////////////////////////////////////////////////
1030 * Get the autopilot GPS lock (true=on).
1033 FGBFI::getGPSLock ()
1035 return (current_autopilot->get_HeadingEnabled() &&
1036 (current_autopilot->get_HeadingMode() ==
1037 FGAutopilot::FG_HEADING_WAYPOINT ));
1042 * Set the autopilot GPS lock (true=on).
1045 FGBFI::setGPSLock (bool lock)
1048 current_autopilot->set_HeadingMode(FGAutopilot::FG_HEADING_WAYPOINT);
1049 current_autopilot->set_HeadingEnabled(true);
1050 } else if (current_autopilot->get_HeadingMode() ==
1051 FGAutopilot::FG_HEADING_WAYPOINT) {
1052 current_autopilot->set_HeadingEnabled(false);
1058 * Get the GPS target airport code.
1061 FGBFI::getTargetAirport ()
1063 return current_options.get_airport_id();
1068 * Set the GPS target airport code.
1071 FGBFI::setTargetAirport (const string &airportId)
1073 current_options.set_airport_id(airportId);
1078 * Get the GPS target latitude in degrees (negative for south).
1081 FGBFI::getGPSTargetLatitude ()
1083 return current_autopilot->get_TargetLatitude();
1088 * Set the GPS target latitude in degrees (negative for south).
1091 FGBFI::setGPSTargetLatitude (double latitude)
1093 current_autopilot->set_TargetLatitude( latitude );
1098 * Get the GPS target longitude in degrees (negative for west).
1101 FGBFI::getGPSTargetLongitude ()
1103 return current_autopilot->get_TargetLongitude();
1108 * Set the GPS target longitude in degrees (negative for west).
1111 FGBFI::setGPSTargetLongitude (double longitude)
1113 current_autopilot->set_TargetLongitude( longitude );
1118 ////////////////////////////////////////////////////////////////////////
1120 ////////////////////////////////////////////////////////////////////////
1124 * Get the current visible (units??).
1127 FGBFI::getVisibility ()
1129 #ifndef FG_OLD_WEATHER
1130 return WeatherDatabase->getWeatherVisibility();
1132 return current_weather.get_visibility();
1138 * Check whether clouds are enabled.
1143 return current_options.get_clouds();
1148 * Check the height of the clouds ASL (units?).
1151 FGBFI::getCloudsASL ()
1153 return current_options.get_clouds_asl();
1158 * Set the current visibility (units??).
1161 FGBFI::setVisibility (double visibility)
1163 #ifndef FG_OLD_WEATHER
1164 WeatherDatabase->setWeatherVisibility(visibility);
1166 current_weather.set_visibility(visibility);
1172 * Switch clouds on or off.
1175 FGBFI::setClouds (bool clouds)
1177 cout << "Set clouds to " << clouds << endl;
1178 current_options.set_clouds(clouds);
1184 * Set the cloud height.
1187 FGBFI::setCloudsASL (double cloudsASL)
1189 current_options.set_clouds_asl(cloudsASL);
1195 ////////////////////////////////////////////////////////////////////////
1197 ////////////////////////////////////////////////////////////////////////
1200 * Return the magnetic variation
1205 return FGTime::cur_time_params->getMagVar() * RAD_TO_DEG;
1210 * Return the magnetic variation
1215 return FGTime::cur_time_params->getMagDip() * RAD_TO_DEG;