Removed FGEnvironmentMgr as a special case in globals, initialization,
etc. Improved the weather system to interpolate between different elevations and deal with boundary-layer conditions. The configuration properties are now different (see $FG_ROOT/preferences.xml).
This commit is contained in:
parent
6f3456a734
commit
e588cbadd8
12 changed files with 444 additions and 120 deletions
|
@ -540,7 +540,8 @@ void FGApproach::get_active_runway() {
|
|||
FGPhysicalProperty stationweather = WeatherDatabase->get(position);
|
||||
#else
|
||||
FGEnvironment stationweather =
|
||||
globals->get_environment_mgr()->getEnvironment(lat, lon, elev);
|
||||
((FGEnvironmentMgr *)globals->get_subsystem("environment"))
|
||||
->getEnvironment(lat, lon, elev);
|
||||
#endif
|
||||
|
||||
SGPath path( globals->get_fg_root() );
|
||||
|
|
|
@ -113,7 +113,8 @@ void FGATIS::UpdateTransmission() {
|
|||
FGPhysicalProperty stationweather = WeatherDatabase->get(position);
|
||||
#else
|
||||
FGEnvironment stationweather =
|
||||
globals->get_environment_mgr()->getEnvironment(lat, lon, elev);
|
||||
((FGEnvironmentMgr *)globals->get_subsystem("environment"))
|
||||
->getEnvironment(lat, lon, elev);
|
||||
#endif
|
||||
|
||||
transmission = "";
|
||||
|
|
|
@ -41,10 +41,79 @@
|
|||
#include "environment.hxx"
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// 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; they were then converted to deltas from the sea-level
|
||||
// defaults (approx. 15degC, 29.92inHG, and 0.00237slugs/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 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 }
|
||||
};
|
||||
|
||||
static SGInterpTable * _temperature_degc_table = 0;
|
||||
static SGInterpTable * _pressure_inhg_table = 0;
|
||||
|
||||
static void
|
||||
_setup_tables ()
|
||||
{
|
||||
if (_temperature_degc_table != 0)
|
||||
return;
|
||||
|
||||
_temperature_degc_table = new SGInterpTable;
|
||||
_pressure_inhg_table = new SGInterpTable;
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of FGEnvironment.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FGEnvironment::FGEnvironment()
|
||||
: _temperature_degc_table(new SGInterpTable),
|
||||
_pressure_inhg_table(new SGInterpTable),
|
||||
elevation_ft(0),
|
||||
: elevation_ft(0),
|
||||
visibility_m(32000),
|
||||
temperature_sea_level_degc(15),
|
||||
temperature_degc(15),
|
||||
|
@ -56,32 +125,85 @@ FGEnvironment::FGEnvironment()
|
|||
wind_speed_kt(0),
|
||||
wind_from_north_fps(0),
|
||||
wind_from_east_fps(0),
|
||||
wind_from_down_fps(0)
|
||||
wind_from_down_fps(0),
|
||||
turbulence_norm(0)
|
||||
{
|
||||
_setup_tables();
|
||||
}
|
||||
|
||||
FGEnvironment::FGEnvironment (const FGEnvironment &env)
|
||||
: _temperature_degc_table(new SGInterpTable),
|
||||
_pressure_inhg_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),
|
||||
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();
|
||||
copy(env);
|
||||
}
|
||||
|
||||
FGEnvironment::~FGEnvironment()
|
||||
{
|
||||
delete _temperature_degc_table;
|
||||
delete _pressure_inhg_table;
|
||||
}
|
||||
|
||||
void
|
||||
FGEnvironment::copy (const FGEnvironment &env)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
turbulence_norm = env.turbulence_norm;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
maybe_copy_value (FGEnvironment * env, const SGPropertyNode * node,
|
||||
const char * name, void (FGEnvironment::*setter)(double))
|
||||
{
|
||||
const SGPropertyNode * child = node->getChild(name);
|
||||
// fragile: depends on not being typed
|
||||
// as a number
|
||||
if (child != 0 && child->getStringValue()[0] != '\0') {
|
||||
(env->*setter)(child->getDoubleValue());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FGEnvironment::read (const SGPropertyNode * node)
|
||||
{
|
||||
maybe_copy_value(this, node, "visibility-m",
|
||||
&FGEnvironment::set_visibility_m);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
maybe_copy_value(this, node, "wind-from-heading-deg",
|
||||
&FGEnvironment::set_wind_from_heading_deg);
|
||||
|
||||
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-norm",
|
||||
&FGEnvironment::set_turbulence_norm);
|
||||
}
|
||||
|
||||
|
||||
|
@ -163,6 +285,12 @@ FGEnvironment::get_wind_from_down_fps () const
|
|||
return wind_from_down_fps;
|
||||
}
|
||||
|
||||
double
|
||||
FGEnvironment::get_turbulence_norm () const
|
||||
{
|
||||
return turbulence_norm;
|
||||
}
|
||||
|
||||
double
|
||||
FGEnvironment::get_elevation_ft () const
|
||||
{
|
||||
|
@ -262,6 +390,12 @@ FGEnvironment::set_wind_from_down_fps (double d)
|
|||
_recalc_hdgspd();
|
||||
}
|
||||
|
||||
void
|
||||
FGEnvironment::set_turbulence_norm (double t)
|
||||
{
|
||||
turbulence_norm = t;
|
||||
}
|
||||
|
||||
void
|
||||
FGEnvironment::set_elevation_ft (double e)
|
||||
{
|
||||
|
@ -272,59 +406,6 @@ FGEnvironment::set_elevation_ft (double e)
|
|||
_recalc_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; they were then converted to deltas from the sea-level
|
||||
// defaults (approx. 15degC, 29.92inHG, and 0.00237slugs/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 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
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FGEnvironment::_recalc_hdgspd ()
|
||||
{
|
||||
|
@ -438,4 +519,76 @@ FGEnvironment::_recalc_density ()
|
|||
density_slugft3 = pressure_psf / (virtual_temperature_degr * 1718);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Functions.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline double
|
||||
do_interp (double a, double b, double fraction)
|
||||
{
|
||||
double retval = (a + ((b - a) * fraction));
|
||||
return retval;
|
||||
}
|
||||
|
||||
static inline double
|
||||
do_interp_deg (double a, double b, double fraction)
|
||||
{
|
||||
a = fmod(a, 360);
|
||||
b = fmod(b, 360);
|
||||
if (fabs(b-a) > 180) {
|
||||
if (a < b)
|
||||
a += 360;
|
||||
else
|
||||
b += 360;
|
||||
}
|
||||
return fmod(do_interp(a, b, fraction), 360);
|
||||
}
|
||||
|
||||
void
|
||||
interpolate (const FGEnvironment * env1, const FGEnvironment * env2,
|
||||
double fraction, FGEnvironment * result)
|
||||
{
|
||||
result->set_visibility_m
|
||||
(do_interp(env1->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(),
|
||||
fraction));
|
||||
|
||||
result->set_dewpoint_sea_level_degc
|
||||
(do_interp(env1->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(),
|
||||
fraction));
|
||||
|
||||
result->set_wind_from_heading_deg
|
||||
(do_interp_deg(env1->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(),
|
||||
fraction));
|
||||
|
||||
result->set_elevation_ft
|
||||
(do_interp(env1->get_elevation_ft(),
|
||||
env2->get_elevation_ft(),
|
||||
fraction));
|
||||
|
||||
result->set_turbulence_norm
|
||||
(do_interp(env1->get_turbulence_norm(),
|
||||
env2->get_turbulence_norm(),
|
||||
fraction));
|
||||
}
|
||||
|
||||
// end of environment.cxx
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
# include <math.h>
|
||||
#endif
|
||||
|
||||
class SGInterpTable;
|
||||
|
||||
|
||||
/**
|
||||
* Model the natural environment.
|
||||
|
@ -53,6 +51,10 @@ public:
|
|||
FGEnvironment();
|
||||
FGEnvironment (const FGEnvironment &environment);
|
||||
virtual ~FGEnvironment();
|
||||
|
||||
virtual void copy (const FGEnvironment &environment);
|
||||
|
||||
virtual void read (const SGPropertyNode * node);
|
||||
|
||||
virtual double get_visibility_m () const;
|
||||
|
||||
|
@ -70,6 +72,8 @@ public:
|
|||
virtual double get_wind_from_east_fps () const;
|
||||
virtual double get_wind_from_down_fps () const;
|
||||
|
||||
virtual double get_turbulence_norm () const;
|
||||
|
||||
virtual void set_visibility_m (double v);
|
||||
|
||||
virtual void set_temperature_sea_level_degc (double t);
|
||||
|
@ -85,17 +89,13 @@ public:
|
|||
virtual void set_wind_from_east_fps (double e);
|
||||
virtual void set_wind_from_down_fps (double d);
|
||||
|
||||
protected:
|
||||
|
||||
friend class FGEnvironmentMgr;
|
||||
virtual void set_turbulence_norm (double t);
|
||||
|
||||
virtual double get_elevation_ft () const;
|
||||
virtual void set_elevation_ft (double elevation_ft);
|
||||
|
||||
private:
|
||||
|
||||
void _setup_tables ();
|
||||
|
||||
void _recalc_hdgspd ();
|
||||
void _recalc_ne ();
|
||||
|
||||
|
@ -107,9 +107,6 @@ private:
|
|||
void _recalc_alt_pressure ();
|
||||
void _recalc_density ();
|
||||
|
||||
SGInterpTable * _temperature_degc_table;
|
||||
SGInterpTable * _pressure_inhg_table;
|
||||
|
||||
double elevation_ft;
|
||||
|
||||
double visibility_m;
|
||||
|
@ -123,6 +120,8 @@ private:
|
|||
double pressure_inhg;
|
||||
double density_slugft3;
|
||||
|
||||
double turbulence_norm;
|
||||
|
||||
double wind_from_heading_deg;
|
||||
double wind_speed_kt;
|
||||
|
||||
|
@ -132,4 +131,7 @@ private:
|
|||
|
||||
};
|
||||
|
||||
void interpolate (const FGEnvironment * env1, const FGEnvironment * env2,
|
||||
double fraction, FGEnvironment * result);
|
||||
|
||||
#endif // _ENVIRONMENT_HXX
|
||||
|
|
|
@ -156,4 +156,143 @@ FGUserDefEnvironmentCtrl::update (double dt)
|
|||
_environment->set_wind_speed_kt(_current_wind_speed_kt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of FGInterpolateEnvironmentCtrl.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FGInterpolateEnvironmentCtrl::FGInterpolateEnvironmentCtrl ()
|
||||
{
|
||||
}
|
||||
|
||||
FGInterpolateEnvironmentCtrl::~FGInterpolateEnvironmentCtrl ()
|
||||
{
|
||||
for (int i = 0; i < _boundary_table.size(); i++)
|
||||
delete _boundary_table[i];
|
||||
for (int i = 0; i < _aloft_table.size(); i++)
|
||||
delete _aloft_table[i];
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
FGInterpolateEnvironmentCtrl::init ()
|
||||
{
|
||||
read_table(fgGetNode("/environment/config/boundary", true),
|
||||
_boundary_table);
|
||||
read_table(fgGetNode("/environment/config/aloft", true),
|
||||
_aloft_table);
|
||||
}
|
||||
|
||||
void
|
||||
FGInterpolateEnvironmentCtrl::reinit ()
|
||||
{
|
||||
for (int i = 0; i < _boundary_table.size(); i++)
|
||||
delete _boundary_table[i];
|
||||
for (int i = 0; i < _aloft_table.size(); i++)
|
||||
delete _aloft_table[i];
|
||||
_boundary_table.clear();
|
||||
_aloft_table.clear();
|
||||
init();
|
||||
}
|
||||
|
||||
void
|
||||
FGInterpolateEnvironmentCtrl::read_table (const SGPropertyNode * node,
|
||||
vector<bucket *> &table)
|
||||
{
|
||||
for (int i = 0; i < node->nChildren(); i++) {
|
||||
const SGPropertyNode * child = node->getChild(i);
|
||||
if (!strcmp(child->getName(), "entry") &&
|
||||
child->getStringValue("elevation-ft", "")[0] != '\0') {
|
||||
bucket * b = new bucket;
|
||||
if (i > 0)
|
||||
b->environment.copy(table[i-1]->environment);
|
||||
b->environment.read(child);
|
||||
b->altitude_ft = b->environment.get_elevation_ft();
|
||||
table.push_back(b);
|
||||
}
|
||||
}
|
||||
sort(table.begin(), table.end());
|
||||
}
|
||||
|
||||
void
|
||||
FGInterpolateEnvironmentCtrl::update (double delta_time_sec)
|
||||
{
|
||||
// FIXME
|
||||
double altitude_ft = fgGetDouble("/position/altitude-ft");
|
||||
double altitude_agl_ft = fgGetDouble("/position/altitude-agl-ft");
|
||||
double boundary_transition =
|
||||
fgGetDouble("/environment/config/boundary-transition-ft", 500);
|
||||
|
||||
double ground_elevation_ft = altitude_ft - altitude_agl_ft;
|
||||
|
||||
int length = _boundary_table.size();
|
||||
|
||||
if (length > 0) {
|
||||
// boundary table
|
||||
double boundary_limit = _boundary_table[length-1]->altitude_ft;
|
||||
if (boundary_limit >= altitude_agl_ft) {
|
||||
do_interpolate(_boundary_table, altitude_agl_ft,
|
||||
_environment);
|
||||
return;
|
||||
} else if ((boundary_limit + boundary_transition) >= altitude_agl_ft) {
|
||||
// both tables
|
||||
do_interpolate(_boundary_table, altitude_agl_ft, &env1);
|
||||
do_interpolate(_aloft_table, altitude_ft, &env2);
|
||||
double fraction =
|
||||
(altitude_agl_ft - boundary_limit) / boundary_transition;
|
||||
interpolate(&env1, &env2, fraction, _environment);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// aloft table
|
||||
do_interpolate(_aloft_table, altitude_ft, _environment);
|
||||
}
|
||||
|
||||
void
|
||||
FGInterpolateEnvironmentCtrl::do_interpolate (vector<bucket *> &table,
|
||||
double altitude_ft,
|
||||
FGEnvironment * environment)
|
||||
{
|
||||
int length = table.size();
|
||||
if (length == 0)
|
||||
return;
|
||||
|
||||
// Boundary conditions
|
||||
if ((length == 1) || (table[0]->altitude_ft >= altitude_ft)) {
|
||||
environment->copy(table[0]->environment);
|
||||
return;
|
||||
} else if (table[length-1]->altitude_ft <= altitude_ft) {
|
||||
environment->copy(table[length-1]->environment);
|
||||
return;
|
||||
}
|
||||
|
||||
// Search the interpolation table
|
||||
for (int i = 0; i < length - 1; i++) {
|
||||
if ((i == length - 1) || (table[i]->altitude_ft <= altitude_ft)) {
|
||||
FGEnvironment * env1 = &(table[i]->environment);
|
||||
FGEnvironment * env2 = &(table[i+1]->environment);
|
||||
double fraction;
|
||||
if (table[i]->altitude_ft == table[i+1]->altitude_ft)
|
||||
fraction = 1.0;
|
||||
else
|
||||
fraction =
|
||||
((altitude_ft - table[i]->altitude_ft) /
|
||||
(table[i+1]->altitude_ft - table[i]->altitude_ft));
|
||||
interpolate(env1, env2, fraction, environment);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
FGInterpolateEnvironmentCtrl::bucket::operator< (const bucket &b) const
|
||||
{
|
||||
return (altitude_ft < b.altitude_ft);
|
||||
}
|
||||
|
||||
|
||||
// end of environment_ctrl.cxx
|
||||
|
|
|
@ -31,8 +31,14 @@
|
|||
# include <math.h>
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
SG_USING_STD(vector);
|
||||
|
||||
class SGPropertyNode;
|
||||
|
||||
#include <Main/fgfs.hxx>
|
||||
|
||||
#include "environment.hxx"
|
||||
|
||||
|
||||
|
@ -40,7 +46,7 @@ class SGPropertyNode;
|
|||
/**
|
||||
* Interface to control environment information for a specific location.
|
||||
*/
|
||||
class FGEnvironmentCtrl
|
||||
class FGEnvironmentCtrl : public FGSubsystem
|
||||
{
|
||||
|
||||
public:
|
||||
|
@ -61,9 +67,6 @@ public:
|
|||
virtual double getLatitudeDeg () const { return _lat_deg; }
|
||||
virtual double getElevationFt () const { return _elev_ft; }
|
||||
|
||||
virtual void init () = 0;
|
||||
virtual void update (double dt) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
FGEnvironment * _environment;
|
||||
|
@ -97,4 +100,38 @@ private:
|
|||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interplation controller using user-supplied parameters.
|
||||
*/
|
||||
class FGInterpolateEnvironmentCtrl : public FGEnvironmentCtrl
|
||||
{
|
||||
public:
|
||||
FGInterpolateEnvironmentCtrl ();
|
||||
virtual ~FGInterpolateEnvironmentCtrl ();
|
||||
|
||||
virtual void init ();
|
||||
virtual void reinit ();
|
||||
virtual void update (double delta_time_sec);
|
||||
|
||||
private:
|
||||
|
||||
struct bucket {
|
||||
double altitude_ft;
|
||||
FGEnvironment environment;
|
||||
bool operator< (const bucket &b) const;
|
||||
};
|
||||
|
||||
void read_table (const SGPropertyNode * node, vector<bucket *> &table);
|
||||
void do_interpolate (vector<bucket *> &table, double altitude_ft,
|
||||
FGEnvironment * environment);
|
||||
|
||||
FGEnvironment env1, env2; // temporaries
|
||||
|
||||
vector<bucket *> _boundary_table;
|
||||
vector<bucket *> _aloft_table;
|
||||
};
|
||||
|
||||
|
||||
#endif // _ENVIRONMENT_CTRL_HXX
|
||||
|
|
|
@ -35,8 +35,10 @@ extern SGSky *thesky; // FIXME: from main.cxx
|
|||
|
||||
FGEnvironmentMgr::FGEnvironmentMgr ()
|
||||
: _environment(new FGEnvironment),
|
||||
_controller(new FGUserDefEnvironmentCtrl)
|
||||
_controller(new FGInterpolateEnvironmentCtrl)
|
||||
{
|
||||
_controller->setEnvironment(_environment);
|
||||
set_subsystem("controller", _controller, 0.5);
|
||||
}
|
||||
|
||||
FGEnvironmentMgr::~FGEnvironmentMgr ()
|
||||
|
@ -49,8 +51,15 @@ void
|
|||
FGEnvironmentMgr::init ()
|
||||
{
|
||||
SG_LOG( SG_GENERAL, SG_INFO, "Initializing environment subsystem");
|
||||
_controller->setEnvironment(_environment);
|
||||
_controller->init();
|
||||
FGSubsystemGroup::init();
|
||||
_update_fdm();
|
||||
}
|
||||
|
||||
void
|
||||
FGEnvironmentMgr::reinit ()
|
||||
{
|
||||
SG_LOG( SG_GENERAL, SG_INFO, "Reinitializing environment subsystem");
|
||||
FGSubsystemGroup::reinit();
|
||||
_update_fdm();
|
||||
}
|
||||
|
||||
|
@ -97,6 +106,10 @@ FGEnvironmentMgr::bind ()
|
|||
&FGEnvironment::get_wind_from_down_fps,
|
||||
&FGEnvironment::set_wind_from_down_fps);
|
||||
fgSetArchivable("/environment/wind-from-down-fps");
|
||||
fgTie("/environment/turbulence-norm", _environment,
|
||||
&FGEnvironment::get_turbulence_norm,
|
||||
&FGEnvironment::set_turbulence_norm);
|
||||
fgSetArchivable("/environment/turbulence-norm");
|
||||
|
||||
for (int i = 0; i < MAX_CLOUD_LAYERS; i++) {
|
||||
char buf[128];
|
||||
|
@ -160,7 +173,8 @@ FGEnvironmentMgr::unbind ()
|
|||
void
|
||||
FGEnvironmentMgr::update (double dt)
|
||||
{
|
||||
_controller->update(dt);
|
||||
FGSubsystemGroup::update(dt);
|
||||
|
||||
// FIXME: the FDMs should update themselves
|
||||
current_aircraft.fdm_state
|
||||
->set_Velocities_Local_Airmass(_environment->get_wind_from_north_fps(),
|
||||
|
|
|
@ -40,7 +40,7 @@ class FGEnvironmentCtrl;
|
|||
/**
|
||||
* Manage environment information.
|
||||
*/
|
||||
class FGEnvironmentMgr : public FGSubsystem
|
||||
class FGEnvironmentMgr : public FGSubsystemGroup
|
||||
{
|
||||
|
||||
public:
|
||||
|
@ -53,6 +53,7 @@ public:
|
|||
virtual ~FGEnvironmentMgr ();
|
||||
|
||||
virtual void init ();
|
||||
virtual void reinit ();
|
||||
virtual void bind ();
|
||||
virtual void unbind ();
|
||||
virtual void update (double dt);
|
||||
|
|
|
@ -1477,8 +1477,7 @@ bool fgInitSubsystems() {
|
|||
global_events.Register( "weather update", &fgUpdateWeatherDatabase,
|
||||
30000);
|
||||
#else
|
||||
globals->get_environment_mgr()->init();
|
||||
globals->get_environment_mgr()->bind();
|
||||
globals->add_subsystem("environment", new FGEnvironmentMgr);
|
||||
#endif
|
||||
|
||||
#ifdef FG_USE_CLOUDS_3D
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
#include <simgear/misc/commands.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
#include <Environment/environment_mgr.hxx>
|
||||
|
||||
#include "globals.hxx"
|
||||
#include "viewmgr.hxx"
|
||||
|
||||
|
@ -59,7 +57,6 @@ FGGlobals::FGGlobals() :
|
|||
route( NULL ),
|
||||
current_panel( NULL ),
|
||||
soundmgr( NULL ),
|
||||
environment_mgr( NULL ),
|
||||
ATC_mgr( NULL ),
|
||||
ATC_display( NULL ),
|
||||
AI_mgr( NULL ),
|
||||
|
|
|
@ -65,8 +65,6 @@ class FGATCDisplay;
|
|||
class FGAircraftModel;
|
||||
class FGAutopilot;
|
||||
class FGControls;
|
||||
class FGEnvironment;
|
||||
class FGEnvironmentMgr;
|
||||
class FGIO;
|
||||
class FGModelMgr;
|
||||
class FGScenery;
|
||||
|
@ -136,9 +134,6 @@ private:
|
|||
// sound manager
|
||||
SGSoundMgr *soundmgr;
|
||||
|
||||
// environment information
|
||||
FGEnvironmentMgr * environment_mgr;
|
||||
|
||||
// ATC manager
|
||||
FGATCMgr *ATC_mgr;
|
||||
|
||||
|
@ -245,13 +240,6 @@ public:
|
|||
inline SGRoute *get_route() const { return route; }
|
||||
inline void set_route( SGRoute *r ) { route = r; }
|
||||
|
||||
inline FGEnvironmentMgr * get_environment_mgr() {
|
||||
return environment_mgr;
|
||||
}
|
||||
inline void set_environment_mgr(FGEnvironmentMgr * mgr) {
|
||||
environment_mgr = mgr;
|
||||
}
|
||||
|
||||
inline FGATCMgr *get_ATC_mgr() const { return ATC_mgr; }
|
||||
inline void set_ATC_mgr( FGATCMgr *a ) {ATC_mgr = a; }
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@ SG_USING_STD(endl);
|
|||
#include <simgear/ephemeris/ephemeris.hxx>
|
||||
#include <simgear/route/route.hxx>
|
||||
|
||||
#include <Environment/environment_mgr.hxx>
|
||||
|
||||
#ifdef SG_MATH_EXCEPTION_CLASH
|
||||
# include <math.h>
|
||||
#endif
|
||||
|
@ -183,8 +185,6 @@ static double delta_time_sec = 0;
|
|||
|
||||
#ifdef FG_WEATHERCM
|
||||
# include <WeatherCM/FGLocalWeatherDatabase.h>
|
||||
#else
|
||||
# include <Environment/environment_mgr.hxx>
|
||||
#endif
|
||||
|
||||
#include "version.h"
|
||||
|
@ -952,10 +952,6 @@ void fgUpdateTimeDepCalcs() {
|
|||
cur_fdm_state->bind();
|
||||
}
|
||||
|
||||
#ifndef FG_WEATHERCM
|
||||
globals->get_environment_mgr()->update(delta_time_sec);
|
||||
#endif
|
||||
|
||||
// conceptually, the following block could be done for each fdm
|
||||
// instance ...
|
||||
if ( !cur_fdm_state->get_inited() ) {
|
||||
|
@ -1582,10 +1578,6 @@ static bool fgMainInit( int argc, char **argv ) {
|
|||
|
||||
globals = new FGGlobals;
|
||||
|
||||
#ifndef FG_WEATHERCM
|
||||
globals->set_environment_mgr(new FGEnvironmentMgr);
|
||||
#endif
|
||||
|
||||
// seed the random number generater
|
||||
sg_srandom_time();
|
||||
|
||||
|
|
Loading…
Reference in a new issue