]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/bfi.cxx
Moved sky code over to simgear.
[flightgear.git] / src / Main / bfi.cxx
index ee0e108e5d77eb74156f736c565576ece4ce1500..cdc577cbed52b30e99fdb1f6f6407d299e52f401 100644 (file)
 #endif
 
 #include <simgear/constants.h>
+#include <simgear/debug/logstream.hxx>
 #include <simgear/math/fg_types.hxx>
+#include <simgear/misc/props.hxx>
 
 #include <Aircraft/aircraft.hxx>
+#include <FDM/UIUCModel/uiuc_aircraftdir.h>
 #include <Controls/controls.hxx>
-#include <Autopilot/autopilot.hxx>
+#include <Autopilot/newauto.hxx>
+#include <Scenery/scenery.hxx>
 #include <Time/fg_time.hxx>
 #include <Time/light.hxx>
+#include <Time/event.hxx>
+#include <Time/sunpos.hxx>
+#include <Cockpit/radiostack.hxx>
+#include <Ephemeris/ephemeris.hxx>
 #ifndef FG_OLD_WEATHER
 #  include <WeatherCM/FGLocalWeatherDatabase.h>
 #else
 
 FG_USING_NAMESPACE(std);
 
-                               // FIXME: these are not part of the
-                               // published interface!!!
-extern fgAPDataPtr APDataGlobal;
-extern void fgAPAltitudeSet (double new_altitude);
-extern void fgAPHeadingSet (double new_heading);
-
 
 #include "bfi.hxx"
 
@@ -75,6 +77,131 @@ bool FGBFI::_needReinit = false;
 ////////////////////////////////////////////////////////////////////////
 
 
+/**
+ * Initialize the BFI by binding its functions to properties.
+ *
+ * TODO: perhaps these should migrate into the individual modules
+ * (i.e. they should register themselves).
+ */
+void
+FGBFI::init ()
+{
+  FG_LOG(FG_GENERAL, FG_INFO, "Starting BFI init");
+                               // Simulation
+  current_properties.tieInt("/sim/flight-model",
+                           getFlightModel, setFlightModel);
+//   current_properties.tieString("/sim/aircraft",
+//                            getAircraft, setAircraft);
+  // TODO: timeGMT
+  current_properties.tieBool("/sim/hud/visibility",
+                            getHUDVisible, setHUDVisible);
+  current_properties.tieBool("/sim/panel/visibility",
+                            getPanelVisible, setPanelVisible);
+
+                               // Position
+  current_properties.tieDouble("/position/latitude",
+                               getLatitude, setLatitude);
+  current_properties.tieDouble("/position/longitude",
+                              getLongitude, setLongitude);
+  current_properties.tieDouble("/position/altitude",
+                              getAltitude, setAltitude);
+  current_properties.tieDouble("/position/altitude-agl",
+                              getAGL, 0);
+
+                               // Orientation
+  current_properties.tieDouble("/orientation/heading",
+                              getHeading, setHeading);
+  current_properties.tieDouble("/orientation/heading-magnetic",
+                              getHeadingMag, 0);
+  current_properties.tieDouble("/orientation/pitch",
+                              getPitch, setPitch);
+  current_properties.tieDouble("/orientation/roll",
+                              getRoll, setRoll);
+
+                               // Velocities
+  current_properties.tieDouble("/velocities/airspeed",
+                              getAirspeed, 0);
+  current_properties.tieDouble("/velocities/side-slip",
+                              getSideSlip, 0);
+  current_properties.tieDouble("/velocities/vertical-speed",
+                              getVerticalSpeed, 0);
+  current_properties.tieDouble("/velocities/speed-north",
+                              getSpeedNorth, setSpeedNorth);
+  current_properties.tieDouble("/velocities/speed-east",
+                              getSpeedEast, setSpeedEast);
+  current_properties.tieDouble("/velocities/speed-down",
+                              getSpeedDown, setSpeedDown);
+
+                               // Controls
+  current_properties.tieDouble("/controls/throttle",
+                              getThrottle, setThrottle);
+  current_properties.tieDouble("/controls/flaps",
+                              getFlaps, setFlaps);
+  current_properties.tieDouble("/controls/aileron",
+                              getAileron, setAileron);
+  current_properties.tieDouble("/controls/rudder",
+                              getRudder, setRudder);
+  current_properties.tieDouble("/controls/elevator",
+                              getElevator, setElevator);
+  current_properties.tieDouble("/controls/elevator-trim",
+                              getElevatorTrim, setElevatorTrim);
+  current_properties.tieDouble("/controls/brake",
+                              getBrake, setBrake);
+
+                               // Autopilot
+  current_properties.tieBool("/autopilot/locks/altitude",
+                            getAPAltitudeLock, setAPAltitudeLock);
+  current_properties.tieDouble("/autopilot/settings/altitude",
+                              getAPAltitude, setAPAltitude);
+  current_properties.tieBool("/autopilot/locks/heading",
+                            getAPHeadingLock, setAPHeadingLock);
+  current_properties.tieDouble("/autopilot/settings/heading-magnetic",
+                              getAPHeadingMag, setAPHeadingMag);
+  current_properties.tieBool("/autopilot/locks/nav1",
+                            getAPNAV1Lock, setAPNAV1Lock);
+
+                               // Radio navigation
+  current_properties.tieDouble("/radios/nav1/frequencies/selected",
+                              getNAV1Freq, setNAV1Freq);
+  current_properties.tieDouble("/radios/nav1/frequencies/standby",
+                              getNAV1AltFreq, setNAV1AltFreq);
+  current_properties.tieDouble("/radios/nav1/radials/actual",
+                              getNAV1Radial, 0);
+  current_properties.tieDouble("/radios/nav1/radials/selected",
+                              getNAV1SelRadial, setNAV1SelRadial);
+  current_properties.tieDouble("/radios/nav1/dme/distance",
+                              getNAV1DistDME, 0);
+  current_properties.tieBool("/radios/nav1/in-range",
+                            getNAV1InRange, 0);
+  current_properties.tieBool("/radios/nav1/dme/in-range",
+                            getNAV1DMEInRange, 0);
+                              
+  current_properties.tieDouble("/radios/nav2/frequencies/selected",
+                              getNAV2Freq, setNAV2Freq);
+  current_properties.tieDouble("/radios/nav2/frequencies/standby",
+                              getNAV2AltFreq, setNAV2AltFreq);
+  current_properties.tieDouble("/radios/nav2/radials/actual",
+                              getNAV2Radial, 0);
+  current_properties.tieDouble("/radios/nav2/radials/selected",
+                              getNAV2SelRadial, setNAV2SelRadial);
+  current_properties.tieDouble("/radios/nav2/dme/distance",
+                              getNAV2DistDME, 0);
+  current_properties.tieBool("/radios/nav2/in-range",
+                            getNAV2InRange, 0);
+  current_properties.tieBool("/radios/nav2/dme/in-range",
+                            getNAV2DMEInRange, 0);
+
+  current_properties.tieDouble("/radios/adf/frequencies/selected",
+                              getADFFreq, setADFFreq);
+  current_properties.tieDouble("/radios/adf/frequencies/standby",
+                              getADFAltFreq, setADFAltFreq);
+  current_properties.tieDouble("/radios/adf/rotation",
+                              getADFRotation, setADFRotation);
+
+  FG_LOG(FG_GENERAL, FG_INFO, "Ending BFI init");
+}
+
+
 /**
  * Reinitialize FGFS if required.
  *
@@ -102,6 +229,18 @@ FGBFI::reinit ()
                                // that's going to get clobbered
                                // when we reinit the subsystems.
 
+  cout << "BFI: start reinit\n";
+
+  setHeading(getHeading());
+  setPitch(getPitch());
+  setRoll(getRoll());
+  setSpeedNorth(getSpeedNorth());
+  setSpeedEast(getSpeedEast());
+  setSpeedDown(getSpeedDown());
+  setLatitude(getLatitude());
+  setLongitude(getLongitude());
+  setAltitude(getAltitude());
+
                                // TODO: add more AP stuff
   double elevator = getElevator();
   double aileron = getAileron();
@@ -111,7 +250,7 @@ FGBFI::reinit ()
   double flaps = getFlaps();
   double brake = getBrake();
   bool apHeadingLock = getAPHeadingLock();
-  double apHeading = getAPHeading();
+  double apHeadingMag = getAPHeadingMag();
   bool apAltitudeLock = getAPAltitudeLock();
   double apAltitude = getAPAltitude();
   const string &targetAirport = getTargetAirport();
@@ -119,9 +258,21 @@ FGBFI::reinit ()
   double gpsLatitude = getGPSTargetLatitude();
   double gpsLongitude = getGPSTargetLongitude();
 
+  setTargetAirport("");
+  cout << "Target airport is " << current_options.get_airport_id() << endl;
+
   fgReInitSubsystems();
-  // solarSystemRebuild();
+
+                               // FIXME: this is wrong.
+                               // All of these are scheduled events,
+                               // and it should be possible to force
+                               // them all to run once.
+  fgUpdateSunPos();
+  fgUpdateMoonPos();
   cur_light_params.Update();
+  FGTime::cur_time_params->updateLocal();
+  fgUpdateWeatherDatabase();
+  fgRadioSearch();
 
                                // Restore all of the old states.
   setElevator(elevator);
@@ -132,7 +283,7 @@ FGBFI::reinit ()
   setFlaps(flaps);
   setBrake(brake);
   setAPHeadingLock(apHeadingLock);
-  setAPHeading(apHeading);
+  setAPHeadingMag(apHeadingMag);
   setAPAltitudeLock(apAltitudeLock);
   setAPAltitude(apAltitude);
   setTargetAirport(targetAirport);
@@ -141,6 +292,8 @@ FGBFI::reinit ()
   setGPSTargetLongitude(gpsLongitude);
 
   _needReinit = false;
+
+  cout << "BFI: end reinit\n";
 }
 
 
@@ -162,6 +315,26 @@ FGBFI::getFlightModel ()
 }
 
 
+/**
+ * Return the current aircraft as a string.
+ */
+const string
+FGBFI::getAircraft ()
+{
+  return current_options.get_aircraft();
+}
+
+
+/**
+ * Return the current aircraft directory (UIUC) as a string.
+ */
+const string
+FGBFI::getAircraftDir ()
+{
+  return aircraft_dir;
+}
+
+
 /**
  * Set the flight model as an integer.
  *
@@ -175,14 +348,35 @@ FGBFI::setFlightModel (int model)
 }
 
 
+/**
+ * Set the current aircraft.
+ */
+void
+FGBFI::setAircraft (const string &aircraft)
+{
+  current_options.set_aircraft(aircraft);
+  needReinit();
+}
+
+
+/**
+ * Set the current aircraft directory (UIUC).
+ */
+void
+FGBFI::setAircraftDir (const string &dir)
+{
+  aircraft_dir = dir;
+  needReinit();
+}
+
+
 /**
  * Return the current Zulu time.
  */
 time_t
 FGBFI::getTimeGMT ()
 {
-                               // FIXME: inefficient
-  return mktime(FGTime::cur_time_params->getGmt());
+  return FGTime::cur_time_params->get_cur_time();
 }
 
 
@@ -271,6 +465,7 @@ void
 FGBFI::setLatitude (double latitude)
 {
   current_options.set_lat(latitude);
+  current_aircraft.fdm_state->set_Latitude(latitude * DEG_TO_RAD);
   needReinit();
 }
 
@@ -292,6 +487,7 @@ void
 FGBFI::setLongitude (double longitude)
 {
   current_options.set_lon(longitude);
+  current_aircraft.fdm_state->set_Longitude(longitude * DEG_TO_RAD);
   needReinit();
 }
 
@@ -306,14 +502,28 @@ FGBFI::getAltitude ()
 }
 
 
+
+/**
+ * Return the current altitude in above the terrain.
+ */
+double
+FGBFI::getAGL ()
+{
+  return current_aircraft.fdm_state->get_Altitude()
+        - scenery.cur_elev * METER_TO_FEET;
+}
+
+
 /**
  * Set the current altitude in feet.
  */
 void
 FGBFI::setAltitude (double altitude)
 {
-  current_options.set_altitude(altitude * FEET_TO_METER);
-  needReinit();
+  fgFDMForceAltitude(getFlightModel(), altitude * FEET_TO_METER);
+//   current_options.set_altitude(altitude * FEET_TO_METER);
+//   current_aircraft.fdm_state->set_Altitude(altitude);
+//   needReinit();
 }
 
 
@@ -333,6 +543,16 @@ FGBFI::getHeading ()
 }
 
 
+/**
+ * Return the current heading in degrees.
+ */
+double
+FGBFI::getHeadingMag ()
+{
+  return current_aircraft.fdm_state->get_Psi() * RAD_TO_DEG - getMagVar();
+}
+
+
 /**
  * Set the current heading in degrees.
  */
