]> git.mxchange.org Git - flightgear.git/commitdiff
Upgrade to JSBSim 1.0-prerelease
authorehofman <ehofman>
Mon, 1 Jun 2009 08:52:34 +0000 (08:52 +0000)
committerTim Moore <timoore@redhat.com>
Tue, 2 Jun 2009 22:18:56 +0000 (00:18 +0200)
23 files changed:
src/FDM/JSBSim/FGFDMExec.cpp
src/FDM/JSBSim/FGFDMExec.h
src/FDM/JSBSim/FGJSBBase.h
src/FDM/JSBSim/JSBSim.cxx
src/FDM/JSBSim/initialization/FGInitialCondition.cpp
src/FDM/JSBSim/initialization/FGInitialCondition.h
src/FDM/JSBSim/input_output/FGScript.cpp
src/FDM/JSBSim/models/FGAerodynamics.cpp
src/FDM/JSBSim/models/FGAtmosphere.cpp
src/FDM/JSBSim/models/FGAuxiliary.h
src/FDM/JSBSim/models/FGInertial.cpp
src/FDM/JSBSim/models/FGLGear.cpp
src/FDM/JSBSim/models/FGMassBalance.cpp
src/FDM/JSBSim/models/FGOutput.cpp
src/FDM/JSBSim/models/FGPropagate.cpp
src/FDM/JSBSim/models/FGPropagate.h
src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp
src/FDM/JSBSim/models/flight_control/FGActuator.cpp
src/FDM/JSBSim/models/flight_control/FGSensor.cpp
src/FDM/JSBSim/models/flight_control/FGSensor.h
src/FDM/JSBSim/models/propulsion/FGPiston.cpp
src/FDM/JSBSim/models/propulsion/FGTurbine.cpp
src/FDM/JSBSim/models/propulsion/FGTurbine.h

index 72f37d4e56319a7d3095f4e2e6097b75f3159386..a6b5a736708f8fe46f7ef9e07a901791f185c453 100644 (file)
@@ -90,7 +90,6 @@ void checkTied ( FGPropertyManager *node )
 
   for (int i=0; i<N; i++) {
     if (node->getChild(i)->nChildren() ) {
-//      cout << "Untieing " << node->getChild(i)->getName() << " property branch." << endl;
       checkTied( (FGPropertyManager*)node->getChild(i) );
     } else if ( node->getChild(i)->isTied() ) {
       name = ((FGPropertyManager*)node->getChild(i))->GetFullyQualifiedName();
@@ -128,19 +127,12 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root) : Root(root)
   Script          = 0;
 
   modelLoaded = false;
-  IsSlave = false;
+  IsChild = false;
   holding = false;
   Terminate = false;
 
-  // Multiple FDM's are stopped for now.  We need to ensure that
-  // the "user" instance always gets the zeroeth instance number,
-  // because there may be instruments or scripts tied to properties
-  // in the jsbsim[0] node.
-  // ToDo: it could be that when JSBSim is reset and a new FDM is wanted, that
-  // process might try setting FDMctr = 0. Then the line below would not need
-  // to be commented out.
-  IdFDM = FDMctr;
-  //FDMctr++;
+  IdFDM = FDMctr; // The main (parent) JSBSim instance is always the "zeroth"
+  FDMctr++;       // instance. "child" instances are loaded last.
 
   try {
     char* num = getenv("JSBSIM_DEBUG");
@@ -189,10 +181,10 @@ FGFDMExec::~FGFDMExec()
     cout << "Caught error: " << msg << endl;
   }
 
-  for (unsigned int i=1; i<SlaveFDMList.size(); i++) delete SlaveFDMList[i]->exec;
-  SlaveFDMList.clear();
+  for (unsigned int i=1; i<ChildFDMList.size(); i++) delete ChildFDMList[i]->exec;
+  ChildFDMList.clear();
 
-  //ToDo remove property catalog.
+  PropertyCatalog.clear();
 
   Debug(1);
 }
@@ -355,9 +347,9 @@ bool FGFDMExec::Run(void)
 
   Debug(2);
 
