]> git.mxchange.org Git - flightgear.git/commitdiff
Updates from JSBSim, including new turbine engine model from David Culp
authortony <tony>
Sun, 23 Mar 2003 15:12:35 +0000 (15:12 +0000)
committertony <tony>
Sun, 23 Mar 2003 15:12:35 +0000 (15:12 +0000)
16 files changed:
src/FDM/JSBSim/FGAuxiliary.cpp
src/FDM/JSBSim/FGAuxiliary.h
src/FDM/JSBSim/FGCoefficient.cpp
src/FDM/JSBSim/FGCoefficient.h
src/FDM/JSBSim/FGConfigFile.cpp
src/FDM/JSBSim/FGEngine.h
src/FDM/JSBSim/FGFDMExec.cpp
src/FDM/JSBSim/FGJSBBase.h
src/FDM/JSBSim/FGOutput.cpp
src/FDM/JSBSim/FGOutput.h
src/FDM/JSBSim/FGPropulsion.cpp
src/FDM/JSBSim/FGPropulsion.h
src/FDM/JSBSim/FGSimTurbine.cpp [new file with mode: 0644]
src/FDM/JSBSim/FGSimTurbine.h [new file with mode: 0644]
src/FDM/JSBSim/FGTranslation.h
src/FDM/JSBSim/Makefile.am

