From 56642901b50ed3c3838251a7c25fe592ff68c2e1 Mon Sep 17 00:00:00 2001 From: david Date: Thu, 6 Jun 2002 00:21:23 +0000 Subject: [PATCH] Air density is now calculated automatically from air pressure, temperature, and dewpoint. The /environment/density-sea-level-slugft3 property has been removed, and the /environment/density-slugft3 property is read-only. --- src/Environment/environment.cxx | 162 +++++++++++++++++----------- src/Environment/environment.hxx | 16 +-- src/Environment/environment_mgr.cxx | 29 +++-- 3 files changed, 127 insertions(+), 80 deletions(-) diff --git a/src/Environment/environment.cxx b/src/Environment/environment.cxx index 75adb24a3..21f4158e7 100644 --- a/src/Environment/environment.cxx +++ b/src/Environment/environment.cxx @@ -44,11 +44,10 @@ FGEnvironment::FGEnvironment() : _temperature_degc_table(new SGInterpTable), _pressure_inhg_table(new SGInterpTable), - _density_slugft3_table(new SGInterpTable), visibility_m(32000), - temperature_sea_level_degc(20), + temperature_sea_level_degc(15), + dewpoint_sea_level_degc(5), // guess pressure_sea_level_inhg(29.92), - density_sea_level_slugft3(0.00237), wind_from_heading_deg(0), wind_speed_kt(0), wind_from_north_fps(0), @@ -61,12 +60,11 @@ FGEnvironment::FGEnvironment() FGEnvironment::FGEnvironment (const FGEnvironment &env) : _temperature_degc_table(new SGInterpTable), _pressure_inhg_table(new SGInterpTable), - _density_slugft3_table(new SGInterpTable), elevation_ft(env.elevation_ft), visibility_m(env.visibility_m), temperature_sea_level_degc(env.temperature_sea_level_degc), + dewpoint_sea_level_degc(env.dewpoint_sea_level_degc), pressure_sea_level_inhg(env.pressure_sea_level_inhg), - density_sea_level_slugft3(env.density_sea_level_slugft3), wind_from_heading_deg(env.wind_from_heading_deg), wind_speed_kt(env.wind_speed_kt), wind_from_north_fps(env.wind_from_north_fps), @@ -80,7 +78,6 @@ FGEnvironment::~FGEnvironment() { delete _temperature_degc_table; delete _pressure_inhg_table; - delete _density_slugft3_table; } @@ -103,21 +100,27 @@ FGEnvironment::get_temperature_degc () const } double -FGEnvironment::get_pressure_sea_level_inhg () const +FGEnvironment::get_dewpoint_sea_level_degc () const { - return pressure_sea_level_inhg; + return dewpoint_sea_level_degc; } double -FGEnvironment::get_pressure_inhg () const +FGEnvironment::get_dewpoint_degc () const { - return pressure_inhg; + return dewpoint_degc; } double -FGEnvironment::get_density_sea_level_slugft3 () const +FGEnvironment::get_pressure_sea_level_inhg () const { - return density_sea_level_slugft3; + return pressure_sea_level_inhg; +} + +double +FGEnvironment::get_pressure_inhg () const +{ + return pressure_inhg; } double @@ -173,6 +176,7 @@ FGEnvironment::set_temperature_sea_level_degc (double t) { temperature_sea_level_degc = t; _recalc_alt_temperature(); + _recalc_density(); } void @@ -180,34 +184,39 @@ FGEnvironment::set_temperature_degc (double t) { temperature_degc = t; _recalc_sl_temperature(); + _recalc_density(); } void -FGEnvironment::set_pressure_sea_level_inhg (double p) +FGEnvironment::set_dewpoint_sea_level_degc (double t) { - pressure_sea_level_inhg = p; - _recalc_alt_pressure(); + dewpoint_sea_level_degc = t; + _recalc_alt_dewpoint(); + _recalc_density(); } void -FGEnvironment::set_pressure_inhg (double p) +FGEnvironment::set_dewpoint_degc (double t) { - pressure_inhg = p; - _recalc_sl_pressure(); + dewpoint_degc = t; + _recalc_sl_dewpoint(); + _recalc_density(); } void -FGEnvironment::set_density_sea_level_slugft3 (double d) +FGEnvironment::set_pressure_sea_level_inhg (double p) { - density_sea_level_slugft3 = d; - _recalc_alt_density(); + pressure_sea_level_inhg = p; + _recalc_alt_pressure(); + _recalc_density(); } void -FGEnvironment::set_density_slugft3 (double d) +FGEnvironment::set_pressure_inhg (double p) { - density_slugft3 = d; - _recalc_sl_density(); + pressure_inhg = p; + _recalc_sl_pressure(); + _recalc_density(); } void @@ -250,8 +259,9 @@ FGEnvironment::set_elevation_ft (double e) { elevation_ft = e; _recalc_alt_temperature(); + _recalc_alt_dewpoint(); _recalc_alt_pressure(); - _recalc_alt_density(); + _recalc_density(); } // Atmosphere model. @@ -269,32 +279,31 @@ FGEnvironment::set_elevation_ft (double e) // R=287. I chose to correct the temperature to 288.20, since 79F is // pretty hot for a "standard" atmosphere. -// Elevation (ft), temperature factor (degK), pressure factor (inHG), -// density factor (slug/ft^3) -static double atmosphere_data[][4] = { - 0.00, 1.00, 1.000, 1.000000, - 2952.76, 0.98, 0.898, 0.916408, - 5905.51, 0.96, 0.804, 0.838286, - 8858.27, 0.94, 0.719, 0.765429, - 11811.02, 0.92, 0.641, 0.697510, - 14763.78, 0.90, 0.570, 0.634318, - 17716.54, 0.88, 0.506, 0.575616, - 20669.29, 0.86, 0.447, 0.521184, - 23622.05, 0.84, 0.394, 0.470784, - 26574.80, 0.82, 0.347, 0.424220, - 29527.56, 0.80, 0.304, 0.381273, - 32480.31, 0.78, 0.266, 0.341747, - 35433.07, 0.76, 0.231, 0.305445, - 38385.83, 0.75, 0.201, 0.266931, - 41338.58, 0.75, 0.174, 0.231739, - 44291.34, 0.75, 0.151, 0.201192, - 47244.09, 0.75, 0.131, 0.174686, - 50196.85, 0.75, 0.114, 0.151673, - 53149.61, 0.75, 0.099, 0.131698, - 56102.36, 0.75, 0.086, 0.114359, - 59055.12, 0.75, 0.075, 0.099306, - 62007.87, 0.75, 0.065, 0.086237, - -1, -1, -1, -1 +// Elevation (ft), temperature factor (degK), pressure factor (inHG) +static double atmosphere_data[][3] = { + 0.00, 1.00, 1.000, + 2952.76, 0.98, 0.898, + 5905.51, 0.96, 0.804, + 8858.27, 0.94, 0.719, + 11811.02, 0.92, 0.641, + 14763.78, 0.90, 0.570, + 17716.54, 0.88, 0.506, + 20669.29, 0.86, 0.447, + 23622.05, 0.84, 0.394, + 26574.80, 0.82, 0.347, + 29527.56, 0.80, 0.304, + 32480.31, 0.78, 0.266, + 35433.07, 0.76, 0.231, + 38385.83, 0.75, 0.201, + 41338.58, 0.75, 0.174, + 44291.34, 0.75, 0.151, + 47244.09, 0.75, 0.131, + 50196.85, 0.75, 0.114, + 53149.61, 0.75, 0.099, + 56102.36, 0.75, 0.086, + 59055.12, 0.75, 0.075, + 62007.87, 0.75, 0.065, + -1, -1, -1 }; void @@ -305,8 +314,6 @@ FGEnvironment::_setup_tables () atmosphere_data[i][1]); _pressure_inhg_table->addEntry(atmosphere_data[i][0], atmosphere_data[i][2]); - _density_slugft3_table->addEntry(atmosphere_data[i][0], - atmosphere_data[i][3]); } } @@ -369,6 +376,28 @@ FGEnvironment::_recalc_alt_temperature () } } +void +FGEnvironment::_recalc_sl_dewpoint () +{ + // 0.2degC/1000ft + // FIXME: this will work only for low + // elevations + dewpoint_sea_level_degc = dewpoint_degc + (elevation_ft * .0002); + if (dewpoint_sea_level_degc > temperature_sea_level_degc) + dewpoint_sea_level_degc = temperature_sea_level_degc; +} + +void +FGEnvironment::_recalc_alt_dewpoint () +{ + // 0.2degC/1000ft + // FIXME: this will work only for low + // elevations + dewpoint_degc = dewpoint_sea_level_degc + (elevation_ft * .0002); + if (dewpoint_degc > temperature_degc) + dewpoint_degc = temperature_degc; +} + void FGEnvironment::_recalc_sl_pressure () { @@ -384,18 +413,21 @@ FGEnvironment::_recalc_alt_pressure () } void -FGEnvironment::_recalc_sl_density () -{ - density_sea_level_slugft3 = - density_slugft3 / _density_slugft3_table->interpolate(elevation_ft); -} - -void -FGEnvironment::_recalc_alt_density () -{ - density_slugft3 = - density_sea_level_slugft3 * - _density_slugft3_table->interpolate(elevation_ft); +FGEnvironment::_recalc_density () +{ + double pressure_psf = pressure_inhg * 70.7487; + + // adjust for humidity + // calculations taken from USA Today (oops!) at + // http://www.usatoday.com/weather/basics/density-calculations.htm + double temperature_degk = temperature_degc + 273.15; + double pressure_mb = pressure_inhg * 33.86; + double vapor_pressure_mb = + 6.11 * pow(10.0, 7.5 * dewpoint_degc / (237.7 + dewpoint_degc)); + double virtual_temperature_degk = temperature_degk / (1 - (vapor_pressure_mb / pressure_mb) * (1.0 - 0.622)); + double virtual_temperature_degr = virtual_temperature_degk * 1.8; + + density_slugft3 = pressure_psf / (virtual_temperature_degr * 1718); } // end of environment.cxx diff --git a/src/Environment/environment.hxx b/src/Environment/environment.hxx index 66a221fc1..264072d65 100644 --- a/src/Environment/environment.hxx +++ b/src/Environment/environment.hxx @@ -58,9 +58,10 @@ public: virtual double get_temperature_sea_level_degc () const; virtual double get_temperature_degc () const; + virtual double get_dewpoint_sea_level_degc () const; + virtual double get_dewpoint_degc () const; virtual double get_pressure_sea_level_inhg () const; virtual double get_pressure_inhg () const; - virtual double get_density_sea_level_slugft3 () const; virtual double get_density_slugft3 () const; virtual double get_wind_from_heading_deg () const; @@ -73,10 +74,10 @@ public: virtual void set_temperature_sea_level_degc (double t); virtual void set_temperature_degc (double t); + virtual void set_dewpoint_sea_level_degc (double d); + virtual void set_dewpoint_degc (double d); virtual void set_pressure_sea_level_inhg (double p); virtual void set_pressure_inhg (double p); - virtual void set_density_sea_level_slugft3 (double d); - virtual void set_density_slugft3 (double d); virtual void set_wind_from_heading_deg (double h); virtual void set_wind_speed_kt (double s); @@ -100,14 +101,14 @@ private: void _recalc_sl_temperature (); void _recalc_alt_temperature (); + void _recalc_sl_dewpoint (); + void _recalc_alt_dewpoint (); void _recalc_sl_pressure (); void _recalc_alt_pressure (); - void _recalc_sl_density (); - void _recalc_alt_density (); + void _recalc_density (); SGInterpTable * _temperature_degc_table; SGInterpTable * _pressure_inhg_table; - SGInterpTable * _density_slugft3_table; double elevation_ft; @@ -116,9 +117,10 @@ private: // Atmosphere double temperature_sea_level_degc; double temperature_degc; + double dewpoint_sea_level_degc; + double dewpoint_degc; double pressure_sea_level_inhg; double pressure_inhg; - double density_sea_level_slugft3; double density_slugft3; double wind_from_heading_deg; diff --git a/src/Environment/environment_mgr.cxx b/src/Environment/environment_mgr.cxx index 6f82b95af..f9368e5ba 100644 --- a/src/Environment/environment_mgr.cxx +++ b/src/Environment/environment_mgr.cxx @@ -68,6 +68,14 @@ FGEnvironmentMgr::bind () &FGEnvironment::get_temperature_degc, &FGEnvironment::set_temperature_degc); fgSetArchivable("/environment/temperature-degc"); + fgTie("/environment/dewpoint-sea-level-degc", _environment, + &FGEnvironment::get_dewpoint_sea_level_degc, + &FGEnvironment::set_dewpoint_sea_level_degc); + fgSetArchivable("/environment/dewpoint-sea-level-degc"); + fgTie("/environment/dewpoint-degc", _environment, + &FGEnvironment::get_dewpoint_degc, + &FGEnvironment::set_dewpoint_degc); + fgSetArchivable("/environment/dewpoint-degc"); fgTie("/environment/pressure-sea-level-inhg", _environment, &FGEnvironment::get_pressure_sea_level_inhg, &FGEnvironment::set_pressure_sea_level_inhg); @@ -76,13 +84,8 @@ FGEnvironmentMgr::bind () &FGEnvironment::get_pressure_inhg, &FGEnvironment::set_pressure_inhg); fgSetArchivable("/environment/pressure-inhg"); - fgTie("/environment/density-sea-level-slugft3", _environment, - &FGEnvironment::get_density_sea_level_slugft3, - &FGEnvironment::set_density_sea_level_slugft3); - fgSetArchivable("/environment/density-sea-level-slugft3"); fgTie("/environment/density-slugft3", _environment, - &FGEnvironment::get_density_slugft3, - &FGEnvironment::set_density_slugft3); + &FGEnvironment::get_density_slugft3); // read-only fgSetArchivable("/environment/density-inhg"); fgTie("/environment/wind-from-heading-deg", _environment, &FGEnvironment::get_wind_from_heading_deg, @@ -108,22 +111,27 @@ FGEnvironmentMgr::bind () fgTie(buf, this, i, &FGEnvironmentMgr::get_cloud_layer_span_m, &FGEnvironmentMgr::set_cloud_layer_span_m); + fgSetArchivable(buf); sprintf(buf, "/environment/clouds/layer[%d]/elevation-ft", i); fgTie(buf, this, i, &FGEnvironmentMgr::get_cloud_layer_elevation_ft, &FGEnvironmentMgr::set_cloud_layer_elevation_ft); + fgSetArchivable(buf); sprintf(buf, "/environment/clouds/layer[%d]/thickness-ft", i); fgTie(buf, this, i, &FGEnvironmentMgr::get_cloud_layer_thickness_ft, &FGEnvironmentMgr::set_cloud_layer_thickness_ft); + fgSetArchivable(buf); sprintf(buf, "/environment/clouds/layer[%d]/transition-ft", i); fgTie(buf, this, i, &FGEnvironmentMgr::get_cloud_layer_transition_ft, &FGEnvironmentMgr::set_cloud_layer_transition_ft); + fgSetArchivable(buf); sprintf(buf, "/environment/clouds/layer[%d]/type", i); fgTie(buf, this, i, &FGEnvironmentMgr::get_cloud_layer_type, &FGEnvironmentMgr::set_cloud_layer_type); + fgSetArchivable(buf); } } @@ -131,8 +139,13 @@ void FGEnvironmentMgr::unbind () { fgUntie("/environment/visibility-m"); - fgUntie("/environment/wind-from-heading-deg"); - fgUntie("/environment/wind-speed-kt"); + fgUntie("/environment/temperature-sea-level-degc"); + fgUntie("/environment/temperature-degc"); + fgUntie("/environment/dewpoint-sea-level-degc"); + fgUntie("/environment/dewpoint-degc"); + fgUntie("/environment/pressure-sea-level-inhg"); + fgUntie("/environment/pressure-inhg"); + fgUntie("/environment/density-inhg"); fgUntie("/environment/wind-from-north-fps"); fgUntie("/environment/wind-from-east-fps"); fgUntie("/environment/wind-from-down-fps"); -- 2.39.5