]> git.mxchange.org Git - flightgear.git/blobdiff - src/FDM/JSBSim/models/propulsion/FGTurbine.cpp
Merge branch 'next' of gitorious.org:fg/flightgear into next
[flightgear.git] / src / FDM / JSBSim / models / propulsion / FGTurbine.cpp
index d751654a03e7ba68a4f231e78bdc853321878456..b5712ad26b069c663a9396139dd7a0b5b5951086 100644 (file)
@@ -39,14 +39,17 @@ HISTORY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <vector>
+#include <iostream>
 #include <sstream>
 
 #include "FGTurbine.h"
+#include "FGThruster.h"
+
+using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id$";
+static const char *IdSrc = "$Id: FGTurbine.cpp,v 1.36 2011/09/25 23:56:11 jentron Exp $";
 static const char *IdHdr = ID_TURBINE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -54,8 +57,8 @@ CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 
-FGTurbine::FGTurbine(FGFDMExec* exec, Element *el, int engine_number)
-  : FGEngine(exec, el, engine_number)
+FGTurbine::FGTurbine(FGFDMExec* exec, Element *el, int engine_number, struct Inputs& input)
+  : FGEngine(exec, el, engine_number, input)
 {
   Type = etTurbine;
 
@@ -69,6 +72,7 @@ FGTurbine::FGTurbine(FGFDMExec* exec, Element *el, int engine_number)
   BypassRatio = BleedDemand = 0.0;
   IdleThrustLookup = MilThrustLookup = MaxThrustLookup = InjectionLookup = 0;
   N1_spinup = 1.0; N2_spinup = 3.0; 
+  EPR = 1.0;
 
   ResetToIC();
 
@@ -91,28 +95,35 @@ FGTurbine::~FGTurbine()
 
 void FGTurbine::ResetToIC(void)
 {
+    
+  FGEngine::ResetToIC();
+    
   N1 = N2 = 0.0;
+  N2norm = 0.0;
   correctedTSFC = TSFC;
-  ThrottlePos = AugmentCmd = 0.0;
+  AugmentCmd = 0.0;
   InletPosition = NozzlePosition = 1.0;
   Stalled = Seized = Overtemp = Fire = Augmentation = Injection = Reversed = false;
   Cutoff = true;
   phase = tpOff;
-  EGT_degC = 0.0;
-  OilTemp_degK = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556 + 273.0;
+  TAT = (in.TotalTempearture - 491.69) * 0.5555556;
+  EGT_degC = TAT;
+  OilTemp_degK = TAT + 273.0;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 // The main purpose of Calculate() is to determine what phase the engine should
 // be in, then call the corresponding function.
 
-double FGTurbine::Calculate(void)
+void FGTurbine::Calculate(void)
 {
   double thrust;
 
-  TAT = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556;
-  dt = State->Getdt() * Propulsion->GetRate();
-  ThrottlePos = FCS->GetThrottlePos(EngineNumber);
+  RunPreFunctions();
+
+  ThrottlePos = in.ThrottlePos[EngineNumber];
+
+  TAT = (in.TotalTempearture - 491.69) * 0.5555556;
   if (ThrottlePos > 1.0) {
     AugmentCmd = ThrottlePos - 1.0;
     ThrottlePos -= AugmentCmd;
@@ -121,7 +132,7 @@ double FGTurbine::Calculate(void)
   }
 
   // When trimming is finished check if user wants engine OFF or RUNNING
-  if ((phase == tpTrim) && (dt > 0)) {
+  if ((phase == tpTrim) && (in.TotalDeltaT > 0)) {
     if (Running && !Starved) {
       phase = tpRun;
       N2 = IdleN2 + ThrottlePos * N2_factor;
@@ -138,10 +149,15 @@ double FGTurbine::Calculate(void)
 
   if (!Running && Cutoff && Starter) {
      if (phase == tpOff) phase = tpSpinUp;
-     }
-  if (!Running && !Cutoff && (N2 > 15.0)) phase = tpStart;
+  }
+
+  // start
+  if ((Starter == true) || (in.qbar > 30.0)) {
+    if (!Running && !Cutoff && (N2 > 15.0)) phase = tpStart;
+  }
+
   if (Cutoff && (phase != tpSpinUp)) phase = tpOff;
-  if (dt == 0) phase = tpTrim;
+  if (in.TotalDeltaT == 0) phase = tpTrim;
   if (Starved) phase = tpOff;
   if (Stalled) phase = tpStall;
   if (Seized) phase = tpSeize;
@@ -157,27 +173,25 @@ double FGTurbine::Calculate(void)
     default: thrust = Off();
   }
 
-  thrust = Thruster->Calculate(thrust); // allow thruster to modify thrust (i.e. reversing)
+  Thruster->Calculate(thrust); // allow thruster to modify thrust (i.e. reversing)
 
-  return thrust;
+  RunPostFunctions();
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 double FGTurbine::Off(void)
 {
-  double qbar = Auxiliary->Getqbar();
   Running = false;
   FuelFlow_pph = Seek(&FuelFlow_pph, 0, 1000.0, 10000.0);
-  N1 = Seek(&N1, qbar/10.0, N1/2.0, N1/2.0);
-  N2 = Seek(&N2, qbar/15.0, N2/2.0, N2/2.0);
+  N1 = Seek(&N1, in.qbar/10.0, N1/2.0, N1/2.0);
+  N2 = Seek(&N2, in.qbar/15.0, N2/2.0, N2/2.0);
   EGT_degC = Seek(&EGT_degC, TAT, 11.7, 7.3);
   OilTemp_degK = Seek(&OilTemp_degK, TAT + 273.0, 0.2, 0.2);
   OilPressure_psi = N2 * 0.62;
   NozzlePosition = Seek(&NozzlePosition, 1.0, 0.8, 0.8);
   EPR = Seek(&EPR, 1.0, 0.2, 0.2);
   Augmentation = false;
-  ConsumeFuel();  
   return 0.0;
 }
 
@@ -186,7 +200,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 = in.DensityRatio;
+  double T = in.Temperature;
 
   idlethrust = MilThrust * IdleThrustLookup->GetValue();
   milthrust = (MilThrust - idlethrust) * MilThrustLookup->GetValue();
@@ -194,8 +210,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,8 +224,8 @@ double FGTurbine::Run()
   OilTemp_degK = Seek(&OilTemp_degK, 366.0, 1.2, 0.1);
 
   if (!Augmentation) {
-    correctedTSFC = TSFC * (0.84 + (1-N2norm)*(1-N2norm));
-    FuelFlow_pph = Seek(&FuelFlow_pph, thrust * correctedTSFC, 1000.0, 100000);
+    correctedTSFC = TSFC * sqrt(T/389.7) * (0.84 + (1-N2norm)*(1-N2norm));
+    FuelFlow_pph = Seek(&FuelFlow_pph, thrust * correctedTSFC, 1000.0, 10000.0);
     if (FuelFlow_pph < IdleFF) FuelFlow_pph = IdleFF;
     NozzlePosition = Seek(&NozzlePosition, 1.0 - N2norm, 0.8, 0.8);
     thrust = thrust * (1.0 - BleedDemand);
@@ -235,7 +256,7 @@ double FGTurbine::Run()
   }
 
   if ((Injected == 1) && Injection) {
-    InjectionTimer += dt;
+    InjectionTimer += in.TotalDeltaT;
     if (InjectionTimer < InjectionTime) {
        thrust = thrust * InjectionLookup->GetValue();
     } else {
@@ -243,7 +264,6 @@ double FGTurbine::Run()
     }
   }
 
-  ConsumeFuel();
   if (Cutoff) phase = tpOff;
   if (Starved) phase = tpOff;
 
@@ -263,6 +283,7 @@ double FGTurbine::SpinUp(void)
   OilTemp_degK = Seek(&OilTemp_degK, TAT + 273.0, 0.2, 0.2);
   EPR = 1.0;
   NozzlePosition = 1.0;
+  if (Starter == false) phase = tpOff;
   return 0.0;
 }
 
@@ -276,9 +297,9 @@ double FGTurbine::Start(void)
       N2 = Seek(&N2, IdleN2, 2.0, N2/2.0);
       N1 = Seek(&N1, IdleN1, 1.4, N1/2.0);
       EGT_degC = Seek(&EGT_degC, TAT + 363.1, 21.3, 7.3);
-      FuelFlow_pph = Seek(&FuelFlow_pph, IdleFF, 103.7, 103.7);
+      FuelFlow_pph = IdleFF * N2 / IdleN2;
       OilPressure_psi = N2 * 0.62;
-      ConsumeFuel();
+      if ((Starter == false) && (in.qbar < 30.0)) phase = tpOff; // aborted start
       }
     else {
       phase = tpRun;
@@ -299,14 +320,14 @@ double FGTurbine::Start(void)
 
 double FGTurbine::Stall(void)
 {
-  double qbar = Auxiliary->Getqbar();
   EGT_degC = TAT + 903.14;
   FuelFlow_pph = IdleFF;
-  N1 = Seek(&N1, qbar/10.0, 0, N1/10.0);
-  N2 = Seek(&N2, qbar/15.0, 0, N2/10.0);
-  ConsumeFuel();
-  if (ThrottlePos < 0.01) phase = tpRun;        // clear the stall with throttle
-
+  N1 = Seek(&N1, in.qbar/10.0, 0, N1/10.0);
+  N2 = Seek(&N2, in.qbar/15.0, 0, N2/10.0);
+  if (ThrottlePos < 0.01) {
+    phase = tpRun;               // clear the stall with throttle to idle
+    Stalled = false;
+    }
   return 0.0;
 }
 
@@ -314,11 +335,9 @@ double FGTurbine::Stall(void)
 
 double FGTurbine::Seize(void)
 {
-    double qbar = Auxiliary->Getqbar();
     N2 = 0.0;
-    N1 = Seek(&N1, qbar/20.0, 0, N1/15.0);
-    FuelFlow_pph = IdleFF;
-    ConsumeFuel();
+    N1 = Seek(&N1, in.qbar/20.0, 0, N1/15.0);
+    FuelFlow_pph = Cutoff ? 0.0 : IdleFF;
     OilPressure_psi = 0.0;
     OilTemp_degK = Seek(&OilTemp_degK, TAT + 273.0, 0, 0.2);
     Running = false;
@@ -329,7 +348,7 @@ double FGTurbine::Seize(void)
 
 double FGTurbine::Trim()
 {
-    double idlethrust, milthrust, thrust, tdiff, N2norm;
+    double idlethrust, milthrust, thrust, tdiff, N2, N2norm;
     idlethrust = MilThrust * IdleThrustLookup->GetValue();
     milthrust = (MilThrust - idlethrust) * MilThrustLookup->GetValue();
     N2 = IdleN2 + ThrottlePos * N2_factor;
@@ -364,9 +383,9 @@ double FGTurbine::Trim()
 
 double FGTurbine::CalcFuelNeed(void)
 {
-  double dT = State->Getdt() * Propulsion->GetRate();
   FuelFlowRate = FuelFlow_pph / 3600.0; // Calculates flow in lbs/sec from lbs/hr
-  FuelExpended = FuelFlowRate * dT;     // Calculates fuel expended in this time step
+  FuelExpended = FuelFlowRate * in.TotalDeltaT;     // Calculates fuel expended in this time step
+  if (!Starved) FuelUsedLbs += FuelExpended; 
   return FuelExpended;
 }
 
@@ -384,10 +403,10 @@ double FGTurbine::GetPowerAvailable(void) {
 double FGTurbine::Seek(double *var, double target, double accel, double decel) {
   double v = *var;
   if (v > target) {
-    v -= dt * decel;
+    v -= in.TotalDeltaT * decel;
     if (v < target) v = target;
   } else if (v < target) {
-    v += dt * accel;
+    v += in.TotalDeltaT * accel;
     if (v > target) v = target;
   }
   return v;
@@ -449,18 +468,15 @@ bool FGTurbine::Load(FGFDMExec* exec, Element *el)
       MaxThrustLookup = new FGFunction(PropertyManager, function_element, property_prefix);
     } else if (name == "Injection") {
       InjectionLookup = new FGFunction(PropertyManager, function_element, property_prefix);
-    } else {
-      cerr << "Unknown function type: " << name << " in turbine definition." <<
-      endl;
     }
   }
 
   // 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;
+  OilTemp_degK = (in.TotalTempearture - 491.69) * 0.5555556 + 273.0;
   IdleFF = pow(MilThrust, 0.2) * 107.0;  // just an estimate
 
   bindmodel();
@@ -469,26 +485,26 @@ bool FGTurbine::Load(FGFDMExec* exec, Element *el)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-string FGTurbine::GetEngineLabels(string delimeter)
+string FGTurbine::GetEngineLabels(const string& delimiter)
 {
   std::ostringstream buf;
 
-  buf << Name << "_N1[" << EngineNumber << "]" << delimeter
-      << Name << "_N2[" << EngineNumber << "]" << delimeter
-      << Thruster->GetThrusterLabels(EngineNumber, delimeter);
+  buf << Name << "_N1[" << EngineNumber << "]" << delimiter
+      << Name << "_N2[" << EngineNumber << "]" << delimiter
+      << Thruster->GetThrusterLabels(EngineNumber, delimiter);
 
   return buf.str();
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-string FGTurbine::GetEngineValues(string delimeter)
+string FGTurbine::GetEngineValues(const string& delimiter)
 {
   std::ostringstream buf;
 
-  buf << N1 << delimeter
-      << N2 << delimeter
-      << Thruster->GetThrusterValues(EngineNumber, delimeter);
+  buf << N1 << delimiter
+      << N2 << delimiter
+      << Thruster->GetThrusterValues(EngineNumber, delimiter);
 
   return buf.str();
 }
@@ -506,17 +522,24 @@ void FGTurbine::bindmodel()
   property_name = base_property_name + "/injection_cmd";
   PropertyManager->Tie( property_name.c_str(), (FGTurbine*)this, 
                         &FGTurbine::GetInjection, &FGTurbine::SetInjection);
+  property_name = base_property_name + "/seized";
+  PropertyManager->Tie( property_name.c_str(), &Seized);
+  property_name = base_property_name + "/stalled";
+  PropertyManager->Tie( property_name.c_str(), &Stalled);
+  property_name = base_property_name + "/bleed-factor";
+  PropertyManager->Tie( property_name.c_str(), (FGTurbine*)this, &FGTurbine::GetBleedDemand, &FGTurbine::SetBleedDemand);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-int FGTurbine::InitRunning(void) {
-  State->SuspendIntegration();
+int FGTurbine::InitRunning(void)
+{
+  FDMExec->SuspendIntegration();
   Cutoff=false;
   Running=true;  
-  N2=16.0;
+  N2=IdleN2;
   Calculate();
-  State->ResumeIntegration();
+  FDMExec->ResumeIntegration();
   return phase==tpRun;
 }