-  for (unsigned int i=1; i<SlaveFDMList.size(); i++) {
-//    SlaveFDMList[i]->exec->State->Initialize(); // Transfer state to the slave FDM
-//    SlaveFDMList[i]->exec->Run();
+  for (unsigned int i=1; i<ChildFDMList.size(); i++) {
+    ChildFDMList[i]->AssignState(Propagate); // Transfer state to the child FDM
+    ChildFDMList[i]->Run();
   }
 
   // returns true if success
@@ -453,8 +445,8 @@ vector <string> FGFDMExec::EnumerateFDMs(void)
 
   FDMList.push_back(Aircraft->GetAircraftName());
 
-  for (unsigned int i=1; i<SlaveFDMList.size(); i++) {
-    FDMList.push_back(SlaveFDMList[i]->exec->GetAircraft()->GetAircraftName());
+  for (unsigned int i=1; i<ChildFDMList.size(); i++) {
+    FDMList.push_back(ChildFDMList[i]->exec->GetAircraft()->GetAircraftName());
   }
 
   return FDMList;
@@ -511,10 +503,16 @@ bool FGFDMExec::LoadModel(string model, bool addModelToPath)
     Allocate();
   }
 
+  int saved_debug_lvl = debug_lvl;
+
   document = LoadXMLDocument(aircraftCfgFileName); // "document" is a class member
   if (document) {
+    if (IsChild) debug_lvl = 0;
+
     ReadPrologue(document);
 
+    if (IsChild) debug_lvl = saved_debug_lvl;
+
     // Process the fileheader element in the aircraft config file. This element is OPTIONAL.
     element = document->FindElement("fileheader");
     if (element) {
@@ -525,6 +523,8 @@ bool FGFDMExec::LoadModel(string model, bool addModelToPath)
       }
     }
 
+    if (IsChild) debug_lvl = 0;
+
     // Process the metrics element. This element is REQUIRED.
     element = document->FindElement("metrics");
     if (element) {
@@ -662,18 +662,27 @@ bool FGFDMExec::LoadModel(string model, bool addModelToPath)
       element = document->FindNextElement("output");
     }
 
-    // Lastly, process the slave element. This element is OPTIONAL - and NOT YET SUPPORTED.
-    element = document->FindElement("slave");
+    // Lastly, process the child element. This element is OPTIONAL - and NOT YET SUPPORTED.
+    element = document->FindElement("child");
     if (element) {
-      result = ReadSlave(element);
+      result = ReadChild(element);
       if (!result) {
-        cerr << endl << "Aircraft slave element has problems in file " << aircraftCfgFileName << endl;
+        cerr << endl << "Aircraft child element has problems in file " << aircraftCfgFileName << endl;
         return result;
       }
     }
 
     modelLoaded = true;
 
+    if (debug_lvl > 0) {
+      cout << endl << fgblue << highint
+           << "End of vehicle configuration loading." << endl
+           << "-------------------------------------------------------------------------------"
+           << reset << endl;
+    }
+    
+    if (IsChild) debug_lvl = saved_debug_lvl;
+
   } else {
     cerr << fgred
          << "  JSBSim failed to open the configuration file: " << aircraftCfgFileName
@@ -745,16 +754,20 @@ bool FGFDMExec::ReadFileHeader(Element* el)
 {
   bool result = true; // true for success
 
-  if (debug_lvl & ~1) return result;
+  if (debug_lvl == 0) return result;
+
+  if (IsChild) {
+    cout << endl <<highint << fgblue << "Reading child model: " << IdFDM << reset << endl << endl;
+  }
 
+  if (el->FindElement("description"))
+    cout << "  Description:   " << el->FindElement("description")->GetDataLine() << endl;
   if (el->FindElement("author"))
     cout << "  Model Author:  " << el->FindElement("author")->GetDataLine() << endl;
   if (el->FindElement("filecreationdate"))
     cout << "  Creation Date: " << el->FindElement("filecreationdate")->GetDataLine() << endl;
   if (el->FindElement("version"))
     cout << "  Version:       " << el->FindElement("version")->GetDataLine() << endl;
-  if (el->FindElement("description"))
-    cout << "  Description:   " << el->FindElement("description")->GetDataLine() << endl;
 
   return result;
 }
@@ -821,54 +834,51 @@ bool FGFDMExec::ReadPrologue(Element* el) // el for ReadPrologue is the document
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGFDMExec::ReadSlave(Element* el)
+bool FGFDMExec::ReadChild(Element* el)
 {
-  // Add a new slaveData object to the slave FDM list
-  // Populate that slaveData element with a new FDMExec object
-  // Set the IsSlave flag for that FDMExec object
+  // Add a new childData object to the child FDM list
+  // Populate that childData element with a new FDMExec object
+  // Set the IsChild flag for that FDMExec object
   // Get the aircraft name
-  // set debug level to print out no additional data for slave objects
+  // set debug level to print out no additional data for child objects
   // Load the model given the aircraft name
   // reset debug level to prior setting
 
-  int saved_debug_lvl = debug_lvl;
   string token;
 
-  SlaveFDMList.push_back(new slaveData);
-  SlaveFDMList.back()->exec = new FGFDMExec();
-  SlaveFDMList.back()->exec->SetSlave(true);
-/*
-  string AircraftName = AC_cfg->GetValue("file");
-
-  debug_lvl = 0;                 // turn off debug output for slave vehicle
-
-  SlaveFDMList.back()->exec->SetAircraftPath( AircraftPath );
-  SlaveFDMList.back()->exec->SetEnginePath( EnginePath );
-  SlaveFDMList.back()->exec->SetSystemsPath( SystemsPath );
-  SlaveFDMList.back()->exec->LoadModel(AircraftName);
-  debug_lvl = saved_debug_lvl;   // turn debug output back on for master vehicle
-
-  AC_cfg->GetNextConfigLine();
-  while ((token = AC_cfg->GetValue()) != string("/SLAVE")) {
-    *AC_cfg >> token;
-    if      (token == "xloc")  { *AC_cfg >> SlaveFDMList.back()->x;    }
-    else if (token == "yloc")  { *AC_cfg >> SlaveFDMList.back()->y;    }
-    else if (token == "zloc")  { *AC_cfg >> SlaveFDMList.back()->z;    }
-    else if (token == "pitch") { *AC_cfg >> SlaveFDMList.back()->pitch;}
-    else if (token == "yaw")   { *AC_cfg >> SlaveFDMList.back()->yaw;  }
-    else if (token == "roll")  { *AC_cfg >> SlaveFDMList.back()->roll;  }
-    else cerr << "Unknown identifier: " << token << " in slave vehicle definition" << endl;
+  struct childData* child = new childData;
+
+  child->exec = new FGFDMExec();
+  child->exec->SetChild(true);
+
+  string childAircraft = el->GetAttributeValue("name");
+  string sMated = el->GetAttributeValue("mated");
+  if (sMated == "false") child->mated = false; // child objects are mated by default.
+  string sInternal = el->GetAttributeValue("internal");
+  if (sInternal == "true") child->internal = true; // child objects are external by default.
+
+  child->exec->SetAircraftPath( AircraftPath );
+  child->exec->SetEnginePath( EnginePath );
+  child->exec->SetSystemsPath( SystemsPath );
+  child->exec->LoadModel(childAircraft);
+
+  Element* location = el->FindElement("location");
+  if (location) {
+    child->Loc = location->FindElementTripletConvertTo("IN");
+  } else {
+    cerr << endl << highint << fgred << "  No location was found for this child object!" << reset << endl;
+    exit(-1);
   }
-*/
-  if (debug_lvl > 0)  {
-    cout << "      X = " << SlaveFDMList.back()->x << endl;
-    cout << "      Y = " << SlaveFDMList.back()->y << endl;
-    cout << "      Z = " << SlaveFDMList.back()->z << endl;
-    cout << "      Pitch = " << SlaveFDMList.back()->pitch << endl;
-    cout << "      Yaw = " << SlaveFDMList.back()->yaw << endl;
-    cout << "      Roll = " << SlaveFDMList.back()->roll << endl;
+  
+  Element* orientation = el->FindElement("orient");
+  if (orientation) {
+    child->Orient = orientation->FindElementTripletConvertTo("RAD");
+  } else if (debug_lvl > 0) {
+    cerr << endl << highint << "  No orientation was found for this child object! Assuming 0,0,0." << reset << endl;
   }
 
+  ChildFDMList.push_back(child);
+
   return true;
 }
 
index 9ab3e33b2410fda50bd7483b8ca34612c2bfda72..904e8e43a6c34b4745d1e8bb8631b9efcdce8fa9 100644 (file)
@@ -51,6 +51,7 @@ INCLUDES
 #include <input_output/FGGroundCallback.h>
 #include <input_output/FGXMLFileRead.h>
 #include <models/FGPropagate.h>
+#include <math/FGColumnVector3.h>
 
 #include <vector>
 #include <string>
@@ -177,6 +178,32 @@ CLASS DECLARATION
 
 class FGFDMExec : public FGJSBBase, public FGXMLFileRead
 {
+  struct childData {
+    FGFDMExec* exec;
+    string info;
+    FGColumnVector3 Loc;
+    FGColumnVector3 Orient;
+    bool mated;
+    bool internal;
+
+    childData(void) {
+      info = "";
+      Loc = FGColumnVector3(0,0,0);
+      Orient = FGColumnVector3(0,0,0);
+      mated = true;
+      internal = false;
+    }
+    
+    void Run(void) {exec->Run();}
+    void AssignState(FGPropagate* source_prop) {
+      exec->GetPropagate()->SetVState(source_prop->GetVState());
+    }
+
+    ~childData(void) {
+      delete exec;
+    }
+  };
+
 public:
 
   /// Default constructor
@@ -335,8 +362,12 @@ public:
   FGPropertyManager* GetPropertyManager(void);
   /// Returns a vector of strings representing the names of all loaded models (future)
   vector <string> EnumerateFDMs(void);
-  /// Marks this instance of the Exec object as a "slave" object.
-  void SetSlave(bool s) {IsSlave = s;}
+  /// Gets the number of child FDMs.
+  int GetFDMCount(void) {return ChildFDMList.size();}
+  /// Gets a particular child FDM.
+  childData* GetChildFDM(int i) {return ChildFDMList[i];}
+  /// Marks this instance of the Exec object as a "child" object.
+  void SetChild(bool ch) {IsChild = ch;}
 
   /** Sets the output (logging) mechanism for this run.
       Calling this function passes the name of an output directives file to
@@ -443,7 +474,7 @@ private:
   bool holding;
   bool Constructing;
   bool modelLoaded;
-  bool IsSlave;
+  bool IsChild;
   string modelName;
   string AircraftPath;
   string FullAircraftPath;
@@ -455,26 +486,6 @@ private:
   bool trim_status;
   int ta_mode;
 
-
-  struct slaveData {
-    FGFDMExec* exec;
-    string info;
-    double x, y, z;
-    double roll, pitch, yaw;
-    bool mated;
-
-    slaveData(void) {
-      info = "";
-      x = y = z = 0.0;
-      roll = pitch = yaw = 0.0;
-      mated = true;
-    }
-
-    ~slaveData(void) {
-      delete exec;
-    }
-  };
-
   static FGPropertyManager *master;
 
   FGModel*            FirstModel;
@@ -502,10 +513,10 @@ private:
 
   vector <string> PropertyCatalog;
   vector <FGOutput*> Outputs;
-  vector <slaveData*> SlaveFDMList;
+  vector <childData*> ChildFDMList;
 
   bool ReadFileHeader(Element*);
-  bool ReadSlave(Element*);
+  bool ReadChild(Element*);
   bool ReadPrologue(Element*);
   void ResetToInitialConditions(int mode);
   bool Allocate(void);
index 93e9d431dd0ddccc2ecd164015a3fb44a8f6452e..8ec700a1515ca0297ff311dd1b2c93628a18b887 100644 (file)
@@ -156,7 +156,7 @@ public:
   /** Places a Message structure on the Message queue.
       @param msg pointer to a Message structure
       @return pointer to a Message structure */
-void PutMessage(const Message& msg);
+  void PutMessage(const Message& msg);
   /** Creates a message with the given text and places it on the queue.
       @param text message text
       @return pointer to a Message structure */
@@ -165,17 +165,17 @@ void PutMessage(const Message& msg);
       @param text message text
       @param bVal boolean value associated with the message
       @return pointer to a Message structure */
-void PutMessage(const string& text, bool bVal);
+  void PutMessage(const string& text, bool bVal);
   /** Creates a message with the given text and integer value and places it on the queue.
       @param text message text
       @param iVal integer value associated with the message
       @return pointer to a Message structure */
-void PutMessage(const string& text, int iVal);
+  void PutMessage(const string& text, int iVal);
   /** Creates a message with the given text and double value and places it on the queue.
       @param text message text
       @param dVal double value associated with the message
       @return pointer to a Message structure */
-void PutMessage(const string& text, double dVal);
+  void PutMessage(const string& text, double dVal);
   /** Reads the message on the queue (but does not delete it).
       @return 1 if some messages */
   int SomeMessages(void);
@@ -295,6 +295,8 @@ void PutMessage(const string& text, double dVal);
   static double Constrain(double min, double value, double max) {
     return value<min?(min):(value>max?(max):(value));
   }
+  
+  static double sign(double num) {return num>=0.0?1.0:-1.0;}
 
 protected:
   static Message localMsg;
@@ -341,6 +343,8 @@ protected:
     static int phase = 0;
     double X;
 
+    V1 = V2 = S = X = 0.0;
+
     if (phase == 0) {
       do {
         double U1 = (double)rand() / RAND_MAX;
@@ -351,7 +355,7 @@ protected:
         S = V1 * V1 + V2 * V2;
       } while(S >= 1 || S == 0);
 
-        X = V1 * sqrt(-2 * log(S) / S);
+      X = V1 * sqrt(-2 * log(S) / S);
     } else
       X = V2 * sqrt(-2 * log(S) / S);
 
index 5a1be0a29b25d1d77b8570e90fb4bb05e099277e..b36c196574f297029eb78015a23680ec17db821e 100644 (file)
@@ -85,7 +85,7 @@ public:
   FGFSGroundCallback(FGJSBsim* ifc) : mInterface(ifc) {}
   virtual ~FGFSGroundCallback() {}
 
-  /** Get the altitude above sea level depenent on the location. */
+  /** Get the altitude above sea level dependent on the location. */
   virtual double GetAltitude(const FGLocation& l) const {
     double pt[3] = { SG_FEET_TO_METER*l(eX),
                      SG_FEET_TO_METER*l(eY),
@@ -145,13 +145,6 @@ FGJSBsim::FGJSBsim( double dt )
 
     fdmex = new FGFDMExec( (FGPropertyManager*)globals->get_props() );
 
-    // begin ugly hack
-    // Untie the write-state-file property to avoid creating an initfile.xml
-    // file on each FlightGear reset.
-    fgGetNode("/fdm/jsbsim/simulation/write-state-file")->untie();
-    fgGetNode("/fdm/jsbsim/simulation")->removeChild("write-state-file", false);
-    // end ugly hack
-
     // Register ground callback.
     fdmex->SetGroundCallback( new FGFSGroundCallback(this) );
 
@@ -391,7 +384,7 @@ void FGJSBsim::init()
     SG_LOG( SG_FLIGHT, SG_INFO, "  Longitude: "
             << Propagate->GetLocation().GetLongitudeDeg() << " deg" );
     SG_LOG( SG_FLIGHT, SG_INFO, "  Altitude: "
-            << Propagate->Geth() << " feet" );
+            << Propagate->GetAltitudeASL() << " feet" );
     SG_LOG( SG_FLIGHT, SG_INFO, "  loaded initial conditions" );
 
     SG_LOG( SG_FLIGHT, SG_INFO, "  set dt" );
@@ -438,7 +431,7 @@ void FGJSBsim::update( double dt )
     double alt, slr, lat, lon;
     FGColumnVector3 cart = Auxiliary->GetLocationVRP();
     if ( needTrim && startup_trim->getBoolValue() ) {
-      alt = fgic->GetAltitudeFtIC();
+      alt = fgic->GetAltitudeASLFtIC();
       slr = fgic->GetSeaLevelRadiusFtIC();
       lat = fgic->GetLatitudeDegIC() * SGD_DEGREES_TO_RADIANS;
       lon = fgic->GetLongitudeDegIC() * SGD_DEGREES_TO_RADIANS;
@@ -452,7 +445,7 @@ void FGJSBsim::update( double dt )
       SG_LOG(SG_FLIGHT, SG_WARN,
              "FGInterface is being called without scenery below the aircraft!");
 
-      alt = fgic->GetAltitudeFtIC();
+      alt = fgic->GetAltitudeASLFtIC();
       SG_LOG(SG_FLIGHT, SG_WARN, "altitude         = " << alt);
 
       slr = fgic->GetSeaLevelRadiusFtIC();
@@ -479,10 +472,10 @@ void FGJSBsim::update( double dt )
              + contact[2]*contact[2]) - fgic->GetSeaLevelRadiusFtIC();
 
         SG_LOG(SG_FLIGHT, SG_INFO,
-          "Ready to trim, terrain altitude is: "
+          "Ready to trim, terrain elevation is: "
             << terrain_alt * SG_METER_TO_FEET );
 
-        fgic->SetTerrainAltitudeFtIC( terrain_alt );
+        fgic->SetTerrainElevationFtIC( terrain_alt );
         do_trim();
       } else {
         fdmex->RunIC();  //apply any changes made through the set_ functions
@@ -638,7 +631,7 @@ bool FGJSBsim::copy_to_JSBsim()
     }
 
     Propulsion->SetFuelFreeze((fgGetNode("/sim/freeze/fuel",true))->getBoolValue());
-    fdmex->SetSlave(slaved->getBoolValue());
+    fdmex->SetChild(slaved->getBoolValue());
 
     return true;
 }
@@ -963,6 +956,7 @@ void FGJSBsim::set_Longitude(double lon)
     needTrim=true;
 }
 
+// Sets the altitude above sea level.
 void FGJSBsim::set_Altitude(double alt)
 {
     static SGConstPropertyNode_ptr latitude = fgGetNode("/position/latitude-deg");
@@ -981,9 +975,9 @@ void FGJSBsim::set_Altitude(double alt)
     _set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET  );
     fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET );
     SG_LOG(SG_FLIGHT, SG_INFO,
-          "Terrain altitude: " << cur_fdm_state->get_Runway_altitude() * SG_METER_TO_FEET );
+          "Terrain elevation: " << cur_fdm_state->get_Runway_altitude() * SG_METER_TO_FEET );
     fgic->SetLatitudeRadIC( lat_geoc );
-    fgic->SetAltitudeFtIC(alt);
+    fgic->SetAltitudeASLFtIC(alt);
     needTrim=true;
 }
 
@@ -1169,7 +1163,7 @@ void FGJSBsim::update_ic(void)
    if ( !needTrim ) {
      fgic->SetLatitudeRadIC(get_Lat_geocentric() );
      fgic->SetLongitudeRadIC( get_Longitude() );
-     fgic->SetAltitudeFtIC( get_Altitude() );
+     fgic->SetAltitudeASLFtIC( get_Altitude() );
      fgic->SetVcalibratedKtsIC( get_V_calibrated_kts() );
      fgic->SetThetaRadIC( get_Theta() );
      fgic->SetPhiRadIC( get_Phi() );
index 4df38860a8600868159346bb6296c83c5b079a10..de904e0e133a6797acbe9b77553d00705c1588e8 100644 (file)
@@ -66,7 +66,7 @@ FGInitialCondition::FGInitialCondition(FGFDMExec *FDMExec) : fdmex(FDMExec)
   InitializeIC();
 
   if(FDMExec != NULL ) {
-    fdmex->GetPropagate()->Seth(altitude);
+    fdmex->GetPropagate()->SetAltitudeASL(altitudeASL);
     fdmex->GetAtmosphere()->Run();
     PropertyManager=fdmex->GetPropertyManager();
     Constructing = true;
@@ -120,7 +120,7 @@ void FGInitialCondition::ResetIC(double u0, double v0, double w0,
   FGColumnVector3 _vUVW_BODY(u,v,w);
   FGColumnVector3 _vUVW_NED = _Tb2l * _vUVW_BODY;
   FGColumnVector3 _vWIND_NED(wnorth,weast,wdown);
-  FGColumnVector3 _vUVWAero = _Tl2b * ( _vUVW_NED + _vWIND_NED );
+//  FGColumnVector3 _vUVWAero = _Tl2b * ( _vUVW_NED + _vWIND_NED );
 
   uw=_vWIND_NED(1); vw=_vWIND_NED(2); ww=_vWIND_NED(3);
 
@@ -134,7 +134,7 @@ void FGInitialCondition::InitializeIC(void)
   mach=0;
   alpha=beta=gamma=0;
   theta=phi=psi=0;
-  altitude=hdot=0;
+  altitudeASL=hdot=0;
   latitude=longitude=0;
   u=v=w=0;
   p=q=r=0;
@@ -146,7 +146,7 @@ void FGInitialCondition::InitializeIC(void)
   lastSpeedSet=setvt;
   lastWindSet=setwned;
   radius_to_vehicle = sea_level_radius = fdmex->GetInertial()->GetRefRadius();
-  terrain_altitude = 0;
+  terrain_elevation = 0;
 
   targetNlfIC = 1.0;
 
@@ -181,7 +181,7 @@ void FGInitialCondition::WriteStateFile(int num)
     outfile << "  <psi unit=\"DEG\"> " << Propagate->GetEuler(ePsi) << " </psi>" << endl;
     outfile << "  <longitude unit=\"DEG\"> " << Propagate->GetLongitudeDeg() << " </longitude>" << endl;
     outfile << "  <latitude unit=\"DEG\"> " << Propagate->GetLatitudeDeg() << " </latitude>" << endl;
-    outfile << "  <altitude unit=\"FT\"> " << Propagate->Geth() << " </altitude>" << endl;
+    outfile << "  <altitude unit=\"FT\"> " << Propagate->GetAltitudeASL() << " </altitude>" << endl;
     outfile << "</initialize>" << endl;
     outfile.close();
   } else {
@@ -538,9 +538,10 @@ void FGInitialCondition::calcWindUVW(void) {
 
 //******************************************************************************
 
-void FGInitialCondition::SetAltitudeFtIC(double tt) {
-  altitude=tt;
-  fdmex->GetPropagate()->Seth(altitude);
+void FGInitialCondition::SetAltitudeASLFtIC(double tt)
+{
+  altitudeASL=tt;
+  fdmex->GetPropagate()->SetAltitudeASL(altitudeASL);
   fdmex->GetAtmosphere()->Run();
   //lets try to make sure the user gets what they intended
 
@@ -567,25 +568,29 @@ void FGInitialCondition::SetAltitudeFtIC(double tt) {
 
 //******************************************************************************
 
-void FGInitialCondition::SetAltitudeAGLFtIC(double tt) {
-  SetAltitudeFtIC(terrain_altitude + tt);
+void FGInitialCondition::SetAltitudeAGLFtIC(double tt)
+{
+  SetAltitudeASLFtIC(terrain_elevation + tt);
 }
 
 //******************************************************************************
 
-void FGInitialCondition::SetSeaLevelRadiusFtIC(double tt) {
+void FGInitialCondition::SetSeaLevelRadiusFtIC(double tt)
+{
   sea_level_radius = tt;
 }
 
 //******************************************************************************
 
-void FGInitialCondition::SetTerrainAltitudeFtIC(double tt) {
-  terrain_altitude=tt;
+void FGInitialCondition::SetTerrainElevationFtIC(double tt)
+{
+  terrain_elevation=tt;
 }
 
 //******************************************************************************
 
-void FGInitialCondition::calcUVWfromNED(void) {
+void FGInitialCondition::calcUVWfromNED(void)
+{
   u=vnorth*ctheta*cpsi +
      veast*ctheta*spsi -
      vdown*stheta;
@@ -858,8 +863,10 @@ bool FGInitialCondition::Load(string rstfile, bool useStoredPath)
     SetLatitudeDegIC(document->FindElementValueAsNumberConvertTo("latitude", "DEG"));
   if (document->FindElement("longitude"))
     SetLongitudeDegIC(document->FindElementValueAsNumberConvertTo("longitude", "DEG"));
-  if (document->FindElement("altitude"))
-    SetAltitudeFtIC(document->FindElementValueAsNumberConvertTo("altitude", "FT"));
+  if (document->FindElement("elevation"))
+    SetTerrainElevationFtIC(document->FindElementValueAsNumberConvertTo("elevation", "FT"));
+  if (document->FindElement("altitude")) // This is feet above ground level
+    SetAltitudeAGLFtIC(document->FindElementValueAsNumberConvertTo("altitude", "FT"));
   if (document->FindElement("ubody"))
     SetUBodyFpsIC(document->FindElementValueAsNumberConvertTo("ubody", "FT/SEC"));
   if (document->FindElement("vbody"))
@@ -979,8 +986,8 @@ void FGInitialCondition::bind(void){
                        &FGInitialCondition::SetLongitudeDegIC,
                        true);
   PropertyManager->Tie("ic/h-sl-ft", this,
-                       &FGInitialCondition::GetAltitudeFtIC,
-                       &FGInitialCondition::SetAltitudeFtIC,
+                       &FGInitialCondition::GetAltitudeASLFtIC,
+                       &FGInitialCondition::SetAltitudeASLFtIC,
                        true);
   PropertyManager->Tie("ic/h-agl-ft", this,
                        &FGInitialCondition::GetAltitudeAGLFtIC,
@@ -990,9 +997,9 @@ void FGInitialCondition::bind(void){
                        &FGInitialCondition::GetSeaLevelRadiusFtIC,
                        &FGInitialCondition::SetSeaLevelRadiusFtIC,
                        true);
-  PropertyManager->Tie("ic/terrain-altitude-ft", this,
-                       &FGInitialCondition::GetTerrainAltitudeFtIC,
-                       &FGInitialCondition::SetTerrainAltitudeFtIC,
+  PropertyManager->Tie("ic/terrain-elevation-ft", this,
+                       &FGInitialCondition::GetTerrainElevationFtIC,
+                       &FGInitialCondition::SetTerrainElevationFtIC,
                        true);
   PropertyManager->Tie("ic/vg-fps", this,
                        &FGInitialCondition::GetVgroundFpsIC,
index c70cfc9ab56d18173eb11ff4a43d3a21342ee5e2..330552e7ffb3d7cf93d74e7a537348f56a892d03 100644 (file)
@@ -85,7 +85,7 @@ CLASS DOCUMENTATION
    @code
    FGInitialCondition fgic=new FGInitialCondition(FDMExec);
    fgic->SetVcalibratedKtsIC()
-   fgic->SetAltitudeFtIC();
+   fgic->SetAltitudeAGLFtIC();
 
    // directly into Run
    FDMExec->GetState()->Initialize(fgic)
@@ -140,7 +140,7 @@ CLASS DOCUMENTATION
    - beta (angle, degrees)
    - gamma (angle, degrees)
    - roc (vertical velocity, ft/sec)
-   - altitude (altitude, ft)
+   - altitude (altitude AGL, ft)
    - winddir (wind from-angle, degrees)
    - vwind (magnitude wind speed, ft/sec)
    - hwind (headwind speed, knots)
@@ -168,7 +168,7 @@ CLASS DOCUMENTATION
    @property ic/h-sl-ft (read/write) Height above sea level initial condition in feet
    @property ic/h-agl-ft (read/write) Height above ground level initial condition in feet
    @property ic/sea-level-radius-ft (read/write) Radius of planet at sea level in feet
-   @property ic/terrain-altitude-ft (read/write) Terrain elevation above sea level in feet
+   @property ic/terrain-elevation-ft (read/write) Terrain elevation above sea level in feet
    @property ic/vg-fps (read/write) Ground speed initial condition in feet/second
    @property ic/vt-fps (read/write) True airspeed initial condition in feet/second
    @property ic/vw-bx-fps (read/write) Wind velocity initial condition in Body X frame in feet/second
@@ -269,9 +269,9 @@ public:
       @param gamma Flight path angle in degrees  */
   inline void SetFlightPathAngleDegIC(double gamma) { SetFlightPathAngleRadIC(gamma*degtorad); }
 
-  /** Sets the altitude initial condition in feet.
-      @param alt Altitude in feet */
-  void SetAltitudeFtIC(double alt);
+  /** Sets the altitude above sea level initial condition in feet.
+      @param altitudeASL Altitude above sea level in feet */
+  void SetAltitudeASLFtIC(double altitudeASL);
 
   /** Sets the initial Altitude above ground level.
       @param agl Altitude above ground level in feet */
@@ -283,7 +283,7 @@ public:
 
   /** Sets the initial terrain elevation.
       @param elev Initial terrain elevation in feet */
-  void SetTerrainAltitudeFtIC(double elev);
+  void SetTerrainElevationFtIC(double elev);
 
   /** Sets the initial latitude.
       @param lat Initial latitude in degrees */
@@ -349,13 +349,13 @@ public:
       @return Initial longitude in degrees */
   inline double GetLongitudeDegIC(void) const { return longitude*radtodeg; }
 
-  /** Gets the initial altitude.
+  /** Gets the initial altitude above sea level.
       @return Initial altitude in feet. */
-  inline double GetAltitudeFtIC(void) const { return altitude; }
+  inline double GetAltitudeASLFtIC(void) const { return altitudeASL; }
 
   /** Gets the initial altitude above ground level.
       @return Initial altitude AGL in feet */
-  inline double GetAltitudeAGLFtIC(void) const { return altitude - terrain_altitude; }
+  inline double GetAltitudeAGLFtIC(void) const { return altitudeASL - terrain_elevation; }
 
   /** Gets the initial sea level radius.
       @return Initial sea level radius */
@@ -363,7 +363,7 @@ public:
 
   /** Gets the initial terrain elevation.
       @return Initial terrain elevation in feet */
-  inline double GetTerrainAltitudeFtIC(void) const { return terrain_altitude; }
+  inline double GetTerrainElevationFtIC(void) const { return terrain_elevation; }
 
   /** Sets the initial ground speed.
       @param vg Initial ground speed in feet/second */
@@ -616,7 +616,7 @@ public:
 private:
   double vt,vc,ve,vg;
   double mach;
-  double altitude,hdot;
+  double altitudeASL,hdot;
   double latitude,longitude;
   double u,v,w;
   double p,q,r;
@@ -625,7 +625,7 @@ private:
   double wnorth,weast,wdown;
   double whead, wcross, wdir, wmag;
   double sea_level_radius;
-  double terrain_altitude;
+  double terrain_elevation;
   double radius_to_vehicle;
   double targetNlfIC;
 
index 9ea8a91860a391147c9180497c2c25e3dcf9375f..dc033e26f4708f81812acd8eb9860ed2e04fb0b3 100755 (executable)
@@ -181,14 +181,20 @@ bool FGScript::LoadScript( string script )
   while (property_element) {
 
     double value=0.0;
+    string title="";
+
+    title = property_element->GetDataLine();
     if ( ! property_element->GetAttributeValue("value").empty())
       value = property_element->GetAttributeValueAsNumber("value");
 
     LocalProps *localProp = new LocalProps(value);
-    localProp->title = property_element->GetDataLine();
+    localProp->title = title;
     local_properties.push_back(localProp);
-
-    PropertyManager->Tie(localProp->title, (local_properties.back())->value);
+    if (PropertyManager->HasNode(title)) {
+      PropertyManager->GetNode(title)->setDoubleValue(value);
+    } else {
+      PropertyManager->Tie(localProp->title, localProp->value);
+    }
     property_element = run_element->FindNextElement("property");
   }
 
@@ -447,6 +453,14 @@ void FGScript::Debug(int from)
            << " seconds with dt = " << State->Getdt() << endl;
       cout << endl;
 
+      for (unsigned int i=0; i<local_properties.size(); i++) {
+        cout << "Local property: " << local_properties[i]->title 
+             << " = " << PropertyManager->GetNode(local_properties[i]->title)->getDoubleValue()
+             << endl;
+      }
+      
+      if (local_properties.size() > 0) cout << endl;
+
       for (unsigned i=0; i<Events.size(); i++) {
         cout << "Event " << i;
         if (!Events[i].Name.empty()) cout << " (" << Events[i].Name << ")";
index 98aef7fa6608fce2e8fcec09f8c5fd16fd097187..1280e0e8b8c13262d355e546b562ee8dc526f4b8 100644 (file)
@@ -36,6 +36,7 @@ HISTORY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
+#include <FGFDMExec.h>
 #include "FGAerodynamics.h"
 #include "FGPropagate.h"
 #include "FGAircraft.h"
index 8c47b022676420c76c3ae9a6f3ebf23aefed24ed..a1bdb89b6ba7d429bb891ed85ce1cca875d9196e 100644 (file)
@@ -136,7 +136,7 @@ bool FGAtmosphere::Run(void)
   if (FDMExec->Holding()) return false;
 
   T_dev = 0.0;
-  h = Propagate->Geth();
+  h = Propagate->GetAltitudeASL();
 
   if (!useExternal) {
     Calculate(h);
index 8d47ce8cc8f6fb595e215cc403177da0f263c53a..c7e066bf4408832871c5a7eb4f392c655f923849 100644 (file)
@@ -40,6 +40,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGModel.h"
+#include <FGFDMExec.h>
 #include <math/FGColumnVector3.h>
 #include <math/FGLocation.h>
 #include "FGPropagate.h"
@@ -185,10 +186,23 @@ public:
   double GetqbarUW        (void) const { return qbarUW;     }
   double GetqbarUV        (void) const { return qbarUV;     }
   double GetReynoldsNumber(void) const { return Re;         }
+
+  /** Gets the magnitude of total vehicle velocity including wind effects in feet per second. */
   double GetVt            (void) const { return Vt;         }
+
+  /** Gets the ground speed in feet per second.
+      The magnitude is the square root of the sum of the squares (RSS) of the 
+      vehicle north and east velocity components.
+      @return The magnitude of the vehicle velocity in the horizontal plane. */
   double GetVground       (void) const { return Vground;    }
+
+  /** Gets the Mach number. */
   double GetMach          (void) const { return Mach;       }
+
+  /** The mach number calculated using the vehicle X axis velocity. */
   double GetMachU         (void) const { return MachU;      }
+
+  /** The vertical acceleration in g's of the aircraft center of gravity. */
   double GetNz            (void) const { return Nz;         }
 
   double GetHOverBCG(void) const { return hoverbcg; }
index 39aa91ddc3750657d57c76151086bc2f6efc0550..9f6373399cc9103b7d38e28dba824680b5fbc0b7 100644 (file)
@@ -36,6 +36,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGInertial.h"
+#include <FGFDMExec.h>
 #include "FGPropagate.h"
 #include "FGState.h"
 #include "FGMassBalance.h"
index f740cf643a9bcc5c1a2e9917e390a626c66bb16c..3031af700ac1ebede657857a2f16b1e1d7b6f12e 100644 (file)
@@ -663,7 +663,8 @@ void FGLGear::Report(ReportType repType)
 
   switch(repType) {
   case erLand:
-    cout << endl << "Touchdown report for " << name << endl;
+    cout << endl << "Touchdown report for " << name << " (WOW at time: "
+         << Exec->GetState()->Getsim_time() << " seconds)" << endl;
     cout << "  Sink rate at contact:  " << SinkRate                << " fps,    "
                                 << SinkRate*0.3048          << " mps"     << endl;
     cout << "  Contact ground speed:  " << GroundSpeed*.5925       << " knots,  "
@@ -677,11 +678,17 @@ void FGLGear::Report(ReportType repType)
     LandingReported = true;
     break;
   case erTakeoff:
-    cout << endl << "Takeoff report for " << name << endl;
+    cout << endl << "Takeoff report for " << name << " (Liftoff at time: "
+         << Exec->GetState()->Getsim_time() << " seconds)" << endl;
     cout << "  Distance traveled:                " << TakeoffDistanceTraveled
          << " ft,     " << TakeoffDistanceTraveled*0.3048  << " meters"  << endl;
     cout << "  Distance traveled (over 50'):     " << TakeoffDistanceTraveled50ft
          << " ft,     " << TakeoffDistanceTraveled50ft*0.3048 << " meters" << endl;
+    cout << "  [Altitude (ASL): " << Exec->GetPropagate()->GetAltitudeASL() << " ft. / "
+         << Exec->GetPropagate()->GetAltitudeASLmeters() << " m  | Temperature: "
+         << Exec->GetAtmosphere()->GetTemperature() - 459.67 << " F / "
+         << RankineToCelsius(Exec->GetAtmosphere()->GetTemperature()) << " C]" << endl;
+    cout << "  [Velocity (KCAS): " << Exec->GetAuxiliary()->GetVcalibratedKTS() << "]" << endl;
     TakeoffReported = true;
     break;
   }
index ecdd86a527ed4a33d629521c35513421a4e2474a..967f0ff44d388838438b907878edda97f8906e63 100644 (file)
@@ -130,8 +130,13 @@ bool FGMassBalance::Load(Element* el)
     element = el->FindNextElement("pointmass");
   }
 
+  double ChildFDMWeight = 0.0;
+  for (int fdm=0; fdm<FDMExec->GetFDMCount(); fdm++) {
+    if (FDMExec->GetChildFDM(fdm)->mated) ChildFDMWeight += FDMExec->GetChildFDM(fdm)->exec->GetMassBalance()->GetWeight();
+  }
+
   Weight = EmptyWeight + Propulsion->GetTanksWeight() + GetTotalPointMassWeight()
-    + BuoyantForces->GetGasMass()*slugtolb;
+    + BuoyantForces->GetGasMass()*slugtolb + ChildFDMWeight;
 
   Mass = lbtoslug*Weight;
 
@@ -149,8 +154,13 @@ bool FGMassBalance::Run(void)
   if (FGModel::Run()) return true;
   if (FDMExec->Holding()) return false;
 
+  double ChildFDMWeight = 0.0;
+  for (int fdm=0; fdm<FDMExec->GetFDMCount(); fdm++) {
+    if (FDMExec->GetChildFDM(fdm)->mated) ChildFDMWeight += FDMExec->GetChildFDM(fdm)->exec->GetMassBalance()->GetWeight();
+  }
+
   Weight = EmptyWeight + Propulsion->GetTanksWeight() + GetTotalPointMassWeight()
-    + BuoyantForces->GetGasMass()*slugtolb;
+    + BuoyantForces->GetGasMass()*slugtolb + ChildFDMWeight;
 
   Mass = lbtoslug*Weight;
 
index b76f5d9a2dd07156f7447d690706f221298aabdc..f8ef6a0b3bd83b2dda17dc591f808d24627daef1 100644 (file)
@@ -323,7 +323,8 @@ void FGOutput::DelimitedOutput(string fname)
     }
     if (SubSystems & ssPropagate) {
       outstream << delimeter;
-      outstream << "Altitude (ft)" + delimeter;
+      outstream << "Altitude ASL (ft)" + delimeter;
+      outstream << "Altitude AGL (ft)" + delimeter;
       outstream << "Phi (deg)" + delimeter + "Theta (deg)" + delimeter + "Psi (deg)" + delimeter;
       outstream << "Alpha (deg)" + delimeter;
       outstream << "Beta (deg)" + delimeter;
@@ -332,7 +333,7 @@ void FGOutput::DelimitedOutput(string fname)
       outstream << "ECEF X (ft)" + delimeter + "ECEF Y (ft)" + delimeter + "ECEF Z (ft)" + delimeter;
       outstream << "EPA (deg)" + delimeter;
       outstream << "Distance AGL (ft)" + delimeter;
-      outstream << "Runway Radius (ft)";
+      outstream << "Terrain Radius (ft)";
     }
     if (SubSystems & ssCoefficients) {
       scratch = Aerodynamics->GetCoefficientStrings(delimeter);
@@ -432,7 +433,8 @@ void FGOutput::DelimitedOutput(string fname)
   if (SubSystems & ssPropagate) {
     outstream.precision(14);
     outstream << delimeter;
-    outstream << Propagate->Geth() << delimeter;
+    outstream << Propagate->GetAltitudeASL() << delimeter;
+    outstream << Propagate->GetDistanceAGL() << delimeter;
     outstream << (radtodeg*Propagate->GetEuler()).Dump(delimeter) << delimeter;
     outstream << Auxiliary->Getalpha(inDegrees) << delimeter;
     outstream << Auxiliary->Getbeta(inDegrees) << delimeter;
@@ -443,7 +445,7 @@ void FGOutput::DelimitedOutput(string fname)
     outstream.precision(14);
     outstream << Inertial->GetEarthPositionAngleDeg() << delimeter;
     outstream << Propagate->GetDistanceAGL() << delimeter;
-    outstream << Propagate->GetRunwayRadius();
+    outstream << Propagate->GetLocalTerrainRadius();
     outstream.precision(10);
   }
   if (SubSystems & ssCoefficients) {
@@ -483,7 +485,7 @@ void FGOutput::SocketDataFill(FGNetFDM* net)
     // Positions
     net->longitude = Propagate->GetLocation().GetLongitude(); // geodetic (radians)
     net->latitude  = Propagate->GetLocation().GetLatitude(); // geodetic (radians)
-    net->altitude  = Propagate->Geth()*0.3048; // altitude, above sea level (meters)
+    net->altitude  = Propagate->GetAltitudeASL()*0.3048; // altitude, above sea level (meters)
     net->agl       = (float)(Propagate->GetDistanceAGL()*0.3048); // altitude, above ground level (meters)
 
     net->phi       = (float)(Propagate->GetEuler(ePhi)); // roll (radians)
@@ -881,7 +883,7 @@ void FGOutput::SocketOutput(void)
     socket->Append(MassBalance->GetXYZcg()(eZ));
   }
   if (SubSystems & ssPropagate) {
-    socket->Append(Propagate->Geth());
+    socket->Append(Propagate->GetAltitudeASL());
     socket->Append(radtodeg*Propagate->GetEuler(ePhi));
     socket->Append(radtodeg*Propagate->GetEuler(eTht));
     socket->Append(radtodeg*Propagate->GetEuler(ePsi));
index 8a41ec21ec083c94ee1178bbcc5e955a118f5094..0b7d7f78af2acb578c827e65e567739765240228 100644 (file)
@@ -118,10 +118,10 @@ bool FGPropagate::InitModel(void)
 {
   if (!FGModel::InitModel()) return false;
 
-  SeaLevelRadius = Inertial->GetRefRadius();          // For initialization ONLY
-  RunwayRadius   = SeaLevelRadius;
+  // For initialization ONLY:
+  SeaLevelRadius = LocalTerrainRadius = Inertial->GetRefRadius();
 
-  VState.vLocation.SetRadius( SeaLevelRadius + 4.0 ); // Todo Add terrain elevation?
+  VState.vLocation.SetRadius( LocalTerrainRadius + 4.0 );
   VState.vLocation.SetEllipse(Inertial->GetSemimajor(), Inertial->GetSemiminor());
   vOmega = FGColumnVector3( 0.0, 0.0, Inertial->omega() ); // Earth rotation vector
 
@@ -155,13 +155,13 @@ bool FGPropagate::InitModel(void)
 
 void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
 {
-  SeaLevelRadius = FGIC->GetSeaLevelRadiusFtIC();
-  RunwayRadius = SeaLevelRadius;
+  SetSeaLevelRadius(FGIC->GetSeaLevelRadiusFtIC());
+  SetTerrainElevation(FGIC->GetTerrainElevationFtIC());
 
   // Set the position lat/lon/radius
   VState.vLocation.SetPosition( FGIC->GetLongitudeRadIC(),
                           FGIC->GetLatitudeRadIC(),
-                          FGIC->GetAltitudeFtIC() + FGIC->GetSeaLevelRadiusFtIC() );
+                          FGIC->GetAltitudeASLFtIC() + FGIC->GetSeaLevelRadiusFtIC() );
 
   VehicleRadius = GetRadius();
   radInv = 1.0/VehicleRadius;
@@ -187,8 +187,8 @@ void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
   // Finally, make sure that the quaternion stays normalized.
   VState.vQtrn.Normalize();
 
-  // Recompute the RunwayRadius level.
-  RecomputeRunwayRadius();
+  // Recompute the LocalTerrainRadius.
+  RecomputeLocalTerrainRadius();
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -216,7 +216,7 @@ bool FGPropagate::Run(void)
   if (FGModel::Run()) return true;  // Fast return if we have nothing to do ...
   if (FDMExec->Holding()) return false;
 
-  RecomputeRunwayRadius();
+  RecomputeLocalTerrainRadius();
 
   // Calculate current aircraft radius from center of planet
 
@@ -424,27 +424,28 @@ void FGPropagate::CalculateLocationdot(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGPropagate::RecomputeRunwayRadius(void)
+void FGPropagate::RecomputeLocalTerrainRadius(void)
 {
-  // Get the runway radius.
+  double t = State->Getsim_time();
+
+  // Get the LocalTerrain radius.
   FGLocation contactloc;
   FGColumnVector3 dv;
-  FGGroundCallback* gcb = FDMExec->GetGroundCallback();
-  double t = State->Getsim_time();
-  gcb->GetAGLevel(t, VState.vLocation, contactloc, dv, dv);
-  RunwayRadius = contactloc.GetRadius();
+  FDMExec->GetGroundCallback()->GetAGLevel(t, VState.vLocation, contactloc, dv, dv);
+  LocalTerrainRadius = contactloc.GetRadius();
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGPropagate::SetTerrainElevationASL(double tt)
+void FGPropagate::SetTerrainElevation(double terrainElev)
 {
-  FDMExec->GetGroundCallback()->SetTerrainGeoCentRadius(tt+SeaLevelRadius);
+  LocalTerrainRadius = terrainElev + SeaLevelRadius;
+  FDMExec->GetGroundCallback()->SetTerrainGeoCentRadius(LocalTerrainRadius);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-double FGPropagate::GetTerrainElevationASL(void) const
+double FGPropagate::GetTerrainElevation(void) const
 {
   return FDMExec->GetGroundCallback()->GetTerrainGeoCentRadius()-SeaLevelRadius;
 }
@@ -465,30 +466,30 @@ const FGMatrix33& FGPropagate::GetTec2i(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGPropagate::Seth(double tt)
+void FGPropagate::SetAltitudeASL(double altASL)
 {
-  VState.vLocation.SetRadius( tt + SeaLevelRadius );
+  VState.vLocation.SetRadius( altASL + SeaLevelRadius );
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-double FGPropagate::GetRunwayRadius(void) const
+double FGPropagate::GetLocalTerrainRadius(void) const
 {
-  return RunwayRadius;
+  return LocalTerrainRadius;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 double FGPropagate::GetDistanceAGL(void) const
 {
-  return VState.vLocation.GetRadius() - RunwayRadius;
+  return VState.vLocation.GetRadius() - LocalTerrainRadius;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 void FGPropagate::SetDistanceAGL(double tt)
 {
-  VState.vLocation.SetRadius( tt + RunwayRadius );
+  VState.vLocation.SetRadius( tt + LocalTerrainRadius );
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -525,8 +526,8 @@ void FGPropagate::bind(void)
   PropertyManager->Tie("accelerations/vdot-ft_sec2", this, eV, (PMF)&FGPropagate::GetUVWdot);
   PropertyManager->Tie("accelerations/wdot-ft_sec2", this, eW, (PMF)&FGPropagate::GetUVWdot);
 
-  PropertyManager->Tie("position/h-sl-ft", this, &FGPropagate::Geth, &FGPropagate::Seth, true);
-  PropertyManager->Tie("position/h-sl-meters", this, &FGPropagate::Gethmeters, &FGPropagate::Sethmeters, true);
+  PropertyManager->Tie("position/h-sl-ft", this, &FGPropagate::GetAltitudeASL, &FGPropagate::SetAltitudeASL, true);
+  PropertyManager->Tie("position/h-sl-meters", this, &FGPropagate::GetAltitudeASLmeters, &FGPropagate::SetAltitudeASLmeters, true);
   PropertyManager->Tie("position/lat-gc-rad", this, &FGPropagate::GetLatitude, &FGPropagate::SetLatitude);
   PropertyManager->Tie("position/long-gc-rad", this, &FGPropagate::GetLongitude, &FGPropagate::SetLongitude);
   PropertyManager->Tie("position/lat-gc-deg", this, &FGPropagate::GetLatitudeDeg, &FGPropagate::SetLatitudeDeg);
@@ -537,10 +538,10 @@ void FGPropagate::bind(void)
   PropertyManager->Tie("position/h-agl-ft", this,  &FGPropagate::GetDistanceAGL, &FGPropagate::SetDistanceAGL);
   PropertyManager->Tie("position/radius-to-vehicle-ft", this, &FGPropagate::GetRadius);
   PropertyManager->Tie("position/terrain-elevation-asl-ft", this,
-                          &FGPropagate::GetTerrainElevationASL,
-                          &FGPropagate::SetTerrainElevationASL, false);
+                          &FGPropagate::GetTerrainElevation,
+                          &FGPropagate::SetTerrainElevation, false);
 
-  PropertyManager->Tie("metrics/runway-radius", this, &FGPropagate::GetRunwayRadius);
+  PropertyManager->Tie("metrics/terrain-radius", this, &FGPropagate::GetLocalTerrainRadius);
 
   PropertyManager->Tie("attitude/phi-rad", this, (int)ePhi, (PMF)&FGPropagate::GetEuler);
   PropertyManager->Tie("attitude/theta-rad", this, (int)eTht, (PMF)&FGPropagate::GetEuler);
index adf136e79f99060b0e35321d2fb5f3631f86ea15..63c2b42c38e5258bb607c2f7a486e5c93bad5a47 100644 (file)
@@ -286,21 +286,19 @@ public:
   */
   double GetInertialVelocityMagnitude(void) const { return vInertialVelocity.Magnitude(); }
 
-  /** Returns the current altitude.
-      Returns the current altitude. Specifically, this function returns the
-      difference between the distance to the center of the Earth, and sea level.
+  /** Returns the current altitude above sea level.
+      This function returns the altitude above sea level.
       units ft
       @return The current altitude above sea level in feet.
   */
-  double Geth(void)   const { return VState.vLocation.GetRadius() - SeaLevelRadius; }
+  double GetAltitudeASL(void)   const { return VState.vLocation.GetRadius() - SeaLevelRadius; }
 
-  /** Returns the current altitude.
-      Returns the curren altitude. Specifically, this function returns the
-      difference between the distance to the center of the Earth, and sea level.
+  /** Returns the current altitude above sea level.
+      This function returns the altitude above sea level.
       units meters
       @return The current altitude above sea level in meters.
   */
-  double Gethmeters(void) const { return Geth()*fttom;}
+  double GetAltitudeASLmeters(void) const { return GetAltitudeASL()*fttom;}
 
   /** Retrieves a body frame angular velocity component relative to the ECEF frame.
       Retrieves a body frame angular velocity component. The angular velocity
@@ -385,16 +383,16 @@ public:
   */
   double Gethdot(void) const { return -vVel(eDown); }
 
-  /** Returns the "constant" RunwayRadius.
-      The RunwayRadius parameter is set by the calling application or set to
-      sea level if JSBSim is running in standalone mode.
+  /** Returns the "constant" LocalTerrainRadius.
+      The LocalTerrainRadius parameter is set by the calling application or set to
+      sea level + terrain elevation if JSBSim is running in standalone mode.
       units feet
-      @return distance of the runway from the center of the earth.
+      @return distance of the local terrain from the center of the earth.
       */
-  double GetRunwayRadius(void) const;
+  double GetLocalTerrainRadius(void) const;
 
   double GetSeaLevelRadius(void) const { return SeaLevelRadius; }
-  double GetTerrainElevationASL(void) const;
+  double GetTerrainElevation(void) const;
   double GetDistanceAGL(void)  const;
   double GetRadius(void) const {
       if (VState.vLocation.GetRadius() == 0) return 1.0;
@@ -481,13 +479,13 @@ public:
   void SetLatitudeDeg(double lat) {SetLatitude(lat*degtorad);}
   void SetRadius(double r) { VState.vLocation.SetRadius(r); }
   void SetLocation(const FGLocation& l) { VState.vLocation = l; }
-  void Seth(double tt);
-  void Sethmeters(double tt) {Seth(tt/fttom);}
+  void SetAltitudeASL(double altASL);
+  void SetAltitudeASLmeters(double altASL) {SetAltitudeASL(altASL/fttom);}
   void SetSeaLevelRadius(double tt) { SeaLevelRadius = tt; }
-  void SetTerrainElevationASL(double tt);
+  void SetTerrainElevation(double tt);
   void SetDistanceAGL(double tt);
   void SetInitialState(const FGInitialCondition *);
-  void RecomputeRunwayRadius(void);
+  void RecomputeLocalTerrainRadius(void);
 
   void CalculatePQRdot(void);
   void CalculateQuatdot(void);
@@ -521,7 +519,7 @@ private:
   FGMatrix33 Ti2b;   // ECI to body frame rotation matrix
   FGMatrix33 Tb2i;   // body to ECI frame rotation matrix
   
-  double RunwayRadius, SeaLevelRadius, VehicleRadius;
+  double LocalTerrainRadius, SeaLevelRadius, VehicleRadius;
   double radInv;
   int integrator_rotational_rate;
   int integrator_translational_rate;
index e3197404d2a131c3c6f5373a47cd9553591e94f5..590e3f6d3ed3e41a7963274af30fd9937a947af9 100755 (executable)
@@ -168,7 +168,7 @@ bool MSIS::Run(void)
     // get at-altitude values
     Calculate(Auxiliary->GetDayOfYear(),
               Auxiliary->GetSecondsInDay(),
-              Propagate->Geth(),
+              Propagate->GetAltitudeASL(),
               Propagate->GetLocation().GetLatitudeDeg(),
               Propagate->GetLocation().GetLongitudeDeg());
     intTemperature = output.t[1] * 1.8;
index 9370c5f84e83ce57e9e83b01659ce0a88c4987ba..3b36b3a920e2aec852c829e2b7f2278dbdf4cd0e 100755 (executable)
@@ -106,7 +106,7 @@ bool FGActuator::Run(void )
   Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
 
   if (fail_zero) Input = 0;
-  if (fail_hardover) Input =  clipmax*fabs(Input)/Input;
+  if (fail_hardover) Input =  clipmax*sign(Input);
 
   Output = Input; // Perfect actuator. At this point, if no failures are present
                   // and no subsequent lag, limiting, etc. is done, the output
index 5e4ede578291c1b3f31f395a2ba8bd7a10035562..824f0ea5c37da9ac3431e50f9436c66acf78d98c 100755 (executable)
@@ -56,7 +56,7 @@ FGSensor::FGSensor(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
 
   // inputs are read from the base class constructor
 
-  bits = quantized = divisions = 0;
+  bits = quantized = divisions = index = delay = 0;
   PreviousInput = PreviousOutput = 0.0;
   min = max = bias = noise_variance = lag = drift_rate = drift = span = 0.0;
   granularity = 0.0;
@@ -103,6 +103,21 @@ FGSensor::FGSensor(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
       cerr << "Unknown noise type in sensor: " << Name << endl;
       cerr << "  defaulting to PERCENT." << endl;
     }
+    string distribution = element->FindElement("noise")->GetAttributeValue("distribution");
+    if (distribution == "UNIFORM") {
+      DistributionType = eUniform;
+    } else if (distribution == "GAUSSIAN") {
+      DistributionType = eGaussian;
+    } else {
+      DistributionType = eUniform;
+      cerr << "Unknown random distribution type in sensor: " << Name << endl;
+      cerr << "  defaulting to UNIFORM." << endl;
+    }
+  }
+  if ( element->FindElement("delay") ) {
+    delay = (unsigned int)element->FindElementValueAsNumber("delay");
+    output_array.resize(delay);
+    for (unsigned int i=0; i<delay; i++) output_array[i] = 0.0;
   }
 
   FGFCSComponent::bind();
@@ -133,16 +148,17 @@ bool FGSensor::Run(void )
     return true;
   }
 
-  if (lag != 0.0)            Lag();       // models sensor lag
+  if (lag != 0.0)            Lag();       // models sensor lag and filter
   if (noise_variance != 0.0) Noise();     // models noise
   if (drift_rate != 0.0)     Drift();     // models drift over time
   if (bias != 0.0)           Bias();      // models a finite bias
 
+  if (delay != 0.0)          Delay();     // models system signal transport latencies
+
   if (fail_low)  Output = -HUGE_VAL;
   if (fail_high) Output =  HUGE_VAL;
 
   if (bits != 0)             Quantize();  // models quantization degradation
-//  if (delay != 0.0)          Delay();     // models system signal transport latencies
 
   Clip(); // Is it right to clip a sensor?
   return true;
@@ -152,7 +168,13 @@ bool FGSensor::Run(void )
 
 void FGSensor::Noise(void)
 {
-  double random_value = ((double)rand()/(double)RAND_MAX) - 0.5;
+  double random_value=0.0;
+
+  if (DistributionType == eUniform) {
+    random_value = ((double)rand()/(double)RAND_MAX) - 0.5;
+  } else {
+    random_value = GaussianRandomNumber();
+  }
 
   switch( NoiseType ) {
   case ePercent:
@@ -195,7 +217,7 @@ void FGSensor::Quantize(void)
 
 void FGSensor::Lag(void)
 {
-  // "Output" on the right side of the "=" is the current frame input
+  // "Output" on the right side of the "=" is the current input
   Output = ca * (Output + PreviousInput) + PreviousOutput * cb;
 
   PreviousOutput = Output;
@@ -204,6 +226,16 @@ void FGSensor::Lag(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+void FGSensor::Delay(void)
+{
+  output_array[index] = Output;
+  if (index == delay-1) index = 0;
+  else index++;
+  Output = output_array[index];
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 void FGSensor::bind(void)
 {
   string tmp = Name;
@@ -258,7 +290,8 @@ void FGSensor::Debug(int from)
         else
           cout << "      INPUT: " << InputNodes[0]->getName() << endl;
       }
-      if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
+      if (delay > 0) cout <<"      Frame delay: " << delay
+                                   << " frames (" << delay*dt << " sec)" << endl;
       if (bits != 0) {
         if (quant_property.empty())
           cout << "      Quantized output" << endl;
@@ -281,7 +314,13 @@ void FGSensor::Debug(int from)
         } else {
           cout << "      Noise variance type is invalid" << endl;
         }
+        if (DistributionType == eUniform) {
+          cout << "      Random noise is uniformly distributed." << endl;
+        } else if (DistributionType == eGaussian) {
+          cout << "      Random noise is gaussian distributed." << endl;
+        }
       }
+      if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
     }
   }
   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
index 87fd3d5182378a18f4aade3aa4371e9f456b1d26..efbc5b7c5d079912ca7fb51fdafe0876a3054419 100755 (executable)
@@ -39,6 +39,7 @@ INCLUDES
 
 #include "FGFCSComponent.h"
 #include <input_output/FGXMLElement.h>
+#include <vector>
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -52,6 +53,7 @@ FORWARD DECLARATIONS
 
 namespace JSBSim {
 
+using std::vector;
 class FGFCS;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -74,6 +76,7 @@ Syntax:
   </quantization>
   <drift_rate> number </drift_rate>
   <bias> number </bias>
+  <delay> number < /delay>
 </sensor>
 @endcode
 
@@ -101,7 +104,8 @@ percentage variance. That is, if the number given is 0.05, the the variance is
 understood to be +/-0.05 percent maximum variance. So, the actual value for the sensor
 will be *anywhere* from 0.95 to 1.05 of the actual "perfect" value at any time -
 even varying all the way from 0.95 to 1.05 in adjacent frames - whatever the delta
-time.
+time. The delay element can specify a frame delay. The integer number provided is
+the number of frames to delay the output signal.
 
 @author Jon S. Berndt
 @version $Revision$
@@ -130,6 +134,7 @@ public:
 
 protected:
   enum eNoiseType {ePercent=0, eAbsolute} NoiseType;
+  enum eDistributionType {eUniform=0, eGaussian} DistributionType;
   double dt;
   double min, max;
   double span;
@@ -147,16 +152,20 @@ protected:
   int bits;
   int quantized;
   int divisions;
+  int delay;
+  int index;
   bool fail_low;
   bool fail_high;
   bool fail_stuck;
   string quant_property;
+  vector <double> output_array;
 
   void Noise(void);
   void Bias(void);
   void Drift(void);
   void Quantize(void);
   void Lag(void);
+  void Delay(void);
 
   void bind(void);
 
index fbb9f2d02425caf6a02e77c0bfdcd5baf2a59314..cd24bfbabdf0c16af61ef5348cbc3fbe7a410ab1 100644 (file)
@@ -548,7 +548,7 @@ void FGPiston::doMAP(void)
       }
     }
     // Boost the manifold pressure.
-    double boost_factor = BoostMul[BoostSpeed] * map_coefficient * RPM/RatedRPM[BoostSpeed];
+    double boost_factor = BoostMul[BoostSpeed] * RPM/RatedRPM[BoostSpeed];
     if (boost_factor < 1.0) boost_factor = 1.0;  // boost will never reduce the MAP
     MAP = TMAP * boost_factor;
     // Now clip the manifold pressure to BCV or Wastegate setting.
@@ -713,7 +713,7 @@ void FGPiston::doEGT(void)
  * Calculate the cylinder head temperature.
  *
  * Inputs: T_amb, IAS, rho_air, m_dot_fuel, calorific_value_fuel,
- *   combustion_efficiency, RPM, MaxRPM
+ *   combustion_efficiency, RPM, MaxRPM, Displacement
  *
  * Outputs: CylinderHeadTemp_degK
  */
@@ -813,7 +813,7 @@ string FGPiston::GetEngineLabels(string delimeter)
   buf << Name << " Power Available (engine " << EngineNumber << " in HP)" << delimeter
       << Name << " HP (engine " << EngineNumber << ")" << delimeter
       << Name << " equivalent ratio (engine " << EngineNumber << ")" << delimeter
-      << Name << " MAP (engine " << EngineNumber << ")" << delimeter
+      << Name << " MAP (engine " << EngineNumber << " in inHg)" << delimeter
       << Thruster->GetThrusterLabels(EngineNumber, delimeter);
 
   return buf.str();
@@ -826,7 +826,7 @@ string FGPiston::GetEngineValues(string delimeter)
   std::ostringstream buf;
 
   buf << PowerAvailable << delimeter << HP << delimeter
-      << equivalence_ratio << delimeter << MAP << delimeter
+      << equivalence_ratio << delimeter << ManifoldPressure_inHg << delimeter
       << Thruster->GetThrusterValues(EngineNumber, delimeter);
 
   return buf.str();
index d751654a03e7ba68a4f231e78bdc853321878456..6c4a7818c4a14a39d599e26f53315546479d8e60 100644 (file)
@@ -92,6 +92,7 @@ FGTurbine::~FGTurbine()
 void FGTurbine::ResetToIC(void)
 {
   N1 = N2 = 0.0;
+  N2norm = 0.0;
   correctedTSFC = TSFC;
   ThrottlePos = AugmentCmd = 0.0;
   InletPosition = NozzlePosition = 1.0;
@@ -186,7 +187,9 @@ double FGTurbine::Off(void)
 double FGTurbine::Run()
 {
   double idlethrust, milthrust, thrust;
-  double N2norm;   // 0.0 = idle N2, 1.0 = maximum N2
+  double spoolup;                        // acceleration in pct/sec
+  double sigma = Atmosphere->GetDensityRatio();
+  double T = Atmosphere->GetTemperature();
 
   idlethrust = MilThrust * IdleThrustLookup->GetValue();
   milthrust = (MilThrust - idlethrust) * MilThrustLookup->GetValue();
@@ -194,8 +197,13 @@ double FGTurbine::Run()
   Running = true;
   Starter = false;
 
-  N2 = Seek(&N2, IdleN2 + ThrottlePos * N2_factor, delay, delay * 3.0);
-  N1 = Seek(&N1, IdleN1 + ThrottlePos * N1_factor, delay, delay * 2.4);
+  // adjust acceleration for N2 and atmospheric density
+  double n = N2norm + 0.1;
+  if (n > 1) n = 1; 
+  spoolup = delay / (1 + 3 * (1-n)*(1-n)*(1-n) + (1 - sigma));
+  
+  N2 = Seek(&N2, IdleN2 + ThrottlePos * N2_factor, spoolup, spoolup * 3.0);
+  N1 = Seek(&N1, IdleN1 + ThrottlePos * N1_factor, spoolup, spoolup * 2.4);
   N2norm = (N2 - IdleN2) / N2_factor;
   thrust = idlethrust + (milthrust * N2norm * N2norm);
   EGT_degC = TAT + 363.1 + ThrottlePos * 357.1;
@@ -203,7 +211,7 @@ double FGTurbine::Run()
   OilTemp_degK = Seek(&OilTemp_degK, 366.0, 1.2, 0.1);
 
   if (!Augmentation) {
-    correctedTSFC = TSFC * (0.84 + (1-N2norm)*(1-N2norm));
+    correctedTSFC = TSFC * sqrt(T/389.7) * (0.84 + (1-N2norm)*(1-N2norm));
     FuelFlow_pph = Seek(&FuelFlow_pph, thrust * correctedTSFC, 1000.0, 100000);
     if (FuelFlow_pph < IdleFF) FuelFlow_pph = IdleFF;
     NozzlePosition = Seek(&NozzlePosition, 1.0 - N2norm, 0.8, 0.8);
@@ -329,7 +337,7 @@ double FGTurbine::Seize(void)
 
 double FGTurbine::Trim()
 {
-    double idlethrust, milthrust, thrust, tdiff, N2norm;
+    double idlethrust, milthrust, thrust, tdiff;
     idlethrust = MilThrust * IdleThrustLookup->GetValue();
     milthrust = (MilThrust - idlethrust) * MilThrustLookup->GetValue();
     N2 = IdleN2 + ThrottlePos * N2_factor;
@@ -457,7 +465,7 @@ bool FGTurbine::Load(FGFDMExec* exec, Element *el)
 
   // Pre-calculations and initializations
 
-  delay = 60.0 / (BypassRatio + 3.0);
+  delay = 90.0 / (BypassRatio + 3.0);
   N1_factor = MaxN1 - IdleN1;
   N2_factor = MaxN2 - IdleN2;
   OilTemp_degK = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556 + 273.0;
index 4c63dc6028c1e7d94da6557e16b97c5c4ddffeea..552c258b14a9d4b5a31fd492f78391085c9370bb 100644 (file)
@@ -224,6 +224,7 @@ private:
   double IdleN2;           ///< Idle N2
   double N1;               ///< N1
   double N2;               ///< N2
+  double N2norm;           ///< N2 normalized (0=idle, 1=max)
   double MaxN1;            ///< N1 at 100% throttle
   double MaxN2;            ///< N2 at 100% throttle
   double IdleFF;           ///< Idle Fuel Flow (lbm/hr)