]> git.mxchange.org Git - flightgear.git/commitdiff
Initial checkin of a TurbineEngine implementation. This hasn't been
authorandy <andy>
Sat, 1 May 2004 00:26:33 +0000 (00:26 +0000)
committerandy <andy>
Sat, 1 May 2004 00:26:33 +0000 (00:26 +0000)
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.

src/FDM/YASim/Engine.hpp
src/FDM/YASim/FGFDM.cpp
src/FDM/YASim/FGFDM.hpp
src/FDM/YASim/Makefile.am
src/FDM/YASim/PropEngine.cpp
src/FDM/YASim/PropEngine.hpp
src/FDM/YASim/TurbineEngine.cpp [new file with mode: 0644]
src/FDM/YASim/TurbineEngine.hpp [new file with mode: 0644]

index edbe15d3d2cb76f10979c0fa1ff147f48e8d4580..8be455507bdd30a79083ab0d6082532250e2d3a8 100644 (file)
@@ -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;
 
index 6454f848e5f2d6695046ec4cf29d0e5bd01c6156..577a8c28fc262a729844000d8187aeed6c3b0b1a 100644 (file)
@@ -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;
index d5e02471d65f16f3b5d83d2e0d371fc3adcffc26..66a842ba1350d640589b4725e76fc2b95687b146 100644 (file)
@@ -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);
index 2d4e557ae1b68c8f8bee1ad7f98aa45bd990fc00..2311fbb111a3e94094d7e63e5cad4a7bc1c68368 100644 (file)
@@ -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 \
index 9b7afdc67dc7d9fcc143eb87087cb79db7a2bdba..a6474bc908b3ab8490eba3106c034aa085185129 100644 (file)
@@ -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();
 
index 92ad8549ec545be06a1be32902bb64d26a0cac6b..4094b2d2cd81c2e8ea98c4e2487563b1e6331ec0 100644 (file)
@@ -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 (file)
index 0000000..4be094e
--- /dev/null
@@ -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 (file)
index 0000000..09c0233
--- /dev/null
@@ -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