From: andy Date: Sat, 1 May 2004 00:26:33 +0000 (+0000) Subject: Initial checkin of a TurbineEngine implementation. This hasn't been X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=a3ba94c39e06a3c5cabb7866f6f88ba82fd0375e;p=flightgear.git Initial checkin of a TurbineEngine implementation. This hasn't been tested at all yet, but it doesn't seem to have broken anything so it should be safe. See the README in the base package for docs. --- diff --git a/src/FDM/YASim/Engine.hpp b/src/FDM/YASim/Engine.hpp index edbe15d3d..8be455507 100644 --- a/src/FDM/YASim/Engine.hpp +++ b/src/FDM/YASim/Engine.hpp @@ -4,6 +4,7 @@ namespace yasim { class PistonEngine; +class TurbineEngine; // // Interface for the "Engine" part of a PropEngine object. This is a @@ -15,6 +16,7 @@ class PistonEngine; class Engine { public: virtual PistonEngine* isPistonEngine() { return 0; } + virtual TurbineEngine* isTurbineEngine() { return 0; } void setThrottle(float throttle) { _throttle = throttle; } void setStarter(bool starter) { _starter = starter; } @@ -28,6 +30,8 @@ public: virtual bool isCranking() { return false; } virtual void calc(float pressure, float temp, float speed) = 0; + virtual void stabilize() {} + virtual void integrate(float dt) {} virtual float getTorque() = 0; virtual float getFuelFlow() = 0; diff --git a/src/FDM/YASim/FGFDM.cpp b/src/FDM/YASim/FGFDM.cpp index 6454f848e..577a8c28f 100644 --- a/src/FDM/YASim/FGFDM.cpp +++ b/src/FDM/YASim/FGFDM.cpp @@ -11,6 +11,7 @@ #include "PropEngine.hpp" #include "Propeller.hpp" #include "PistonEngine.hpp" +#include "TurbineEngine.hpp" #include "Rotor.hpp" #include "Rotorpart.hpp" #include "Rotorblade.hpp" @@ -35,6 +36,8 @@ static const float K2DEGFOFFSET = -459.4; static const float CIN2CM = 1.6387064e-5; static const float YASIM_PI = 3.14159265358979323846; +static const float NM2FTLB = (1/(LBS2N*FT2M)); + // Stubs, so that this can be compiled without the FlightGear // binary. What's the best way to handle this? @@ -175,6 +178,10 @@ void FGFDM::startElement(const char* name, const XMLAttributes &atts) _airplane.setTail(parseWing(a, name)); } else if(eq(name, "vstab") || eq(name, "mstab")) { _airplane.addVStab(parseWing(a, name)); + } else if(eq(name, "piston-engine")) { + parsePistonEngine(a); + } else if(eq(name, "turbine-engine")) { + parseTurbineEngine(a); } else if(eq(name, "propeller")) { parsePropeller(a); } else if(eq(name, "thruster")) { @@ -448,22 +455,24 @@ void FGFDM::setOutputProperties() float lbs = Math::mag3(tmp) * (KG2LBS/9.8); node->setFloatValue("prop-thrust", lbs); // Deprecated name node->setFloatValue("thrust-lbs", lbs); - node->setFloatValue("fuel-flow-gph", (t->getFuelFlow()/fuelDensity) * 3600 * CM2GALS); if(t->getPropEngine()) { PropEngine* p = t->getPropEngine(); node->setFloatValue("rpm", p->getOmega() * (1/RPM2RAD)); - + node->setFloatValue("torque-ftlb", + p->getEngine()->getTorque() * NM2FTLB); + if(p->getEngine()->isPistonEngine()) { PistonEngine* pe = p->getEngine()->isPistonEngine(); node->setFloatValue("mp-osi", pe->getMP() * (1/INHG2PA)); node->setFloatValue("mp-inhg", pe->getMP() * (1/INHG2PA)); node->setFloatValue("egt-degf", pe->getEGT() * K2DEGF + K2DEGFOFFSET); -// } else if(p->isTurbineEngine()) { -// TurbineEngine* te = p->isTurbineEngine(); + } else if(p->getEngine()->isTurbineEngine()) { + TurbineEngine* te = p->getEngine()->isTurbineEngine(); + node->setFloatValue("n2", te->getN2()); } } @@ -595,28 +604,12 @@ Rotor* FGFDM::parseRotor(XMLAttributes* a, const char* type) return w; } -void FGFDM::parsePropeller(XMLAttributes* a) +void FGFDM::parsePistonEngine(XMLAttributes* a) { - float cg[3]; - cg[0] = attrf(a, "x"); - cg[1] = attrf(a, "y"); - cg[2] = attrf(a, "z"); - float mass = attrf(a, "mass") * LBS2KG; - float moment = attrf(a, "moment"); - float radius = attrf(a, "radius"); - float speed = attrf(a, "cruise-speed") * KTS2MPS; - float omega = attrf(a, "cruise-rpm") * RPM2RAD; - float power = attrf(a, "cruise-power") * HP2W; - float rho = Atmosphere::getStdDensity(attrf(a, "cruise-alt") * FT2M); - - // Hack, fix this pronto: float engP = attrf(a, "eng-power") * HP2W; float engS = attrf(a, "eng-rpm") * RPM2RAD; - Propeller* prop = new Propeller(radius, speed, omega, rho, power); PistonEngine* eng = new PistonEngine(engP, engS); - PropEngine* thruster = new PropEngine(prop, eng, moment); - _airplane.addThruster(thruster, mass, cg); if(a->hasAttribute("displacement")) eng->setDisplacement(attrf(a, "displacement") * CIN2CM); @@ -630,6 +623,66 @@ void FGFDM::parsePropeller(XMLAttributes* a) eng->setTurboParams(mul, mp); } + ((PropEngine*)_currObj)->setEngine(eng); +} + +void FGFDM::parseTurbineEngine(XMLAttributes* a) +{ + float power = attrf(a, "eng-power") * HP2W; + float omega = attrf(a, "eng-rpm") * RPM2RAD; + float alt = attrf(a, "alt") * FT2M; + float flatRating = attrf(a, "flat-rating") * HP2W; + TurbineEngine* eng = new TurbineEngine(power, omega, alt, flatRating); + + if(a->hasAttribute("min-n2")) + eng->setN2Range(attrf(a, "min-n2"), attrf(a, "max-n2")); + + // Nasty units conversion: lbs/hr per hp -> kg/s per watt + if(a->hasAttribute("bsfc")) + eng->setFuelConsumption(attrf(a, "bsfc") * (LBS2KG/(3600*HP2W))); + + ((PropEngine*)_currObj)->setEngine(eng); +} + +void FGFDM::parsePropeller(XMLAttributes* a) +{ + // Legacy Handling for the old engines syntax: + PistonEngine* eng = 0; + if(a->hasAttribute("eng-power")) { + SG_LOG(SG_FLIGHT,SG_ALERT, "WARNING: " + << "Legacy engine definition in YASim configuration file. " + << "Please fix."); + float engP = attrf(a, "eng-power") * HP2W; + float engS = attrf(a, "eng-rpm") * RPM2RAD; + eng = new PistonEngine(engP, engS); + if(a->hasAttribute("displacement")) + eng->setDisplacement(attrf(a, "displacement") * CIN2CM); + if(a->hasAttribute("compression")) + eng->setCompression(attrf(a, "compression")); + if(a->hasAttribute("turbo-mul")) { + float mul = attrf(a, "turbo-mul"); + float mp = attrf(a, "wastegate-mp", 1e6) * INHG2PA; + eng->setTurboParams(mul, mp); + } + } + + // Now parse the actual propeller definition: + float cg[3]; + cg[0] = attrf(a, "x"); + cg[1] = attrf(a, "y"); + cg[2] = attrf(a, "z"); + float mass = attrf(a, "mass") * LBS2KG; + float moment = attrf(a, "moment"); + float radius = attrf(a, "radius"); + float speed = attrf(a, "cruise-speed") * KTS2MPS; + float omega = attrf(a, "cruise-rpm") * RPM2RAD; + float power = attrf(a, "cruise-power") * HP2W; + float rho = Atmosphere::getStdDensity(attrf(a, "cruise-alt") * FT2M); + + Propeller* prop = new Propeller(radius, speed, omega, rho, power); + PropEngine* thruster = new PropEngine(prop, eng, moment); + _airplane.addThruster(thruster, mass, cg); + if(a->hasAttribute("takeoff-power")) { float power0 = attrf(a, "takeoff-power") * HP2W; float omega0 = attrf(a, "takeoff-rpm") * RPM2RAD; diff --git a/src/FDM/YASim/FGFDM.hpp b/src/FDM/YASim/FGFDM.hpp index d5e02471d..66a842ba1 100644 --- a/src/FDM/YASim/FGFDM.hpp +++ b/src/FDM/YASim/FGFDM.hpp @@ -41,6 +41,8 @@ private: int parseAxis(const char* name); int parseOutput(const char* name); void parseWeight(XMLAttributes* a); + void parseTurbineEngine(XMLAttributes* a); + void parsePistonEngine(XMLAttributes* a); void parsePropeller(XMLAttributes* a); bool eq(const char* a, const char* b); bool caseeq(const char* a, const char* b); diff --git a/src/FDM/YASim/Makefile.am b/src/FDM/YASim/Makefile.am index 2d4e557ae..2311fbb11 100644 --- a/src/FDM/YASim/Makefile.am +++ b/src/FDM/YASim/Makefile.am @@ -18,9 +18,11 @@ SHARED_SOURCE_FILES = \ Jet.cpp Jet.hpp \ Math.cpp Math.hpp \ Model.cpp Model.hpp \ - PistonEngine.cpp PistonEngine.hpp \ PropEngine.cpp PropEngine.hpp \ Propeller.cpp Propeller.hpp \ + Engine.hpp \ + PistonEngine.cpp PistonEngine.hpp \ + TurbineEngine.cpp TurbineEngine.hpp \ RigidBody.cpp RigidBody.hpp \ Rotor.cpp Rotor.hpp \ Rotorblade.cpp Rotorblade.hpp \ diff --git a/src/FDM/YASim/PropEngine.cpp b/src/FDM/YASim/PropEngine.cpp index 9b7afdc67..a6474bc90 100644 --- a/src/FDM/YASim/PropEngine.cpp +++ b/src/FDM/YASim/PropEngine.cpp @@ -113,6 +113,7 @@ void PropEngine::stabilize() float ptau, dummy; _prop->calc(_rho, speed, _omega * _gearRatio, &dummy, &ptau); _eng->calc(_pressure, _temp, _omega); + _eng->stabilize(); float etau = _eng->getTorque(); float tdiff = etau - ptau; @@ -157,6 +158,7 @@ void PropEngine::integrate(float dt) _prop->calc(_rho, speed, _omega * _gearRatio, &thrust, &propTorque); _eng->calc(_pressure, _temp, _omega); + _eng->integrate(dt); engTorque = _eng->getTorque(); _fuelFlow = _eng->getFuelFlow(); diff --git a/src/FDM/YASim/PropEngine.hpp b/src/FDM/YASim/PropEngine.hpp index 92ad8549e..4094b2d2c 100644 --- a/src/FDM/YASim/PropEngine.hpp +++ b/src/FDM/YASim/PropEngine.hpp @@ -2,17 +2,19 @@ #define _PROPENGINE_HPP #include "Thruster.hpp" +#include "Engine.hpp" namespace yasim { class Propeller; -class Engine; class PropEngine : public Thruster { public: PropEngine(Propeller* prop, Engine* eng, float moment); virtual ~PropEngine(); + void setEngine(Engine* eng) { delete _eng; _eng = eng; } + void setMagnetos(int magnetos); void setAdvance(float advance); void setPropPitch(float proppitch); diff --git a/src/FDM/YASim/TurbineEngine.cpp b/src/FDM/YASim/TurbineEngine.cpp new file mode 100644 index 000000000..4be094e18 --- /dev/null +++ b/src/FDM/YASim/TurbineEngine.cpp @@ -0,0 +1,61 @@ +#include "Atmosphere.hpp" + +#include "TurbineEngine.hpp" + +namespace yasim { + +TurbineEngine::TurbineEngine(float power, float omega, float alt, + float flatRating) +{ + _rho0 = Atmosphere::getStdDensity(0); + _maxTorque = (power/omega) * _rho0 / Atmosphere::getStdDensity(alt); + _flatRating = flatRating; + _bsfc = 0.047; // == 0.5 lb/hr per hp + _n2Min = 65; + _n2Max = 100; + + _rho = _rho0; + _omega = 0; + _n2 = _n2Target = _n2Min; + _torque = 0; + _fuelFlow = 0; +} + +void TurbineEngine::setOutputFromN2() +{ + float frac = (_n2 - _n2Min) / (_n2Max - _n2Min); + _torque = frac * _maxTorque * (_rho / _rho0); + _fuelFlow = _bsfc * _torque * _omega; +} + +void TurbineEngine::stabilize() +{ + _n2 = _n2Target; + setOutputFromN2(); +} + +void TurbineEngine::integrate(float dt) +{ + // Low-pass the N2 speed to give a realistic spooling time. See + // the notes in Jet::setSpooling() for details; this corresponds + // to a hard-coded spool time of 2 seconds. + const float DECAY = 1.15; + _n2 = (_n2 + dt * DECAY * _n2Target)/(1 + dt * DECAY); + setOutputFromN2(); +} + +void TurbineEngine::calc(float pressure, float temp, float omega) +{ + _omega = omega; + _rho = Atmosphere::calcStdDensity(pressure, temp); + + float torque = _throttle * _maxTorque * _rho / _rho0; + float power = torque * omega; + if(power > _flatRating) + torque = _flatRating / omega; + + float frac = torque / (_maxTorque * (_rho / _rho0)); + _n2Target = _n2Min + (_n2Max - _n2Min) * frac; +} + +}; // namespace yasim diff --git a/src/FDM/YASim/TurbineEngine.hpp b/src/FDM/YASim/TurbineEngine.hpp new file mode 100644 index 000000000..09c0233d2 --- /dev/null +++ b/src/FDM/YASim/TurbineEngine.hpp @@ -0,0 +1,46 @@ +#ifndef _TURBINEENGINE_HPP +#define _TURBINEENGINE_HPP + +#include "Engine.hpp" + +namespace yasim { + +class TurbineEngine : public Engine { +public: + virtual TurbineEngine* isTurbineEngine() { return this; } + + TurbineEngine(float power, float omega, float alt, float flatRating); + void setN2Range(float min, float max) { _n2Min = min; _n2Max = max; } + void setFuelConsumption(float bsfc) { _bsfc = bsfc; } + + virtual void calc(float pressure, float temp, float speed); + virtual void stabilize(); + virtual void integrate(float dt); + + virtual float getTorque() { return _torque; } + virtual float getFuelFlow() { return _fuelFlow; } + float getN2() { return _n2; } + +private: + void setOutputFromN2(); + + float _maxTorque; + float _flatRating; + float _rho0; + float _bsfc; // SI units! kg/s per watt + float _n2Min; + float _n2Max; + + float _n2Target; + float _torqueTarget; + float _fuelFlowTarget; + + float _n2; + float _rho; + float _omega; + float _torque; + float _fuelFlow; +}; + +}; // namespace yasim +#endif // _TURBINEENGINE_HPP