index 845341b24c15b2cebbaafdc769e1bdf6d73ffdbe..aa188c32c446c1d2b68a1276dceaaa60b37ce17a 100644 (file)
@@ -97,6 +97,10 @@ bool FGAuxiliary::Run()
 
   if (!FGModel::Run()) {
     GetState();
+    
+    //caculate total temperature assuming isentropic flow
+    tat=sat*(1 + 0.2*mach*mach);
+    
     if (mach < 1) {   //calculate total pressure assuming isentropic flow
       pt=p*pow((1 + 0.2*mach*mach),3.5);
     } else {
@@ -218,6 +222,11 @@ void FGAuxiliary::bind(void)
                        &FGAuxiliary::GetVequivalentFPS);
   PropertyManager->Tie("velocities/ve-kts", this,
                        &FGAuxiliary::GetVequivalentKTS);
+  PropertyManager->Tie("velocities/tat-r", this,
+                       &FGAuxiliary::GetTotalTemperature);
+  PropertyManager->Tie("velocities/pt-lbs_sqft", this,
+                       &FGAuxiliary::GetTotalPressure);
+                     
   PropertyManager->Tie("accelerations/a-pilot-x-ft_sec2", this,1,
                        (PMF)&FGAuxiliary::GetPilotAccel);
   PropertyManager->Tie("accelerations/a-pilot-y-ft_sec2", this,2,
@@ -269,6 +278,7 @@ void FGAuxiliary::GetState(void)
   p = Atmosphere->GetPressure();
   rhosl = Atmosphere->GetDensitySL();
   psl = Atmosphere->GetPressureSL();
+  sat = Atmosphere->GetTemperature();
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index 3f6018edca503f8a6671f604ab3ded11c4d85a3c..dcd6efd23c3831700c5e15479a55ca296b2c2185 100644 (file)
@@ -95,6 +95,12 @@ public:
   inline double GetVequivalentFPS(void) const { return veas; }
   inline double GetVequivalentKTS(void) const { return veas*fpstokts; }
   
+  inline double GetTotalTemperature(void) const { return tat; }
+
+  // total pressure above is freestream total pressure for subsonic only
+  // for supersonic it is the 1D total pressure behind a normal shock
+  inline double GetTotalPressure(void) const { return pt; }
+  
   inline FGColumnVector3& GetPilotAccel(void) { return vPilotAccel; }
   inline double GetPilotAccel(int idx) const { return vPilotAccel(idx); }
   FGColumnVector3 GetNpilot(void) const { return vPilotAccelN; }
@@ -112,14 +118,9 @@ private:
   double vcas;
   double veas;
   double mach;
-  double qbar,rhosl,rho,p,psl,pt;
+  double qbar,rhosl,rho,p,psl,pt,tat,sat;
 
   // Don't add a getter for pt!
-  // pt above is freestream total pressure for subsonic only
-  // for supersonic it is the 1D total pressure behind a normal shock
-  // if a general freestream total is needed, e-mail Tony Peden
-  // (apeden@earthlink.net) or you can add it your self using the
-  // isentropic flow equations
 
   FGColumnVector3 vPilotAccel;
   FGColumnVector3 vPilotAccelN;
index ab7927a441b568c788c4d951d8d6908c5263bb6d..bb78c4d94d26a1095e77137a18975870cd511e04 100644 (file)
@@ -304,7 +304,7 @@ void FGCoefficient::bind(FGPropertyManager *parent)
   string mult;
   unsigned i;
   
-  node=parent->GetNode(name,true);
+  node = parent->GetNode(name,true);
   
   node->SetString("description",description);
   if (LookupR) node->SetString("row-parm",LookupR->getName() );
@@ -343,14 +343,16 @@ void FGCoefficient::unbind(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-FGPropertyManager* FGCoefficient::resolveSymbol(string name){
-        FGPropertyManager* tmpn;
-        tmpn = PropertyManager->GetNode(name,false);
-        if( !tmpn ) {
-          cerr << "Coefficient multipliers cannot create properties, check spelling?" << endl;
-          exit(1);
-        } 
-        return tmpn; 
+FGPropertyManager* FGCoefficient::resolveSymbol(string name)
+{
+  FGPropertyManager* tmpn;
+
+  tmpn = PropertyManager->GetNode(name,false);
+  if ( !tmpn ) {
+    cerr << "Coefficient multipliers cannot create properties, check spelling?" << endl;
+    exit(1);
+  } 
+  return tmpn; 
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index 55ad7a165018d3f9aa7fe9ad6736e46fa74acee0..abd95e3c029a89bea813f4dcf3333ab65c7ccf01 100644 (file)
@@ -131,7 +131,7 @@ public:
       @return the current value of the coefficient represented by this instance of
       FGCoefficient. */
   virtual double TotalValue(void);
-  
+
   /** Returns the value for this coefficient.
       TotalValue is stored each time TotalValue() is called. This function returns
       the stored value but does not calculate it anew. This is valuable for merely
@@ -139,25 +139,24 @@ public:
       @return the most recently calculated and stored value of the coefficient
       represented by this instance of FGCoefficient. */
   virtual inline double GetValue(void) const { return totalValue; }
-  
+
   /// Returns the name of this coefficient.
   virtual inline string Getname(void) const {return name;}
-  
+
   /// Returns the value of the coefficient only - before it is re-dimensionalized.
   virtual inline double GetSD(void) const { return SD;}
-  
+
   /** Outputs coefficient information.
       Non-dimensionalizing parameter descriptions are output
       for each aero coefficient defined.
       @param multipliers the list of multipliers for this coefficient.*/
   virtual void DisplayCoeffFactors(void);
-  
+
   /// Returns the name of the coefficient.
   virtual inline string GetCoefficientName(void) { return name; }
   /// Returns the stability derivative or coefficient value as a string.
   virtual string GetSDstring(void);
-  
-  
+
   inline void setBias(double b) { bias=b; }
   inline void setGain(double g) { gain=g; };
   inline double getBias(void) const { return bias; }
index e0d42cb061833250ba028305c5041a3f38efc7c9..c6c3832880ed5177a293b2c88347e706587179c9 100644 (file)
@@ -223,6 +223,12 @@ string FGConfigFile::GetLine(void)
       }
     }
   }
+
+  int index = scratch.find_last_not_of(" ");
+  if (index != string::npos && index < (scratch.size()-1)) {
+    scratch = scratch.substr(0,index+1);
+  }
+
   if (cfgfile.eof() && scratch.empty()) return string("EOF");
   return scratch;
 }
index 14d15149bc59e4e7209046dc8716c23f84a1cbbb..e17358f5f438735ee0597f3d3ddc31705a89fe98 100644 (file)
@@ -112,7 +112,7 @@ public:
   FGEngine(FGFDMExec* exec);
   virtual ~FGEngine();
 
-  enum EngineType {etUnknown, etRocket, etPiston, etTurbine};
+  enum EngineType {etUnknown, etRocket, etPiston, etTurbine, etSimTurbine};
 
   virtual double  GetThrottleMin(void) { return MinThrottle; }
   virtual double  GetThrottleMax(void) { return MaxThrottle; }
@@ -127,6 +127,16 @@ public:
   virtual bool    GetCranking(void) { return Cranking; }
   virtual int     GetType(void) { return Type; }
   virtual string  GetName(void) { return Name; }
+  virtual double  GetN1(void) { return N1; }
+  virtual double  GetN2(void) { return N2; }
+  virtual double  GetEGT(void) { return EGT_degC; }
+  virtual double  GetEPR(void) { return EPR; }
+  virtual double  GetInlet(void) { return InletPosition; }
+  virtual double  GetNozzle(void) { return NozzlePosition; } 
+  virtual bool    GetAugmentation(void) { return Augmentation; } 
+  virtual bool    GetInjection(void) { return Injection; }
+  virtual bool    GetIgnition(void) { return Ignition; }
+  virtual bool    GetReversed(void) { return Reversed; }
 
   virtual double getFuelFlow_gph () const {
     return FuelFlow_gph;
@@ -148,6 +158,10 @@ public:
     return (OilTemp_degK - 273.0) * (9.0 / 5.0) + 32.0;
   }
 
+  virtual double getFuelFlow_pph () const {
+    return FuelFlow_pph;
+  }
+
   virtual void SetStarved(bool tt) {Starved = tt;}
   virtual void SetStarved(void)    {Starved = true;}
 
@@ -227,6 +241,19 @@ protected:
   double OilPressure_psi;
   double OilTemp_degK;
 
+  double FuelFlow_pph;
+  double N1;
+  double N2;
+  double EGT_degC;
+  double EPR;
+  double BleedDemand;
+  double InletPosition;
+  double NozzlePosition;
+  bool Augmentation;
+  bool Injection;
+  bool Ignition;
+  bool Reversed;
+
   FGFDMExec*      FDMExec;
   FGState*        State;
   FGAtmosphere*   Atmosphere;
index 166fdee453296f24a61bd2dbbcf663b63e503216..ee6386705eab9641124d7dcfd75005a6f8af0548 100644 (file)
@@ -89,19 +89,22 @@ FGPropertyManager* FGFDMExec::master=0;
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-void checkTied( FGPropertyManager *node ) {
+void checkTied ( FGPropertyManager *node )
+{
   int N = node->nChildren();
   string name;
-  for(int i=0;i<N;i++) {
-    if(node->getChild(i)->nChildren() ) {
+
+  for (int i=0; i<N; i++) {
+    if (node->getChild(i)->nChildren() ) {
       checkTied( (FGPropertyManager*)node->getChild(i) );
-    } else if( node->getChild(i)->isTied() ) {
-      name=((FGPropertyManager*)node->getChild(i))->GetFullyQualifiedName();
+    } else if ( node->getChild(i)->isTied() ) {
+      name = ((FGPropertyManager*)node->getChild(i))->GetFullyQualifiedName();
       cerr << name << " is tied" << endl;
     } 
   }
 }        
 
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 // Constructor
 
 FGFDMExec::FGFDMExec(FGPropertyManager* root)
@@ -274,8 +277,8 @@ bool FGFDMExec::Allocate(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGFDMExec::DeAllocate(void) {
-
+bool FGFDMExec::DeAllocate(void)
+{
   delete Atmosphere;
   delete FCS;
   delete Propulsion;
@@ -293,8 +296,6 @@ bool FGFDMExec::DeAllocate(void) {
   
   delete IC;
   delete Trim;
-  
-  
     
   FirstModel  = 0L;
   Error       = 0;
@@ -381,6 +382,7 @@ bool FGFDMExec::RunIC(void)
   State->Initialize(IC);
   Run();
   State->Resume();
+
   return true;
 }
 
@@ -401,9 +403,11 @@ vector <string> FGFDMExec::EnumerateFDMs(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGFDMExec::LoadModel(string AircraftPath, string EnginePath, string model) {
-  FGFDMExec::AircraftPath=AircraftPath;
-  FGFDMExec::EnginePath=EnginePath;
+bool FGFDMExec::LoadModel(string AircraftPath, string EnginePath, string model)
+{
+  FGFDMExec::AircraftPath = AircraftPath;
+  FGFDMExec::EnginePath = EnginePath;
+
   return LoadModel(model);
 }  
 
index 80d3e17ea78e11d18dba47760d350a6daf366f5b..49275cff0adfec51e38e98332959a231736b38cc 100644 (file)
@@ -47,6 +47,11 @@ INCLUDES
 SG_USING_STD(string);
 SG_USING_STD(queue);
 
+# ifndef M_PI
+#  include <simgear/constants.h>
+#  define M_PI SG_PI
+# endif
+
 #else
 
 #  include <queue>
@@ -59,13 +64,16 @@ SG_USING_STD(queue);
 
 using std::string;
 using std::queue;
-#endif
 
-#ifndef M_PI 
-#  include <simgear/constants.h>
-#  define M_PI SG_PI
+# ifndef M_PI
+#  define M_PI 3.14159265358979323846
+# endif
+
 #endif
 
+
+using std::max;
+
 #ifdef __FreeBSD__ // define gcvt on FreeBSD
 
 #include <stdio.h>
index f35662a6c39b3f05a93ff6e2f88acec45e718e62..afe6a7a8d84ff0d1680abfe868bd78cc3d40b1d6 100644 (file)
@@ -67,9 +67,10 @@ FGOutput::FGOutput(FGFDMExec* fdmex) : FGModel(fdmex)
   sFirstPass = dFirstPass = true;
   socket = 0;
   Type = otNone;
-  Filename = "JSBSim.out";
+  Filename = "";
   SubSystems = 0;
   enabled = true;
+  outputInFileName = "";
   
   Debug(0);
 }
@@ -79,6 +80,8 @@ FGOutput::FGOutput(FGFDMExec* fdmex) : FGModel(fdmex)
 FGOutput::~FGOutput()
 {
   if (socket) delete socket;
+  for (int i=0; i<OutputProperties.size(); i++) delete OutputProperties[i];
+
   Debug(1);
 }
 
@@ -225,6 +228,11 @@ void FGOutput::DelimitedOutput(string fname)
       outstream << ", ";
       outstream << Propulsion->GetPropulsionStrings();
     }
+    if (OutputProperties.size() > 0) {
+      for (int i=0;i<OutputProperties.size();i++) {
+        outstream << ", " << OutputProperties[i]->GetName();
+      }
+    }
 
     outstream << endl;
     dFirstPass = false;
@@ -313,6 +321,10 @@ void FGOutput::DelimitedOutput(string fname)
     outstream << Propulsion->GetPropulsionValues();
   }
 
+  for (int i=0;i<OutputProperties.size();i++) {
+    outstream << ", " << OutputProperties[i]->getDoubleValue();
+  }
+
   outstream << endl;
   outstream.flush();
 }
@@ -435,11 +447,20 @@ void FGOutput::SocketStatusOutput(string out_str)
 
 bool FGOutput::Load(FGConfigFile* AC_cfg)
 {
-  string token, parameter;
+  string token="", parameter="", separator="";
+  string name="", fname="";
   int OutRate = 0;
+  FGConfigFile* Output_cfg;
+  string property;
 
-  token = AC_cfg->GetValue("NAME");
-  Output->SetFilename(token);
+# ifndef macintosh
+    separator = "/";
+# else
+    separator = ";";
+# endif
+
+  name = AC_cfg->GetValue("NAME");
+  fname = AC_cfg->GetValue("FILE");
   token = AC_cfg->GetValue("TYPE");
   Output->SetType(token);
 
@@ -448,69 +469,90 @@ bool FGOutput::Load(FGConfigFile* AC_cfg)
     socket = new FGfdmSocket("localhost",1138);
   }
 #endif
-  
-  AC_cfg->GetNextConfigLine();
 
-  while ((token = AC_cfg->GetValue()) != string("/OUTPUT")) {
-    *AC_cfg >> parameter;
-    if (parameter == "RATE_IN_HZ") *AC_cfg >> OutRate;
+  if (!fname.empty()) {
+    outputInFileName = FDMExec->GetAircraftPath() + separator
+                        + FDMExec->GetModelName() + separator + fname + ".xml";
+    Output_cfg = new FGConfigFile(outputInFileName);
+    if (!Output_cfg->IsOpen()) {
+      cerr << "Could not open file: " << outputInFileName << endl;
+      return false;
+    }
+  } else {
+    Output_cfg = AC_cfg;
+  }
+  Output->SetFilename(name);
+
+  while ((token = Output_cfg->GetValue()) != string("/OUTPUT")) {
+    *Output_cfg >> parameter;
+    if (parameter == "RATE_IN_HZ") {
+      *Output_cfg >> OutRate;
+    }
     if (parameter == "SIMULATION") {
-      *AC_cfg >> parameter;
+      *Output_cfg >> parameter;
       if (parameter == "ON") SubSystems += ssSimulation;
     }
     if (parameter == "AEROSURFACES") {
-      *AC_cfg >> parameter;
+      *Output_cfg >> parameter;
       if (parameter == "ON") SubSystems += ssAerosurfaces;
     }
     if (parameter == "RATES") {
-      *AC_cfg >> parameter;
+      *Output_cfg >> parameter;
       if (parameter == "ON") SubSystems += ssRates;
     }
     if (parameter == "VELOCITIES") {
-      *AC_cfg >> parameter;
+      *Output_cfg >> parameter;
       if (parameter == "ON") SubSystems += ssVelocities;
     }
     if (parameter == "FORCES") {
-      *AC_cfg >> parameter;
+      *Output_cfg >> parameter;
       if (parameter == "ON") SubSystems += ssForces;
     }
     if (parameter == "MOMENTS") {
-      *AC_cfg >> parameter;
+      *Output_cfg >> parameter;
       if (parameter == "ON") SubSystems += ssMoments;
     }
     if (parameter == "ATMOSPHERE") {
-      *AC_cfg >> parameter;
+      *Output_cfg >> parameter;
       if (parameter == "ON") SubSystems += ssAtmosphere;
     }
     if (parameter == "MASSPROPS") {
-      *AC_cfg >> parameter;
+      *Output_cfg >> parameter;
       if (parameter == "ON") SubSystems += ssMassProps;
     }
     if (parameter == "POSITION") {
-      *AC_cfg >> parameter;
+      *Output_cfg >> parameter;
       if (parameter == "ON") SubSystems += ssPosition;
     }
     if (parameter == "COEFFICIENTS") {
-      *AC_cfg >> parameter;
+      *Output_cfg >> parameter;
       if (parameter == "ON") SubSystems += ssCoefficients;
     }
     if (parameter == "GROUND_REACTIONS") {
-      *AC_cfg >> parameter;
+      *Output_cfg >> parameter;
       if (parameter == "ON") SubSystems += ssGroundReactions;
     }
     if (parameter == "FCS") {
-      *AC_cfg >> parameter;
+      *Output_cfg >> parameter;
       if (parameter == "ON") SubSystems += ssFCS;
     }
     if (parameter == "PROPULSION") {
-      *AC_cfg >> parameter;
+      *Output_cfg >> parameter;
       if (parameter == "ON") SubSystems += ssPropulsion;
     }
+    if (parameter == "PROPERTY") {
+      *Output_cfg >> property;
+      OutputProperties.push_back(PropertyManager->GetNode(property));
+    }
+
+    if (Output_cfg->GetNextConfigLine() == "EOF") break;
   }
 
   OutRate = OutRate>120?120:(OutRate<0?0:OutRate);
   rate = (int)(0.5 + 1.0/(State->Getdt()*OutRate));
 
+  Debug(2);
+
   return true;
 }
 
@@ -535,12 +577,33 @@ bool FGOutput::Load(FGConfigFile* AC_cfg)
 
 void FGOutput::Debug(int from)
 {
+  string scratch="";
+
   if (debug_lvl <= 0) return;
 
   if (debug_lvl & 1) { // Standard console startup message output
     if (from == 0) { // Constructor
 
     }
+    if (from == 2) {
+      if (outputInFileName.empty())
+        cout << "  " << "Output parameters read inline" << endl;
+      else
+        cout << "    Output parameters read from file: " << outputInFileName << endl;
+      if (Filename == "cout" || Filename == "COUT") {
+        scratch = "    Log output goes to screen console";
+      } else if (!Filename.empty()) {
+        scratch = "    Log output goes to file: " + Filename;
+      }
+      switch (Type) {
+      case otCSV:
+        cout << scratch << " in CSV format output at rate " << 120/rate << " Hz" << endl;
+        break;
+      case otNone:
+        cout << "  No log output" << endl;
+        break;
+      }
+    }
   }
   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
     if (from == 0) cout << "Instantiated: FGOutput" << endl;
index 37bf06c4cafe4d8de4a438bda3502db3d6cc385c..83b0d7c88c6f7b3cdff0ac9253d6935f2d39be00 100644 (file)
@@ -103,10 +103,11 @@ public:
 private:
   bool sFirstPass, dFirstPass, enabled;
   int SubSystems;
-  string Filename;
+  string Filename, outputInFileName;
   enum {otNone, otCSV, otTab, otSocket, otTerminal, otUnknown} Type;
   ofstream datafile;
   FGfdmSocket* socket;
+  vector <FGPropertyManager*> OutputProperties;
   void Debug(int from);
 };
 }
index f40972fa21e3b8950ba9a228bf709d62d13a92c1..405882a8af282cd7e94c1ddc8ddff18735289a66 100644 (file)
@@ -237,6 +237,8 @@ bool FGPropulsion::Load(FGConfigFile* AC_cfg)
           Engines.push_back(new FGPiston(FDMExec, &Eng_cfg));
         } else if (engType == "FG_TURBINE") {
           Engines.push_back(new FGTurbine(FDMExec, &Eng_cfg));
+        } else if (engType == "FG_SIMTURBINE") {
+          Engines.push_back(new FGSimTurbine(FDMExec, &Eng_cfg));
         } else {
           cerr << fgred << "    Unrecognized engine type: " << underon << engType
                     << underoff << " found in config file." << fgdef << endl;
@@ -379,6 +381,8 @@ string FGPropulsion::GetPropulsionStrings(void)
       break;
     case FGEngine::etTurbine:
       break;
+    case FGEngine::etSimTurbine:
+      break;
     default:
       PropulsionStrings += "INVALID ENGINE TYPE";
       break;
@@ -433,6 +437,8 @@ string FGPropulsion::GetPropulsionValues(void)
       break;
     case FGEngine::etTurbine:
       break;
+    case FGEngine::etSimTurbine:
+      break;
     }
 
     PropulsionValues += ", ";
index 2e8e803a73b60d1be9f58284aa313d8e7810e575..92b0c64ebd716c2de6cbb54fd8323a90790466dd 100644 (file)
@@ -57,6 +57,7 @@ INCLUDES
 #include "FGRocket.h"
 #include "FGPiston.h"
 #include "FGTurbine.h"
+#include "FGSimTurbine.h"
 #include "FGTank.h"
 #include "FGPropeller.h"
 #include "FGNozzle.h"
diff --git a/src/FDM/JSBSim/FGSimTurbine.cpp b/src/FDM/JSBSim/FGSimTurbine.cpp
new file mode 100644 (file)
index 0000000..e47dc22
--- /dev/null
@@ -0,0 +1,265 @@
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Module:       FGSimTurbine.cpp
+ Author:       David Culp
+ Date started: 03/11/2003
+ Purpose:      This module models a turbine engine.
+
+ ------------- Copyright (C) 2003  David Culp (davidculp2@attbi.com) -----------
+
+ This program is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any later
+ version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ Place - Suite 330, Boston, MA  02111-1307, USA.
+
+ Further information about the GNU General Public License can also be found on
+ the world wide web at http://www.gnu.org.
+
+FUNCTIONAL DESCRIPTION
+--------------------------------------------------------------------------------
+
+This class descends from the FGEngine class and models a Turbine engine based
+on parameters given in the engine config file for this class
+
+HISTORY
+--------------------------------------------------------------------------------
+03/11/2003  DPC  Created
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+INCLUDES
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#include <vector>
+#include "FGSimTurbine.h"
+
+namespace JSBSim {
+
+static const char *IdSrc = "$Id$";
+static const char *IdHdr = ID_SIMTURBINE;
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS IMPLEMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+
+FGSimTurbine::FGSimTurbine(FGFDMExec* exec, FGConfigFile* cfg) : FGEngine(exec)
+{
+  SetDefaults();
+  FGEngine::Type=etSimTurbine;
+  Load(cfg);
+  Debug(0);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+FGSimTurbine::~FGSimTurbine()
+{
+  Debug(1);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+double FGSimTurbine::Calculate(double dummy)
+{
+  double idlethrust, milthrust, thrust;
+  double TAT = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556;
+  dt = State->Getdt() * Propulsion->GetRate();
+
+  // calculate virtual throttle position (actual +/- lag) based on
+  // FCS Throttle value (except when trimming)
+  if (dt > 0.0) {
+    ThrottleCmd = FCS->GetThrottleCmd(EngineNumber);
+    if ( ThrottleCmd > throttle ) {
+      throttle += (dt * delay);
+      if (throttle > ThrottleCmd ) throttle = ThrottleCmd;
+      }
+    else {
+      throttle -= (dt * delay * 3.0);
+      if (throttle < ThrottleCmd ) throttle = ThrottleCmd;
+      }
+    }
+  else {
+    throttle = ThrottleCmd = FCS->GetThrottleCmd(EngineNumber);
+    }
+    
+  idlethrust = MaxMilThrust * ThrustTables[0]->TotalValue();
+  milthrust = MaxMilThrust * ThrustTables[1]->TotalValue();
+
+  if (!Starved) {
+    thrust = milthrust * throttle * throttle;
+    if (thrust < idlethrust) thrust = idlethrust;
+    FuelFlow_pph = thrust * TSFC;
+    thrust = thrust * (1.0 - BleedDemand);
+    IdleFF = pow(MaxMilThrust, 0.2) * 107.0;
+    if (FuelFlow_pph < IdleFF) FuelFlow_pph = IdleFF;
+    N1 = IdleN1 + throttle * N1_factor;
+    N2 = IdleN2 + throttle * N2_factor;
+    EGT_degC = TAT + 363.1 + ThrottleCmd * 357.1;
+    OilPressure_psi = N2 * 0.62;
+    OilTemp_degK += dt * 1.2;
+    if (OilTemp_degK > 366.0) OilTemp_degK = 366.0;
+    EPR = 1.0 + thrust/MaxMilThrust;
+    NozzlePosition = 1.0 - throttle;
+    if (Reversed) thrust = thrust * -0.2;
+    }
+  else {
+    thrust = 0.0;
+    FuelFlow_pph = 0.0;
+    N1 -= (dt * 3.0);
+    if (N1 < (Translation->Getqbar()/10.0)) N1 = Translation->Getqbar()/10.0;
+    N2 -= (dt * 3.5);
+    if (N2 < (Translation->Getqbar()/15.0)) N2 = Translation->Getqbar()/15.0;
+    EGT_degC -= (dt * 11.7);
+    if (EGT_degC < TAT) EGT_degC = TAT;
+    OilPressure_psi = N2 * 0.62;
+    OilTemp_degK -= (dt * 0.2);
+    if (OilTemp_degK < (TAT + 273.0)) OilTemp_degK = (TAT + 273.0);
+    EPR = 1.0;
+    }
+
+  if (AugMethod == 1) {
+    if (throttle > 0.99) {Augmentation = true;} 
+      else {Augmentation = false;}
+    }
+
+  if ((Augmented == 1) && Augmentation) {
+    thrust = thrust * ThrustTables[2]->TotalValue();
+    FuelFlow_pph = thrust * ATSFC;
+    NozzlePosition = 1.0;
+    }
+
+  if ((Injected == 1) && Injection)
+    thrust = thrust * ThrustTables[3]->TotalValue();  
+  
+  ConsumeFuel();
+  
+  return Thrust = thrust;
+  
+}
+        
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+double FGSimTurbine::CalcFuelNeed(void)
+{
+  return FuelFlow_pph /3600 * State->Getdt() * Propulsion->GetRate();
+}
+
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGSimTurbine::SetDefaults(void)
+{
+  Name = "None_Defined";
+  MaxMilThrust = 10000.0;
+  BypassRatio = 0.0;
+  TSFC = 0.8;
+  ATSFC = 1.7;
+  IdleN1 = 30.0;
+  IdleN2 = 60.0;
+  MaxN1 = 100.0;
+  MaxN2 = 100.0;
+  Augmented = 0;
+  AugMethod = 0;
+  Injected = 0;
+  BleedDemand = 0.0;
+  throttle = 0.0;
+  InletPosition = 1.0;
+  NozzlePosition = 1.0;
+  Augmentation = false;
+  Injection = false;
+  Reversed = false;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+bool FGSimTurbine::Load(FGConfigFile *Eng_cfg)
+{
+  int i;
+  string token;
+  Name = Eng_cfg->GetValue("NAME");
+  cout << Name << endl;
+  Eng_cfg->GetNextConfigLine();
+  *Eng_cfg >> token >> MaxMilThrust;
+  *Eng_cfg >> token >> BypassRatio;
+  *Eng_cfg >> token >> TSFC;
+  *Eng_cfg >> token >> ATSFC;
+  *Eng_cfg >> token >> IdleN1;
+  *Eng_cfg >> token >> IdleN2;
+  *Eng_cfg >> token >> MaxN1;
+  *Eng_cfg >> token >> MaxN2;
+  *Eng_cfg >> token >> Augmented;
+  *Eng_cfg >> token >> AugMethod;
+  *Eng_cfg >> token >> Injected;
+  i=0;
+  while( Eng_cfg->GetValue() != string("/FG_SIMTURBINE") && i < 10){
+    ThrustTables.push_back( new FGCoefficient(FDMExec) );
+    ThrustTables.back()->Load(Eng_cfg);
+    i++;
+  }
+  
+  // pre-calculations and initializations
+  delay= 1.0 / (BypassRatio + 3.0);
+  N1_factor = MaxN1 - IdleN1;
+  N2_factor = MaxN2 - IdleN2;
+  OilTemp_degK = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556 + 273.0;
+  IdleFF = pow(MaxMilThrust, 0.2) * 107.0;  // just an estimate
+  AddFeedTank(EngineNumber);   // engine[n] feeds from tank[n]
+  return true;
+}
+
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+//    The bitmasked value choices are as follows:
+//    unset: In this case (the default) JSBSim would only print
+//       out the normally expected messages, essentially echoing
+//       the config files as they are read. If the environment
+//       variable is not set, debug_lvl is set to 1 internally
+//    0: This requests JSBSim not to output any messages
+//       whatsoever.
+//    1: This value explicity requests the normal JSBSim
+//       startup messages
+//    2: This value asks for a message to be printed out when
+//       a class is instantiated
+//    4: When this value is set, a message is displayed when a
+//       FGModel object executes its Run() method
+//    8: When this value is set, various runtime state variables
+//       are printed out periodically
+//    16: When set various parameters are sanity checked and
+//       a message is printed out when they go out of bounds
+
+void FGSimTurbine::Debug(int from)
+{
+  if (debug_lvl <= 0) return;
+
+  if (debug_lvl & 1) { // Standard console startup message output
+    if (from == 0) { // Constructor
+
+    }
+  }
+  if (debug_lvl & 2 ) { // Instantiation/Destruction notification
+    if (from == 0) cout << "Instantiated: FGSimTurbine" << endl;
+    if (from == 1) cout << "Destroyed:    FGSimTurbine" << endl;
+  }
+  if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
+  }
+  if (debug_lvl & 8 ) { // Runtime state variables
+  }
+  if (debug_lvl & 16) { // Sanity checking
+  }
+  if (debug_lvl & 64) {
+    if (from == 0) { // Constructor
+      cout << IdSrc << endl;
+      cout << IdHdr << endl;
+    }
+  }
+}
+}
diff --git a/src/FDM/JSBSim/FGSimTurbine.h b/src/FDM/JSBSim/FGSimTurbine.h
new file mode 100644 (file)
index 0000000..76e7962
--- /dev/null
@@ -0,0 +1,100 @@
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Header:       FGSimTurbine.h
+ Author:       David Culp
+ Date started: 03/11/2003
+
+ ------------- Copyright (C) 2003  David Culp (davidculp2@attbi.com)------------
+
+ This program is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any later
+ version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ Place - Suite 330, Boston, MA  02111-1307, USA.
+
+ Further information about the GNU General Public License can also be found on
+ the world wide web at http://www.gnu.org.
+
+HISTORY
+--------------------------------------------------------------------------------
+03/11/2003  DPC  Created
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+COMMENTS, REFERENCES,  and NOTES
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+SENTRY
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#ifndef FGSIMTURBINE_H
+#define FGSIMTURBINE_H
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+INCLUDES
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#include <vector>
+#include "FGEngine.h"
+#include "FGConfigFile.h"
+#include "FGCoefficient.h"
+
+#define ID_SIMTURBINE "$Id$"
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DECLARATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+namespace JSBSim {
+
+class FGSimTurbine : public FGEngine
+{
+public:
+  FGSimTurbine(FGFDMExec* exec, FGConfigFile* Eng_cfg);
+  ~FGSimTurbine();
+
+  double Calculate(double);
+  double CalcFuelNeed(void);
+  
+private:
+
+  typedef vector<FGCoefficient*> CoeffArray;
+  CoeffArray ThrustTables;
+
+  double MaxMilThrust;     // Maximum Rated Thrust, static @ S.L. (lbf)
+  double BypassRatio;      // Bypass Ratio
+  double TSFC;             // Thrust Specific Fuel Consumption (lbm/hr/lbf)
+  double ATSFC;            // Augmented TSFC (lbm/hr/lbf)
+  double IdleN1;           // Idle N1
+  double IdleN2;           // Idle N2
+  double MaxN1;            // N1 at 100% throttle
+  double MaxN2;            // N2 at 100% throttle
+  double IdleFF;           // Idle Fuel Flow (lbm/hr)
+  double delay;            // Inverse spool-up time from idle to 100% (seconds)
+  double dt;               // Simulator time slice
+  double N1_factor;        // factor to tie N1 and throttle
+  double N2_factor;        // factor to tie N2 and throttle
+  double ThrottleCmd;      // FCS-supplied throttle position
+  double throttle;         // virtual throttle position
+  int Augmented;           // = 1 if augmentation installed
+  int Injected;            // = 1 if water injection installed
+  int AugMethod;           // = 0 if using property /engine[n]/augmentation
+                           // = 1 if using last 1% of throttle movement
+
+  void SetDefaults(void);
+  bool Load(FGConfigFile *ENG_cfg);
+  void Debug(int from);
+
+};
+}
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+#endif
+
index 814857e67c80c408d6c4801c2ad4dbdf00197207..cd2e9ee52a039ffe8c7e1b1e7c93db31c0906a47 100644 (file)
@@ -89,93 +89,35 @@ public:
   FGTranslation(FGFDMExec*);
   ~FGTranslation();
   
-    /** Bound Properties
-        GetUVW(1): velocities/u-fps
-        GetUVW(2): velocities/v-fps
-        GetUVW(3): velocities/w-fps
-    */
   inline double           GetUVW   (int idx) const { return vUVW(idx); }
   inline FGColumnVector3& GetUVW   (void)    { return vUVW; }
   inline FGColumnVector3& GetUVWdot(void)    { return vUVWdot; }
-    /** Bound Properties
-        GetUVWdot(1): accelerations/udot-fps
-        GetUVWdot(2): accelerations/vdot-fps
-        GetUVWdot(3): accelerations/wdot-fps
-    */
   inline double           GetUVWdot(int idx) const { return vUVWdot(idx); }
   inline FGColumnVector3& GetAeroUVW (void)    { return vAeroUVW; }
-    /** Bound Properties
-        GetAeroUVW(1): velocities/u-aero-fps
-        GetAeroUVW(2): velocities/v-aero-fps
-        GetAeroUVW(3): velocities/w-aero-fps
-    */
   inline double           GetAeroUVW (int idx) const { return vAeroUVW(idx); }
 
-    /** Bound Property:  aero/alpha-rad
-    */
   double Getalpha(void) const { return alpha; }
-    /** Bound Property:  aero/beta-rad
-    */
   double Getbeta (void) const { return beta; }
-    /** Bound Property:  aero/mag-beta-rad
-    */
   inline double GetMagBeta(void) const { return fabs(beta); }
-    /** Bound Property:  aero/qbar-psf
-    */
   double Getqbar (void) const { return qbar; }
-    /** Bound Property:  aero/qbarUW-psf
-    */
   double GetqbarUW (void) const { return qbarUW; }
-    /** Bound Property:  aero/qbarUV-psf
-    */
   double GetqbarUV (void) const { return qbarUV; }
-    /** Bound Property:  velocities/vt-fps
-    */
   inline double GetVt   (void) const { return Vt; }
-    /** Bound Property:  velocities/mach-norm
-    */
   double GetMach (void) const { return Mach; }
-    /** Bound Property:  aero/alphadot-rad_sec
-    */
   double Getadot (void) const { return adot; }
-    /** Bound Property:  aero/betadot-rad_sec
-    */
   double Getbdot (void) const { return bdot; }
 
-    /** Bound Properties
-        SetUVW(1): velocities/u-fps
-        SetUVW(2): velocities/v-fps
-        SetUVW(3): velocities/w-fps
-    */
   void SetUVW(FGColumnVector3 tt) { vUVW = tt; }
   void SetAeroUVW(FGColumnVector3 tt) { vAeroUVW = tt; }
 
-    /** Bound Property:  aero/alpha-rad
-    */
   inline void Setalpha(double tt) { alpha = tt; }
-    /** Bound Property:  aero/beta-rad
-    */
   inline void Setbeta (double tt) { beta  = tt; }
-    /** Bound Property:  aero/qbar-psf
-    */
   inline void Setqbar (double tt) { qbar = tt; }
-    /** Bound Property:  aero/qbarUW-psf
-    */
   inline void SetqbarUW (double tt) { qbarUW = tt; }
-    /** Bound Property:  aero/qbarUV-psf
-    */
   inline void SetqbarUV (double tt) { qbarUV = tt; }
-    /** Bound Property:  velocities/vt-fps
-    */
   inline void SetVt   (double tt) { Vt = tt; }
-    /** Bound Property:  velocities/mach-norm
-    */
   inline void SetMach (double tt) { Mach=tt; }
-    /** Bound Property:  aero/alphadot-rad_sec
-    */
   inline void Setadot (double tt) { adot = tt; }
-    /** Bound Property:  aero/betadot-rad_sec
-    */
   inline void Setbdot (double tt) { bdot = tt; }
 
   inline void SetAB(double t1, double t2) { alpha=t1; beta=t2; }
index d8e245fc32aa98d5e3ad08cd50d97c9406cd1cf6..f944ad79bc6dafed1c412892f8a8110f3afe2154 100644 (file)
@@ -48,6 +48,7 @@ libJSBSim_a_SOURCES = \
        FGfdmSocket.cpp FGfdmSocket.h \
   FGTurbine.cpp FGTurbine.h \
   FGPropertyManager.cpp FGPropertyManager.h  \
+  FGSimTurbine.cpp FGSimTurbine.h \
        JSBSim.cxx JSBSim.hxx