]> git.mxchange.org Git - flightgear.git/blobdiff - src/Environment/ridge_lift.cxx
remove obsolete comments
[flightgear.git] / src / Environment / ridge_lift.cxx
index fa121a1a5ca5f984d065ac4063aae7d6cfc9dec4..bb461216de5626af37a74b7c3f6584fce00ad422 100644 (file)
 #include <Main/util.hxx>
 #include <Scenery/scenery.hxx>
 #include <string>
-#include <math.h>
-
+#include <cmath>
+#include <simgear/sg_inlines.h>
 
 using std::string;
 
 #include "ridge_lift.hxx"
 
-static string CreateIndexedPropertyName(string Property, int index)
-{
-       std::stringstream str;
-       str << index;
-       string tmp;
-       str >> tmp;
-       return Property + "[" + tmp + "]";
-}
-
-static inline double sign(double x) {
-       return x == 0 ? 0 : x > 0 ? 1.0 : -1.0;
-}
+static const double BOUNDARY1_m = 40.0;
 
-static const   double BOUNDARY1_m = 40.0;
+const double FGRidgeLift::dist_probe_m[] = { // in meters
+     0.0, 
+   250.0,
+   750.0,
+  2000.0,
+  -100.0
+};
 
 //constructor
-FGRidgeLift::FGRidgeLift ()
+FGRidgeLift::FGRidgeLift () :
+  lift_factor(0.0)
 {      
-       dist_probe_m[0] = 0.0; // in meters
-       dist_probe_m[1] = 250.0;
-       dist_probe_m[2] = 750.0;
-       dist_probe_m[3] = 2000.0;
-       dist_probe_m[4] = -100.0;
-
        strength = 0.0;
        timer = 0.0;
+       for( int i = 0; i < 5; i++ )
+               probe_elev_m[i] = probe_lat_deg[i] = probe_lon_deg[i] = 0.0;
+
+       for( int i = 0; i < 4; i++ )
+               slope[i] = 0.0;
 }
 
 //destructor