@@ -340,6 +560,9 @@ void
 FGBFI::setHeading (double heading)
 {
   current_options.set_heading(heading);
+  current_aircraft.fdm_state->set_Euler_Angles(getRoll() * DEG_TO_RAD,
+                                              getPitch() * DEG_TO_RAD,
+                                              heading * DEG_TO_RAD);
   needReinit();
 }
 
@@ -362,6 +585,9 @@ FGBFI::setPitch (double pitch)
 {
 
   current_options.set_pitch(pitch);
+  current_aircraft.fdm_state->set_Euler_Angles(getRoll() * DEG_TO_RAD,
+                                              pitch * DEG_TO_RAD,
+                                              getHeading() * DEG_TO_RAD);
   needReinit();
 }
 
@@ -383,6 +609,9 @@ void
 FGBFI::setRoll (double roll)
 {
   current_options.set_roll(roll);
+  current_aircraft.fdm_state->set_Euler_Angles(roll * DEG_TO_RAD,
+                                              getPitch() * DEG_TO_RAD,
+                                              getHeading() * DEG_TO_RAD);
   needReinit();
 }
 
@@ -415,7 +644,7 @@ FGBFI::getSideSlip ()
 
 
 /**
- * Return the current climb rate in feet/second (FIXME: verify).
+ * Return the current climb rate in feet/minute
  */
 double
 FGBFI::getVerticalSpeed ()
@@ -442,6 +671,9 @@ void
 FGBFI::setSpeedNorth (double speed)
 {
   current_options.set_uBody(speed);
+  current_aircraft.fdm_state->set_Velocities_Local(speed,
+                                                  getSpeedEast(),
+                                                  getSpeedDown());
   needReinit();
 }
 
@@ -463,6 +695,9 @@ void
 FGBFI::setSpeedEast (double speed)
 {
   current_options.set_vBody(speed);
+  current_aircraft.fdm_state->set_Velocities_Local(getSpeedNorth(),
+                                                  speed,
+                                                  getSpeedDown());
   needReinit();
 }
 
@@ -484,6 +719,9 @@ void
 FGBFI::setSpeedDown (double speed)
 {
   current_options.set_wBody(speed);
+  current_aircraft.fdm_state->set_Velocities_Local(getSpeedNorth(),
+                                                  getSpeedEast(),
+                                                  speed);
   needReinit();
 }
 
@@ -657,7 +895,7 @@ FGBFI::setBrake (double brake)
 bool
 FGBFI::getAPAltitudeLock ()
 {
-  return fgAPAltitudeEnabled();
+    return current_autopilot->get_AltitudeEnabled();
 }
 
 
@@ -667,7 +905,8 @@ FGBFI::getAPAltitudeLock ()
 void
 FGBFI::setAPAltitudeLock (bool lock)
 {
-  APDataGlobal->altitude_hold = lock;
+  current_autopilot->set_AltitudeMode(FGAutopilot::FG_ALTITUDE_LOCK);
+  current_autopilot->set_AltitudeEnabled(lock);
 }
 
 
@@ -677,7 +916,7 @@ FGBFI::setAPAltitudeLock (bool lock)
 double
 FGBFI::getAPAltitude ()
 {
-  return fgAPget_TargetAltitude() * METER_TO_FEET;
+  return current_autopilot->get_TargetAltitude() * METER_TO_FEET;
 }
 
 
@@ -687,7 +926,7 @@ FGBFI::getAPAltitude ()
 void
 FGBFI::setAPAltitude (double altitude)
 {
-  fgAPAltitudeSet(altitude);
+    current_autopilot->set_TargetAltitude( altitude );
 }
 
 
@@ -697,7 +936,9 @@ FGBFI::setAPAltitude (double altitude)
 bool
 FGBFI::getAPHeadingLock ()
 {
-  return fgAPHeadingEnabled();
+    return
+      (current_autopilot->get_HeadingEnabled() &&
+       current_autopilot->get_HeadingMode() == FGAutopilot::FG_HEADING_LOCK);
 }
 
 
@@ -707,7 +948,19 @@ FGBFI::getAPHeadingLock ()
 void
 FGBFI::setAPHeadingLock (bool lock)
 {
-  APDataGlobal->heading_hold = lock;
+  if (lock) {
+                               // We need to do this so that
+                               // it's possible to lock onto a
+                               // heading other than the current
+                               // heading.
+    double heading = getAPHeadingMag();
+    current_autopilot->set_HeadingMode(FGAutopilot::FG_HEADING_LOCK);
+    current_autopilot->set_HeadingEnabled(true);
+    setAPHeadingMag(heading);
+  } else if (current_autopilot->get_HeadingMode() ==
+            FGAutopilot::FG_HEADING_LOCK) {
+    current_autopilot->set_HeadingEnabled(false);
+  }
 }
 
 
