X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FFDM%2Fflight.cxx;h=86324a8312e8a02c300996e0b59041b48349d6e3;hb=18ff3a6108bc29bd5fed76322c4ab63589095a2a;hp=c7f6b0944db618faf5bcad32cccf7bcd60107099;hpb=68522eb75c12f198a49dffce10ef433f210058aa;p=flightgear.git diff --git a/src/FDM/flight.cxx b/src/FDM/flight.cxx index c7f6b0944..86324a831 100644 --- a/src/FDM/flight.cxx +++ b/src/FDM/flight.cxx @@ -2,7 +2,7 @@ // // Written by Curtis Olson, started May 1997. // -// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com +// Copyright (C) 1997 Curtis L. Olson - http://www.flightgear.org/~curt // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,15 +28,13 @@ #include #include #include +#include #include #include -#include #include
#include
-#include
-#include -#include +#include #include "flight.hxx" @@ -81,7 +79,9 @@ FGInterface::_calc_multiloop (double dt) dt += remainder; remainder = 0; double ml = dt * hz; - int multiloop = int(floor(ml)); + // Avoid roundoff problems by adding the roundoff itself. + // ... ok, two times the roundoff to have enough room. + int multiloop = int(floor(ml * (1.0 + 2.0*DBL_EPSILON))); remainder = (ml - multiloop) / hz; return (multiloop * speedup); } @@ -163,7 +163,6 @@ FGInterface::_setup () sin_latitude=cos_latitude=0; sin_longitude=cos_longitude=0; altitude_agl=0; - _acmodel = 0; } void @@ -187,12 +186,6 @@ FGInterface::common_init () // stamp(); // set_remainder( 0 ); - // linking in FGAircraft instance... - // FIXME: when using multiple instances, then there will be more than - // one model so get_aircraft_model will have to be indexed to the correct - // model. - _acmodel = globals->get_aircraft_model(); - // Set initial position SG_LOG( SG_FLIGHT, SG_INFO, "...initializing position..." ); set_Longitude( fgGetDouble("/sim/presets/longitude-deg") @@ -201,14 +194,15 @@ FGInterface::common_init () * SGD_DEGREES_TO_RADIANS ); double ground_elev_m = globals->get_scenery()->get_cur_elev(); double ground_elev_ft = ground_elev_m * SG_METER_TO_FEET; - _acmodel->get3DModel()->getFGLocation()->set_cur_elev_m( ground_elev_m ); + fgSetDouble("/position/ground-elev-m", ground_elev_m); _set_Runway_altitude ( ground_elev_ft ); if ( fgGetBool("/sim/presets/onground") || fgGetDouble("/sim/presets/altitude-ft") < ground_elev_ft ) { - fgSetDouble("/sim/presets/altitude-ft", ground_elev_ft); fgSetDouble("/position/altitude-ft", ground_elev_ft); + set_Altitude( ground_elev_ft ); + } else { + set_Altitude( fgGetDouble("/sim/presets/altitude-ft") ); } - set_Altitude( fgGetDouble("/sim/presets/altitude-ft") ); // Set ground elevation SG_LOG( SG_FLIGHT, SG_INFO, @@ -219,12 +213,12 @@ FGInterface::common_init () SG_LOG( SG_FLIGHT, SG_INFO, "...initializing sea-level radius..." ); SG_LOG( SG_FLIGHT, SG_INFO, " lat = " << fgGetDouble("/sim/presets/latitude-deg") - << " alt = " << fgGetDouble("/sim/presets/altitude-ft") ); + << " alt = " << get_Altitude() ); double sea_level_radius_meters; double lat_geoc; sgGeodToGeoc( fgGetDouble("/sim/presets/latitude-deg") * SGD_DEGREES_TO_RADIANS, - fgGetDouble("/sim/presets/altitude-ft") * SG_FEET_TO_METER, + get_Altitude() * SG_FEET_TO_METER, &sea_level_radius_meters, &lat_geoc ); _set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET ); @@ -503,9 +497,7 @@ void FGInterface::_updateGeodeticPosition( double lat, double lon, double alt ) _set_Geodetic_Position( lat, lon, alt ); _set_Sea_level_radius( sl_radius * SG_METER_TO_FEET ); - if ( getACModel() != NULL ) { - _set_Runway_altitude( getACModel()->get3DModel()->getFGLocation()->get_cur_elev_m() * SG_METER_TO_FEET ); - } + _set_Runway_altitude( fgGetDouble("/position/ground-elev-m") * SG_METER_TO_FEET ); _set_sin_lat_geocentric( lat_geoc ); _set_cos_lat_geocentric( lat_geoc ); @@ -561,7 +553,7 @@ void FGInterface::_updateGeocentricPosition( double lat_geoc, double lon, _set_Geodetic_Position( lat_geod, lon, alt ); _set_Sea_level_radius( sl_radius2 * SG_METER_TO_FEET ); - _set_Runway_altitude( getACModel()->get3DModel()->getFGLocation()->get_cur_elev_m() * SG_METER_TO_FEET ); + _set_Runway_altitude( fgGetDouble("/position/ground-elev-m") * SG_METER_TO_FEET ); _set_sin_lat_geocentric( lat_geoc ); _set_cos_lat_geocentric( lat_geoc ); @@ -797,6 +789,129 @@ void FGInterface::_busdump(void) { SG_LOG(SG_FLIGHT,SG_INFO,"altitude_agl: " << altitude_agl ); } +bool +FGInterface::prepare_ground_cache_m(double ref_time, const double pt[3], + double rad) +{ + return ground_cache.prepare_ground_cache(ref_time, pt, rad); +} + +bool FGInterface::prepare_ground_cache_ft(double ref_time, const double pt[3], + double rad) +{ + // Convert units and do the real work. + sgdVec3 pt_ft; + sgdScaleVec3( pt_ft, pt, SG_FEET_TO_METER ); + return ground_cache.prepare_ground_cache(ref_time, pt_ft, rad*SG_FEET_TO_METER); +} + +bool +FGInterface::is_valid_m(double *ref_time, double pt[3], double *rad) +{ + return ground_cache.is_valid(ref_time, pt, rad); +} + +bool FGInterface::is_valid_ft(double *ref_time, double pt[3], double *rad) +{ + // Convert units and do the real work. + bool found_ground = ground_cache.is_valid(ref_time, pt, rad); + sgdScaleVec3(pt, SG_METER_TO_FEET); + *rad *= SG_METER_TO_FEET; + return found_ground; +} + +double +FGInterface::get_cat_m(double t, const double pt[3], + double end[2][3], double vel[2][3]) +{ + return ground_cache.get_cat(t, pt, end, vel); +} + +double +FGInterface::get_cat_ft(double t, const double pt[3], + double end[2][3], double vel[2][3]) +{ + // Convert units and do the real work. + sgdVec3 pt_m; + sgdScaleVec3( pt_m, pt, SG_FEET_TO_METER ); + double dist = ground_cache.get_cat(t, pt_m, end, vel); + for (int k=0; k<2; ++k) { + sgdScaleVec3( end[k], SG_METER_TO_FEET ); + sgdScaleVec3( vel[k], SG_METER_TO_FEET ); + } + return dist*SG_METER_TO_FEET; +} + +bool +FGInterface::get_agl_m(double t, const double pt[3], + double contact[3], double normal[3], double vel[3], + int *type, double *loadCapacity, + double *frictionFactor, double *agl) +{ + return ground_cache.get_agl(t, pt, contact, normal, vel, type, + loadCapacity, frictionFactor, agl); +} + +bool +FGInterface::get_agl_ft(double t, const double pt[3], + double contact[3], double normal[3], double vel[3], + int *type, double *loadCapacity, + double *frictionFactor, double *agl) +{ + // Convert units and do the real work. + sgdVec3 pt_m; + sgdScaleVec3( pt_m, pt, SG_FEET_TO_METER ); + bool ret = ground_cache.get_agl(t, pt_m, contact, normal, vel, + type, loadCapacity, frictionFactor, agl); + // Convert units back ... + sgdScaleVec3( contact, SG_METER_TO_FEET ); + sgdScaleVec3( vel, SG_METER_TO_FEET ); + *agl *= SG_METER_TO_FEET; + // FIXME: scale the load limit to something in the english unit system. + // Be careful with the DBL_MAX which is returned by default. + return ret; +} + +bool +FGInterface::caught_wire_m(double t, const double pt[4][3]) +{ + return ground_cache.caught_wire(t, pt); +} + +bool +FGInterface::caught_wire_ft(double t, const double pt[4][3]) +{ + // Convert units and do the real work. + double pt_m[4][3]; + for (int i=0; i<4; ++i) + sgdScaleVec3(pt_m[i], pt[i], SG_FEET_TO_METER); + + return ground_cache.caught_wire(t, pt_m); +} + +bool +FGInterface::get_wire_ends_m(double t, double end[2][3], double vel[2][3]) +{ + return ground_cache.get_wire_ends(t, end, vel); +} + +bool +FGInterface::get_wire_ends_ft(double t, double end[2][3], double vel[2][3]) +{ + // Convert units and do the real work. + bool ret = ground_cache.get_wire_ends(t, end, vel); + for (int k=0; k<2; ++k) { + sgdScaleVec3( end[k], SG_METER_TO_FEET ); + sgdScaleVec3( vel[k], SG_METER_TO_FEET ); + } + return ret; +} + +void +FGInterface::release_wire(void) +{ + ground_cache.release_wire(); +} void fgToggleFDMdataLogging(void) { cur_fdm_state->ToggleDataLogging();