X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=src%2FEnvironment%2Fenvironment.cxx;h=5707eea96add221341050117603cfa10edd00b4c;hb=cee943076ca56cfe4686df8629b55714d362aff0;hp=eed66fa17cd28c5ece0da1d192b53254cc7e79c9;hpb=7b6d15d537308363fa8967e0edda879a80ddaa21;p=flightgear.git diff --git a/src/Environment/environment.cxx b/src/Environment/environment.cxx index eed66fa17..5707eea96 100644 --- a/src/Environment/environment.cxx +++ b/src/Environment/environment.cxx @@ -18,8 +18,6 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // -// $Id$ - #ifdef HAVE_CONFIG_H # include @@ -29,16 +27,10 @@ #include -#include - -#include -#include -#include #include -#include +#include #include
-#include #include "environment.hxx" #include "atmosphere.hxx" @@ -125,6 +117,7 @@ _setup_tables () void FGEnvironment::_init() { + live_update = false; elevation_ft = 0; visibility_m = 32000; temperature_sea_level_degc = 15; @@ -133,6 +126,7 @@ void FGEnvironment::_init() dewpoint_degc = 5; pressure_sea_level_inhg = 29.92; pressure_inhg = 29.92; + density_slugft3 = 0; turbulence_magnitude_norm = 0; turbulence_rate_hz = 1; wind_from_heading_deg = 0; @@ -147,7 +141,7 @@ void FGEnvironment::_init() #endif _recalc_density(); _recalc_relative_humidity(); - + live_update = true; } FGEnvironment::FGEnvironment() @@ -163,6 +157,13 @@ FGEnvironment::FGEnvironment (const FGEnvironment &env) FGEnvironment::~FGEnvironment() { + Untie(); +} + +FGEnvironment & FGEnvironment::operator = ( const FGEnvironment & other ) +{ + copy( other ); + return *this; } void @@ -182,6 +183,13 @@ FGEnvironment::copy (const FGEnvironment &env) wind_from_down_fps = env.wind_from_down_fps; turbulence_magnitude_norm = env.turbulence_magnitude_norm; turbulence_rate_hz = env.turbulence_rate_hz; + pressure_inhg = env.pressure_inhg; + density_slugft3 = env.density_slugft3; + density_tropo_avg_kgm3 = env.density_tropo_avg_kgm3; + relative_humidity = env.relative_humidity; + altitude_half_to_sun_m = env.altitude_half_to_sun_m; + altitude_tropo_top_m = env.altitude_tropo_top_m; + live_update = env.live_update; } static inline bool @@ -203,23 +211,36 @@ 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); + maybe_copy_value(this, node, "elevation-ft", + &FGEnvironment::set_elevation_ft); + if (!maybe_copy_value(this, node, "temperature-sea-level-degc", - &FGEnvironment::set_temperature_sea_level_degc)) - maybe_copy_value(this, node, "temperature-degc", - &FGEnvironment::set_temperature_degc); + &FGEnvironment::set_temperature_sea_level_degc)) { + if( maybe_copy_value(this, node, "temperature-degc", + &FGEnvironment::set_temperature_degc)) { + _recalc_sl_temperature(); + } + } if (!maybe_copy_value(this, node, "dewpoint-sea-level-degc", - &FGEnvironment::set_dewpoint_sea_level_degc)) - maybe_copy_value(this, node, "dewpoint-degc", - &FGEnvironment::set_dewpoint_degc); + &FGEnvironment::set_dewpoint_sea_level_degc)) { + if( maybe_copy_value(this, node, "dewpoint-degc", + &FGEnvironment::set_dewpoint_degc)) { + _recalc_sl_dewpoint(); + } + } if (!maybe_copy_value(this, node, "pressure-sea-level-inhg", - &FGEnvironment::set_pressure_sea_level_inhg)) - maybe_copy_value(this, node, "pressure-inhg", - &FGEnvironment::set_pressure_inhg); + &FGEnvironment::set_pressure_sea_level_inhg)) { + if( maybe_copy_value(this, node, "pressure-inhg", + &FGEnvironment::set_pressure_inhg)) { + _recalc_sl_pressure(); + } + } maybe_copy_value(this, node, "wind-from-heading-deg", &FGEnvironment::set_wind_from_heading_deg); @@ -227,16 +248,109 @@ FGEnvironment::read (const SGPropertyNode * node) maybe_copy_value(this, node, "wind-speed-kt", &FGEnvironment::set_wind_speed_kt); - maybe_copy_value(this, node, "elevation-ft", - &FGEnvironment::set_elevation_ft); - maybe_copy_value(this, node, "turbulence/magnitude-norm", &FGEnvironment::set_turbulence_magnitude_norm); 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); +} + +void FGEnvironment::Tie( SGPropertyNode_ptr base, bool archivable ) +{ + _tiedProperties.setRoot( base ); + + _tiedProperties.Tie( "visibility-m", this, + &FGEnvironment::get_visibility_m, + &FGEnvironment::set_visibility_m); + + _tiedProperties.Tie("temperature-sea-level-degc", this, + &FGEnvironment::get_temperature_sea_level_degc, + &FGEnvironment::set_temperature_sea_level_degc); + + _tiedProperties.Tie("temperature-degc", this, + &FGEnvironment::get_temperature_degc, + &FGEnvironment::set_temperature_degc); + + _tiedProperties.Tie("dewpoint-sea-level-degc", this, + &FGEnvironment::get_dewpoint_sea_level_degc, + &FGEnvironment::set_dewpoint_sea_level_degc); + + _tiedProperties.Tie("dewpoint-degc", this, + &FGEnvironment::get_dewpoint_degc, + &FGEnvironment::set_dewpoint_degc); + + _tiedProperties.Tie("pressure-sea-level-inhg", this, + &FGEnvironment::get_pressure_sea_level_inhg, + &FGEnvironment::set_pressure_sea_level_inhg); + + _tiedProperties.Tie("pressure-inhg", this, + &FGEnvironment::get_pressure_inhg, + &FGEnvironment::set_pressure_inhg); + + _tiedProperties.Tie("atmosphere/altitude-half-to-sun", this, + &FGEnvironment::get_altitude_half_to_sun_m, + &FGEnvironment::set_altitude_half_to_sun_m); + + _tiedProperties.Tie("atmosphere/altitude-troposphere-top", this, + &FGEnvironment::get_altitude_tropo_top_m, + &FGEnvironment::set_altitude_tropo_top_m); + + _tiedProperties.Tie("wind-from-heading-deg", this, + &FGEnvironment::get_wind_from_heading_deg, + &FGEnvironment::set_wind_from_heading_deg); + + _tiedProperties.Tie("wind-speed-kt", this, + &FGEnvironment::get_wind_speed_kt, + &FGEnvironment::set_wind_speed_kt); + + _tiedProperties.Tie("wind-from-north-fps", this, + &FGEnvironment::get_wind_from_north_fps, + &FGEnvironment::set_wind_from_north_fps); + + _tiedProperties.Tie("wind-from-east-fps", this, + &FGEnvironment::get_wind_from_east_fps, + &FGEnvironment::set_wind_from_east_fps); + + _tiedProperties.Tie("wind-from-down-fps", this, + &FGEnvironment::get_wind_from_down_fps, + &FGEnvironment::set_wind_from_down_fps); + + _tiedProperties.Tie("turbulence/magnitude-norm", this, + &FGEnvironment::get_turbulence_magnitude_norm, + &FGEnvironment::set_turbulence_magnitude_norm); + + _tiedProperties.Tie("turbulence/rate-hz", this, + &FGEnvironment::get_turbulence_rate_hz, + &FGEnvironment::set_turbulence_rate_hz); + + _tiedProperties.setAttribute( SGPropertyNode::ARCHIVE, archivable ); + + _tiedProperties.Tie("temperature-degf", this, + &FGEnvironment::get_temperature_degf); + + _tiedProperties.Tie("density-slugft3", this, + &FGEnvironment::get_density_slugft3); // read-only + + _tiedProperties.Tie("relative-humidity", this, + &FGEnvironment::get_relative_humidity); //ro + + _tiedProperties.Tie("atmosphere/density-tropo-avg", this, + &FGEnvironment::get_density_tropo_avg_kgm3); //ro } +void FGEnvironment::Untie() +{ + _tiedProperties.Untie(); +} double FGEnvironment::get_visibility_m () const @@ -349,9 +463,6 @@ FGEnvironment::get_wind_from_down_fps () const double FGEnvironment::get_turbulence_magnitude_norm () const { - if( sgEnviro.get_turbulence_enable_state() ) - if (fgGetBool("/environment/params/real-world-weather-fetch") == true) - return sgEnviro.get_cloud_turbulence(); return turbulence_magnitude_norm; } @@ -379,19 +490,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_pt(); - _recalc_density(); + if( live_update ) { + _recalc_alt_pt(); + _recalc_density(); + } } void FGEnvironment::set_temperature_degc (double t) { temperature_degc = t; - _recalc_sl_temperature(); - _recalc_sl_pressure(); - _recalc_alt_pt(); - _recalc_density(); - _recalc_relative_humidity(); + if( live_update ) { + _recalc_sl_temperature(); + _recalc_sl_pressure(); + _recalc_alt_pt(); + _recalc_density(); + _recalc_relative_humidity(); + } } void @@ -400,68 +515,86 @@ 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_pt(); - _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 @@ -480,58 +613,45 @@ void FGEnvironment::set_elevation_ft (double e) { elevation_ft = e; - _recalc_alt_dewpoint(); - _recalc_alt_pt(); - _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(); + } } void FGEnvironment::_recalc_hdgspd () { - double angle_rad; + wind_from_heading_deg = + atan2(wind_from_east_fps, wind_from_north_fps) * SGD_RADIANS_TO_DEGREES; - if (wind_from_east_fps == 0) { - angle_rad = (wind_from_north_fps >= 0 ? SGD_PI_2 : -SGD_PI_2); - } else { - angle_rad = atan(wind_from_north_fps/wind_from_east_fps); - } - wind_from_heading_deg = angle_rad * SGD_RADIANS_TO_DEGREES; - if (wind_from_east_fps >= 0) - wind_from_heading_deg = 90 - wind_from_heading_deg; - else - wind_from_heading_deg = 270 - wind_from_heading_deg; + if( wind_from_heading_deg < 0 ) + wind_from_heading_deg += 360.0; -#if 0 - // FIXME: Windspeed can become negative with these formulas. - // which can cause problems for animations that rely - // on the windspeed property. - if (angle_rad == 0) - wind_speed_kt = fabs(wind_from_east_fps - * SG_METER_TO_NM * SG_FEET_TO_METER * 3600); - else - wind_speed_kt = (wind_from_north_fps / sin(angle_rad)) - * SG_METER_TO_NM * SG_FEET_TO_METER * 3600; -#else wind_speed_kt = sqrt(wind_from_north_fps * wind_from_north_fps + wind_from_east_fps * wind_from_east_fps) * SG_METER_TO_NM * SG_FEET_TO_METER * 3600; -#endif } void @@ -554,13 +674,13 @@ FGEnvironment::_recalc_sl_temperature () #if 0 { - SG_LOG(SG_GENERAL, SG_DEBUG, "recalc_sl_temperature: using " + SG_LOG(SG_ENVIRONMENT, SG_DEBUG, "recalc_sl_temperature: using " << temperature_degc << " @ " << elevation_ft << " :: " << this); } #endif - if (elevation_ft >= ISA_def[1].height) { - SG_LOG(SG_GENERAL, SG_ALERT, "recalc_sl_temperature: " + if (elevation_ft * atmodel::foot >= ISA_def[1].height) { + SG_LOG(SG_ENVIRONMENT, SG_ALERT, "recalc_sl_temperature: " << "valid only in troposphere, not " << elevation_ft); return; } @@ -569,7 +689,7 @@ FGEnvironment::_recalc_sl_temperature () 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 * ISA_def[0].lapse; + temperature_degc + elevation_ft * atmodel::foot * ISA_def[0].lapse; // Alternative implemenation: // else temperature_sea_level_inhg = T_layer(0., elevation_ft * foot, @@ -604,7 +724,7 @@ FGEnvironment::_recalc_sl_pressure () using namespace atmodel; #if 0 { - SG_LOG(SG_GENERAL, SG_ALERT, "recalc_sl_pressure: using " + SG_LOG(SG_ENVIRONMENT, SG_ALERT, "recalc_sl_pressure: using " << pressure_inhg << " and " << temperature_degc << " @ " << elevation_ft << " :: " << this); } @@ -625,17 +745,17 @@ FGEnvironment::_recalc_alt_pt () { static int count(0); if (++count % 1000 == 0) { - SG_LOG(SG_GENERAL, SG_ALERT, + SG_LOG(SG_ENVIRONMENT, SG_ALERT, "recalc_alt_pt for: " << elevation_ft << " using " << pressure_sea_level_inhg << " and " << temperature_sea_level_degc << " :: " << this << " # " << count); - ///////////////////////////////////raise(SIGUSR1); } } #endif - double press, temp; + double press = pressure_inhg * inHg; + double temp = temperature_degc + freezing; boost::tie(press, temp) = PT_vs_hpt(elevation_ft * foot, pressure_sea_level_inhg * inHg, temperature_sea_level_degc + freezing); temperature_degc = temp - freezing; @@ -682,12 +802,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; +} //////////////////////////////////////////////////////////////////////// @@ -715,54 +849,69 @@ do_interp_deg (double a, double b, double fraction) return fmod(do_interp(a, b, fraction), 360); } -void -interpolate (const FGEnvironment * env1, const FGEnvironment * env2, - double fraction, FGEnvironment * result) +FGEnvironment & +FGEnvironment::interpolate( const FGEnvironment & env2, + double fraction, FGEnvironment * result) const { + // 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(), + (do_interp(get_visibility_m(), + env2.get_visibility_m(), fraction)); result->set_temperature_sea_level_degc - (do_interp(env1->get_temperature_sea_level_degc(), - env2->get_temperature_sea_level_degc(), + (do_interp(get_temperature_sea_level_degc(), + env2.get_temperature_sea_level_degc(), fraction)); - result->set_dewpoint_degc - (do_interp(env1->get_dewpoint_sea_level_degc(), - env2->get_dewpoint_sea_level_degc(), + result->set_dewpoint_sea_level_degc + (do_interp(get_dewpoint_sea_level_degc(), + env2.get_dewpoint_sea_level_degc(), fraction)); result->set_pressure_sea_level_inhg - (do_interp(env1->get_pressure_sea_level_inhg(), - env2->get_pressure_sea_level_inhg(), + (do_interp(get_pressure_sea_level_inhg(), + env2.get_pressure_sea_level_inhg(), fraction)); result->set_wind_from_heading_deg - (do_interp_deg(env1->get_wind_from_heading_deg(), - env2->get_wind_from_heading_deg(), + (do_interp_deg(get_wind_from_heading_deg(), + env2.get_wind_from_heading_deg(), fraction)); result->set_wind_speed_kt - (do_interp(env1->get_wind_speed_kt(), - env2->get_wind_speed_kt(), + (do_interp(get_wind_speed_kt(), + env2.get_wind_speed_kt(), fraction)); result->set_elevation_ft - (do_interp(env1->get_elevation_ft(), - env2->get_elevation_ft(), + (do_interp(get_elevation_ft(), + env2.get_elevation_ft(), fraction)); result->set_turbulence_magnitude_norm - (do_interp(env1->get_turbulence_magnitude_norm(), - env2->get_turbulence_magnitude_norm(), + (do_interp(get_turbulence_magnitude_norm(), + env2.get_turbulence_magnitude_norm(), fraction)); result->set_turbulence_rate_hz - (do_interp(env1->get_turbulence_rate_hz(), - env2->get_turbulence_rate_hz(), + (do_interp(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); + + return *result; } // end of environment.cxx