⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fgturboprop.cpp

📁 6 DOF Missle Simulation
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Module:       FGTurboProp.cpp Author:       Jiri "Javky" Javurek               based on SimTurbine and Turbine engine from David Culp Date started: 05/14/2004 Purpose:      This module models a turbo propeller engine. ------------- Copyright (C) 2004  (javky@email.cz) --------- This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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 Lesser 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 Turbo propeller enginebased on parameters given in the engine config file for this classHISTORY--------------------------------------------------------------------------------05/14/2004  Created//JVK (mark)%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%INCLUDES%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/#include <vector>#include <sstream>#include "FGTurboProp.h"#include "FGPropeller.h"namespace JSBSim {static const char *IdSrc = "$Id$";static const char *IdHdr = ID_TURBOPROP;/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%CLASS IMPLEMENTATION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/FGTurboProp::FGTurboProp(FGFDMExec* exec, Element *el, int engine_number)  : FGEngine(exec, el, engine_number){  SetDefaults();  Load(exec, el);  Debug(0);}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%FGTurboProp::~FGTurboProp(){  Debug(1);}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%bool FGTurboProp::Load(FGFDMExec* exec, Element *el){  char property_prefix[80];  snprintf(property_prefix, 80, "propulsion/engine[%u]/", EngineNumber);  IdleFF=-1;  MaxStartingTime = 999999; //very big timeout -> infinite  Ielu_max_torque=-1;// ToDo: Need to make sure units are properly accounted for below.  if (el->FindElement("milthrust"))    MilThrust = el->FindElementValueAsNumberConvertTo("milthrust","LBS");  if (el->FindElement("idlen1"))    IdleN1 = el->FindElementValueAsNumber("idlen1");  if (el->FindElement("idlen2"))    IdleN2 = el->FindElementValueAsNumber("idlen1");  if (el->FindElement("maxn1"))    MaxN1 = el->FindElementValueAsNumber("maxn1");  if (el->FindElement("maxn2"))    MaxN2 = el->FindElementValueAsNumber("maxn2");  if (el->FindElement("betarangeend"))    BetaRangeThrottleEnd = el->FindElementValueAsNumber("betarangeend")/100.0;  if (el->FindElement("reversemaxpower"))    ReverseMaxPower = el->FindElementValueAsNumber("reversemaxpower")/100.0;  if (el->FindElement("maxpower"))    MaxPower = el->FindElementValueAsNumber("maxpower");  if (el->FindElement("idlefuelflow"))    IdleFF = el->FindElementValueAsNumber("idlefuelflow");  if (el->FindElement("psfc"))    PSFC = el->FindElementValueAsNumber("psfc");  if (el->FindElement("n1idle_max_delay"))    Idle_Max_Delay = el->FindElementValueAsNumber("n1idle_max_delay");  if (el->FindElement("maxstartingtime"))    MaxStartingTime = el->FindElementValueAsNumber("maxstartingtime");  if (el->FindElement("startern1"))    StarterN1 = el->FindElementValueAsNumber("startern1");  if (el->FindElement("ielumaxtorque"))    Ielu_max_torque = el->FindElementValueAsNumber("ielumaxtorque");  if (el->FindElement("itt_delay"))    ITT_Delay = el->FindElementValueAsNumber("itt_delay");  Element *table_element;  string name;  FGPropertyManager* PropertyManager = exec->GetPropertyManager();  while (true) {    table_element = el->FindNextElement("table");    if (!table_element) break;    name = table_element->GetAttributeValue("name");    if (name == "EnginePowerVC") {      EnginePowerVC = new FGTable(PropertyManager, table_element);    } else if (name == "EnginePowerRPM_N1") {      EnginePowerRPM_N1 = new FGTable(PropertyManager, table_element);    } else if (name == "ITT_N1") {      ITT_N1 = new FGTable(PropertyManager, table_element);    } else {      cerr << "Unknown table type: " << name << " in turbine definition." <<      endl;    }  }  // Pre-calculations and initializations  delay=1;  N1_factor = MaxN1 - IdleN1;  N2_factor = MaxN2 - IdleN2;  OilTemp_degK = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556 + 273.0;  if (IdleFF==-1) IdleFF = pow(MilThrust, 0.2) * 107.0;  // just an estimate  cout << "ENG POWER:" << EnginePowerRPM_N1->GetValue(1200,90) << "\n";  return true;}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%// The main purpose of Calculate() is to determine what phase the engine should// be in, then call the corresponding function.double FGTurboProp::Calculate(void){  TAT = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556;  dt = State->Getdt() * Propulsion->GetRate();  ThrottleCmd = FCS->GetThrottleCmd(EngineNumber);  Prop_RPM = Thruster->GetRPM() * Thruster->GetGearRatio();  if (Thruster->GetType() == FGThruster::ttPropeller) {    ((FGPropeller*)Thruster)->SetAdvance(FCS->GetPropAdvance(EngineNumber));    ((FGPropeller*)Thruster)->SetFeather(FCS->GetPropFeather(EngineNumber));    ((FGPropeller*)Thruster)->SetReverse(Reversed);    if (Reversed) {      ((FGPropeller*)Thruster)->SetReverseCoef(ThrottleCmd);    } else {      ((FGPropeller*)Thruster)->SetReverseCoef(0.0);    }  }  if (Reversed) {    if (ThrottleCmd < BetaRangeThrottleEnd) {        ThrottleCmd = 0.0;  // idle when in Beta-range    } else {      // when reversed:      ThrottleCmd = (ThrottleCmd-BetaRangeThrottleEnd)/(1-BetaRangeThrottleEnd) * ReverseMaxPower;    }  }  // When trimming is finished check if user wants engine OFF or RUNNING  if ((phase == tpTrim) && (dt > 0)) {    if (Running && !Starved) {      phase = tpRun;      N2 = IdleN2;      N1 = IdleN1;      OilTemp_degK = 366.0;      Cutoff = false;    } else {      phase = tpOff;      Cutoff = true;      Eng_ITT_degC = TAT;      Eng_Temperature = TAT;      OilTemp_degK = TAT+273.15;    }  }  if (!Running && Starter) {    if (phase == tpOff) {      phase = tpSpinUp;      if (StartTime < 0) StartTime=0;    }  }  if (!Running && !Cutoff && (N1 > 15.0)) {    phase = tpStart;    StartTime = -1;  }  if (Cutoff && (phase != tpSpinUp)) phase = tpOff;  if (dt == 0) phase = tpTrim;  if (Starved) phase = tpOff;  if (Condition >= 10) {    phase = tpOff;    StartTime=-1;  }  if (Condition < 1) {    if (Ielu_max_torque > 0      && -Ielu_max_torque > ((FGPropeller*)(Thruster))->GetTorque()      && ThrottleCmd >= OldThrottle ) {      ThrottleCmd = OldThrottle - 0.1 * dt; //IELU down      Ielu_intervent = true;    } else if (Ielu_max_torque > 0 && Ielu_intervent && ThrottleCmd >= OldThrottle) {      ThrottleCmd = OldThrottle;      ThrottleCmd = OldThrottle + 0.05 * dt; //IELU up      Ielu_intervent = true;    } else {      Ielu_intervent = false;    }  } else {    Ielu_intervent = false;  }  OldThrottle = ThrottleCmd;  switch (phase) {    case tpOff:    Eng_HP = Off(); break;    case tpRun:    Eng_HP = Run(); break;    case tpSpinUp: Eng_HP = SpinUp(); break;    case tpStart:  Eng_HP = Start(); break;    default: Eng_HP = 0;  }  //printf ("EngHP: %lf / Requi: %lf\n",Eng_HP,Prop_Required_Power);  return Thruster->Calculate((Eng_HP * hptoftlbssec)-Thruster->GetPowerRequired());}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%double FGTurboProp::Off(void){  double qbar = Auxiliary->Getqbar();  Running = false; EngStarting = false;  FuelFlow_pph = Seek(&FuelFlow_pph, 0, 800.0, 800.0);  //allow the air turn with generator  N1 = ExpSeek(&N1, qbar/15.0, Idle_Max_Delay*2.5, Idle_Max_Delay * 5);  OilTemp_degK = ExpSeek(&OilTemp_degK,273.15 + TAT, 400 , 400);  Eng_Temperature = ExpSeek(&Eng_Temperature,TAT,300,400);  double ITT_goal = ITT_N1->GetValue(N1,0.1) + ((N1>20) ? 0.0 : (20-N1)/20.0 * Eng_Temperature);  Eng_ITT_degC  = ExpSeek(&Eng_ITT_degC,ITT_goal,ITT_Delay,ITT_Delay*1.2);  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  ConsumeFuel(); // for possible setting Starved = false when fuel tank                 // is refilled (fuel crossfeed etc.)  if (Prop_RPM>5) return -0.012; // friction in engine when propeller spining (estimate)  return 0.0;}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%double FGTurboProp::Run(void){  double thrust = 0.0, EngPower_HP, eff_coef;  Running = true; Starter = false; EngStarting = false;//---  double old_N1 = N1;  N1 = ExpSeek(&N1, IdleN1 + ThrottleCmd * N1_factor, Idle_Max_Delay, Idle_Max_Delay * 2.4);  EngPower_HP = EnginePowerRPM_N1->GetValue(Prop_RPM,N1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -