]> git.mxchange.org Git - flightgear.git/blobdiff - src/Environment/environment_ctrl.cxx
Merge commit 'refs/merge-requests/1551' of git://gitorious.org/fg/flightgear into...
[flightgear.git] / src / Environment / environment_ctrl.cxx
index 6efcbde3ee747f3eb69bc90e32afcbfb4339fa56..74f1d82ea9275f15de2e80d4a2be999ed826e47f 100644 (file)
@@ -25,6 +25,7 @@
 #endif
 
 #include <algorithm>
+#include <cstring>
 
 #include <simgear/debug/logstream.hxx>
 #include <simgear/structure/commands.hxx>
@@ -132,7 +133,9 @@ void
 FGInterpolateEnvironmentCtrl::init ()
 {
        read_table( boundary_n, _boundary_table);
-       read_table( aloft_n, _aloft_table);
+       // pass in a pointer to the environment of the last bondary layer as
+       // a starting point
+       read_table( aloft_n, _aloft_table, &(*(_boundary_table.end()-1))->environment);
 }
 
 void
@@ -142,7 +145,7 @@ FGInterpolateEnvironmentCtrl::reinit ()
 }
 
 void
-FGInterpolateEnvironmentCtrl::read_table (const SGPropertyNode * node, vector<bucket *> &table)
+FGInterpolateEnvironmentCtrl::read_table (const SGPropertyNode * node, vector<bucket *> &table, FGEnvironment * parent )
 {
        double last_altitude_ft = 0.0;
        double sort_required = false;
@@ -163,8 +166,11 @@ FGInterpolateEnvironmentCtrl::read_table (const SGPropertyNode * node, vector<bu
                                b = new bucket;
                                table.push_back(b);
                        }
+                       if (i == 0 && parent != NULL )
+                               b->environment.copy( *parent );
                        if (i > 0)
                                b->environment.copy(table[i-1]->environment);
+                       
                        b->environment.read(child);
                        b->altitude_ft = b->environment.get_elevation_ft();
 
@@ -183,6 +189,14 @@ FGInterpolateEnvironmentCtrl::read_table (const SGPropertyNode * node, vector<bu
 
        if( sort_required )
                sort(table.begin(), table.end(), bucket::lessThan);
+
+       // cleanup entries with (almost)same altitude
+       for( vector<bucket *>::size_type n = 1; n < table.size(); n++ ) {
+               if( fabs(table[n]->altitude_ft - table[n-1]->altitude_ft ) < 1 ) {
+                       SG_LOG( SG_GENERAL, SG_ALERT, "Removing duplicate altitude entry in environment config for altitude " << table[n]->altitude_ft );
+                       table.erase( table.begin() + n );
+               }
+       }
 }
 
 void
@@ -196,7 +210,7 @@ FGInterpolateEnvironmentCtrl::update (double delta_time_sec)
        int length = _boundary_table.size();
 
        if (length > 0) {
-                                                               // boundary table
+               // 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);
@@ -204,16 +218,16 @@ FGInterpolateEnvironmentCtrl::update (double delta_time_sec)
                } else if ((boundary_limit + boundary_transition) >= altitude_agl_ft) {
                        //TODO: this is 500ft above the top altitude of boundary layer
                        //shouldn't this be +/-250 ft off of the top altitude?
-                                                               // both tables
+                       // 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;
+                       double fraction = boundary_transition > SGLimitsd::min() ?
+                               (altitude_agl_ft - boundary_limit) / boundary_transition : 1.0;
                        interpolate(&env1, &env2, fraction, _environment);
                        return;
                }
        }
-                                                               // aloft table
+       // aloft table
        do_interpolate(_aloft_table, altitude_ft, _environment);
 }
 
@@ -224,31 +238,26 @@ FGInterpolateEnvironmentCtrl::do_interpolate (vector<bucket *> &table, double al
        if (length == 0)
                return;
 
-                                                               // Boundary conditions
+       // Boundary conditions
        if ((length == 1) || (table[0]->altitude_ft >= altitude_ft)) {
-               environment->copy(table[0]->environment);
+               environment->copy(table[0]->environment); // below bottom of table
                return;
        } else if (table[length-1]->altitude_ft <= altitude_ft) {
-               environment->copy(table[length-1]->environment);
+               environment->copy(table[length-1]->environment); // above top of table
                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;
-               }
-       }
+       } 
+
+       // Search the interpolation table
+       int layer;
+       for ( layer = 1; // can't be below bottom layer, handled above
+             layer < length && table[layer]->altitude_ft <= altitude_ft;
+             layer++);
+       FGEnvironment * env1 = &(table[layer-1]->environment);
+       FGEnvironment * env2 = &(table[layer]->environment);
+       // two layers of same altitude were sorted out in read_table
+       double fraction = ((altitude_ft - table[layer-1]->altitude_ft) /
+                         (table[layer]->altitude_ft - table[layer-1]->altitude_ft));
+       interpolate(env1, env2, fraction, environment);
 }
 
 bool
@@ -747,7 +756,7 @@ void FGMetarCtrl::set_metar( const char * metar_string )
                m = new FGMetar( metar_string );
        }
        catch( sg_io_exception ) {
-               fprintf( stderr, "can't get metar: %s\n", metar_string );
+               SG_LOG( SG_GENERAL, SG_WARN, "Can't get metar: " << metar_string );
                metar_valid = false;
                return;
        }