#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"
////////////////////////////////////////////////////////////////////////
+/**
+ * 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.
*
// 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();
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();
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);
setFlaps(flaps);
setBrake(brake);
setAPHeadingLock(apHeadingLock);
- setAPHeading(apHeading);
+ setAPHeadingMag(apHeadingMag);
setAPAltitudeLock(apAltitudeLock);
setAPAltitude(apAltitude);
setTargetAirport(targetAirport);
setGPSTargetLongitude(gpsLongitude);
_needReinit = false;
+
+ cout << "BFI: end reinit\n";
}
}
+/**
+ * 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.
*
}
+/**
+ * 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();
}
FGBFI::setLatitude (double latitude)
{
current_options.set_lat(latitude);
+ current_aircraft.fdm_state->set_Latitude(latitude * DEG_TO_RAD);
needReinit();
}
FGBFI::setLongitude (double longitude)
{
current_options.set_lon(longitude);
+ current_aircraft.fdm_state->set_Longitude(longitude * DEG_TO_RAD);
needReinit();
}
}
+
+/**
+ * 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();
}
}
+/**
+ * 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.
*/
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();
}
{
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();
}
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();
}
/**
- * Return the current climb rate in feet/second (FIXME: verify).
+ * Return the current climb rate in feet/minute
*/
double
FGBFI::getVerticalSpeed ()
FGBFI::setSpeedNorth (double speed)
{
current_options.set_uBody(speed);
+ current_aircraft.fdm_state->set_Velocities_Local(speed,
+ getSpeedEast(),
+ getSpeedDown());
needReinit();
}
FGBFI::setSpeedEast (double speed)
{
current_options.set_vBody(speed);
+ current_aircraft.fdm_state->set_Velocities_Local(getSpeedNorth(),
+ speed,
+ getSpeedDown());
needReinit();
}
FGBFI::setSpeedDown (double speed)
{
current_options.set_wBody(speed);
+ current_aircraft.fdm_state->set_Velocities_Local(getSpeedNorth(),
+ getSpeedEast(),
+ speed);
needReinit();
}
bool
FGBFI::getAPAltitudeLock ()
{
- return fgAPAltitudeEnabled();
+ return current_autopilot->get_AltitudeEnabled();
}
void
FGBFI::setAPAltitudeLock (bool lock)
{
- APDataGlobal->altitude_hold = lock;
+ current_autopilot->set_AltitudeMode(FGAutopilot::FG_ALTITUDE_LOCK);
+ current_autopilot->set_AltitudeEnabled(lock);
}
double
FGBFI::getAPAltitude ()
{
- return fgAPget_TargetAltitude() * METER_TO_FEET;
+ return current_autopilot->get_TargetAltitude() * METER_TO_FEET;
}
void
FGBFI::setAPAltitude (double altitude)
{
- fgAPAltitudeSet(altitude);
+ current_autopilot->set_TargetAltitude( altitude );
}
bool
FGBFI::getAPHeadingLock ()
{
- return fgAPHeadingEnabled();
+ return
+ (current_autopilot->get_HeadingEnabled() &&
+ current_autopilot->get_HeadingMode() == FGAutopilot::FG_HEADING_LOCK);
}
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);
+ }
}
* Get the autopilot target heading in degrees.
*/
double
-FGBFI::getAPHeading ()
+FGBFI::getAPHeadingMag ()
{
- return fgAPget_TargetHeading();
+ return current_autopilot->get_TargetHeading() - getMagVar();
}
* 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);
}
bool
FGBFI::getGPSLock ()
{
- return fgAPWayPointEnabled();
+ return (current_autopilot->get_HeadingEnabled() &&
+ (current_autopilot->get_HeadingMode() ==
+ FGAutopilot::FG_HEADING_WAYPOINT ));
}
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);
+ }
}
double
FGBFI::getGPSTargetLatitude ()
{
- return fgAPget_TargetLatitude();
+ return current_autopilot->get_TargetLatitude();
}
void
FGBFI::setGPSTargetLatitude (double latitude)
{
- APDataGlobal->TargetLatitude = latitude;
+ current_autopilot->set_TargetLatitude( latitude );
}
double
FGBFI::getGPSTargetLongitude ()
{
- return fgAPget_TargetLongitude();
+ return current_autopilot->get_TargetLongitude();
}
void
FGBFI::setGPSTargetLongitude (double longitude)
{
- APDataGlobal->TargetLongitude = longitude;
+ current_autopilot->set_TargetLongitude( longitude );
}
}
+/**
+ * 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??).
*/
}
+/**
+ * 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