X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FEnvironment%2Fenvironment.cxx;h=212e51d856aed4fa286ea947c63ffcd5d6e21eb3;hb=11d15b451347674fba77648700d23c5aaec3c6c2;hp=7a516b139d1df5042d743fa1c87f152f63da683d;hpb=70be1629e61d9b751a2f73df30b83bb1be6ca4fe;p=flightgear.git diff --git a/src/Environment/environment.cxx b/src/Environment/environment.cxx index 7a516b139..212e51d85 100644 --- a/src/Environment/environment.cxx +++ b/src/Environment/environment.cxx @@ -27,6 +27,8 @@ #include +#include + #include #include #include @@ -34,15 +36,18 @@ #include #include
+#include #include "environment.hxx" - +#include "atmosphere.hxx" //////////////////////////////////////////////////////////////////////// // Atmosphere model. //////////////////////////////////////////////////////////////////////// +#ifdef USING_TABLES + // Calculated based on the ISA standard day, as found at e.g. // http://www.av8n.com/physics/altimetry.htm @@ -109,7 +114,7 @@ _setup_tables () atmosphere_data[i][2]); } } - +#endif //////////////////////////////////////////////////////////////////////// @@ -137,10 +142,12 @@ void FGEnvironment::_init() ridge_lift_fps= 0; altitude_half_to_sun_m = 1000; altitude_tropo_top_m = 10000; +#ifdef USING_TABLES _setup_tables(); +#endif _recalc_density(); _recalc_relative_humidity(); - + live_update = true; } FGEnvironment::FGEnvironment() @@ -198,6 +205,7 @@ maybe_copy_value (FGEnvironment * env, const SGPropertyNode * node, void FGEnvironment::read (const SGPropertyNode * node) { + bool live_update = set_live_update( false ); maybe_copy_value(this, node, "visibility-m", &FGEnvironment::set_visibility_m); @@ -230,6 +238,14 @@ FGEnvironment::read (const SGPropertyNode * node) maybe_copy_value(this, node, "turbulence/rate-hz", &FGEnvironment::set_turbulence_rate_hz); + // calculate derived properties here to avoid duplicate expensive computations + _recalc_ne(); + _recalc_alt_pt(); + _recalc_alt_dewpoint(); + _recalc_density(); + _recalc_relative_humidity(); + + set_live_update(live_update); } @@ -386,17 +402,23 @@ FGEnvironment::set_temperature_sea_level_degc (double t) temperature_sea_level_degc = t; if (dewpoint_sea_level_degc > t) dewpoint_sea_level_degc = t; - _recalc_alt_temperature(); - _recalc_density(); + if( live_update ) { + _recalc_alt_pt(); + _recalc_density(); + } } void FGEnvironment::set_temperature_degc (double t) { temperature_degc = t; - _recalc_sl_temperature(); - _recalc_density(); - _recalc_relative_humidity(); + if( live_update ) { + _recalc_sl_temperature(); + _recalc_sl_pressure(); + _recalc_alt_pt(); + _recalc_density(); + _recalc_relative_humidity(); + } } void @@ -405,82 +427,104 @@ FGEnvironment::set_dewpoint_sea_level_degc (double t) dewpoint_sea_level_degc = t; if (temperature_sea_level_degc < t) temperature_sea_level_degc = t; - _recalc_alt_dewpoint(); - _recalc_density(); + if( live_update ) { + _recalc_alt_dewpoint(); + _recalc_density(); + } } void FGEnvironment::set_dewpoint_degc (double t) { dewpoint_degc = t; - _recalc_sl_dewpoint(); - _recalc_density(); - _recalc_relative_humidity(); + if( live_update ) { + _recalc_sl_dewpoint(); + _recalc_density(); + _recalc_relative_humidity(); + } } void FGEnvironment::set_pressure_sea_level_inhg (double p) { pressure_sea_level_inhg = p; - _recalc_alt_pressure(); - _recalc_density(); + if( live_update ) { + _recalc_alt_pt(); + _recalc_density(); + } } void FGEnvironment::set_pressure_inhg (double p) { pressure_inhg = p; - _recalc_sl_pressure(); - _recalc_density(); + if( live_update ) { + _recalc_sl_pressure(); + _recalc_density(); + } } void FGEnvironment::set_wind_from_heading_deg (double h) { wind_from_heading_deg = h; - _recalc_ne(); + if( live_update ) { + _recalc_ne(); + } } void FGEnvironment::set_wind_speed_kt (double s) { wind_speed_kt = s; - _recalc_ne(); + if( live_update ) { + _recalc_ne(); + } } void FGEnvironment::set_wind_from_north_fps (double n) { wind_from_north_fps = n; - _recalc_hdgspd(); + if( live_update ) { + _recalc_hdgspd(); + } } void FGEnvironment::set_wind_from_east_fps (double e) { wind_from_east_fps = e; - _recalc_hdgspd(); + if( live_update ) { + _recalc_hdgspd(); + } } void FGEnvironment::set_wind_from_down_fps (double d) { wind_from_down_fps = d; - _recalc_hdgspd(); + if( live_update ) { + _recalc_hdgspd(); + } } void FGEnvironment::set_thermal_lift_fps (double th) { thermal_lift_fps = th; - _recalc_updraft(); + if( live_update ) { + _recalc_updraft(); + } } void FGEnvironment::set_ridge_lift_fps (double ri) { ridge_lift_fps = ri; - _recalc_updraft(); + if( live_update ) { + _recalc_updraft(); +} } void @@ -499,25 +543,30 @@ void FGEnvironment::set_elevation_ft (double e) { elevation_ft = e; - _recalc_alt_temperature(); - _recalc_alt_dewpoint(); - _recalc_alt_pressure(); - _recalc_density(); - _recalc_relative_humidity(); + if( live_update ) { + _recalc_alt_pt(); + _recalc_alt_dewpoint(); + _recalc_density(); + _recalc_relative_humidity(); + } } void FGEnvironment::set_altitude_half_to_sun_m (double alt) { - altitude_half_to_sun_m = alt; - _recalc_density_tropo_avg_kgm3(); + altitude_half_to_sun_m = alt; + if( live_update ) { + _recalc_density_tropo_avg_kgm3(); + } } void FGEnvironment::set_altitude_tropo_top_m (double alt) { - altitude_tropo_top_m = alt; - _recalc_density_tropo_avg_kgm3(); + altitude_tropo_top_m = alt; + if( live_update ) { + _recalc_density_tropo_avg_kgm3(); + } } @@ -572,26 +621,34 @@ FGEnvironment::_recalc_updraft () wind_from_down_fps = thermal_lift_fps + ridge_lift_fps ; } +// Intended to help with the interpretation of METAR data, +// not for random in-flight outside-air temperatures. void FGEnvironment::_recalc_sl_temperature () { - // If we're in the stratosphere, leave sea-level temp alone - if (elevation_ft < 38000) { - temperature_sea_level_degc = (temperature_degc + 273.15) - / _temperature_degc_table->interpolate(elevation_ft) - - 273.15; + +#if 0 + { + SG_LOG(SG_GENERAL, SG_DEBUG, "recalc_sl_temperature: using " + << temperature_degc << " @ " << elevation_ft << " :: " << this); } -} +#endif -void -FGEnvironment::_recalc_alt_temperature () -{ - if (elevation_ft < 38000) { - temperature_degc = (temperature_sea_level_degc + 273.15) * - _temperature_degc_table->interpolate(elevation_ft) - 273.15; - } else { - temperature_degc = -56.49; // Stratosphere is constant + if (elevation_ft >= ISA_def[1].height) { + SG_LOG(SG_GENERAL, SG_ALERT, "recalc_sl_temperature: " + << "valid only in troposphere, not " << elevation_ft); + return; } + +// Clamp: temperature of the stratosphere, in degrees C: + double t_strato = ISA_def[1].temp - atmodel::freezing; + if (temperature_degc < t_strato) temperature_sea_level_degc = t_strato; + else temperature_sea_level_degc = + temperature_degc + elevation_ft * atmodel::foot * ISA_def[0].lapse; + +// Alternative implemenation: +// else temperature_sea_level_inhg = T_layer(0., elevation_ft * foot, +// pressure_inhg * inHg, temperature_degc + freezing, ISA_def[0].lapse) - freezing; } void @@ -619,15 +676,44 @@ FGEnvironment::_recalc_alt_dewpoint () void FGEnvironment::_recalc_sl_pressure () { - pressure_sea_level_inhg = - pressure_inhg / _pressure_inhg_table->interpolate(elevation_ft); + using namespace atmodel; +#if 0 + { + SG_LOG(SG_GENERAL, SG_ALERT, "recalc_sl_pressure: using " + << pressure_inhg << " and " + << temperature_degc << " @ " << elevation_ft << " :: " << this); + } +#endif + pressure_sea_level_inhg = P_layer(0., elevation_ft * foot, + pressure_inhg * inHg, temperature_degc + freezing, ISA_def[0].lapse) / inHg; } +// This gets called at frame rate, to account for the aircraft's +// changing altitude. +// Called by set_elevation_ft() which is called by FGEnvironmentMgr::update + void -FGEnvironment::_recalc_alt_pressure () +FGEnvironment::_recalc_alt_pt () { - pressure_inhg = - pressure_sea_level_inhg * _pressure_inhg_table->interpolate(elevation_ft); + using namespace atmodel; +#if 0 + { + static int count(0); + if (++count % 1000 == 0) { + SG_LOG(SG_GENERAL, SG_ALERT, + "recalc_alt_pt for: " << elevation_ft + << " using " << pressure_sea_level_inhg + << " and " << temperature_sea_level_degc + << " :: " << this + << " # " << count); + } + } +#endif + double press, temp; + boost::tie(press, temp) = PT_vs_hpt(elevation_ft * foot, + pressure_sea_level_inhg * inHg, temperature_sea_level_degc + freezing); + temperature_degc = temp - freezing; + pressure_inhg = press / inHg; } void @@ -670,12 +756,26 @@ FGEnvironment::_recalc_density_tropo_avg_kgm3 () void FGEnvironment::_recalc_relative_humidity () { +/* double vaporpressure = 6.11 * pow(10.0, ((7.5 * dewpoint_degc) / ( 237.7 + dewpoint_degc))); double sat_vaporpressure = 6.11 * pow(10.0, ((7.5 * temperature_degc) / ( 237.7 + temperature_degc)) ); relative_humidity = 100 * vaporpressure / sat_vaporpressure ; + + with a little algebra, this gets the same result and spares two multiplications and one pow() +*/ + double a = (7.5 * dewpoint_degc) / ( 237.7 + dewpoint_degc); + double b = (7.5 * temperature_degc) / ( 237.7 + temperature_degc); + relative_humidity = 100 * pow(10.0,a-b); } +bool +FGEnvironment::set_live_update( bool _live_update ) +{ + bool b = live_update; + live_update = _live_update; + return b; +} //////////////////////////////////////////////////////////////////////// @@ -707,6 +807,10 @@ void interpolate (const FGEnvironment * env1, const FGEnvironment * env2, double fraction, FGEnvironment * result) { + // don't calculate each internal property every time we set a single value + // we trigger that at the end of the interpolation process + bool live_update = result->set_live_update( false ); + result->set_visibility_m (do_interp(env1->get_visibility_m(), env2->get_visibility_m(), @@ -717,7 +821,7 @@ interpolate (const FGEnvironment * env1, const FGEnvironment * env2, env2->get_temperature_sea_level_degc(), fraction)); - result->set_dewpoint_degc + result->set_dewpoint_sea_level_degc (do_interp(env1->get_dewpoint_sea_level_degc(), env2->get_dewpoint_sea_level_degc(), fraction)); @@ -751,6 +855,15 @@ interpolate (const FGEnvironment * env1, const FGEnvironment * env2, (do_interp(env1->get_turbulence_rate_hz(), env2->get_turbulence_rate_hz(), fraction)); + + // calculate derived properties here to avoid duplicate expensive computations + result->_recalc_ne(); + result->_recalc_alt_pt(); + result->_recalc_alt_dewpoint(); + result->_recalc_density(); + result->_recalc_relative_humidity(); + + result->set_live_update(live_update); } // end of environment.cxx