diff --git a/src/FDM/JSBSim/FGAuxiliary.cpp b/src/FDM/JSBSim/FGAuxiliary.cpp index 845341b24..aa188c32c 100644 --- a/src/FDM/JSBSim/FGAuxiliary.cpp +++ b/src/FDM/JSBSim/FGAuxiliary.cpp @@ -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(); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/FGAuxiliary.h b/src/FDM/JSBSim/FGAuxiliary.h index 3f6018edc..dcd6efd23 100644 --- a/src/FDM/JSBSim/FGAuxiliary.h +++ b/src/FDM/JSBSim/FGAuxiliary.h @@ -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; diff --git a/src/FDM/JSBSim/FGCoefficient.cpp b/src/FDM/JSBSim/FGCoefficient.cpp index ab7927a44..bb78c4d94 100644 --- a/src/FDM/JSBSim/FGCoefficient.cpp +++ b/src/FDM/JSBSim/FGCoefficient.cpp @@ -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; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/FGCoefficient.h b/src/FDM/JSBSim/FGCoefficient.h index 55ad7a165..abd95e3c0 100644 --- a/src/FDM/JSBSim/FGCoefficient.h +++ b/src/FDM/JSBSim/FGCoefficient.h @@ -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; } diff --git a/src/FDM/JSBSim/FGConfigFile.cpp b/src/FDM/JSBSim/FGConfigFile.cpp index e0d42cb06..c6c383288 100644 --- a/src/FDM/JSBSim/FGConfigFile.cpp +++ b/src/FDM/JSBSim/FGConfigFile.cpp @@ -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; } diff --git a/src/FDM/JSBSim/FGEngine.h b/src/FDM/JSBSim/FGEngine.h index 14d15149b..e17358f5f 100644 --- a/src/FDM/JSBSim/FGEngine.h +++ b/src/FDM/JSBSim/FGEngine.h @@ -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; diff --git a/src/FDM/JSBSim/FGFDMExec.cpp b/src/FDM/JSBSim/FGFDMExec.cpp index 166fdee45..ee6386705 100644 --- a/src/FDM/JSBSim/FGFDMExec.cpp +++ b/src/FDM/JSBSim/FGFDMExec.cpp @@ -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;igetChild(i)->nChildren() ) { + + for (int i=0; igetChild(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 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); } diff --git a/src/FDM/JSBSim/FGJSBBase.h b/src/FDM/JSBSim/FGJSBBase.h index 80d3e17ea..49275cff0 100644 --- a/src/FDM/JSBSim/FGJSBBase.h +++ b/src/FDM/JSBSim/FGJSBBase.h @@ -47,6 +47,11 @@ INCLUDES SG_USING_STD(string); SG_USING_STD(queue); +# ifndef M_PI +# include +# define M_PI SG_PI +# endif + #else # include @@ -59,12 +64,15 @@ SG_USING_STD(queue); using std::string; using std::queue; + +# ifndef M_PI +# define M_PI 3.14159265358979323846 +# endif + #endif -#ifndef M_PI -# include -# define M_PI SG_PI -#endif + +using std::max; #ifdef __FreeBSD__ // define gcvt on FreeBSD diff --git a/src/FDM/JSBSim/FGOutput.cpp b/src/FDM/JSBSim/FGOutput.cpp index f35662a6c..afe6a7a8d 100644 --- a/src/FDM/JSBSim/FGOutput.cpp +++ b/src/FDM/JSBSim/FGOutput.cpp @@ -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; iGetPropulsionStrings(); } + if (OutputProperties.size() > 0) { + for (int i=0;iGetName(); + } + } outstream << endl; dFirstPass = false; @@ -313,6 +321,10 @@ void FGOutput::DelimitedOutput(string fname) outstream << Propulsion->GetPropulsionValues(); } + for (int i=0;igetDoubleValue(); + } + 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; diff --git a/src/FDM/JSBSim/FGOutput.h b/src/FDM/JSBSim/FGOutput.h index 37bf06c4c..83b0d7c88 100644 --- a/src/FDM/JSBSim/FGOutput.h +++ b/src/FDM/JSBSim/FGOutput.h @@ -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 OutputProperties; void Debug(int from); }; } diff --git a/src/FDM/JSBSim/FGPropulsion.cpp b/src/FDM/JSBSim/FGPropulsion.cpp index f40972fa2..405882a8a 100644 --- a/src/FDM/JSBSim/FGPropulsion.cpp +++ b/src/FDM/JSBSim/FGPropulsion.cpp @@ -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 += ", "; diff --git a/src/FDM/JSBSim/FGPropulsion.h b/src/FDM/JSBSim/FGPropulsion.h index 2e8e803a7..92b0c64eb 100644 --- a/src/FDM/JSBSim/FGPropulsion.h +++ b/src/FDM/JSBSim/FGPropulsion.h @@ -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 index 000000000..e47dc2256 --- /dev/null +++ b/src/FDM/JSBSim/FGSimTurbine.cpp @@ -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 +#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 index 000000000..76e79624f --- /dev/null +++ b/src/FDM/JSBSim/FGSimTurbine.h @@ -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 +#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 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 + diff --git a/src/FDM/JSBSim/FGTranslation.h b/src/FDM/JSBSim/FGTranslation.h index 814857e67..cd2e9ee52 100644 --- a/src/FDM/JSBSim/FGTranslation.h +++ b/src/FDM/JSBSim/FGTranslation.h @@ -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; } diff --git a/src/FDM/JSBSim/Makefile.am b/src/FDM/JSBSim/Makefile.am index d8e245fc3..f944ad79b 100644 --- a/src/FDM/JSBSim/Makefile.am +++ b/src/FDM/JSBSim/Makefile.am @@ -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