1
0
Fork 0

Finished off the atmosphere model (Troposphere and lower

Stratosphere).  The atmospheric properties are as follow:

/environment/temperature-sea-level-degc
/environment/temperature-degc
/environment/pressure-sea-level-inhg
/environment/pressure-inhg
/environment/density-sea-level-slugft3
/environment/density-slugft3

Setting either the sea-level or altitude value automatically sets the
other value appropriate, except for temperature at altitude above the
Troposphere (where there's no reliable way to back-calculate it).  The
atmosphere model appears in the atmosphere_data array in
environment.cxx, and can easily be extended into the upper
stratosphere and beyond.

These are not yet tied into the FDMs or steam module.
This commit is contained in:
david 2002-05-15 03:00:41 +00:00
parent abdb5abb6a
commit 8a5cdbdbc6
3 changed files with 167 additions and 40 deletions

View file

@ -35,38 +35,52 @@
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/interpolater.hxx>
#include <Main/fg_props.hxx>
#include "environment.hxx"
FGEnvironment::FGEnvironment()
: visibility_m(32000),
: _temperature_degc_table(new SGInterpTable),
_pressure_inhg_table(new SGInterpTable),
_density_slugft3_table(new SGInterpTable),
visibility_m(32000),
temperature_sea_level_degc(20),
pressure_sea_level_inhg(28),
density_sea_level_slugft3(0.0024),
wind_from_heading_deg(0),
wind_speed_kt(0),
wind_from_north_fps(0),
wind_from_east_fps(0),
wind_from_down_fps(0)
{
_setup_tables();
}
FGEnvironment::FGEnvironment (const FGEnvironment &env)
: elevation_ft(env.elevation_ft),
: _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),
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),
wind_from_east_fps(env.wind_from_east_fps),
wind_from_down_fps(env.wind_from_down_fps)
{
_setup_tables();
}
FGEnvironment::~FGEnvironment()
{
delete _temperature_degc_table;
delete _pressure_inhg_table;
delete _density_slugft3_table;
}
@ -100,6 +114,18 @@ FGEnvironment::get_pressure_inhg () const
return pressure_inhg;
}
double
FGEnvironment::get_density_sea_level_slugft3 () const
{
return density_sea_level_slugft3;
}
double
FGEnvironment::get_density_slugft3 () const
{
return density_slugft3;
}
double
FGEnvironment::get_wind_from_heading_deg () const
{
@ -136,8 +162,6 @@ FGEnvironment::get_elevation_ft () const
return elevation_ft;
}
void
FGEnvironment::set_visibility_m (double v)
{
@ -148,28 +172,42 @@ void
FGEnvironment::set_temperature_sea_level_degc (double t)
{
temperature_sea_level_degc = t;
_recalc_alt_temp();
_recalc_alt_temperature();
}
void
FGEnvironment::set_temperature_degc (double t)
{
temperature_degc = t;
_recalc_sl_temp();
_recalc_sl_temperature();
}
void
FGEnvironment::set_pressure_sea_level_inhg (double p)
{
pressure_sea_level_inhg = p;
_recalc_alt_press();
_recalc_alt_pressure();
}
void
FGEnvironment::set_pressure_inhg (double p)
{
pressure_inhg = p;
_recalc_sl_press();
_recalc_sl_pressure();
}
void
FGEnvironment::set_density_sea_level_slugft3 (double d)
{
density_sea_level_slugft3 = d;
_recalc_alt_density();
}
void
FGEnvironment::set_density_slugft3 (double d)
{
density_slugft3 = d;
_recalc_sl_density();
}
void
@ -211,8 +249,63 @@ void
FGEnvironment::set_elevation_ft (double e)
{
elevation_ft = e;
_recalc_alt_temp();
_recalc_alt_press();
_recalc_alt_temperature();
_recalc_alt_pressure();
_recalc_alt_density();
}
// Atmosphere model.
// Copied from YASim Atmosphere.cxx, with m converted to ft, degK
// converted to degC, Pa converted to inHG, and kg/m^3 converted to
// slug/ft^3.
// Original comment from YASim:
// Copied from McCormick, who got it from "The ARDC Model Atmosphere"
// Note that there's an error in the text in the first entry,
// McCormick lists 299.16/101325/1.22500, but those don't agree with
// R=287. I chose to correct the temperature to 288.20, since 79F is
// pretty hot for a "standard" atmosphere.
// Elevation (ft), temperature (degC), pressure (inHG), density (slug/ft^3)
static double atmosphere_data[][4] = {
0, 0.00, 0.000, 0.000000,
2952, -5.89, -3.058, -0.000198,
5905, -11.74, -5.856, -0.000384,
8858, -17.58, -8.413, -0.000556,
11811, -23.43, -10.745, -0.000717,
14763, -29.27, -12.867, -0.000867,
17716, -35.11, -14.794, -0.001006,
20669, -40.95, -16.541, -0.001136,
23622, -46.79, -18.120, -0.001255,
26574, -52.62, -19.544, -0.001366,
29527, -58.46, -20.826, -0.001467,
32480, -64.29, -21.976, -0.001561,
35433, -70.12, -23.005, -0.001647,
38385, -71.54, -23.916, -0.001739,
41338, -71.54, -24.708, -0.001822,
44291, -71.54, -25.395, -0.001894,
47244, -71.54, -25.991, -0.001957,
50196, -71.54, -26.509, -0.002012,
53149, -71.54, -26.959, -0.002059,
56102, -71.54, -27.349, -0.002100,
59055, -71.54, -27.687, -0.002136,
62007, -71.54, -27.981, -0.002167,
-1, -1, -1, -1
};
void
FGEnvironment::_setup_tables ()
{
for (int i = 0; atmosphere_data[i][0] != -1; i++) {
_temperature_degc_table->addEntry(atmosphere_data[i][0],
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]);
}
}
void
@ -251,47 +344,50 @@ FGEnvironment::_recalc_ne ()
}
void
FGEnvironment::_recalc_sl_temp ()
FGEnvironment::_recalc_sl_temperature ()
{
// Earth atmosphere model from
// http://www.grc.nasa.gov/WWW/K-12/airplane/atmos.html
// Stratospheric temperatures are not really reversible, so use 15degC.
if (elevation_ft < 36152) // Troposphere
if (elevation_ft < 38000) {
temperature_sea_level_degc =
temperature_degc + (.00649 * SG_FEET_TO_METER * elevation_ft);
temperature_degc - _temperature_degc_table->interpolate(elevation_ft);
}
// If we're in the stratosphere, leave sea-level temp alone
}
void
FGEnvironment::_recalc_alt_temp ()
FGEnvironment::_recalc_alt_temperature ()
{
// Earth atmosphere model from
// http://www.grc.nasa.gov/WWW/K-12/airplane/atmos.html
if (elevation_ft < 36152) // Troposphere
temperature_degc =
temperature_sea_level_degc - (.00649 * SG_FEET_TO_METER * elevation_ft);
else if (elevation_ft < 82345) // Lower Stratosphere
temperature_degc = -56.46;
else
temperature_degc = -131.21 + (.00299 * SG_FEET_TO_METER * elevation_ft);
temperature_sea_level_degc +
_temperature_degc_table->interpolate(elevation_ft);
}
void
FGEnvironment::_recalc_sl_press ()
FGEnvironment::_recalc_sl_pressure ()
{
// FIXME: calculate properly
pressure_sea_level_inhg = pressure_inhg;
pressure_sea_level_inhg =
pressure_inhg - _pressure_inhg_table->interpolate(elevation_ft);
}
void
FGEnvironment::_recalc_alt_press ()
FGEnvironment::_recalc_alt_pressure ()
{
// FIXME: calculate properly
pressure_inhg = pressure_sea_level_inhg;
pressure_inhg =
pressure_sea_level_inhg + _pressure_inhg_table->interpolate(elevation_ft);
}
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);
}
// end of environment.cxx

View file

@ -34,6 +34,8 @@
# include <math.h>
#endif
class SGInterpTable;
/**
* Model the natural environment.
@ -53,10 +55,14 @@ public:
virtual ~FGEnvironment();
virtual double get_visibility_m () const;
virtual double get_temperature_sea_level_degc () const;
virtual double get_temperature_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;
virtual double get_wind_speed_kt () const;
virtual double get_wind_from_north_fps () const;
@ -64,10 +70,14 @@ public:
virtual double get_wind_from_down_fps () const;
virtual void set_visibility_m (double v);
virtual void set_temperature_sea_level_degc (double t);
virtual void set_temperature_degc (double t);
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);
virtual void set_wind_from_north_fps (double n);
@ -83,20 +93,33 @@ protected:
private:
void _setup_tables ();
void _recalc_hdgspd ();
void _recalc_ne ();
void _recalc_sl_temp ();
void _recalc_alt_temp ();
void _recalc_sl_press ();
void _recalc_alt_press ();
void _recalc_sl_temperature ();
void _recalc_alt_temperature ();
void _recalc_sl_pressure ();
void _recalc_alt_pressure ();
void _recalc_sl_density ();
void _recalc_alt_density ();
SGInterpTable * _temperature_degc_table;
SGInterpTable * _pressure_inhg_table;
SGInterpTable * _density_slugft3_table;
double elevation_ft;
double visibility_m;
// Atmosphere
double temperature_sea_level_degc;
double temperature_degc;
double pressure_sea_level_inhg;
double pressure_inhg;
double density_sea_level_slugft3;
double density_slugft3;
double wind_from_heading_deg;
double wind_speed_kt;

View file

@ -72,6 +72,14 @@ 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);
fgSetArchivable("/environment/density-inhg");
fgTie("/environment/wind-from-heading-deg", _environment,
&FGEnvironment::get_wind_from_heading_deg,
&FGEnvironment::set_wind_from_heading_deg);