@@ -715,9 +968,9 @@ FGBFI::setAPHeadingLock (bool lock)
  * Get the autopilot target heading in degrees.
  */
 double
-FGBFI::getAPHeading ()
+FGBFI::getAPHeadingMag ()
 {
-  return fgAPget_TargetHeading();
+  return current_autopilot->get_TargetHeading() - getMagVar();
 }
 
 
@@ -725,9 +978,201 @@ FGBFI::getAPHeading ()
  * Set the autopilot target heading in degrees.
  */
 void
-FGBFI::setAPHeading (double heading)
+FGBFI::setAPHeadingMag (double heading)
+{
+  current_autopilot->set_TargetHeading( heading + getMagVar() );
+}
+
+
+/**
+ * Return true if the autopilot is locked to NAV1.
+ */
+bool
+FGBFI::getAPNAV1Lock ()
 {
-  fgAPHeadingSet(heading);
+  return
+    (current_autopilot->get_HeadingEnabled() &&
+     current_autopilot->get_HeadingMode() == FGAutopilot::FG_HEADING_NAV1);
+}
+
+
+/**
+ * Set the autopilot NAV1 lock.
+ */
+void
+FGBFI::setAPNAV1Lock (bool lock)
+{
+  if (lock) {
+    current_autopilot->set_HeadingMode(FGAutopilot::FG_HEADING_NAV1);
+    current_autopilot->set_HeadingEnabled(true);
+  } else if (current_autopilot->get_HeadingMode() ==
+            FGAutopilot::FG_HEADING_NAV1) {
+    current_autopilot->set_HeadingEnabled(false);
+  }
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Radio navigation.
+////////////////////////////////////////////////////////////////////////
+
+double
+FGBFI::getNAV1Freq ()
+{
+  return current_radiostack->get_nav1_freq();
+}
+
+double
+FGBFI::getNAV1AltFreq ()
+{
+  return current_radiostack->get_nav1_alt_freq();
+}
+
+double
+FGBFI::getNAV1Radial ()
+{
+  return current_radiostack->get_nav1_radial();
+}
+
+double
+FGBFI::getNAV1SelRadial ()
+{
+  return current_radiostack->get_nav1_sel_radial();
+}
+
+double
+FGBFI::getNAV1DistDME ()
+{
+  return current_radiostack->get_nav1_dme_dist();
+}
+
+bool
+FGBFI::getNAV1InRange ()
+{
+  return current_radiostack->get_nav1_inrange();
+}
+
+bool
+FGBFI::getNAV1DMEInRange ()
+{
+  return (current_radiostack->get_nav1_inrange() &&
+         current_radiostack->get_nav1_has_dme());
+}
+
+double
+FGBFI::getNAV2Freq ()
+{
+  return current_radiostack->get_nav2_freq();
+}
+
+double
+FGBFI::getNAV2AltFreq ()
+{
+  return current_radiostack->get_nav2_alt_freq();
+}
+
+double
+FGBFI::getNAV2Radial ()
+{
+  return current_radiostack->get_nav2_radial();
+}
+
+double
+FGBFI::getNAV2SelRadial ()
+{
+  return current_radiostack->get_nav2_sel_radial();
+}
+
+double
+FGBFI::getNAV2DistDME ()
+{
+  return current_radiostack->get_nav2_dme_dist();
+}
+
+bool
+FGBFI::getNAV2InRange ()
+{
+  return current_radiostack->get_nav2_inrange();
+}
+
+bool
+FGBFI::getNAV2DMEInRange ()
+{
+  return (current_radiostack->get_nav2_inrange() &&
+         current_radiostack->get_nav2_has_dme());
+}
+
+double
+FGBFI::getADFFreq ()
+{
+  return current_radiostack->get_adf_freq();
+}
+
+double
+FGBFI::getADFAltFreq ()
+{
+  return current_radiostack->get_adf_alt_freq();
+}
+
+double
+FGBFI::getADFRotation ()
+{
+  return current_radiostack->get_adf_rotation();
+}
+
+void
+FGBFI::setNAV1Freq (double freq)
+{
+  current_radiostack->set_nav1_freq(freq);
+}
+
+void
+FGBFI::setNAV1AltFreq (double freq)
+{
+  current_radiostack->set_nav1_alt_freq(freq);
+}
+
+void
+FGBFI::setNAV1SelRadial (double radial)
+{
+  current_radiostack->set_nav1_sel_radial(radial);
+}
+
+void
+FGBFI::setNAV2Freq (double freq)
+{
+  current_radiostack->set_nav2_freq(freq);
+}
+
+void
+FGBFI::setNAV2AltFreq (double freq)
+{
+  current_radiostack->set_nav2_alt_freq(freq);
+}
+
+void
+FGBFI::setNAV2SelRadial (double radial)
+{
+  current_radiostack->set_nav2_sel_radial(radial);
+}
+
+void
+FGBFI::setADFFreq (double freq)
+{
+  current_radiostack->set_adf_freq(freq);
+}
+
+void
+FGBFI::setADFAltFreq (double freq)
+{
+  current_radiostack->set_adf_alt_freq(freq);
+}
+
+void
+FGBFI::setADFRotation (double rot)
+{
+  current_radiostack->set_adf_rotation(rot);
 }
 
 
@@ -743,7 +1188,9 @@ FGBFI::setAPHeading (double heading)
 bool
 FGBFI::getGPSLock ()
 {
-  return fgAPWayPointEnabled();
+  return (current_autopilot->get_HeadingEnabled() &&
+         (current_autopilot->get_HeadingMode() ==
+          FGAutopilot::FG_HEADING_WAYPOINT ));
 }
 
 
@@ -753,7 +1200,13 @@ FGBFI::getGPSLock ()
 void
 FGBFI::setGPSLock (bool lock)
 {
-  APDataGlobal->waypoint_hold = lock;
+  if (lock) {
+    current_autopilot->set_HeadingMode(FGAutopilot::FG_HEADING_WAYPOINT);
+    current_autopilot->set_HeadingEnabled(true);
+  } else if (current_autopilot->get_HeadingMode() ==
+            FGAutopilot::FG_HEADING_WAYPOINT) {
+    current_autopilot->set_HeadingEnabled(false);
+  }
 }
 
 
@@ -783,7 +1236,7 @@ FGBFI::setTargetAirport (const string &airportId)
 double
 FGBFI::getGPSTargetLatitude ()
 {
-  return fgAPget_TargetLatitude();
+    return current_autopilot->get_TargetLatitude();
 }
 
 
@@ -793,7 +1246,7 @@ FGBFI::getGPSTargetLatitude ()
 void
 FGBFI::setGPSTargetLatitude (double latitude)
 {
-  APDataGlobal->TargetLatitude = latitude;
+  current_autopilot->set_TargetLatitude( latitude );
 }
 
 
@@ -803,7 +1256,7 @@ FGBFI::setGPSTargetLatitude (double latitude)
 double
 FGBFI::getGPSTargetLongitude ()
 {
-  return fgAPget_TargetLongitude();
+  return current_autopilot->get_TargetLongitude();
 }
 
 
@@ -813,7 +1266,7 @@ FGBFI::getGPSTargetLongitude ()
 void
 FGBFI::setGPSTargetLongitude (double longitude)
 {
-  APDataGlobal->TargetLongitude = longitude;
+  current_autopilot->set_TargetLongitude( longitude );
 }
 
 
@@ -837,6 +1290,26 @@ FGBFI::getVisibility ()
 }
 
 
+/**
+ * Check whether clouds are enabled.
+ */
+bool
+FGBFI::getClouds ()
+{
+  return current_options.get_clouds();
+}
+
+
+/**
+ * Check the height of the clouds ASL (units?).
+ */
+double
+FGBFI::getCloudsASL ()
+{
+  return current_options.get_clouds_asl();
+}
+
+
 /**
  * Set the current visibility (units??).
  */
@@ -851,6 +1324,29 @@ FGBFI::setVisibility (double visibility)
 }
 
 
+/**
+ * Switch clouds on or off.
+ */
+void
+FGBFI::setClouds (bool clouds)
+{
+  cout << "Set clouds to " << clouds << endl;
+  current_options.set_clouds(clouds);
+  needReinit();
+}
+
+
+/**
+ * Set the cloud height.
+ */
+void
+FGBFI::setCloudsASL (double cloudsASL)
+{
+  current_options.set_clouds_asl(cloudsASL);
+  needReinit();
+}
+
+
 \f
 ////////////////////////////////////////////////////////////////////////
 // Time