@@ -78,6 +73,8 @@ FGRidgeLift::~FGRidgeLift()
 
 void FGRidgeLift::init(void)
 {
+       _enabled_node = fgGetNode( "/environment/ridge-lift/enabled", false );
+
        _ridge_lift_fps_node = fgGetNode("/environment/ridge-lift-fps", true);
        _surface_wind_from_deg_node =
                        fgGetNode("/environment/config/boundary/entry[0]/wind-from-heading-deg"
@@ -85,119 +82,91 @@ void FGRidgeLift::init(void)
        _surface_wind_speed_node =
                        fgGetNode("/environment/config/boundary/entry[0]/wind-speed-kt"
                        , true);
-       _earth_radius_node = fgGetNode("/position/sea-level-radius-ft", true);
        _user_longitude_node = fgGetNode("/position/longitude-deg", true);
        _user_latitude_node = fgGetNode("/position/latitude-deg", true);
-       _user_altitude_ft_node = fgGetNode("/position/altitude-ft", true);
        _user_altitude_agl_ft_node = fgGetNode("/position/altitude-agl-ft", true);
+       _ground_elev_node = fgGetNode("/position/ground-elev-ft", true );
 }
 
 void FGRidgeLift::bind() {
        string prop;
 
+       _tiedProperties.setRoot( fgGetNode("/environment/ridge-lift",true));
        for( int i = 0; i < 5; i++ ) {
-               prop = CreateIndexedPropertyName("/environment/ridge-lift/probe-elev-m", i );
-               fgTie( prop.c_str(), this, i, &FGRidgeLift::get_probe_elev_m); // read-only
-
-               prop = CreateIndexedPropertyName("/environment/ridge-lift/probe-lat-deg", i );
-               fgTie( prop.c_str(), this, i, &FGRidgeLift::get_probe_lat_deg); // read-only
-
-               prop = CreateIndexedPropertyName("/environment/ridge-lift/probe-lon-deg", i );
-               fgTie( prop.c_str(), this, i, &FGRidgeLift::get_probe_lon_deg); // read-only
+               _tiedProperties.Tie( "probe-elev-m", i, this, i, &FGRidgeLift::get_probe_elev_m );
+               _tiedProperties.Tie( "probe-lat-deg", i, this, i, &FGRidgeLift::get_probe_lat_deg );
+               _tiedProperties.Tie( "probe-lon-deg", i, this, i, &FGRidgeLift::get_probe_lon_deg );
        }
 
        for( int i = 0; i < 4; i++ ) {
-               prop = CreateIndexedPropertyName("/environment/ridge-lift/slope", i );
-               fgTie( prop.c_str(), this, i, &FGRidgeLift::get_slope); // read-only
+               _tiedProperties.Tie( "slope", i, this, i, &FGRidgeLift::get_slope );
        }
 }
 
 void FGRidgeLift::unbind() {
-       string prop;
-
-       for( int i = 0; i < 5; i++ ) {
-
-               prop = CreateIndexedPropertyName("/environment/ridge-lift/probe-elev-m", i );
-               fgUntie( prop.c_str() );
-
-               prop = CreateIndexedPropertyName("/environment/ridge-lift/probe-lat-deg", i );
-               fgUntie( prop.c_str() );
-
-               prop = CreateIndexedPropertyName("/environment/ridge-lift/probe-lon-deg", i );
-               fgUntie( prop.c_str() );
-       }
-
-       for( int i = 0; i < 4; i++ ) {
-               prop = CreateIndexedPropertyName("/environment/ridge-lift/slope", i );
-               fgUntie( prop.c_str() );
-       }
+       _tiedProperties.Untie();
 }
 
 void FGRidgeLift::update(double dt) {
 
-       //get the windspeed at ground level
+       if( dt <= SGLimitsd::min() ) // paused, do nothing but keep current lift
+               return;
 
-       double ground_wind_from_rad = _surface_wind_from_deg_node->getDoubleValue() * SG_DEGREES_TO_RADIANS;
-       double ground_wind_speed_mps = _surface_wind_speed_node->getDoubleValue() * SG_NM_TO_METER / 3600;
+       if( _enabled_node && false == _enabled_node->getBoolValue() ) {
+               // do nothing if lift has been zeroed
+               if( strength != 0.0 ) {
+                       if( strength > 0.1 ) {
+                               // slowly fade out strong lifts
+                               strength = fgGetLowPass( strength, 0, dt );
+                       } else {
+                               strength = 0.0;
+                       }
+                       _ridge_lift_fps_node->setDoubleValue( strength );
+               }
+               return;
+       }
 
        timer -= dt;
        if (timer <= 0.0 ) {
-               // copy values 
 
-               double user_latitude_rad = _user_latitude_node->getDoubleValue() * SG_DEGREES_TO_RADIANS;
-               double user_longitude_rad = _user_longitude_node->getDoubleValue() * SG_DEGREES_TO_RADIANS;
-       
-               double earth_rad_m = _earth_radius_node->getDoubleValue() * SG_FEET_TO_METER;
-               if( earth_rad_m < SG_EPSILON )
-                               earth_rad_m = SG_EARTH_RAD * 1000;
-
-               // Placing the probes
-       
-               for (int i = 0; i < sizeof(probe_lat_rad)/sizeof(probe_lat_rad[0]); i++) {
-                       double probe_radius_ratio = dist_probe_m[i]/earth_rad_m;
-
-                       probe_lat_rad[i] = asin(sin(user_latitude_rad)*cos(probe_radius_ratio)
-                                       +cos(user_latitude_rad)*sin(probe_radius_ratio)*cos(ground_wind_from_rad));
-                       if (probe_lat_rad[i] < SG_EPSILON ) {
-                               probe_lon_rad[i] = user_latitude_rad; // probe on a pole        
-                       } else {
-                               probe_lon_rad[i] = fmod((user_longitude_rad+asin(sin(ground_wind_from_rad)
-                                                       *sin(probe_radius_ratio)/cos(probe_lat_rad[i]))+SG_PI)
-                                               ,SGD_2PI)-SG_PI;
-                       }
-                       probe_lat_deg[i]= probe_lat_rad[i] * SG_RADIANS_TO_DEGREES;
-                       probe_lon_deg[i]= probe_lon_rad[i] * SG_RADIANS_TO_DEGREES;
-               }
-       
-               for (int i = 0; i < sizeof(probe_elev_m)/sizeof(probe_elev_m[0]); i++) {
-                       double elevation = 0;
-                       if (globals->get_scenery()->get_elevation_m(SGGeod::fromGeodM(
-                               SGGeod::fromRad(probe_lon_rad[i],probe_lat_rad[i]), 20000), elevation, 0)) {
-                               if ( elevation > 0.1 ) { 
-                                       probe_elev_m[i] = elevation; 
-                               } else { 
-                                       probe_elev_m[i] = 0.1 ;
-                               }
-                       } else { 
-                               probe_elev_m[i] = 0.1;
+               // probe0 is current position
+               probe_lat_deg[0] = _user_latitude_node->getDoubleValue();
+               probe_lon_deg[0] = _user_longitude_node->getDoubleValue();
+               probe_elev_m[0]  = _ground_elev_node->getDoubleValue() * SG_FEET_TO_METER;
+
+               // position is geodetic, need geocentric for advanceRadM
+               SGGeod myGeodPos = SGGeod::fromDegM( probe_lon_deg[0], probe_lat_deg[0], 20000.0 );
+               SGGeoc myGeocPos = SGGeoc::fromGeod( myGeodPos );
+               double ground_wind_from_rad = _surface_wind_from_deg_node->getDoubleValue() * SG_DEGREES_TO_RADIANS;
+
+               // compute the remaining probes
+               for (unsigned i = 1; i < sizeof(probe_elev_m)/sizeof(probe_elev_m[0]); i++) {
+                       SGGeoc probe = myGeocPos.advanceRadM( ground_wind_from_rad, dist_probe_m[i] );
+                       // convert to geodetic position for ground level computation
+                       SGGeod probeGeod = SGGeod::fromGeoc( probe );
+                       probe_lat_deg[i] = probeGeod.getLatitudeDeg();
+                       probe_lon_deg[i] = probeGeod.getLongitudeDeg();
+                       if (!globals->get_scenery()->get_elevation_m( probeGeod, probe_elev_m[i], NULL )) {
+                               // no ground found? use elevation of previous probe :-(
+                               probe_elev_m[i] = probe_elev_m[i-1];
                        }
                }
 
                // slopes
-               double adj_slope[4];
+               double adj_slope[sizeof(slope)];
                slope[0] = (probe_elev_m[0] - probe_elev_m[1]) / dist_probe_m[1];
                slope[1] = (probe_elev_m[1] - probe_elev_m[2]) / dist_probe_m[2];
                slope[2] = (probe_elev_m[2] - probe_elev_m[3]) / dist_probe_m[3];
                slope[3] = (probe_elev_m[4] - probe_elev_m[0]) / -dist_probe_m[4];
        
-               for (int i = 0; i < sizeof(slope)/sizeof(slope[0]); i++)
-                       adj_slope[i] = sin(atan(5.0 * pow ( (fabs(slope[i])),1.7) ) ) *sign(slope[i]);
+               for (unsigned i = 0; i < sizeof(slope)/sizeof(slope[0]); i++)
+                       adj_slope[i] = sin(atan(5.0 * pow ( (fabs(slope[i])),1.7) ) ) *SG_SIGN<double>(slope[i]);
        
                //adjustment
-               adj_slope[0] = 0.2 * adj_slope[0];
-               adj_slope[1] = 0.2 * adj_slope[1];
+               adj_slope[0] *= 0.2;
+               adj_slope[1] *= 0.2;
                if ( adj_slope [2] < 0.0 ) {
-                       adj_slope[2] = 0.5 * adj_slope[2];
+                       adj_slope[2] *= 0.5;
                } else {
                        adj_slope[2] = 0.0 ;
                }
@@ -205,7 +174,7 @@ void FGRidgeLift::update(double dt) {
                if ( ( adj_slope [0] >= 0.0 ) && ( adj_slope [3] < 0.0 ) ) {
                        adj_slope[3] = 0.0;
                } else {
-                       adj_slope[3] = 0.2 * adj_slope[3];
+                       adj_slope[3] *= 0.2;
                }
                lift_factor = adj_slope[0]+adj_slope[1]+adj_slope[2]+adj_slope[3];
        
@@ -219,8 +188,8 @@ void FGRidgeLift::update(double dt) {
        //boundaries
        double boundary2_m = 130.0; // in the lift
        if (lift_factor < 0.0) { // in the sink
-               double highest_probe_temp= max ( probe_elev_m[1], probe_elev_m[2] );
-               double highest_probe_downwind_m= max ( highest_probe_temp, probe_elev_m[3] );
+               double highest_probe_temp= std::max ( probe_elev_m[1], probe_elev_m[2] );
+               double highest_probe_downwind_m= std::max ( highest_probe_temp, probe_elev_m[3] );
                boundary2_m = highest_probe_downwind_m - probe_elev_m[0];
        }
 
@@ -231,13 +200,13 @@ void FGRidgeLift::update(double dt) {
                agl_factor = 1.0;
        } else {
                agl_factor = exp(-(2 + probe_elev_m[0] / 2000) * 
-                               (user_altitude_agl_m - boundary2_m) / max(probe_elev_m[0],200.0));
+                     (user_altitude_agl_m - boundary2_m) / std::max(probe_elev_m[0],200.0));
        }
        
+       double ground_wind_speed_mps = _surface_wind_speed_node->getDoubleValue() * SG_NM_TO_METER / 3600;
        double lift_mps = lift_factor* ground_wind_speed_mps * agl_factor;
        
        //the updraft, finally, in ft per second
        strength = fgGetLowPass( strength, lift_mps * SG_METER_TO_FEET, dt );
-//     if(isnan(strength)) strength=0; 
-        _ridge_lift_fps_node->setDoubleValue( strength );
+       _ridge_lift_fps_node->setDoubleValue( strength );
 }