]> git.mxchange.org Git - flightgear.git/blobdiff - src/FDM/JSBSim/models/FGAtmosphere.cpp
Sync. withn JSBSim CVS
[flightgear.git] / src / FDM / JSBSim / models / FGAtmosphere.cpp
index 88ffbd5e0fb8e8d06cb3b65c897ab77325ac7781..8acb17c1b42056c7c112169b7023c5294727a8f8 100644 (file)
@@ -7,7 +7,7 @@
  Purpose:      Models the atmosphere
  Called by:    FGSimExec
 
- ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
+ ------------- Copyright (C) 1999  Jon S. Berndt (jon@jsbsim.org) -------------
 
  This program is free software; you can redistribute it and/or modify it under
  the terms of the GNU Lesser General Public License as published by the Free Software
@@ -48,12 +48,16 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGAtmosphere.h"
-#include <FGState.h>
-#include <FGFDMExec.h>
+#include "FGState.h"
+#include "FGFDMExec.h"
 #include "FGAircraft.h"
 #include "FGPropagate.h"
 #include "FGInertial.h"
-#include <input_output/FGPropertyManager.h>
+#include "input_output/FGPropertyManager.h"
+#include <iostream>
+#include <cstdlib>
+
+using namespace std;
 
 namespace JSBSim {
 
@@ -71,21 +75,24 @@ FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex)
   h = 0.0;
   psiw = 0.0;
   htab[0]=0;
-  htab[1]=36089.239;
-  htab[2]=65616.798;
-  htab[3]=104986.878;
-  htab[4]=154199.475;
-  htab[5]=170603.675;
-  htab[6]=200131.234;
-  htab[7]=259186.352; //ft.
+  htab[1]= 36089.0;
+  htab[2]= 65617.0;
+  htab[3]=104987.0;
+  htab[4]=154199.0;
+  htab[5]=167322.0;
+  htab[6]=232940.0;
+  htab[7]=278385.0; //ft.
 
   MagnitudedAccelDt = MagnitudeAccel = Magnitude = 0.0;
-  SetTurbType( ttCulp );
-  TurbGain = 0.0;
-  TurbRate = 1.7;
+//  SetTurbType( ttCulp );
+  SetTurbType( ttNone );
+  TurbGain = 1.0;
+  TurbRate = 10.0;
   Rhythmicity = 0.1;
   spike = target_time = strength = 0.0;
   wind_from_clockwise = 0.0;
+  SutherlandConstant = 198.72; // deg Rankine
+  Beta = 2.269690E-08; // slug/(sec ft R^0.5)
 
   T_dev_sl = T_dev = delta_T = 0.0;
   StandardTempOnly = false;
@@ -132,8 +139,10 @@ bool FGAtmosphere::Run(void)
   if (FGModel::Run()) return true;
   if (FDMExec->Holding()) return false;
 
+  RunPreFunctions();
+
   T_dev = 0.0;
-  h = Propagate->Geth();
+  h = Propagate->GetAltitudeASL();
 
   if (!useExternal) {
     Calculate(h);
@@ -142,6 +151,8 @@ bool FGAtmosphere::Run(void)
     CalculateDerived();
   }
 
+  RunPostFunctions();
+
   Debug(2);
   return false;
 }
@@ -174,52 +185,57 @@ void FGAtmosphere::Calculate(double altitude)
   }
 
   switch(i) {
-  case 1:     // 36089 ft.
+  case 0: // Sea level
+    slope     = -0.00356616; // R/ft.
+    reftemp   = 518.67;   // in degrees Rankine, 288.15 Kelvin
+    refpress  = 2116.22;    // psf
+    //refdens   = 0.00237767;  // slugs/cubic ft.
+    break;
+  case 1:     // 36089 ft. or 11 km
     slope     = 0;
-    reftemp   = 389.97;
-    refpress  = 472.452;
+    reftemp   = 389.97; // in degrees Rankine, 216.65 Kelvin
+    refpress  = 472.763;
     //refdens   = 0.000706032;
     break;
-  case 2:     // 65616 ft.
+  case 2:     // 65616 ft. or 20 km
     slope     = 0.00054864;
-    reftemp   = 389.97;
+    reftemp   = 389.97; // in degrees Rankine, 216.65 Kelvin
     refpress  = 114.636;
     //refdens   = 0.000171306;
     break;
-  case 3:     // 104986 ft.
-    slope     = 0.00153619;
-    reftemp   = 411.57;
-    refpress  = 8.36364;
+  case 3:     // 104986 ft. or 32 km
+    slope     = 0.001536192;
+    reftemp   = 411.57; // in degrees Rankine, 228.65 Kelvin
+    refpress  = 18.128;
     //refdens   = 1.18422e-05;
     break;
-  case 4:     // 154199 ft.
+  case 4:     // 154199 ft. 47 km
     slope     = 0;
-    reftemp   = 487.17;
-    refpress  = 0.334882;
+    reftemp   = 487.17; // in degrees Rankine, 270.65 Kelvin
+    refpress  = 2.316;
     //refdens   = 4.00585e-7;
     break;
-  case 5:     // 170603 ft.
-    slope     = -0.00109728;
-    reftemp   = 487.17;
-    refpress  = 0.683084;
+  case 5:     // 167322 ft. or 51 km
+    slope     = -0.001536192;
+    reftemp   = 487.17; // in degrees Rankine, 270.65 Kelvin
+    refpress  = 1.398;
     //refdens   = 8.17102e-7;
     break;
-  case 6:     // 200131 ft.
-    slope     = -0.00219456;
-    reftemp   = 454.17;
-    refpress  = 0.00684986;
+  case 6:     // 232940 ft. or 71 km
+    slope     = -0.00109728;
+    reftemp   = 386.368; // in degrees Rankine, 214.649 Kelvin
+    refpress  = 0.0826;
     //refdens   = 8.77702e-9;
     break;
-  case 7:     // 259186 ft.
+  case 7:     // 278385 ft. or 84.8520 km
     slope     = 0;
-    reftemp   = 325.17;
-    refpress  = 0.000122276;
+    reftemp   = 336.5; // in degrees Rankine, 186.94 Kelvin
+    refpress  = 0.00831;
     //refdens   = 2.19541e-10;
     break;
-  case 0:
   default:     // sea level
     slope     = -0.00356616; // R/ft.
-    reftemp   = 518.67;    // R
+    reftemp   = 518.67;   // in degrees Rankine, 288.15 Kelvin
     refpress  = 2116.22;    // psf
     //refdens   = 0.00237767;  // slugs/cubic ft.
     break;
@@ -250,7 +266,7 @@ void FGAtmosphere::Calculate(double altitude)
     intPressure = refpress*pow(intTemperature/reftemp,-Inertial->SLgravity()/(slope*Reng));
     intDensity = intPressure/(Reng*intTemperature);
   }
-
+  
   lastIndex=i;
 }
 
@@ -263,14 +279,18 @@ void FGAtmosphere::CalculateDerived(void)
   T_dev = (*temperature) - GetTemperature(h);
   density_altitude = h + T_dev * 66.7;
 
-  if (turbType == ttStandard || ttCulp) Turbulence();
+  if (turbType != ttNone) Turbulence();
 
   vTotalWindNED = vWindNED + vGustNED + vTurbulenceNED;
 
+   // psiw (Wind heading) is the direction the wind is blowing towards
   if (vWindNED(eX) != 0.0) psiw = atan2( vWindNED(eY), vWindNED(eX) );
   if (psiw < 0) psiw += 2*M_PI;
 
   soundspeed = sqrt(SHRatio*Reng*(*temperature));
+
+  intViscosity = Beta * pow(intTemperature, 1.5) / (SutherlandConstant + intTemperature);
+  intKinematicViscosity = intViscosity / intDensity;
 }
 
 
@@ -326,6 +346,8 @@ static inline double square_signed (double value)
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+//
+// psi is the angle that the wind is blowing *towards*
 
 void FGAtmosphere::SetWindspeed(double speed)
 {
@@ -347,6 +369,8 @@ double FGAtmosphere::GetWindspeed(void) const
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+//
+// psi is the angle that the wind is blowing *towards*
 
 void FGAtmosphere::SetWindPsi(double dir)
 {
@@ -359,9 +383,11 @@ void FGAtmosphere::SetWindPsi(double dir)
 
 void FGAtmosphere::Turbulence(void)
 {
+  double DeltaT = rate*State->Getdt();
+
   switch (turbType) {
   case ttStandard: {
-    TurbGain = TurbGain * TurbGain * 100.0;
+    // TurbGain = TurbGain * TurbGain * 100.0; // what is this!?
 
     vDirectiondAccelDt(eX) = 1 - 2.0*(double(rand())/double(RAND_MAX));
     vDirectiondAccelDt(eY) = 1 - 2.0*(double(rand())/double(RAND_MAX));
@@ -372,8 +398,8 @@ void FGAtmosphere::Turbulence(void)
                                 // away from the peaks
     MagnitudedAccelDt = ((MagnitudedAccelDt - Magnitude) /
                          (1 + fabs(Magnitude)));
-    MagnitudeAccel    += MagnitudedAccelDt*rate*TurbRate*State->Getdt();
-    Magnitude         += MagnitudeAccel*rate*State->Getdt();
+    MagnitudeAccel    += MagnitudedAccelDt*TurbRate*DeltaT;
+    Magnitude         += MagnitudeAccel*DeltaT;
     Magnitude          = fabs(Magnitude);
 
     vDirectiondAccelDt.Normalize();
@@ -382,9 +408,9 @@ void FGAtmosphere::Turbulence(void)
     vDirectiondAccelDt(eX) = square_signed(vDirectiondAccelDt(eX));
     vDirectiondAccelDt(eY) = square_signed(vDirectiondAccelDt(eY));
 
-    vDirectionAccel += vDirectiondAccelDt*rate*TurbRate*State->Getdt();
+    vDirectionAccel += vDirectiondAccelDt*TurbRate*DeltaT;
     vDirectionAccel.Normalize();
-    vDirection      += vDirectionAccel*rate*State->Getdt();
+    vDirection      += vDirectionAccel*DeltaT;
 
     vDirection.Normalize();
 
@@ -433,42 +459,39 @@ void FGAtmosphere::Turbulence(void)
   }
   case ttBerndt: { // This is very experimental and incomplete at the moment.
 
-    TurbGain = TurbGain * TurbGain * 100.0;
-  
-    vDirectiondAccelDt(eX) = 1 - 2.0*(double(rand())/double(RAND_MAX));
-    vDirectiondAccelDt(eY) = 1 - 2.0*(double(rand())/double(RAND_MAX));
-    vDirectiondAccelDt(eZ) = 1 - 2.0*(double(rand())/double(RAND_MAX));
-
-
-    MagnitudedAccelDt = 1 - 2.0*(double(rand())/double(RAND_MAX)) - Magnitude;
-    MagnitudeAccel    += MagnitudedAccelDt*rate*State->Getdt();
-    Magnitude         += MagnitudeAccel*rate*State->Getdt();
+    vDirectiondAccelDt(eX) = GaussianRandomNumber();
+    vDirectiondAccelDt(eY) = GaussianRandomNumber();
+    vDirectiondAccelDt(eZ) = GaussianRandomNumber();
+/*
+    MagnitudedAccelDt = GaussianRandomNumber();
+    MagnitudeAccel    += MagnitudedAccelDt * DeltaT;
+    Magnitude         += MagnitudeAccel * DeltaT;
+*/
+    Magnitude         += GaussianRandomNumber() * DeltaT;
 
     vDirectiondAccelDt.Normalize();
-    vDirectionAccel += vDirectiondAccelDt*rate*State->Getdt();
+    vDirectionAccel += TurbRate * vDirectiondAccelDt * DeltaT;
     vDirectionAccel.Normalize();
-    vDirection      += vDirectionAccel*rate*State->Getdt();
+    vDirection      += vDirectionAccel*DeltaT;
 
-                                // Diminish z-vector within two wingspans
-                                // of the ground
+    // Diminish z-vector within two wingspans of the ground
     double HOverBMAC = Auxiliary->GetHOverBMAC();
-    if (HOverBMAC < 2.0)
-        vDirection(eZ) *= HOverBMAC / 2.0;
+    if (HOverBMAC < 2.0) vDirection(eZ) *= HOverBMAC / 2.0;
 
     vDirection.Normalize();
 
     vTurbulenceNED = TurbGain*Magnitude * vDirection;
     vTurbulenceGrad = TurbGain*MagnitudeAccel * vDirection;
 
-    vBodyTurbGrad = Propagate->GetTl2b()*vTurbulenceGrad;
-    vTurbPQR(eP) = vBodyTurbGrad(eY)/Aircraft->GetWingSpan();
+    vBodyTurbGrad = Propagate->GetTl2b() * vTurbulenceGrad;
+    vTurbPQR(eP) = vBodyTurbGrad(eY) / Aircraft->GetWingSpan();
     if (Aircraft->GetHTailArm() > 0)
-      vTurbPQR(eQ) = vBodyTurbGrad(eZ)/Aircraft->GetHTailArm();
+      vTurbPQR(eQ) = vBodyTurbGrad(eZ) / Aircraft->GetHTailArm();
     else
-      vTurbPQR(eQ) = vBodyTurbGrad(eZ)/10.0;
+      vTurbPQR(eQ) = vBodyTurbGrad(eZ) / 10.0;
 
     if (Aircraft->GetVTailArm() > 0)
-      vTurbPQR(eR) = vBodyTurbGrad(eX)/Aircraft->GetVTailArm();
+      vTurbPQR(eR) = vBodyTurbGrad(eX) / Aircraft->GetVTailArm();
     else
       vTurbPQR(eR) = vBodyTurbGrad(eX)/10.0;
 
@@ -555,7 +578,9 @@ void FGAtmosphere::bind(void)
 {
   typedef double (FGAtmosphere::*PMF)(int) const;
   typedef double (FGAtmosphere::*PMFv)(void) const;
+  typedef int (FGAtmosphere::*PMFt)(void) const;
   typedef void   (FGAtmosphere::*PMFd)(int,double);
+  typedef void   (FGAtmosphere::*PMFi)(int);
   PropertyManager->Tie("atmosphere/T-R", this, (PMFv)&FGAtmosphere::GetTemperature);
   PropertyManager->Tie("atmosphere/rho-slugs_ft3", this, (PMFv)&FGAtmosphere::GetDensity);
   PropertyManager->Tie("atmosphere/P-psf", this, (PMFv)&FGAtmosphere::GetPressure);
@@ -568,7 +593,7 @@ void FGAtmosphere::bind(void)
   PropertyManager->Tie("atmosphere/sigma", this, &FGAtmosphere::GetDensityRatio);
   PropertyManager->Tie("atmosphere/delta", this, &FGAtmosphere::GetPressureRatio);
   PropertyManager->Tie("atmosphere/a-ratio", this, &FGAtmosphere::GetSoundSpeedRatio);
-  PropertyManager->Tie("atmosphere/psiw-rad", this, &FGAtmosphere::GetWindPsi);
+  PropertyManager->Tie("atmosphere/psiw-rad", this, &FGAtmosphere::GetWindPsi, &FGAtmosphere::SetWindPsi);
   PropertyManager->Tie("atmosphere/delta-T", this, &FGAtmosphere::GetDeltaT, &FGAtmosphere::SetDeltaT);
   PropertyManager->Tie("atmosphere/T-sl-dev-F", this, &FGAtmosphere::GetSLTempDev, &FGAtmosphere::SetSLTempDev);
   PropertyManager->Tie("atmosphere/density-altitude", this, &FGAtmosphere::GetDensityAltitude);
@@ -579,8 +604,6 @@ void FGAtmosphere::bind(void)
                                                           (PMFd)&FGAtmosphere::SetWindNED);
   PropertyManager->Tie("atmosphere/wind-down-fps",  this, eDown, (PMF)&FGAtmosphere::GetWindNED,
                                                           (PMFd)&FGAtmosphere::SetWindNED);
-  PropertyManager->Tie("atmosphere/wind-from-cw", this, &FGAtmosphere::GetWindFromClockwise,
-                                                        &FGAtmosphere::SetWindFromClockwise);
   PropertyManager->Tie("atmosphere/wind-mag-fps", this, &FGAtmosphere::GetWindspeed,
                                                         &FGAtmosphere::SetWindspeed);
   PropertyManager->Tie("atmosphere/total-wind-north-fps", this, eNorth, (PMF)&FGAtmosphere::GetTotalWindNED);
@@ -594,9 +617,17 @@ void FGAtmosphere::bind(void)
   PropertyManager->Tie("atmosphere/gust-down-fps",  this, eDown, (PMF)&FGAtmosphere::GetGustNED,
                                                           (PMFd)&FGAtmosphere::SetGustNED);
 
+  PropertyManager->Tie("atmosphere/turb-north-fps", this, eNorth, (PMF)&FGAtmosphere::GetTurbNED,
+                                                          (PMFd)&FGAtmosphere::SetTurbNED);
+  PropertyManager->Tie("atmosphere/turb-east-fps",  this, eEast, (PMF)&FGAtmosphere::GetTurbNED,
+                                                          (PMFd)&FGAtmosphere::SetTurbNED);
+  PropertyManager->Tie("atmosphere/turb-down-fps",  this, eDown, (PMF)&FGAtmosphere::GetTurbNED,
+                                                          (PMFd)&FGAtmosphere::SetTurbNED);
+
   PropertyManager->Tie("atmosphere/p-turb-rad_sec", this,1, (PMF)&FGAtmosphere::GetTurbPQR);
   PropertyManager->Tie("atmosphere/q-turb-rad_sec", this,2, (PMF)&FGAtmosphere::GetTurbPQR);
   PropertyManager->Tie("atmosphere/r-turb-rad_sec", this,3, (PMF)&FGAtmosphere::GetTurbPQR);
+  PropertyManager->Tie("atmosphere/turb-type", this, (PMFt)&FGAtmosphere::GetTurbType, (PMFi)&FGAtmosphere::SetTurbType);
   PropertyManager->Tie("atmosphere/turb-rate", this, &FGAtmosphere::GetTurbRate, &FGAtmosphere::SetTurbRate);
   PropertyManager->Tie("atmosphere/turb-gain", this, &FGAtmosphere::GetTurbGain, &FGAtmosphere::SetTurbGain);
   PropertyManager->Tie("atmosphere/turb-rhythmicity", this, &FGAtmosphere::GetRhythmicity,