Hi!

First of all I'd like to say hi to all as this is my first message to
this list! Hi :)

Then, when messing around with fg, I noticed that the current atmosphere
model is somewhat correct only on troposphere (around 12km or so), and I
think some aircrafts we have can go higher than that.

So I did some improvements on that function. At low altitudes it behaves
(almost) like the old one. It also has latitude dependency, and it
should behave quite well up to 85km. Of course, that is a bit overkill.

However, I have the patch attached, it was done againts the latest git
version with "git diff". I hope it is correctly done.

I also plotted some altitude-temperature curves at different latitudes
(0, 37 and 80 degrees). They can be seen here
http://users.tkk.fi/~lapelto2/fgfs_temperature.jpg . The source cites
some references I used so the accuracy could be examined.

Lauri
--
Lauri Peltonen
lauri.pelto...@gmail.com
diff --git a/src/Environment/environment.cxx b/src/Environment/environment.cxx
index dfb8824..7887fbb 100644
--- a/src/Environment/environment.cxx
+++ b/src/Environment/environment.cxx
@@ -38,7 +38,7 @@
 #include "environment.hxx"
 
 
-
+
 ////////////////////////////////////////////////////////////////////////
 // Atmosphere model.
 ////////////////////////////////////////////////////////////////////////
@@ -119,6 +119,7 @@ _setup_tables ()
 void FGEnvironment::_init()
 {
     elevation_ft = 0;
+    latitude_deg = 0;
     visibility_m = 32000;
     temperature_sea_level_degc = 15;
     temperature_degc = 15;
@@ -160,6 +161,7 @@ void
 FGEnvironment::copy (const FGEnvironment &env)
 {
     elevation_ft = env.elevation_ft;
+    latitude_deg = env.latitude_deg;
     visibility_m = env.visibility_m;
     temperature_sea_level_degc = env.temperature_sea_level_degc;
     temperature_degc = env.temperature_degc;
@@ -358,6 +360,12 @@ FGEnvironment::get_elevation_ft () const
   return elevation_ft;
 }
 
+double
+FGEnvironment::get_latitude_deg () const
+{
+  return latitude_deg;
+}
+
 void
 FGEnvironment::set_visibility_m (double v)
 {
@@ -477,6 +485,20 @@ FGEnvironment::set_elevation_ft (double e)
 }
 
 void
+FGEnvironment::set_latitude_deg (double alt)
+{
+  latitude_deg = alt;
+
+  // Latitude affects temperature, so recalc everything
+  // that depends on temp
+  _recalc_alt_temperature();
+  _recalc_alt_dewpoint();
+  _recalc_alt_pressure();
+  _recalc_density();
+  _recalc_relative_humidity();
+}
+
+void
 FGEnvironment::set_altitude_half_to_sun_m (double alt)
 {
  altitude_half_to_sun_m = alt;
@@ -540,7 +562,8 @@ void
 FGEnvironment::_recalc_sl_temperature ()
 {
   // If we're in the stratosphere, leave sea-level temp alone
-  if (elevation_ft < 38000) {
+  // (a little smaller to also work correctly at poles!)
+  if (elevation_ft < 28000) {
     temperature_sea_level_degc = (temperature_degc + 273.15)
         / _temperature_degc_table->interpolate(elevation_ft)
       - 273.15;
@@ -550,11 +573,84 @@ FGEnvironment::_recalc_sl_temperature ()
 void
 FGEnvironment::_recalc_alt_temperature ()
 {
-  if (elevation_ft < 38000) {
+  // This should calculate troposphere temperature
+  // quite accurately.
+  // In real life tropopause is different elevation in south and north
+  // but the difference is quite small.
+  // Info from: http://www.ux1.eiu.edu/~cfjps/1400/atmos_struct.html
+  // and: http://eospso.gsfc.nasa.gov/eos_homepage/for_scientists/data_products/OurChangingPlanet/PDF/Page_05_new.pdf
+
+  // take the absolute value of lat for simplicity
+  double lat = (latitude_deg < 0) ? -latitude_deg : latitude_deg;
+
+  // Using simple interpolation instead of the real curve
+  double tropopause = 51562;  // Default tropopause at -30 < lat < 30
+  if(lat > 60) {
+    tropopause = 31250 - 104.1 * (lat - 60);
+  } else if(lat > 30) {
+    tropopause = 51562 - 677.1 * (lat - 30);
+  }
+
+  // This is quite good estimation for elevations below ~35000
+  // We need to calculate this for all elevations above this!
+  double e = elevation_ft;
+  if(e > tropopause) e = tropopause;
+
+  if(e <= 35000)
+  {
     temperature_degc = (temperature_sea_level_degc + 273.15) *
-        _temperature_degc_table->interpolate(elevation_ft) - 273.15;
-  } else {
-    temperature_degc = -56.49;	// Stratosphere is constant
+          _temperature_degc_table->interpolate(e) - 273.15;
+  }
+  else
+  {
+    // at equator tropopause is much higher than 35000 so new estimation :)
+    // Using lapse rate of 6,5 degC / km
+    // use the temp @ 35000 as a starting point
+    temperature_degc = (temperature_sea_level_degc + 273.15) *
+      _temperature_degc_table->interpolate(35000) - 273.15 - 0.00208 * (e - 35000);
+  }
+
+  // At this point the temperature below tropopause is calculated :)
+  // Continue with upper levels
+
+  if(elevation_ft > tropopause)  
+  {
+    // tropopause is not really constant, so estimate different lapse rates
+    double lapse_rate = 0.00053; // at equator
+    double pause_top = 93750;
+
+    if(lat > 60) {
+      lapse_rate = 0;
+      pause_top = 43750;
+    } else if(lat > 30) {
+      lapse_rate = 0.00053 - 0.0000176*(lat-30);  // Linear approximation
+      pause_top = 93750 - 1666.67*(lat-30);
+    }
+
+    e = elevation_ft;
+    if(e > pause_top) e = pause_top;
+
+    // Approximate the temperature change at tropopause
+    temperature_degc += lapse_rate*(e - tropopause);
+
+    // If we are even higher...! STRATOSPHERE
+    if(elevation_ft > pause_top)
+    {
+      if(elevation_ft < 150000) {
+        // we could use some even better approximation here
+        // Because north and south poles, for example, have very different
+        // temperatures after tropopause (see my 2nd source)
+        // But as almost no plane flies that high, let's assume
+        // linear transition to 10 degC in 48 km or 150000 ft
+        temperature_degc += (elevation_ft - pause_top) * (10-temperature_degc) / (150000-pause_top);
+      }
+
+      // For the sake of it, let's add one more layer, MESOSPHERE!
+      else
+      {
+        temperature_degc = 10 - 0.000865*(elevation_ft-150000);
+      }
+    }
   }
 }
 
diff --git a/src/Environment/environment.hxx b/src/Environment/environment.hxx
index 4d82685..4c964f0 100644
--- a/src/Environment/environment.hxx
+++ b/src/Environment/environment.hxx
@@ -93,7 +93,9 @@ public:
   virtual void set_turbulence_rate_hz (double t);
 
   virtual double get_elevation_ft () const;
+  virtual double get_latitude_deg () const;
   virtual void set_elevation_ft (double elevation_ft);
+  virtual void set_latitude_deg (double latitude_deg);
   virtual void set_altitude_half_to_sun_m (double alt);
   virtual void set_altitude_tropo_top_m (double alt);
 
@@ -114,6 +116,7 @@ private:
   void _recalc_relative_humidity ();
 
   double elevation_ft;
+  double latitude_deg;
   double visibility_m;
 
   // Atmosphere
diff --git a/src/Environment/environment_mgr.cxx b/src/Environment/environment_mgr.cxx
index 0ff1abb..3b97a4b 100644
--- a/src/Environment/environment_mgr.cxx
+++ b/src/Environment/environment_mgr.cxx
@@ -263,6 +263,7 @@ FGEnvironmentMgr::update (double dt)
 				   _environment->get_wind_from_east_fps(),
 				   _environment->get_wind_from_down_fps());
   _environment->set_elevation_ft(fgGetDouble("/position/altitude-ft"));
+  _environment->set_latitude_deg(fgGetDouble("/position/latitude-deg"));
   osg::Vec3 windVec(-_environment->get_wind_from_north_fps(),
                     -_environment->get_wind_from_east_fps(),
                     _environment->get_wind_from_down_fps());
@@ -285,6 +286,7 @@ FGEnvironmentMgr::getEnvironment (double lat, double lon, double alt) const
 				// later.
   FGEnvironment env = *_environment;
   env.set_elevation_ft(alt);
+  env.set_latitude_deg(lat);
   return env;
 }
 
@@ -296,6 +298,7 @@ FGEnvironmentMgr::getEnvironment(const SGGeod& aPos) const
   // later.
   FGEnvironment env = *_environment;
   env.set_elevation_ft(aPos.getElevationFt());
+  env.set_latitude_deg(aPos.getLatitudeDeg());
   return env;
 
 }
------------------------------------------------------------------------------
Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are
powering Web 2.0 with engaging, cross-platform capabilities. Quickly and
easily build your RIAs with Flex Builder, the Eclipse(TM)based development
software that enables intelligent coding and step-through debugging.
Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com
_______________________________________________
Flightgear-devel mailing list
Flightgear-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/flightgear-devel

Reply via email to