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:
parent
abdb5abb6a
commit
8a5cdbdbc6
3 changed files with 167 additions and 40 deletions
|
@ -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_degc =
|
||||
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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue