JSBSim Flight Dynamics Model 1.0 (23 February 2013)
An Open Source Flight Dynamics and Control Software Library in C++

FGTurboProp.cpp

00001 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00002 
00003  Module:       FGTurboProp.cpp
00004  Author:       Jiri "Javky" Javurek
00005                based on SimTurbine and Turbine engine from David Culp
00006  Date started: 05/14/2004
00007  Purpose:      This module models a turbo propeller engine.
00008 
00009  ------------- Copyright (C) 2004  (javky@email.cz) ---------
00010 
00011  This program is free software; you can redistribute it and/or modify it under
00012  the terms of the GNU Lesser General Public License as published by the Free Software
00013  Foundation; either version 2 of the License, or (at your option) any later
00014  version.
00015 
00016  This program is distributed in the hope that it will be useful, but WITHOUT
00017  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00019  details.
00020 
00021  You should have received a copy of the GNU Lesser General Public License along with
00022  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00023  Place - Suite 330, Boston, MA  02111-1307, USA.
00024 
00025  Further information about the GNU Lesser General Public License can also be found on
00026  the world wide web at http://www.gnu.org.
00027 
00028 FUNCTIONAL DESCRIPTION
00029 --------------------------------------------------------------------------------
00030 
00031 This class descends from the FGEngine class and models a Turbo propeller engine
00032 based on parameters given in the engine config file for this class
00033 
00034 HISTORY
00035 --------------------------------------------------------------------------------
00036 05/14/2004  Created
00037 02/08/2011  T. Kreitler, added rotor support
00038 
00039 //JVK (mark)
00040 
00041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00042 INCLUDES
00043 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
00044 
00045 #include <iostream>
00046 #include <sstream>
00047 
00048 #include "FGTurboProp.h"
00049 #include "FGPropeller.h"
00050 #include "FGRotor.h"
00051 
00052 using namespace std;
00053 
00054 namespace JSBSim {
00055 
00056 static const char *IdSrc = "$Id: FGTurboProp.cpp,v 1.24 2011/09/25 23:56:11 jentron Exp $";
00057 static const char *IdHdr = ID_TURBOPROP;
00058 
00059 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00060 CLASS IMPLEMENTATION
00061 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
00062 
00063 FGTurboProp::FGTurboProp(FGFDMExec* exec, Element *el, int engine_number, struct Inputs& input)
00064   : FGEngine(exec, el, engine_number, input),
00065     ITT_N1(NULL), EnginePowerRPM_N1(NULL), EnginePowerVC(NULL)
00066 {
00067   SetDefaults();
00068   thrusterType = Thruster->GetType();
00069 
00070   Load(exec, el);
00071   bindmodel();
00072   Debug(0);
00073 }
00074 
00075 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00076 
00077 FGTurboProp::~FGTurboProp()
00078 {
00079   delete ITT_N1;
00080   delete EnginePowerRPM_N1;
00081   delete EnginePowerVC;
00082   Debug(1);
00083 }
00084 
00085 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00086 
00087 bool FGTurboProp::Load(FGFDMExec* exec, Element *el)
00088 {
00089   IdleFF=-1;
00090   MaxStartingTime = 999999; //very big timeout -> infinite
00091   Ielu_max_torque=-1;
00092 
00093 // ToDo: Need to make sure units are properly accounted for below.
00094 
00095   if (el->FindElement("milthrust"))
00096     MilThrust = el->FindElementValueAsNumberConvertTo("milthrust","LBS");
00097   if (el->FindElement("idlen1"))
00098     IdleN1 = el->FindElementValueAsNumber("idlen1");
00099   if (el->FindElement("idlen2"))
00100     IdleN2 = el->FindElementValueAsNumber("idlen2");
00101   if (el->FindElement("maxn1"))
00102     MaxN1 = el->FindElementValueAsNumber("maxn1");
00103   if (el->FindElement("maxn2"))
00104     MaxN2 = el->FindElementValueAsNumber("maxn2");
00105   if (el->FindElement("betarangeend"))
00106     BetaRangeThrottleEnd = el->FindElementValueAsNumber("betarangeend")/100.0;
00107   BetaRangeThrottleEnd = Constrain(0.0, BetaRangeThrottleEnd, 0.99999);
00108   if (el->FindElement("reversemaxpower"))
00109     ReverseMaxPower = el->FindElementValueAsNumber("reversemaxpower")/100.0;
00110 
00111   if (el->FindElement("maxpower"))
00112     MaxPower = el->FindElementValueAsNumber("maxpower");
00113   if (el->FindElement("idlefuelflow"))
00114     IdleFF = el->FindElementValueAsNumber("idlefuelflow");
00115   if (el->FindElement("psfc"))
00116     PSFC = el->FindElementValueAsNumber("psfc");
00117   if (el->FindElement("n1idle_max_delay"))
00118     Idle_Max_Delay = el->FindElementValueAsNumber("n1idle_max_delay");
00119   if (el->FindElement("maxstartingtime"))
00120     MaxStartingTime = el->FindElementValueAsNumber("maxstartingtime");
00121   if (el->FindElement("startern1"))
00122     StarterN1 = el->FindElementValueAsNumber("startern1");
00123   if (el->FindElement("ielumaxtorque"))
00124     Ielu_max_torque = el->FindElementValueAsNumber("ielumaxtorque");
00125   if (el->FindElement("itt_delay"))
00126     ITT_Delay = el->FindElementValueAsNumber("itt_delay");
00127 
00128   Element *table_element;
00129   string name;
00130   FGPropertyManager* PropertyManager = exec->GetPropertyManager();
00131 
00132   while (true) {
00133     table_element = el->FindNextElement("table");
00134     if (!table_element) break;
00135     name = table_element->GetAttributeValue("name");
00136     if (name == "EnginePowerVC") {
00137       EnginePowerVC = new FGTable(PropertyManager, table_element);
00138     } else if (name == "EnginePowerRPM_N1") {
00139       EnginePowerRPM_N1 = new FGTable(PropertyManager, table_element);
00140     } else if (name == "ITT_N1") {
00141       ITT_N1 = new FGTable(PropertyManager, table_element);
00142     } else {
00143       cerr << "Unknown table type: " << name << " in turbine definition." <<
00144       endl;
00145     }
00146   }
00147 
00148   // Pre-calculations and initializations
00149 
00150   delay=1;
00151   N1_factor = MaxN1 - IdleN1;
00152   N2_factor = MaxN2 - IdleN2;
00153   OilTemp_degK = in.TAT_c + 273.0;
00154   if (IdleFF==-1) IdleFF = pow(MilThrust, 0.2) * 107.0;  // just an estimate
00155 
00156   // cout << "ENG POWER:" << EnginePowerRPM_N1->GetValue(1200,90) << endl;
00157 
00158   return true;
00159 }
00160 
00161 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00162 // The main purpose of Calculate() is to determine what phase the engine should
00163 // be in, then call the corresponding function.
00164 
00165 void FGTurboProp::Calculate(void)
00166 {
00167   RunPreFunctions();
00168 
00169   TAT = in.TAT_c;
00170 
00171   ThrottlePos = in.ThrottlePos[EngineNumber];
00172 
00173 /* The thruster controls the engine RPM because it encapsulates the gear ratio and other transmission variables */
00174   RPM = Thruster->GetEngineRPM();
00175   if (thrusterType == FGThruster::ttPropeller) {
00176     ((FGPropeller*)Thruster)->SetAdvance(in.PropAdvance[EngineNumber]);
00177     ((FGPropeller*)Thruster)->SetFeather(in.PropFeather[EngineNumber]);
00178     ((FGPropeller*)Thruster)->SetReverse(Reversed);
00179     if (Reversed) {
00180       ((FGPropeller*)Thruster)->SetReverseCoef(ThrottlePos);
00181     } else {
00182       ((FGPropeller*)Thruster)->SetReverseCoef(0.0);
00183     }
00184 
00185     if (Reversed) {
00186       if (ThrottlePos < BetaRangeThrottleEnd) {
00187           ThrottlePos = 0.0;  // idle when in Beta-range
00188       } else {
00189         // when reversed:
00190         ThrottlePos = (ThrottlePos-BetaRangeThrottleEnd)/(1-BetaRangeThrottleEnd) * ReverseMaxPower;
00191       }
00192     }
00193   }
00194 
00195   // When trimming is finished check if user wants engine OFF or RUNNING
00196   if ((phase == tpTrim) && (in.TotalDeltaT > 0)) {
00197     if (Running && !Starved) {
00198       phase = tpRun;
00199       N2 = IdleN2;
00200       N1 = IdleN1;
00201       OilTemp_degK = 366.0;
00202       Cutoff = false;
00203     } else {
00204       phase = tpOff;
00205       Cutoff = true;
00206       Eng_ITT_degC = TAT;
00207       Eng_Temperature = TAT;
00208       OilTemp_degK = TAT+273.15;
00209     }
00210   }
00211 
00212   if (!Running && Starter) {
00213     if (phase == tpOff) {
00214       phase = tpSpinUp;
00215       if (StartTime < 0) StartTime=0;
00216     }
00217   }
00218   if (!Running && !Cutoff && (N1 > 15.0)) {
00219     phase = tpStart;
00220     StartTime = -1;
00221   }
00222   if (Cutoff && (phase != tpSpinUp)) phase = tpOff;
00223   if (in.TotalDeltaT == 0) phase = tpTrim;
00224   if (Starved) phase = tpOff;
00225   if (Condition >= 10) {
00226     phase = tpOff;
00227     StartTime=-1;
00228   }
00229 
00230   // limiter intervention wanted?
00231   if (Ielu_max_torque > 0.0) {
00232     double torque = 0.0;
00233     
00234     if (thrusterType == FGThruster::ttPropeller) {
00235       torque = ((FGPropeller*)(Thruster))->GetTorque();
00236     } else if (thrusterType == FGThruster::ttRotor) {
00237       torque = ((FGRotor*)(Thruster))->GetTorque();
00238     }
00239 
00240     if (Condition < 1) {
00241       if ( abs(torque) > Ielu_max_torque && ThrottlePos >= OldThrottle ) {
00242         ThrottlePos = OldThrottle - 0.1 * in.TotalDeltaT; //IELU down
00243         Ielu_intervent = true;
00244       } else if ( Ielu_intervent && ThrottlePos >= OldThrottle) {
00245         ThrottlePos = OldThrottle + 0.05 * in.TotalDeltaT; //IELU up
00246         Ielu_intervent = true;
00247       } else {
00248         Ielu_intervent = false;
00249       }
00250     } else {
00251       Ielu_intervent = false;
00252     }
00253     OldThrottle = ThrottlePos;
00254   }
00255 
00256   switch (phase) {
00257     case tpOff:    HP = Off(); break;
00258     case tpRun:    HP = Run(); break;
00259     case tpSpinUp: HP = SpinUp(); break;
00260     case tpStart:  HP = Start(); break;
00261     default: HP = 0;
00262   }
00263  
00264   LoadThrusterInputs();
00265   Thruster->Calculate(HP * hptoftlbssec);
00266 
00267   RunPostFunctions();
00268 }
00269 
00270 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00271 
00272 double FGTurboProp::Off(void)
00273 {
00274   Running = false; EngStarting = false;
00275 
00276   FuelFlow_pph = Seek(&FuelFlow_pph, 0, 800.0, 800.0);
00277 
00278   //allow the air turn with generator
00279   N1 = ExpSeek(&N1, in.qbar/15.0, Idle_Max_Delay*2.5, Idle_Max_Delay * 5);
00280 
00281   OilTemp_degK = ExpSeek(&OilTemp_degK,273.15 + TAT, 400 , 400);
00282 
00283   Eng_Temperature = ExpSeek(&Eng_Temperature,TAT,300,400);
00284   double ITT_goal = ITT_N1->GetValue(N1,0.1) + ((N1>20) ? 0.0 : (20-N1)/20.0 * Eng_Temperature);
00285   Eng_ITT_degC  = ExpSeek(&Eng_ITT_degC,ITT_goal,ITT_Delay,ITT_Delay*1.2);
00286 
00287   OilPressure_psi = (N1/100.0*0.25+(0.1-(OilTemp_degK-273.15)*0.1/80.0)*N1/100.0) / 7692.0e-6; //from MPa to psi
00288 
00289   if (RPM>5) return -0.012; // friction in engine when propeller spining (estimate)
00290   return 0.0;
00291 }
00292 
00293 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00294 
00295 double FGTurboProp::Run(void)
00296 {
00297   double thrust = 0.0, EngPower_HP, eff_coef;
00298   Running = true; Starter = false; EngStarting = false;
00299 
00300 //---
00301   double old_N1 = N1;
00302   N1 = ExpSeek(&N1, IdleN1 + ThrottlePos * N1_factor, Idle_Max_Delay, Idle_Max_Delay * 2.4);
00303 
00304   EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1);
00305   EngPower_HP *= EnginePowerVC->GetValue();
00306   if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
00307 
00308   eff_coef = 9.333 - (N1)/12; // 430%Fuel at 60%N1
00309   FuelFlow_pph = PSFC * EngPower_HP * eff_coef;
00310 
00311   Eng_Temperature = ExpSeek(&Eng_Temperature,Eng_ITT_degC,300,400);
00312   double ITT_goal = ITT_N1->GetValue((N1-old_N1)*300+N1,1);
00313   Eng_ITT_degC  = ExpSeek(&Eng_ITT_degC,ITT_goal,ITT_Delay,ITT_Delay*1.2);
00314 
00315   OilPressure_psi = (N1/100.0*0.25+(0.1-(OilTemp_degK-273.15)*0.1/80.0)*N1/100.0) / 7692.0e-6; //from MPa to psi
00316 //---
00317   EPR = 1.0 + thrust/MilThrust;
00318 
00319   OilTemp_degK = Seek(&OilTemp_degK, 353.15, 0.4-N1*0.001, 0.04);
00320 
00321   if (Cutoff) phase = tpOff;
00322   if (Starved) phase = tpOff;
00323 
00324   return EngPower_HP;
00325 }
00326 
00327 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00328 
00329 double FGTurboProp::SpinUp(void)
00330 {
00331   double EngPower_HP;
00332   Running = false; EngStarting = true;
00333   FuelFlow_pph = 0.0;
00334 
00335   if (!GeneratorPower) {
00336     EngStarting=false;
00337     phase=tpOff;
00338     StartTime = -1;
00339     return 0.0;
00340   }
00341 
00342   N1 = ExpSeek(&N1, StarterN1, Idle_Max_Delay * 6, Idle_Max_Delay * 2.4);
00343 
00344   Eng_Temperature = ExpSeek(&Eng_Temperature,TAT,300,400);
00345   double ITT_goal = ITT_N1->GetValue(N1,0.1) + ((N1>20) ? 0.0 : (20-N1)/20.0 * Eng_Temperature);
00346   Eng_ITT_degC  = ExpSeek(&Eng_ITT_degC,ITT_goal,ITT_Delay,ITT_Delay*1.2);
00347 
00348   OilTemp_degK = ExpSeek(&OilTemp_degK,273.15 + TAT, 400 , 400);
00349 
00350   OilPressure_psi = (N1/100.0*0.25+(0.1-(OilTemp_degK-273.15)*0.1/80.0)*N1/100.0) / 7692.0e-6; //from MPa to psi
00351   NozzlePosition = 1.0;
00352 
00353   EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1);
00354   EngPower_HP *= EnginePowerVC->GetValue();
00355   if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
00356 
00357   if (StartTime>=0) StartTime+=in.TotalDeltaT;
00358   if (StartTime > MaxStartingTime && MaxStartingTime > 0) { //start failed due timeout
00359     phase = tpOff;
00360     StartTime = -1;
00361   }
00362 
00363   return EngPower_HP;
00364 }
00365 
00366 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00367 
00368 double FGTurboProp::Start(void)
00369 {
00370   double EngPower_HP = 0.0;
00371   double eff_coef;
00372 
00373   EngStarting = false;
00374   if ((N1 > 15.0) && !Starved) {       // minimum 15% N2 needed for start
00375     double old_N1 = N1;
00376     Cranking = true;                   // provided for sound effects signal
00377     if (N1 < IdleN1) {
00378       EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1);
00379       EngPower_HP *= EnginePowerVC->GetValue();
00380       if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
00381       N1 = ExpSeek(&N1, IdleN1*1.1, Idle_Max_Delay*4, Idle_Max_Delay * 2.4);
00382       eff_coef = 9.333 - (N1)/12; // 430%Fuel at 60%N1
00383       FuelFlow_pph = PSFC * EngPower_HP * eff_coef;
00384       Eng_Temperature = ExpSeek(&Eng_Temperature,Eng_ITT_degC,300,400);
00385       double ITT_goal = ITT_N1->GetValue((N1-old_N1)*300+N1,1);
00386       Eng_ITT_degC  = ExpSeek(&Eng_ITT_degC,ITT_goal,ITT_Delay,ITT_Delay*1.2);
00387 
00388       OilPressure_psi = (N1/100.0*0.25+(0.1-(OilTemp_degK-273.15)*0.1/80.0)*N1/100.0) / 7692.0e-6; //from MPa to psi
00389       OilTemp_degK = Seek(&OilTemp_degK, 353.15, 0.4-N1*0.001, 0.04);
00390 
00391     } else {
00392       phase = tpRun;
00393       Running = true;
00394       Starter = false;
00395       Cranking = false;
00396       FuelFlow_pph = 0;
00397     }
00398   } else {                 // no start if N2 < 15% or Starved
00399     phase = tpOff;
00400     Starter = false;
00401   }
00402 
00403   return EngPower_HP;
00404 }
00405 
00406 
00407 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00408 
00409 double FGTurboProp::CalcFuelNeed(void)
00410 {
00411   FuelFlowRate = FuelFlow_pph / 3600.0;
00412   FuelExpended = FuelFlowRate * in.TotalDeltaT;
00413   if (!Starved) FuelUsedLbs += FuelExpended;
00414   return FuelExpended;
00415 }
00416 
00417 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00418 
00419 double FGTurboProp::Seek(double *var, double target, double accel, double decel)
00420 {
00421   double v = *var;
00422   if (v > target) {
00423     v -= in.TotalDeltaT * decel;
00424     if (v < target) v = target;
00425   } else if (v < target) {
00426     v += in.TotalDeltaT * accel;
00427     if (v > target) v = target;
00428   }
00429   return v;
00430 }
00431 
00432 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00433 
00434 double FGTurboProp::ExpSeek(double *var, double target, double accel_tau, double decel_tau)
00435 {
00436 // exponential delay instead of the linear delay used in Seek
00437   double v = *var;
00438   if (v > target) {
00439     v = (v - target) * exp ( -in.TotalDeltaT / decel_tau) + target;
00440   } else if (v < target) {
00441     v = (target - v) * (1 - exp ( -in.TotalDeltaT / accel_tau)) + v;
00442   }
00443   return v;
00444 }
00445 
00446 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00447 
00448 void FGTurboProp::SetDefaults(void)
00449 {
00450 //  Name = "Not defined";
00451   N1 = N2 = 0.0;
00452   HP = 0.0;
00453   Type = etTurboprop;
00454   MilThrust = 10000.0;
00455   IdleN1 = 30.0;
00456   IdleN2 = 60.0;
00457   MaxN1 = 100.0;
00458   MaxN2 = 100.0;
00459   InletPosition = 1.0;
00460   NozzlePosition = 1.0;
00461   Reversed = false;
00462   Cutoff = true;
00463   phase = tpOff;
00464   Stalled = false;
00465   Seized = false;
00466   Overtemp = false;
00467   Fire = false;
00468   Eng_ITT_degC = 0.0;
00469 
00470   GeneratorPower=true;
00471   Condition = 0;
00472   Ielu_intervent=false;
00473 
00474   Idle_Max_Delay = 1.0;
00475 
00476   ThrottlePos = OldThrottle = 0.0;
00477   ITT_Delay = 0.05;
00478   ReverseMaxPower = 0.0;
00479   BetaRangeThrottleEnd = 0.0;
00480 }
00481 
00482 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00483 
00484 
00485 string FGTurboProp::GetEngineLabels(const string& delimiter)
00486 {
00487   std::ostringstream buf;
00488 
00489   buf << Name << "_N1[" << EngineNumber << "]" << delimiter
00490       << Name << "_N2[" << EngineNumber << "]" << delimiter
00491       << Name << "_PwrAvail[" << EngineNumber << "]" << delimiter
00492       << Thruster->GetThrusterLabels(EngineNumber, delimiter);
00493 
00494   return buf.str();
00495 }
00496 
00497 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00498 
00499 string FGTurboProp::GetEngineValues(const string& delimiter)
00500 {
00501   std::ostringstream buf;
00502 
00503   buf << N1 << delimiter
00504       << N2 << delimiter
00505       << HP << delimiter
00506       << Thruster->GetThrusterValues(EngineNumber,delimiter);
00507 
00508   return buf.str();
00509 }
00510 
00511 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00512 
00513 int FGTurboProp::InitRunning(void)
00514 {
00515   FDMExec->SuspendIntegration();
00516   Cutoff=false;
00517   Running=true;  
00518   N2=16.0;
00519   Calculate();
00520   FDMExec->ResumeIntegration();
00521   return phase==tpRun;
00522 }
00523 
00524 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00525 
00526 void FGTurboProp::bindmodel()
00527 {
00528   string property_name, base_property_name;
00529   base_property_name = CreateIndexedPropertyName("propulsion/engine", EngineNumber);
00530   property_name = base_property_name + "/n1";
00531   PropertyManager->Tie( property_name.c_str(), &N1);
00532   // property_name = base_property_name + "/n2";
00533   // PropertyManager->Tie( property_name.c_str(), &N2);
00534   property_name = base_property_name + "/reverser";
00535   PropertyManager->Tie( property_name.c_str(), &Reversed);
00536   property_name = base_property_name + "/power-hp";
00537   PropertyManager->Tie( property_name.c_str(), &HP);
00538   property_name = base_property_name + "/itt-c";
00539   PropertyManager->Tie( property_name.c_str(), &Eng_ITT_degC);
00540   property_name = base_property_name + "/engtemp-c";
00541   PropertyManager->Tie( property_name.c_str(), &Eng_Temperature);
00542   property_name = base_property_name + "/ielu_intervent";
00543   PropertyManager->Tie( property_name.c_str(), &Ielu_intervent);
00544 }
00545 
00546 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00547 //    The bitmasked value choices are as follows:
00548 //    unset: In this case (the default) JSBSim would only print
00549 //       out the normally expected messages, essentially echoing
00550 //       the config files as they are read. If the environment
00551 //       variable is not set, debug_lvl is set to 1 internally
00552 //    0: This requests JSBSim not to output any messages
00553 //       whatsoever.
00554 //    1: This value explicity requests the normal JSBSim
00555 //       startup messages
00556 //    2: This value asks for a message to be printed out when
00557 //       a class is instantiated
00558 //    4: When this value is set, a message is displayed when a
00559 //       FGModel object executes its Run() method
00560 //    8: When this value is set, various runtime state variables
00561 //       are printed out periodically
00562 //    16: When set various parameters are sanity checked and
00563 //       a message is printed out when they go out of bounds
00564 
00565 void FGTurboProp::Debug(int from)
00566 {
00567   if (debug_lvl <= 0) return;
00568 
00569   if (debug_lvl & 1) { // Standard console startup message output
00570     if (from == 0) { // Constructor
00571 
00572     }
00573     if (from == 2) { // called from Load()
00574       cout << "\n ****MUJ MOTOR TURBOPROP****\n";
00575       cout << "\n    Engine Name: "         << Name << endl;
00576       cout << "      MilThrust:   "         << MilThrust << endl;
00577       cout << "      IdleN1:      "         << IdleN1 << endl;
00578       cout << "      MaxN1:       "         << MaxN1 << endl;
00579 
00580       cout << endl;
00581     }
00582   }
00583   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
00584     if (from == 0) cout << "Instantiated: FGTurboProp" << endl;
00585     if (from == 1) cout << "Destroyed:    FGTurboProp" << endl;
00586   }
00587   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
00588   }
00589   if (debug_lvl & 8 ) { // Runtime state variables
00590   }
00591   if (debug_lvl & 16) { // Sanity checking
00592   }
00593   if (debug_lvl & 64) {
00594     if (from == 0) { // Constructor
00595       cout << IdSrc << endl;
00596       cout << IdHdr << endl;
00597     }
00598   }
00599 }
00600 }