1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 
3  Header:       FGTurbine.h
4  Author:       David Culp
5  Date started: 03/11/2003
6 
7  ------------- Copyright (C) 2003  David Culp (daveculp@cox.net)----------
8 
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13 
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
17  details.
18 
19  You should have received a copy of the GNU Lesser General Public License along with
20  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21  Place - Suite 330, Boston, MA  02111-1307, USA.
22 
23  Further information about the GNU Lesser General Public License can also be found on
24  the world wide web at http://www.gnu.org.
25 
26 HISTORY
27 --------------------------------------------------------------------------------
28 03/11/2003  DPC  Created, based on FGTurbine
29 09/22/2003  DPC  Added starting, stopping, new framework
30 04/29/2004  DPC  Renamed from FGSimTurbine to FGTurbine
31 
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33 SENTRY
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
35 
36 #ifndef FGTURBINE_H
37 #define FGTURBINE_H
38 
39 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40 INCLUDES
41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
42 
43 #include "FGEngine.h"
44 
45 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
46 FORWARD DECLARATIONS
47 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
48 
49 namespace JSBSim {
50 
51 class Element;
52 class FGFunction;
53 
54 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
55 CLASS DOCUMENTATION
56 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
57 
58 /** This class models a turbine engine.  Based on Jon Berndt's FGTurbine module.
59     Here the term "phase" signifies the engine's mode of operation.  At any given
60     time the engine is in only one phase.  At simulator startup the engine will be
61     placed in the Trim phase in order to provide a simplified thrust value without
62     throttle lag.  When trimming is complete the engine will go to the Off phase,
63     unless the value FGEngine::Running has been previously set to true, in which
64     case the engine will go to the Run phase.  Once an engine is in the Off phase
65     the full starting procedure (or airstart) must be used to get it running.
66 <P>
67     - STARTING (on ground):
68       -# Set the control FGEngine::Starter to true.  The engine will spin up to
69          a maximum of about %25 N2 (%5.2 N1). This value may be changed using the <startnX> parameter.
70 		 This simulates the action of a pneumatic starter.
71       -# After reaching %15 N2 set the control FGEngine::Cutoff to false. If fuel
72          is available the engine will now accelerate to idle.  The starter will
73          automatically be set to false after the start cycle.
74 <P>
75     - STARTING (in air):
76       -# Increase speed to obtain a minimum of %15 N2.  If this is not possible,
77          the starter may be used to assist.
78       -# Place the control FGEngine::Cutoff to false.
79 <P>
80     Ignition is assumed to be on anytime the Cutoff control is set to false,
81     therefore a separate ignition system is not modeled.
82 
83 <h3>Configuration File Format:</h3>
84 @code
85  <turbine_engine name="{string}">
86   <milthrust unit="{LBS | N}"> {number} </milthrust>
87   <maxthrust unit="{LBS | N}"> {number} </maxthrust>
88   <bypassratio> {number} </bypassratio>
89   <bleed> {number} </bleed>
90   <tsfc> {number} </tsfc>
91   <atsfc> {number} </atsfc>
92   <ignitionn1> {number} </ignitionn1>
93   <ignitionn2> {number} </ignitionn2>
94   <idlen1> {number} </idlen1>
95   <idlen2> {number} </idlen2>
96   <n1spinup> {number} </n1spinup>
97   <n2spinup> {number} </n2spinup>
98   <n1startrate> {number} </n1startrate>
99   <n2startrate> {number} </n2startrate>
100   <n1spindown> {number} </n1spindown>
101   <n2spindown> {number} </n2spindown>
102   <maxn1> {number} </maxn1>
103   <maxn2> {number} </maxn2>
104   <augmented> {0 | 1} </augmented>
105   <augmethod> {0 | 1 | 2} </augmethod>
106   <injected> {0 | 1} </injected>
107   <injection-time> {number} </injection-time>
108   <disable-windmill> {0 | 1}</disable-windmill>
109  </turbine_engine>
110 @endcode
111 
112 <h3>Definition of the turbine engine configuration file parameters:</h3>
113 
114 <pre>
115   milthrust   - Maximum thrust, static, at sea level.
116   maxthrust   - Afterburning thrust, static, at sea level.
117   bypassratio - Ratio of bypass air flow to core air flow.
118   bleed       - Thrust reduction factor due to losses (0.0 to 1.0).
119   tsfc        - Thrust-specific fuel consumption at cruise, lbm/hr/lbf
120   atsfc       - Afterburning TSFC, lbm/hr/lbf
121   ignitionn1  - Fan rotor rpm (% of max) while starting
122   ignitionn2  - Core rotor rpm (% of max) while starting
123   idlen1      - Fan rotor rpm (% of max) at idle
124   idlen2      - Core rotor rpm (% of max) at idle
125   n1spinup    - Fan rotor rpm starter acceleration to ignitionn1 value (default 1.0)
126   n2spinup    - Core rotor rpm starter acceleration to ignitionn2 value (default 3.0)
127   n1startrate - Fan rotor rpm time taken to accelerate from ignitionn1 to idlen1 value (default 1.4)
128   n2startrate - Core rotor rpm time taken to accelerate to ignitionn2 idlen2 value (default 2.0)
129   n1spindown  - Factor used in calculation for fan rotor time to spool down to zero (default 2.0)
130   n2spindown  - Factor used in calculation for core rotor time to spool down to zero (default 2.0)
131   maxn1       - Fan rotor rpm (% of max) at full throttle
132   maxn2       - Core rotor rpm (% of max) at full throttle
133   augmented
134               0 = afterburner not installed
135               1 = afterburner installed
136   augmethod
137               0 = afterburner activated by property /engines/engine[n]/augmentation
138               1 = afterburner activated by pushing throttle above 99% position
139               2 = throttle range is expanded in the FCS, and values above 1.0 are afterburner range
140   injected
141               0 = Water injection not installed
142               1 = Water injection installed
143   injection-time - Time, in seconds, of water injection duration
144   InjN1increment - % increase in N1 when injection is taking place
145   InjN2increment - % increase in N2 when injection is taking place
146   disable-windmill - flag that disables engine windmilling when off if true
147 </pre>
148 
149 <h3>NOTES:</h3>
150 <pre>
151     Bypass ratio is used only to estimate engine acceleration time.  The
152     effect of bypass ratio on engine efficiency is already included in
153     the TSFC value.  Feel free to set this parameter (even for turbojets) to
154     whatever value gives a desired spool-up rate. Default value is 0.
155 
156     The bleed factor is multiplied by thrust to give a resulting thrust
157     after losses.  This can represent losses due to bleed, or any other cause.
158     Default value is 0.  A common value would be 0.04.
159 
160     Nozzle position, for variable area exhaust nozzles, is provided for users
161     needing to drive a nozzle gauge or animate a virtual nozzle.
162 
163     This model can only be used with the "direct" thruster.  See the file:
164     /engine/direct.xml
165 </pre>
166     @author David P. Culp
167 */
168 
169 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
170 CLASS DECLARATION
171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
172 
173 class FGTurbine : public FGEngine
174 {
175 public:
176   /** Constructor
177       @param Executive pointer to executive structure
178       @param el pointer to the XML element representing the turbine engine
179       @param engine_number engine number  */
180   FGTurbine(FGFDMExec* Executive, Element *el, int engine_number, struct Inputs& input);
181   /// Destructor
182   ~FGTurbine();
183 
184   enum phaseType { tpOff, tpRun, tpSpinUp, tpStart, tpStall, tpSeize, tpTrim };
185 
186   void Calculate(void);
187   double CalcFuelNeed(void);
188   double GetPowerAvailable(void);
189   /** A lag filter.
190       Used to control the rate at which values are allowed to change.
191       @param var a pointer to a variable of type double
192       @param target the desired (target) value
193       @param accel the rate, per second, the value may increase
194       @param decel the rate, per second, the value may decrease    */
195   double Seek(double* var, double target, double accel, double decel);
196 
GetPhase(void)197   phaseType GetPhase(void) { return phase; }
198 
GetOvertemp(void)199   bool GetOvertemp(void)  const {return Overtemp; }
GetInjection(void)200   bool GetInjection(void) const {return Injection;}
GetFire(void)201   bool GetFire(void) const { return Fire; }
GetAugmentation(void)202   bool GetAugmentation(void) const {return Augmentation;}
GetReversed(void)203   bool GetReversed(void) const { return Reversed; }
GetCutoff(void)204   bool GetCutoff(void) const { return Cutoff; }
GetIgnition(void)205   int GetIgnition(void) const {return Ignition;}
206 
GetInlet(void)207   double GetInlet(void) const { return InletPosition; }
GetNozzle(void)208   double GetNozzle(void) const { return NozzlePosition; }
GetBleedDemand(void)209   double GetBleedDemand(void) const {return BleedDemand;}
GetN1(void)210   double GetN1(void) const {return N1;}
GetN2(void)211   double GetN2(void) const {return N2;}
GetEPR(void)212   double GetEPR(void) const {return EPR;}
GetEGT(void)213   double GetEGT(void) const {return EGT_degC;}
214 
GetMaxN1(void)215   double GetMaxN1(void) const {return MaxN1;}
GetMaxN2(void)216   double GetMaxN2(void) const {return MaxN2;}
getOilPressure_psi()217   double getOilPressure_psi () const {return OilPressure_psi;}
getOilTemp_degF(void)218   double getOilTemp_degF (void) {return KelvinToFahrenheit(OilTemp_degK);}
GetInjectionTimer(void)219   double GetInjectionTimer(void) const {return InjectionTimer;}
GetInjWaterNorm(void)220   double GetInjWaterNorm(void) const {return InjWaterNorm;}
GetInjN1increment(void)221   double GetInjN1increment(void) const {return InjN1increment;}
GetInjN2increment(void)222   double GetInjN2increment(void) const {return InjN2increment;}
223 
SetInjection(bool injection)224   void SetInjection(bool injection) {Injection = injection;}
SetIgnition(int ignition)225   void SetIgnition(int ignition) {Ignition = ignition;}
SetAugmentation(bool augmentation)226   void SetAugmentation(bool augmentation) {Augmentation = augmentation;}
SetPhase(phaseType p)227   void SetPhase( phaseType p ) { phase = p; }
SetEPR(double epr)228   void SetEPR(double epr) {EPR = epr;}
SetBleedDemand(double bleedDemand)229   void SetBleedDemand(double bleedDemand) {BleedDemand = bleedDemand;}
SetReverse(bool reversed)230   void SetReverse(bool reversed) { Reversed = reversed; }
SetCutoff(bool cutoff)231   void SetCutoff(bool cutoff) { Cutoff = cutoff; }
SetMaxN1(double maxn1)232   void SetMaxN1(double maxn1) {MaxN1 = maxn1;}
SetMaxN2(double maxn2)233   void SetMaxN2(double maxn2) {MaxN2 = maxn2;}
SetInjectionTimer(double injtimer)234   void SetInjectionTimer(double injtimer) {InjectionTimer = injtimer;}
SetInjWaterNorm(double injwater)235   void SetInjWaterNorm(double injwater) {InjWaterNorm = injwater;}
SetInjN1increment(double injN1inc)236   void SetInjN1increment(double injN1inc) {InjN1increment = injN1inc;}
SetInjN2increment(double injN2inc)237   void SetInjN2increment(double injN2inc) {InjN2increment = injN2inc;}
238 
239   int InitRunning(void);
240   void ResetToIC(void);
241 
242   std::string GetEngineLabels(const std::string& delimiter);
243   std::string GetEngineValues(const std::string& delimiter);
244 
245 private:
246 
247   phaseType phase;         ///< Operating mode, or "phase"
248   double MilThrust;        ///< Maximum Unaugmented Thrust, static @ S.L. (lbf)
249   double MaxThrust;        ///< Maximum Augmented Thrust, static @ S.L. (lbf)
250   double BypassRatio;      ///< Bypass Ratio
251   double TSFC;             ///< Thrust Specific Fuel Consumption (lbm/hr/lbf)
252   double ATSFC;            ///< Augmented TSFC (lbm/hr/lbf)
253   double IdleN1;           ///< Idle N1
254   double IdleN2;           ///< Idle N2
255   double IgnitionN1;       ///< Ignition N1
256   double IgnitionN2;       ///< Ignition N2
257   double N1;               ///< N1
258   double N2;               ///< N2
259   double N2norm;           ///< N2 normalized (0=idle, 1=max)
260   double MaxN1;            ///< N1 at 100% throttle
261   double MaxN2;            ///< N2 at 100% throttle
262   double IdleFF;           ///< Idle Fuel Flow (lbm/hr)
263   double N1_factor;        ///< factor to tie N1 and throttle
264   double N2_factor;        ///< factor to tie N2 and throttle
265   double ThrottlePos;      ///< FCS-supplied throttle position - modified for local use!
266   double AugmentCmd;       ///< modulated afterburner command (0.0 to 1.0)
267   double N1_spinup;        ///< N1 spin up rate from pneumatic starter (per second)
268   double N2_spinup;        ///< N2 spin up rate from pneumatic starter (per second)
269   double N1_start_rate;    ///< N1 spin up rate from ignition (per second)
270   double N2_start_rate;    ///< N2 spin up rate from ignition (per second)
271   double N1_spindown;      ///< N1 spin down factor
272   double N2_spindown;      ///< N2 spin down factor
273   bool Stalled;            ///< true if engine is compressor-stalled
274   bool Seized;             ///< true if inner spool is seized
275   bool Overtemp;           ///< true if EGT exceeds limits
276   bool Fire;               ///< true if engine fire detected
277   bool Injection;
278   bool Augmentation;
279   bool Reversed;
280   bool Cutoff;
281   bool disableWindmill;    ///< flag to disable windmilling of engine in Off phase
282   int Injected;            ///< = 1 if water injection installed
283   int Ignition;
284   int Augmented;           ///< = 1 if augmentation installed
285   int AugMethod;           ///< = 0 if using property /engine[n]/augmentation
286                            ///< = 1 if using last 1% of throttle movement
287                            ///< = 2 if using FCS-defined throttle
288   double EGT_degC;
289   double EPR;
290   double OilPressure_psi;
291   double OilTemp_degK;
292   double BleedDemand;
293   double InletPosition;
294   double NozzlePosition;
295   double correctedTSFC;
296   double InjectionTimer;
297   double InjectionTime;
298   double InjWaterNorm;
299   double InjN1increment;
300   double InjN2increment;
301 
302   double Off(void);
303   double Run();
304   double SpinUp(void);
305   double Start(void);
306   double Stall(void);
307   double Seize(void);
308   double Trim();
309 
310   FGFunction *IdleThrustLookup;
311   FGFunction *MilThrustLookup;
312   FGFunction *MaxThrustLookup;
313   FGFunction *InjectionLookup;
314   FGFDMExec* FDMExec;
315   FGParameter *N1SpoolUp;
316   FGParameter *N1SpoolDown;
317   FGParameter *N2SpoolUp;
318   FGParameter *N2SpoolDown;
319 
320   bool Load(FGFDMExec *exec, Element *el);
321   void bindmodel(FGPropertyManager* pm);
322   void Debug(int from);
323 
324   friend class FGSpoolUp;
325 };
326 
327 class FGSpoolUp : public FGParameter
328 {
329 public:
FGSpoolUp(FGTurbine * _turb,double BPR,double factor)330   FGSpoolUp(FGTurbine* _turb, double BPR, double factor)
331     : turb(_turb), delay(factor * 90.0 / (BPR + 3.0)) {}
GetName(void)332   string GetName(void) const { return string(); };
GetValue(void)333   double GetValue(void) const {
334     // adjust acceleration for N2 and atmospheric density
335     double n = std::min(1.0, turb->N2norm + 0.1);
336     return delay / (1 + 3 * (1-n)*(1-n)*(1-n) + (1 - turb->in.DensityRatio));
337   }
338 private:
339   FGTurbine* turb;
340   double delay; ///< Inverse spool-up time from idle to 100% (seconds)
341 };
342 }
343 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
344 #endif
345