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 {
&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,
p = Atmosphere->GetPressure();
rhosl = Atmosphere->GetDensitySL();
psl = Atmosphere->GetPressureSL();
+ sat = Atmosphere->GetTemperature();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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; }
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;
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() );
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@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
@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; }
}
}
}
+
+ 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;
}
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; }
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;
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;}
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;
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-void checkTied( FGPropertyManager *node ) {
+void checkTied ( FGPropertyManager *node )
+{
int N = node->nChildren();
string name;
- for(int i=0;i<N;i++) {
- if(node->getChild(i)->nChildren() ) {
+
+ for (int i=0; i<N; i++) {
+ if (node->getChild(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)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-bool FGFDMExec::DeAllocate(void) {
-
+bool FGFDMExec::DeAllocate(void)
+{
delete Atmosphere;
delete FCS;
delete Propulsion;
delete IC;
delete Trim;
-
-
FirstModel = 0L;
Error = 0;
State->Initialize(IC);
Run();
State->Resume();
+
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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);
}
SG_USING_STD(string);
SG_USING_STD(queue);
+# ifndef M_PI
+# include <simgear/constants.h>
+# define M_PI SG_PI
+# endif
+
#else
# include <queue>
using std::string;
using std::queue;
-#endif
-#ifndef M_PI
-# include <simgear/constants.h>
-# define M_PI SG_PI
+# ifndef M_PI
+# define M_PI 3.14159265358979323846
+# endif
+
#endif
+
+using std::max;
+
#ifdef __FreeBSD__ // define gcvt on FreeBSD
#include <stdio.h>
sFirstPass = dFirstPass = true;
socket = 0;
Type = otNone;
- Filename = "JSBSim.out";
+ Filename = "";
SubSystems = 0;
enabled = true;
+ outputInFileName = "";
Debug(0);
}
FGOutput::~FGOutput()
{
if (socket) delete socket;
+ for (int i=0; i<OutputProperties.size(); i++) delete OutputProperties[i];
+
Debug(1);
}
outstream << ", ";
outstream << Propulsion->GetPropulsionStrings();
}
+ if (OutputProperties.size() > 0) {
+ for (int i=0;i<OutputProperties.size();i++) {
+ outstream << ", " << OutputProperties[i]->GetName();
+ }
+ }
outstream << endl;
dFirstPass = false;
outstream << Propulsion->GetPropulsionValues();
}
+ for (int i=0;i<OutputProperties.size();i++) {
+ outstream << ", " << OutputProperties[i]->getDoubleValue();
+ }
+
outstream << endl;
outstream.flush();
}
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);
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;
}
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;
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 <FGPropertyManager*> OutputProperties;
void Debug(int from);
};
}
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;
break;
case FGEngine::etTurbine:
break;
+ case FGEngine::etSimTurbine:
+ break;
default:
PropulsionStrings += "INVALID ENGINE TYPE";
break;
break;
case FGEngine::etTurbine:
break;
+ case FGEngine::etSimTurbine:
+ break;
}
PropulsionValues += ", ";
#include "FGRocket.h"
#include "FGPiston.h"
#include "FGTurbine.h"
+#include "FGSimTurbine.h"
#include "FGTank.h"
#include "FGPropeller.h"
#include "FGNozzle.h"
--- /dev/null
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ 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 <vector>
+#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;
+ }
+ }
+}
+}
--- /dev/null
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ 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 <vector>
+#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<FGCoefficient*> 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
+
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; }
FGfdmSocket.cpp FGfdmSocket.h \
FGTurbine.cpp FGTurbine.h \
FGPropertyManager.cpp FGPropertyManager.h \
+ FGSimTurbine.cpp FGSimTurbine.h \
JSBSim.cxx JSBSim.hxx