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.
25 #include <simgear/constants.h>
26 #include <simgear/debug/logstream.hxx>
27 #include <simgear/ephemeris/ephemeris.hxx>
28 #include <simgear/math/sg_types.hxx>
29 #include <simgear/misc/props.hxx>
30 #include <simgear/timing/sg_time.hxx>
32 #include <Aircraft/aircraft.hxx>
33 #include <FDM/UIUCModel/uiuc_aircraftdir.h>
34 #include <Controls/controls.hxx>
35 #include <Autopilot/newauto.hxx>
36 #include <Scenery/scenery.hxx>
37 #include <Time/light.hxx>
38 #include <Time/event.hxx>
39 #include <Time/sunpos.hxx>
40 #include <Time/tmp.hxx>
41 #include <Cockpit/radiostack.hxx>
42 #include <Cockpit/panel.hxx>
43 #ifndef FG_OLD_WEATHER
44 # include <WeatherCM/FGLocalWeatherDatabase.h>
46 # include <Weather/weather.hxx>
49 #include "globals.hxx"
50 #include "fg_init.hxx"
51 #include "fg_props.hxx"
53 FG_USING_NAMESPACE(std);
60 ////////////////////////////////////////////////////////////////////////
62 ////////////////////////////////////////////////////////////////////////
64 // Yech -- not thread-safe, etc. etc.
65 static bool _needReinit = false;
68 static inline void needReinit ()
75 * Reinitialize FGFS to use the new BFI settings.
80 // Save the state of everything
81 // that's going to get clobbered
82 // when we reinit the subsystems.
84 FG_LOG(FG_GENERAL, FG_INFO, "Starting BFI reinit");
86 // TODO: add more AP stuff
87 double elevator = FGBFI::getElevator();
88 double aileron = FGBFI::getAileron();
89 double rudder = FGBFI::getRudder();
90 double throttle = FGBFI::getThrottle();
91 double elevator_trim = FGBFI::getElevatorTrim();
92 double flaps = FGBFI::getFlaps();
93 double brake = FGBFI::getBrakes();
94 bool apHeadingLock = FGBFI::getAPHeadingLock();
95 double apHeadingMag = FGBFI::getAPHeadingMag();
96 bool apAltitudeLock = FGBFI::getAPAltitudeLock();
97 double apAltitude = FGBFI::getAPAltitude();
98 const string &targetAirport = FGBFI::getTargetAirport();
99 bool gpsLock = FGBFI::getGPSLock();
100 // double gpsLatitude = FGBFI::getGPSTargetLatitude();
101 // double gpsLongitude = FGBFI::getGPSTargetLongitude();
103 FGBFI::setTargetAirport("");
105 fgReInitSubsystems();
107 // FIXME: this is wrong.
108 // All of these are scheduled events,
109 // and it should be possible to force
110 // them all to run once.
113 cur_light_params.Update();
115 fgUpdateWeatherDatabase();
118 // Restore all of the old states.
119 FGBFI::setElevator(elevator);
120 FGBFI::setAileron(aileron);
121 FGBFI::setRudder(rudder);
122 FGBFI::setThrottle(throttle);
123 FGBFI::setElevatorTrim(elevator_trim);
124 FGBFI::setFlaps(flaps);
125 FGBFI::setBrakes(brake);
126 FGBFI::setAPHeadingLock(apHeadingLock);
127 FGBFI::setAPHeadingMag(apHeadingMag);
128 FGBFI::setAPAltitudeLock(apAltitudeLock);
129 FGBFI::setAPAltitude(apAltitude);
130 FGBFI::setTargetAirport(targetAirport);
131 FGBFI::setGPSLock(gpsLock);
135 FG_LOG(FG_GENERAL, FG_INFO, "Ending BFI reinit");
138 // BEGIN: kludge 2000-12-07
139 // This is a kludge around a LaRCsim problem; see setAltitude()
141 static int _altitude_countdown = 0;
142 static double _requested_altitude = -9999;
143 static bool _saved_freeze = false;
144 static inline void _check_altitude ()
146 if (_altitude_countdown > 0) {
147 _altitude_countdown--;
148 if (_altitude_countdown == 0) {
149 current_aircraft.fdm_state->set_Altitude(_requested_altitude);
150 globals->set_freeze(_saved_freeze);
155 static int _lighting_countdown = 0;
156 static inline void _check_lighting ()
158 if (_lighting_countdown > 0) {
159 _lighting_countdown--;
160 if (_lighting_countdown == 0)
161 fgUpdateSkyAndLightingParams();
168 // Allow the view to be set from two axes (i.e. a joystick hat)
169 // This needs to be in FGViewer itself, somehow.
170 static double axisLong = 0.0;
171 static double axisLat = 0.0;
174 _set_view_from_axes ()
176 // Take no action when hat is centered
177 if (axisLong == 0 && axisLat == 0)
182 if (axisLong < 0) { // Longitudinal axis forward
185 else if (axisLat > 0)
189 } else if (axisLong > 0) { // Longitudinal axis backward
192 else if (axisLat > 0)
196 } else { // Longitudinal axis neutral
203 globals->get_current_view()->set_goal_view_offset(viewDir*DEG_TO_RAD);
204 // globals->get_current_view()->set_view_offset(viewDir*DEG_TO_RAD);
211 ////////////////////////////////////////////////////////////////////////
213 ////////////////////////////////////////////////////////////////////////
216 * Initialize the BFI by binding its functions to properties.
218 * TODO: perhaps these should migrate into the individual modules
219 * (i.e. they should register themselves).
224 FG_LOG(FG_GENERAL, FG_INFO, "Starting BFI init");
226 fgTie("/sim/flight-model", getFlightModel, setFlightModel);
227 fgTie("/sim/aircraft", getAircraft, setAircraft);
228 fgTie("/sim/aircraft-dir", getAircraftDir, setAircraftDir);
229 fgTie("/sim/time/gmt", getDateString, setDateString);
230 fgTie("/sim/time/gmt-string", getGMTString);
231 fgTie("/sim/hud/visibility", getHUDVisible, setHUDVisible);
232 fgTie("/sim/panel/visibility", getPanelVisible, setPanelVisible);
233 fgTie("/sim/panel/x-offset", getPanelXOffset, setPanelXOffset);
234 fgTie("/sim/panel/y-offset", getPanelYOffset, setPanelYOffset);
237 fgTie("/position/airport-id", getTargetAirport, setTargetAirport);
238 fgTie("/position/latitude", getLatitude, setLatitude);
239 fgTie("/position/longitude", getLongitude, setLongitude);
240 fgTie("/position/altitude", getAltitude, setAltitude);
241 fgTie("/position/altitude-agl", getAGL);
244 fgTie("/orientation/heading", getHeading, setHeading);
245 fgTie("/orientation/heading-magnetic", getHeadingMag);
246 fgTie("/orientation/pitch", getPitch, setPitch);
247 fgTie("/orientation/roll", getRoll, setRoll);
250 fgTie("/engines/engine0/rpm", getRPM);
251 fgTie("/engines/engine0/egt", getEGT);
252 fgTie("/engines/engine0/cht", getCHT);
253 fgTie("/engines/engine0/mp", getMP);
256 fgTie("/velocities/airspeed", getAirspeed, setAirspeed);
257 fgTie("/velocities/side-slip", getSideSlip);
258 fgTie("/velocities/vertical-speed", getVerticalSpeed);
259 fgTie("/velocities/speed-north", getSpeedNorth);
260 fgTie("/velocities/speed-east", getSpeedEast);
261 fgTie("/velocities/speed-down", getSpeedDown);
265 fgTie("/controls/throttle", getThrottle, setThrottle);
266 fgTie("/controls/mixture", getMixture, setMixture);
267 fgTie("/controls/propellor-pitch", getPropAdvance, setPropAdvance);
268 fgTie("/controls/flaps", getFlaps, setFlaps);
269 fgTie("/controls/aileron", getAileron, setAileron);
270 fgTie("/controls/rudder", getRudder, setRudder);
271 fgTie("/controls/elevator", getElevator, setElevator);
272 fgTie("/controls/elevator-trim", getElevatorTrim, setElevatorTrim);
273 fgTie("/controls/brakes/all", getBrakes, setBrakes);
274 fgTie("/controls/brakes/left", getLeftBrake, setLeftBrake);
275 fgTie("/controls/brakes/right", getRightBrake, setRightBrake);
276 fgTie("/controls/brakes/center", getRightBrake, setCenterBrake);
280 fgTie("/autopilot/locks/altitude", getAPAltitudeLock, setAPAltitudeLock);
281 fgTie("/autopilot/settings/altitude", getAPAltitude, setAPAltitude);
282 fgTie("/autopilot/locks/heading", getAPHeadingLock, setAPHeadingLock);
283 fgTie("/autopilot/settings/heading", getAPHeading, setAPHeading);
284 fgTie("/autopilot/settings/heading-magnetic",
285 getAPHeadingMag, setAPHeadingMag);
286 fgTie("/autopilot/locks/nav1", getAPNAV1Lock, setAPNAV1Lock);
289 fgTie("/radios/nav1/frequencies/selected", getNAV1Freq, setNAV1Freq);
290 fgTie("/radios/nav1/frequencies/standby", getNAV1AltFreq, setNAV1AltFreq);
291 fgTie("/radios/nav1/radials/actual", getNAV1Radial);
292 fgTie("/radios/nav1/radials/selected",
293 getNAV1SelRadial, setNAV1SelRadial);
294 fgTie("/radios/nav1/dme/distance", getNAV1DistDME);
295 fgTie("/radios/nav1/to-flag", getNAV1TO);
296 fgTie("/radios/nav1/from-flag", getNAV1FROM);
297 fgTie("/radios/nav1/in-range", getNAV1InRange);
298 fgTie("/radios/nav1/dme/in-range", getNAV1DMEInRange);
300 fgTie("/radios/nav2/frequencies/selected", getNAV2Freq, setNAV2Freq);
301 fgTie("/radios/nav2/frequencies/standby",
302 getNAV2AltFreq, setNAV2AltFreq);
303 fgTie("/radios/nav2/radials/actual", getNAV2Radial);
304 fgTie("/radios/nav2/radials/selected",
305 getNAV2SelRadial, setNAV2SelRadial);
306 fgTie("/radios/nav2/dme/distance", getNAV2DistDME);
307 fgTie("/radios/nav2/to-flag", getNAV2TO);
308 fgTie("/radios/nav2/from-flag", getNAV2FROM);
309 fgTie("/radios/nav2/in-range", getNAV2InRange);
310 fgTie("/radios/nav2/dme/in-range", getNAV2DMEInRange);
312 fgTie("/radios/adf/frequencies/selected", getADFFreq, setADFFreq);
313 fgTie("/radios/adf/frequencies/standby", getADFAltFreq, setADFAltFreq);
314 fgTie("/radios/adf/rotation", getADFRotation, setADFRotation);
317 fgTie("/environment/visibility", getVisibility, setVisibility);
318 fgTie("/environment/wind-north", getWindNorth, setWindNorth);
319 fgTie("/environment/wind-east", getWindEast, setWindEast);
320 fgTie("/environment/wind-down", getWindDown, setWindDown);
323 fgTie("/sim/view/axes/long", (double(*)())0, setViewAxisLong);
324 fgTie("/sim/view/axes/lat", (double(*)())0, setViewAxisLat);
326 _altitude_countdown = 0;
329 FG_LOG(FG_GENERAL, FG_INFO, "Ending BFI init");
334 * Reinitialize FGFS if required.
336 * Some changes (especially those in aircraft position) require that
337 * FGFS be reinitialized afterwards. Rather than reinitialize after
338 * every change, the setter methods simply set a flag so that there
339 * can be a single reinit at the end of the frame.
346 _set_view_from_axes();
354 ////////////////////////////////////////////////////////////////////////
356 ////////////////////////////////////////////////////////////////////////
360 * Return the flight model as an integer.
362 * TODO: use a string instead.
365 FGBFI::getFlightModel ()
367 return globals->get_options()->get_flight_model();
372 * Return the current aircraft as a string.
375 FGBFI::getAircraft ()
377 _temp = globals->get_options()->get_aircraft();
383 * Return the current aircraft directory (UIUC) as a string.
386 FGBFI::getAircraftDir ()
388 _temp = aircraft_dir;
394 * Set the flight model as an integer.
396 * TODO: use a string instead.
399 FGBFI::setFlightModel (int model)
401 if (getFlightModel() != model) {
402 globals->get_options()->set_flight_model(model);
409 * Set the current aircraft.
412 FGBFI::setAircraft (string aircraft)
414 if (getAircraft() != aircraft) {
415 globals->get_options()->set_aircraft(aircraft);
422 * Set the current aircraft directory (UIUC).
425 FGBFI::setAircraftDir (string dir)
427 if (getAircraftDir() != dir) {
435 * Return the current Zulu time.
438 FGBFI::getDateString ()
442 struct tm * t = globals->get_time_params()->getGmt();
443 sprintf(buf, "%.4d-%.2d-%.2dT%.2d:%.2d:%.2d",
444 t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
445 t->tm_hour, t->tm_min, t->tm_sec);
452 * Set the current Zulu time.
455 FGBFI::setDateString (string date_string)
456 // FGBFI::setTimeGMT (time_t time)
458 SGTime * st = globals->get_time_params();
459 struct tm * current_time = st->getGmt();
462 // Scan for basic ISO format
463 // YYYY-MM-DDTHH:MM:SS
464 int ret = sscanf(date_string.c_str(), "%d-%d-%dT%d:%d:%d",
465 &(new_time.tm_year), &(new_time.tm_mon),
466 &(new_time.tm_mday), &(new_time.tm_hour),
467 &(new_time.tm_min), &(new_time.tm_sec));
469 // Be pretty picky about this, so
470 // that strange things don't happen
471 // if the save file has been edited
474 FG_LOG(FG_INPUT, FG_ALERT, "Date/time string " << date_string
475 << " not in YYYY-MM-DDTHH:MM:SS format; skipped");
479 // OK, it looks like we got six
480 // values, one way or another.
481 new_time.tm_year -= 1900;
482 new_time.tm_mon -= 1;
484 // Now, tell flight gear to use
485 // the new time. This was far
486 // too difficult, by the way.
488 mktime(&new_time) - mktime(current_time) + globals->get_warp();
489 double lon = current_aircraft.fdm_state->get_Longitude();
490 double lat = current_aircraft.fdm_state->get_Latitude();
491 double alt = current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER;
492 globals->set_warp(warp);
493 st->update(lon, lat, warp);
494 fgUpdateSkyAndLightingParams();
499 * Return the GMT as a string.
502 FGBFI::getGMTString ()
506 struct tm * t = globals->get_time_params()->getGmt();
507 sprintf(buf, " %.2d:%.2d:%.2d",
508 t->tm_hour, t->tm_min, t->tm_sec);
515 * Return true if the HUD is visible.
518 FGBFI::getHUDVisible ()
520 return globals->get_options()->get_hud_status();
525 * Ensure that the HUD is visible or hidden.
528 FGBFI::setHUDVisible (bool visible)
530 globals->get_options()->set_hud_status(visible);
535 * Return true if the 2D panel is visible.
538 FGBFI::getPanelVisible ()
540 return globals->get_options()->get_panel_status();
545 * Ensure that the 2D panel is visible or hidden.
548 FGBFI::setPanelVisible (bool visible)
550 if (globals->get_options()->get_panel_status() != visible) {
551 globals->get_options()->toggle_panel();
557 * Get the panel's current x-shift.
560 FGBFI::getPanelXOffset ()
562 if (current_panel != 0)
563 return current_panel->getXOffset();
570 * Set the panel's current x-shift.
573 FGBFI::setPanelXOffset (int offset)
575 if (current_panel != 0)
576 current_panel->setXOffset(offset);
581 * Get the panel's current y-shift.
584 FGBFI::getPanelYOffset ()
586 if (current_panel != 0)
587 return current_panel->getYOffset();
594 * Set the panel's current y-shift.
597 FGBFI::setPanelYOffset (int offset)
599 if (current_panel != 0)
600 current_panel->setYOffset(offset);
607 ////////////////////////////////////////////////////////////////////////
609 ////////////////////////////////////////////////////////////////////////
613 * Return the current latitude in degrees (negative for south).
616 FGBFI::getLatitude ()
618 return current_aircraft.fdm_state->get_Latitude() * RAD_TO_DEG;
623 * Set the current latitude in degrees (negative for south).
626 FGBFI::setLatitude (double latitude)
628 current_aircraft.fdm_state->set_Latitude(latitude * DEG_TO_RAD);
629 fgUpdateSkyAndLightingParams();
630 if (_lighting_countdown <= 0)
631 _lighting_countdown = 5;
636 * Return the current longitude in degrees (negative for west).
639 FGBFI::getLongitude ()
641 return current_aircraft.fdm_state->get_Longitude() * RAD_TO_DEG;
646 * Set the current longitude in degrees (negative for west).
649 FGBFI::setLongitude (double longitude)
651 current_aircraft.fdm_state->set_Longitude(longitude * DEG_TO_RAD);
652 fgUpdateSkyAndLightingParams();
653 if (_lighting_countdown <= 0)
654 _lighting_countdown = 5;
659 * Return the current altitude in feet.
662 FGBFI::getAltitude ()
664 return current_aircraft.fdm_state->get_Altitude();
670 * Return the current altitude in above the terrain.
675 return current_aircraft.fdm_state->get_Altitude()
676 - (scenery.cur_elev * METER_TO_FEET);
681 * Set the current altitude in feet.
684 FGBFI::setAltitude (double altitude)
686 current_aircraft.fdm_state->set_Altitude(altitude);
689 // This is an ugly kludge around a
690 // LaRCsim problem; if the
691 // requested altitude cannot be
692 // set right away (because it's
693 // below the last-calculated ground
694 // level), pause FGFS, wait for
695 // five frames, and then try again.
696 if (_altitude_countdown <= 0 &&
697 fabs(getAltitude() - altitude) > 5.0) {
698 _altitude_countdown = 5;
699 _requested_altitude = altitude;
700 _saved_freeze = globals->get_freeze();
701 globals->set_freeze(true);
707 ////////////////////////////////////////////////////////////////////////
709 ////////////////////////////////////////////////////////////////////////
713 * Return the current heading in degrees.
718 return current_aircraft.fdm_state->get_Psi() * RAD_TO_DEG;
723 * Return the current heading in degrees.
726 FGBFI::getHeadingMag ()
728 return current_aircraft.fdm_state->get_Psi() * RAD_TO_DEG - getMagVar();
733 * Set the current heading in degrees.
736 FGBFI::setHeading (double heading)
738 FGInterface * fdm = current_aircraft.fdm_state;
739 fdm->set_Euler_Angles(fdm->get_Phi(), fdm->get_Theta(),
740 heading * DEG_TO_RAD);
745 * Return the current pitch in degrees.
750 return current_aircraft.fdm_state->get_Theta() * RAD_TO_DEG;
755 * Set the current pitch in degrees.
758 FGBFI::setPitch (double pitch)
760 FGInterface * fdm = current_aircraft.fdm_state;
761 fdm->set_Euler_Angles(fdm->get_Phi(), pitch * DEG_TO_RAD, fdm->get_Psi());
766 * Return the current roll in degrees.
771 return current_aircraft.fdm_state->get_Phi() * RAD_TO_DEG;
776 * Set the current roll in degrees.
779 FGBFI::setRoll (double roll)
781 FGInterface * fdm = current_aircraft.fdm_state;
782 fdm->set_Euler_Angles(roll * DEG_TO_RAD, fdm->get_Theta(), fdm->get_Psi());
787 * Return the current engine0 rpm
792 if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
793 return current_aircraft.fdm_state->get_engine(0)->get_RPM();
801 * Set the current engine0 rpm
804 FGBFI::setRPM (double rpm)
806 if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
807 if (getRPM() != rpm) {
808 current_aircraft.fdm_state->get_engine(0)->set_RPM( rpm );
815 * Return the current engine0 EGT.
820 if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
821 return current_aircraft.fdm_state->get_engine(0)->get_EGT();
829 * Return the current engine0 CHT.
834 if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
835 return current_aircraft.fdm_state->get_engine(0)->get_CHT();
843 * Return the current engine0 CHT.
848 if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
849 return current_aircraft.fdm_state->get_engine(0)->get_Manifold_Pressure();
857 ////////////////////////////////////////////////////////////////////////
859 ////////////////////////////////////////////////////////////////////////
863 * Return the current airspeed in knots.
866 FGBFI::getAirspeed ()
868 // FIXME: should we add speed-up?
869 return current_aircraft.fdm_state->get_V_calibrated_kts();
874 * Set the calibrated airspeed in knots.
877 FGBFI::setAirspeed (double speed)
879 current_aircraft.fdm_state->set_V_calibrated_kts(speed);
884 * Return the current sideslip (FIXME: units unknown).
887 FGBFI::getSideSlip ()
889 return current_aircraft.fdm_state->get_Beta();
894 * Return the current climb rate in feet/minute
897 FGBFI::getVerticalSpeed ()
899 // What about meters?
900 return current_aircraft.fdm_state->get_Climb_Rate() * 60.0;
905 * Get the current north velocity (units??).
908 FGBFI::getSpeedNorth ()
910 return current_aircraft.fdm_state->get_V_north();
915 // * Set the current north velocity (units??).
918 // FGBFI::setSpeedNorth (double speed)
920 // FGInterface * fdm = current_aircraft.fdm_state;
921 // // fdm->set_Velocities_Local(speed, fdm->get_V_east(), fdm->get_V_down());
926 * Get the current east velocity (units??).
929 FGBFI::getSpeedEast ()
931 return current_aircraft.fdm_state->get_V_east();
936 // * Set the current east velocity (units??).
939 // FGBFI::setSpeedEast (double speed)
941 // FGInterface * fdm = current_aircraft.fdm_state;
942 // // fdm->set_Velocities_Local(fdm->get_V_north(), speed, fdm->get_V_down());
947 * Get the current down velocity (units??).
950 FGBFI::getSpeedDown ()
952 return current_aircraft.fdm_state->get_V_down();
957 // * Set the current down velocity (units??).
960 // FGBFI::setSpeedDown (double speed)
962 // FGInterface * fdm = current_aircraft.fdm_state;
963 // // fdm->set_Velocities_Local(fdm->get_V_north(), fdm->get_V_east(), speed);
968 ////////////////////////////////////////////////////////////////////////
970 ////////////////////////////////////////////////////////////////////////
974 * Get the throttle setting, from 0.0 (none) to 1.0 (full).
977 FGBFI::getThrottle ()
979 // FIXME: add engine selector
980 return controls.get_throttle(0);
985 * Set the throttle, from 0.0 (none) to 1.0 (full).
988 FGBFI::setThrottle (double throttle)
990 // FIXME: allow engine selection
991 controls.set_throttle(0, throttle);
996 * Get the fuel mixture setting, from 0.0 (none) to 1.0 (full).
1001 // FIXME: add engine selector
1002 return controls.get_mixture(0);
1007 * Set the fuel mixture, from 0.0 (none) to 1.0 (full).
1010 FGBFI::setMixture (double mixture)
1012 // FIXME: allow engine selection
1013 controls.set_mixture(0, mixture);
1018 * Get the propellor pitch setting, from 0.0 (none) to 1.0 (full).
1021 FGBFI::getPropAdvance ()
1023 // FIXME: add engine selector
1024 return controls.get_prop_advance(0);
1029 * Set the propellor pitch, from 0.0 (none) to 1.0 (full).
1032 FGBFI::setPropAdvance (double pitch)
1034 // FIXME: allow engine selection
1035 controls.set_prop_advance(0, pitch);
1040 * Get the flaps setting, from 0.0 (none) to 1.0 (full).
1045 return controls.get_flaps();
1050 * Set the flaps, from 0.0 (none) to 1.0 (full).
1053 FGBFI::setFlaps (double flaps)
1056 controls.set_flaps(flaps);
1061 * Get the aileron, from -1.0 (left) to 1.0 (right).
1064 FGBFI::getAileron ()
1066 return controls.get_aileron();
1071 * Set the aileron, from -1.0 (left) to 1.0 (right).
1074 FGBFI::setAileron (double aileron)
1077 controls.set_aileron(aileron);
1082 * Get the rudder setting, from -1.0 (left) to 1.0 (right).
1087 return controls.get_rudder();
1092 * Set the rudder, from -1.0 (left) to 1.0 (right).
1095 FGBFI::setRudder (double rudder)
1098 controls.set_rudder(rudder);
1103 * Get the elevator setting, from -1.0 (down) to 1.0 (up).
1106 FGBFI::getElevator ()
1108 return controls.get_elevator();
1113 * Set the elevator, from -1.0 (down) to 1.0 (up).
1116 FGBFI::setElevator (double elevator)
1119 controls.set_elevator(elevator);
1124 * Get the elevator trim, from -1.0 (down) to 1.0 (up).
1127 FGBFI::getElevatorTrim ()
1129 return controls.get_elevator_trim();
1134 * Set the elevator trim, from -1.0 (down) to 1.0 (up).
1137 FGBFI::setElevatorTrim (double trim)
1140 controls.set_elevator_trim(trim);
1145 * Get the highest brake setting, from 0.0 (none) to 1.0 (full).
1150 double b1 = getCenterBrake();
1151 double b2 = getLeftBrake();
1152 double b3 = getRightBrake();
1153 return (b1 > b2 ? (b1 > b3 ? b1 : b3) : (b2 > b3 ? b2 : b3));
1158 * Set all brakes, from 0.0 (none) to 1.0 (full).
1161 FGBFI::setBrakes (double brake)
1163 setCenterBrake(brake);
1164 setLeftBrake(brake);
1165 setRightBrake(brake);
1170 * Get the center brake, from 0.0 (none) to 1.0 (full).
1173 FGBFI::getCenterBrake ()
1175 return controls.get_brake(2);
1180 * Set the center brake, from 0.0 (none) to 1.0 (full).
1183 FGBFI::setCenterBrake (double brake)
1185 controls.set_brake(2, brake);
1190 * Get the left brake, from 0.0 (none) to 1.0 (full).
1193 FGBFI::getLeftBrake ()
1195 return controls.get_brake(0);
1200 * Set the left brake, from 0.0 (none) to 1.0 (full).
1203 FGBFI::setLeftBrake (double brake)
1205 controls.set_brake(0, brake);
1210 * Get the right brake, from 0.0 (none) to 1.0 (full).
1213 FGBFI::getRightBrake ()
1215 return controls.get_brake(1);
1220 * Set the right brake, from 0.0 (none) to 1.0 (full).
1223 FGBFI::setRightBrake (double brake)
1225 controls.set_brake(1, brake);
1232 ////////////////////////////////////////////////////////////////////////
1234 ////////////////////////////////////////////////////////////////////////
1238 * Get the autopilot altitude lock (true=on).
1241 FGBFI::getAPAltitudeLock ()
1243 return current_autopilot->get_AltitudeEnabled();
1248 * Set the autopilot altitude lock (true=on).
1251 FGBFI::setAPAltitudeLock (bool lock)
1253 current_autopilot->set_AltitudeMode(FGAutopilot::FG_ALTITUDE_LOCK);
1254 current_autopilot->set_AltitudeEnabled(lock);
1259 * Get the autopilot target altitude in feet.
1262 FGBFI::getAPAltitude ()
1264 return current_autopilot->get_TargetAltitude() * METER_TO_FEET;
1269 * Set the autopilot target altitude in feet.
1272 FGBFI::setAPAltitude (double altitude)
1274 current_autopilot->set_TargetAltitude( altitude );
1279 * Get the autopilot heading lock (true=on).
1282 FGBFI::getAPHeadingLock ()
1285 (current_autopilot->get_HeadingEnabled() &&
1286 current_autopilot->get_HeadingMode() == FGAutopilot::FG_HEADING_LOCK);
1291 * Set the autopilot heading lock (true=on).
1294 FGBFI::setAPHeadingLock (bool lock)
1297 // We need to do this so that
1298 // it's possible to lock onto a
1299 // heading other than the current
1301 double heading = getAPHeadingMag();
1302 current_autopilot->set_HeadingMode(FGAutopilot::FG_HEADING_LOCK);
1303 current_autopilot->set_HeadingEnabled(true);
1304 setAPHeadingMag(heading);
1305 } else if (current_autopilot->get_HeadingMode() ==
1306 FGAutopilot::FG_HEADING_LOCK) {
1307 current_autopilot->set_HeadingEnabled(false);
1313 * Get the autopilot target heading in degrees.
1316 FGBFI::getAPHeading ()
1318 return current_autopilot->get_TargetHeading();
1323 * Set the autopilot target heading in degrees.
1326 FGBFI::setAPHeading (double heading)
1328 current_autopilot->set_TargetHeading( heading );
1333 * Get the autopilot target heading in degrees.
1336 FGBFI::getAPHeadingMag ()
1338 return current_autopilot->get_TargetHeading() - getMagVar();
1343 * Set the autopilot target heading in degrees.
1346 FGBFI::setAPHeadingMag (double heading)
1348 current_autopilot->set_TargetHeading( heading + getMagVar() );
1353 * Return true if the autopilot is locked to NAV1.
1356 FGBFI::getAPNAV1Lock ()
1359 (current_autopilot->get_HeadingEnabled() &&
1360 current_autopilot->get_HeadingMode() == FGAutopilot::FG_HEADING_NAV1);
1365 * Set the autopilot NAV1 lock.
1368 FGBFI::setAPNAV1Lock (bool lock)
1371 current_autopilot->set_HeadingMode(FGAutopilot::FG_HEADING_NAV1);
1372 current_autopilot->set_HeadingEnabled(true);
1373 } else if (current_autopilot->get_HeadingMode() ==
1374 FGAutopilot::FG_HEADING_NAV1) {
1375 current_autopilot->set_HeadingEnabled(false);
1381 ////////////////////////////////////////////////////////////////////////
1382 // Radio navigation.
1383 ////////////////////////////////////////////////////////////////////////
1386 FGBFI::getNAV1Freq ()
1388 return current_radiostack->get_nav1_freq();
1392 FGBFI::getNAV1AltFreq ()
1394 return current_radiostack->get_nav1_alt_freq();
1398 FGBFI::getNAV1Radial ()
1400 return current_radiostack->get_nav1_radial();
1404 FGBFI::getNAV1SelRadial ()
1406 return current_radiostack->get_nav1_sel_radial();
1410 FGBFI::getNAV1DistDME ()
1412 return current_radiostack->get_nav1_dme_dist();
1418 if (current_radiostack->get_nav1_inrange()) {
1419 double heading = current_radiostack->get_nav1_heading();
1420 double radial = current_radiostack->get_nav1_radial();
1421 // double var = FGBFI::getMagVar();
1422 if (current_radiostack->get_nav1_loc()) {
1423 double offset = fabs(heading - radial);
1424 return (offset<= 8.0 || offset >= 352.0);
1427 // fabs(heading - var - radial);
1428 double offset = fabs(heading - radial);
1429 return (offset <= 20.0 || offset >= 340.0);
1437 FGBFI::getNAV1FROM ()
1439 if (current_radiostack->get_nav1_inrange()) {
1440 double heading = current_radiostack->get_nav1_heading();
1441 double radial = current_radiostack->get_nav1_radial();
1442 // double var = FGBFI::getMagVar();
1443 if (current_radiostack->get_nav1_loc()) {
1444 double offset = fabs(heading - radial);
1445 return (offset >= 172.0 && offset<= 188.0);
1448 // fabs(heading - var - radial);
1449 double offset = fabs(heading - radial);
1450 return (offset >= 160.0 && offset <= 200.0);
1458 FGBFI::getNAV1InRange ()
1460 return current_radiostack->get_nav1_inrange();
1464 FGBFI::getNAV1DMEInRange ()
1466 return (current_radiostack->get_nav1_inrange() &&
1467 current_radiostack->get_nav1_has_dme());
1471 FGBFI::getNAV2Freq ()
1473 return current_radiostack->get_nav2_freq();
1477 FGBFI::getNAV2AltFreq ()
1479 return current_radiostack->get_nav2_alt_freq();
1483 FGBFI::getNAV2Radial ()
1485 return current_radiostack->get_nav2_radial();
1489 FGBFI::getNAV2SelRadial ()
1491 return current_radiostack->get_nav2_sel_radial();
1495 FGBFI::getNAV2DistDME ()
1497 return current_radiostack->get_nav2_dme_dist();
1503 if (current_radiostack->get_nav2_inrange()) {
1504 double heading = current_radiostack->get_nav2_heading();
1505 double radial = current_radiostack->get_nav2_radial();
1506 // double var = FGBFI::getMagVar();
1507 if (current_radiostack->get_nav2_loc()) {
1508 double offset = fabs(heading - radial);
1509 return (offset<= 8.0 || offset >= 352.0);
1512 // fabs(heading - var - radial);
1513 double offset = fabs(heading - radial);
1514 return (offset <= 20.0 || offset >= 340.0);
1522 FGBFI::getNAV2FROM ()
1524 if (current_radiostack->get_nav2_inrange()) {
1525 double heading = current_radiostack->get_nav2_heading();
1526 double radial = current_radiostack->get_nav2_radial();
1527 // double var = FGBFI::getMagVar();
1528 if (current_radiostack->get_nav2_loc()) {
1529 double offset = fabs(heading - radial);
1530 return (offset >= 172.0 && offset<= 188.0);
1533 // fabs(heading - var - radial);
1534 double offset = fabs(heading - radial);
1535 return (offset >= 160.0 && offset <= 200.0);
1544 FGBFI::getNAV2InRange ()
1546 return current_radiostack->get_nav2_inrange();
1550 FGBFI::getNAV2DMEInRange ()
1552 return (current_radiostack->get_nav2_inrange() &&
1553 current_radiostack->get_nav2_has_dme());
1557 FGBFI::getADFFreq ()
1559 return current_radiostack->get_adf_freq();
1563 FGBFI::getADFAltFreq ()
1565 return current_radiostack->get_adf_alt_freq();
1569 FGBFI::getADFRotation ()
1571 return current_radiostack->get_adf_rotation();
1575 FGBFI::setNAV1Freq (double freq)
1577 current_radiostack->set_nav1_freq(freq);
1581 FGBFI::setNAV1AltFreq (double freq)
1583 current_radiostack->set_nav1_alt_freq(freq);
1587 FGBFI::setNAV1SelRadial (double radial)
1589 current_radiostack->set_nav1_sel_radial(radial);
1593 FGBFI::setNAV2Freq (double freq)
1595 current_radiostack->set_nav2_freq(freq);
1599 FGBFI::setNAV2AltFreq (double freq)
1601 current_radiostack->set_nav2_alt_freq(freq);
1605 FGBFI::setNAV2SelRadial (double radial)
1607 current_radiostack->set_nav2_sel_radial(radial);
1611 FGBFI::setADFFreq (double freq)
1613 current_radiostack->set_adf_freq(freq);
1617 FGBFI::setADFAltFreq (double freq)
1619 current_radiostack->set_adf_alt_freq(freq);
1623 FGBFI::setADFRotation (double rot)
1625 current_radiostack->set_adf_rotation(rot);
1630 ////////////////////////////////////////////////////////////////////////
1632 ////////////////////////////////////////////////////////////////////////
1636 * Get the autopilot GPS lock (true=on).
1639 FGBFI::getGPSLock ()
1641 return (current_autopilot->get_HeadingEnabled() &&
1642 (current_autopilot->get_HeadingMode() ==
1643 FGAutopilot::FG_HEADING_WAYPOINT ));
1648 * Set the autopilot GPS lock (true=on).
1651 FGBFI::setGPSLock (bool lock)
1654 current_autopilot->set_HeadingMode(FGAutopilot::FG_HEADING_WAYPOINT);
1655 current_autopilot->set_HeadingEnabled(true);
1656 } else if (current_autopilot->get_HeadingMode() ==
1657 FGAutopilot::FG_HEADING_WAYPOINT) {
1658 current_autopilot->set_HeadingEnabled(false);
1664 * Get the GPS target airport code.
1667 FGBFI::getTargetAirport ()
1669 // FIXME: not thread-safe
1671 out = globals->get_options()->get_airport_id();
1678 * Set the GPS target airport code.
1681 FGBFI::setTargetAirport (string airportId)
1683 globals->get_options()->set_airport_id(airportId);
1688 * Get the GPS target latitude in degrees (negative for south).
1691 FGBFI::getGPSTargetLatitude ()
1693 return current_autopilot->get_TargetLatitude();
1698 * Get the GPS target longitude in degrees (negative for west).
1701 FGBFI::getGPSTargetLongitude ()
1703 return current_autopilot->get_TargetLongitude();
1708 * Set the GPS target longitude in degrees (negative for west).
1711 FGBFI::setGPSTargetLongitude (double longitude)
1713 current_autopilot->set_TargetLongitude( longitude );
1719 ////////////////////////////////////////////////////////////////////////
1721 ////////////////////////////////////////////////////////////////////////
1725 * Get the current visibility (meters).
1728 FGBFI::getVisibility ()
1730 #ifndef FG_OLD_WEATHER
1731 return WeatherDatabase->getWeatherVisibility();
1733 return current_weather.get_visibility();
1739 * Set the current visibility (meters).
1742 FGBFI::setVisibility (double visibility)
1744 #ifndef FG_OLD_WEATHER
1745 WeatherDatabase->setWeatherVisibility(visibility);
1747 current_weather.set_visibility(visibility);
1753 * Get the current wind north velocity (feet/second).
1756 FGBFI::getWindNorth ()
1758 return current_aircraft.fdm_state->get_V_north_airmass();
1763 * Set the current wind north velocity (feet/second).
1766 FGBFI::setWindNorth (double speed)
1768 current_aircraft.fdm_state->set_Velocities_Local_Airmass(speed,
1775 * Get the current wind east velocity (feet/second).
1778 FGBFI::getWindEast ()
1780 return current_aircraft.fdm_state->get_V_east_airmass();
1785 * Set the current wind east velocity (feet/second).
1788 FGBFI::setWindEast (double speed)
1790 cout << "Set wind-east to " << speed << endl;
1791 current_aircraft.fdm_state->set_Velocities_Local_Airmass(getWindNorth(),
1798 * Get the current wind down velocity (feet/second).
1801 FGBFI::getWindDown ()
1803 return current_aircraft.fdm_state->get_V_down_airmass();
1808 * Set the current wind down velocity (feet/second).
1811 FGBFI::setWindDown (double speed)
1813 current_aircraft.fdm_state->set_Velocities_Local_Airmass(getWindNorth(),
1820 ////////////////////////////////////////////////////////////////////////
1822 ////////////////////////////////////////////////////////////////////////
1825 FGBFI::setViewAxisLong (double axis)
1831 FGBFI::setViewAxisLat (double axis)
1837 ////////////////////////////////////////////////////////////////////////
1839 ////////////////////////////////////////////////////////////////////////
1842 * Return the magnetic variation
1847 return globals->get_mag()->get_magvar() * RAD_TO_DEG;
1852 * Return the magnetic variation
1857 return globals->get_mag()->get_magdip() * RAD_TO_DEG;