From 388d714fdc78956ecd7e8e16fe583caa0261224d Mon Sep 17 00:00:00 2001 From: andy Date: Sat, 30 Nov 2002 06:12:20 +0000 Subject: [PATCH] Fuel consumption. Simple implementation without support for tank selection or engine-specific feeds. --- src/FDM/YASim/Airplane.cpp | 29 ++++++++++++++++++++++++++++- src/FDM/YASim/Airplane.hpp | 1 + src/FDM/YASim/FGFDM.cpp | 15 +++++++++++++-- src/FDM/YASim/Jet.cpp | 7 +++++++ src/FDM/YASim/PistonEngine.cpp | 4 ++++ src/FDM/YASim/PistonEngine.hpp | 2 ++ src/FDM/YASim/PropEngine.cpp | 2 ++ src/FDM/YASim/Thruster.hpp | 4 +++- 8 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/FDM/YASim/Airplane.cpp b/src/FDM/YASim/Airplane.cpp index 1a4e7713a..60081d0a0 100644 --- a/src/FDM/YASim/Airplane.cpp +++ b/src/FDM/YASim/Airplane.cpp @@ -62,7 +62,28 @@ void Airplane::iterate(float dt) _model.iterate(); - // FIXME: Consume fuel + // Consume fuel. This is a really simple implementation that + // assumes all engines draw equally from all tanks in proportion + // to the amount of fuel stored there. Needs to be fixed, but + // that has to wait for a decision as to what the property + // interface will look like. + int i, outOfFuel = 0; + float fuelFlow = 0, totalFuel = 0.00001; // <-- overflow protection + for(i=0; i<_thrusters.size(); i++) + fuelFlow += ((ThrustRec*)_thrusters.get(i))->thruster->getFuelFlow(); + for(i=0; i<_tanks.size(); i++) + totalFuel += ((Tank*)_tanks.get(i))->fill; + for(i=0; i<_tanks.size(); i++) { + Tank* t = (Tank*)_tanks.get(i); + t->fill -= dt * fuelFlow * (t->fill/totalFuel); + if(t->fill <= 0) { + t->fill = 0; + outOfFuel = 1; + } + } + if(outOfFuel) + for(int i=0; i<_thrusters.size(); i++) + ((ThrustRec*)_thrusters.get(i))->thruster->setFuelState(false); } ControlMap* Airplane::getControlMap() @@ -189,6 +210,11 @@ float Airplane::getFuelDensity(int tank) return ((Tank*)_tanks.get(tank))->density; } +float Airplane::getTankCapacity(int tank) +{ + return ((Tank*)_tanks.get(tank))->cap; +} + void Airplane::setWeight(float weight) { _emptyWeight = weight; @@ -298,6 +324,7 @@ void Airplane::setFuelFraction(float frac) int i; for(i=0; i<_tanks.size(); i++) { Tank* t = (Tank*)_tanks.get(i); + t->fill = frac * t->cap; _model.getBody()->setMass(t->handle, t->cap * frac); } } diff --git a/src/FDM/YASim/Airplane.hpp b/src/FDM/YASim/Airplane.hpp index f44d496fc..23cf3b6b6 100644 --- a/src/FDM/YASim/Airplane.hpp +++ b/src/FDM/YASim/Airplane.hpp @@ -57,6 +57,7 @@ public: void setFuelFraction(float frac); // 0-1, total amount of fuel float getFuel(int tank); // in kg! float getFuelDensity(int tank); // kg/m^3 + float getTankCapacity(int tank); void compile(); // generate point masses & such, then solve void initEngines(); diff --git a/src/FDM/YASim/FGFDM.cpp b/src/FDM/YASim/FGFDM.cpp index 74bb94a96..8e7767e9b 100644 --- a/src/FDM/YASim/FGFDM.cpp +++ b/src/FDM/YASim/FGFDM.cpp @@ -148,7 +148,7 @@ void FGFDM::startElement(const char* name, const XMLAttributes &atts) float n2max = attrf(a, "n2-max", 103); j->setRPMs(n1min, n1max, n2min, n2max); - if(a->hasAttribute("tsfc")) j->setTSFC(attrf(a, "tsfc")); + j->setTSFC(attrf(a, "tsfc", 0.8)); if(a->hasAttribute("egt")) j->setEGT(attrf(a, "egt")); if(a->hasAttribute("epr")) j->setEPR(attrf(a, "epr")); if(a->hasAttribute("exhaust-speed")) @@ -328,11 +328,22 @@ void FGFDM::setOutputProperties() p->prop->setFloatValue(val); } - float fuelDensity = 718.95; // default to gasoline: ~6 lb/gal + float totalFuel = 0, totalCap = 0; + float fuelDensity = 720; // in kg/m^3, default to gasoline: ~6 lb/gal for(i=0; i<_airplane.numTanks(); i++) { fuelDensity = _airplane.getFuelDensity(i); sprintf(buf, "/consumables/fuel/tank[%d]/level-gal_us", i); fgSetFloat(buf, CM2GALS*_airplane.getFuel(i)/fuelDensity); + sprintf(buf, "/consumables/fuel/tank[%d]/level-lbs", i); + fgSetFloat(buf, KG2LBS*_airplane.getFuel(i)); + totalFuel += _airplane.getFuel(i); + totalCap += _airplane.getTankCapacity(i); + } + if(totalCap != 0) { + fgSetFloat("/consumables/fuel/total-fuel-lbs", KG2LBS*totalFuel); + fgSetFloat("/consumables/fuel/total-fuel-gals", + CM2GALS*totalFuel/fuelDensity); + fgSetFloat("/consumables/fuel/total-fuel-norm", totalFuel/totalCap); } for(i=0; i<_thrusters.size(); i++) { diff --git a/src/FDM/YASim/Jet.cpp b/src/FDM/YASim/Jet.cpp index 200a743db..edd364bee 100644 --- a/src/FDM/YASim/Jet.cpp +++ b/src/FDM/YASim/Jet.cpp @@ -31,6 +31,7 @@ Jet::Jet() // And sanify the remaining junk, just in case. _running = true; _cranking = false; + _fuel = true; _epr = 1; _fuelFlow = 0; _egt = 273; @@ -148,6 +149,12 @@ void Jet::integrate(float dt) _pressureCorrect = statP/P0; _tempCorrect = Math::sqrt(statT/T0); + // Handle running out of fuel. This is a hack. What should + // really happen is a simulation of ram air torque on the + // turbine. This just forces the engine into ground idle. + if(_fuel == false) + _throttle = 0; + // Linearly taper maxThrust to zero at vMax float vCorr = 1 - (speed/_vMax); diff --git a/src/FDM/YASim/PistonEngine.cpp b/src/FDM/YASim/PistonEngine.cpp index b32dae60c..edc54025d 100644 --- a/src/FDM/YASim/PistonEngine.cpp +++ b/src/FDM/YASim/PistonEngine.cpp @@ -12,6 +12,7 @@ PistonEngine::PistonEngine(float power, float speed) _boost = 1; _running = false; _cranking = false; + _fuel = true; // Presume a BSFC (in lb/hour per HP) of 0.45. In SI that becomes // (2.2 lb/kg, 745.7 W/hp, 3600 sec/hour) 7.62e-08 kg/Ws. @@ -131,6 +132,8 @@ void PistonEngine::calc(float pressure, float temp, float speed) { if(_magnetos == 0 || speed < 200*RPM2RADPS) _running = false; + else if(_fuel == false) + _running = false; else _running = true; @@ -157,6 +160,7 @@ void PistonEngine::calc(float pressure, float temp, float speed) // mixture setting. Not all of this will burn with the same // efficiency. _fuelFlow = _mixture * speed * _mixCoeff; + if(_fuel == false) _fuelFlow = 0; // How much fuel could be burned with ideal (i.e. uncorrected!) // combustion. diff --git a/src/FDM/YASim/PistonEngine.hpp b/src/FDM/YASim/PistonEngine.hpp index 1e61da539..bd7ffb362 100644 --- a/src/FDM/YASim/PistonEngine.hpp +++ b/src/FDM/YASim/PistonEngine.hpp @@ -16,6 +16,7 @@ public: void setMagnetos(int magnetos); void setMixture(float mixture); void setBoost(float boost); // fraction of turbo-mul used + void setFuelState(bool hasFuel) { _fuel = hasFuel; } // For solver use void setRunning(bool r); @@ -48,6 +49,7 @@ private: int _magnetos; // 0=off, 1=right, 2=left, 3=both float _mixture; float _boost; + bool _fuel; // Runtime state/output: bool _running; diff --git a/src/FDM/YASim/PropEngine.cpp b/src/FDM/YASim/PropEngine.cpp index 219734760..0fc35582d 100644 --- a/src/FDM/YASim/PropEngine.cpp +++ b/src/FDM/YASim/PropEngine.cpp @@ -15,6 +15,7 @@ PropEngine::PropEngine(Propeller* prop, PistonEngine* eng, float moment) _prop = prop; _eng = eng; _moment = moment; + _fuel = true; } PropEngine::~PropEngine() @@ -140,6 +141,7 @@ void PropEngine::integrate(float dt) _eng->setStarter(_starter); _eng->setMagnetos(_magnetos); _eng->setMixture(_mixture); + _eng->setFuelState(_fuel); _prop->calc(_rho, speed, _omega, &thrust, &propTorque); _eng->calc(_pressure, _temp, _omega); diff --git a/src/FDM/YASim/Thruster.hpp b/src/FDM/YASim/Thruster.hpp index 8f2d1ceb8..7d6e0c9cd 100644 --- a/src/FDM/YASim/Thruster.hpp +++ b/src/FDM/YASim/Thruster.hpp @@ -31,6 +31,7 @@ public: void setThrottle(float throttle); void setMixture(float mixture); void setStarter(bool starter); + void setFuelState(bool hasFuel) { _fuel = hasFuel; } // Dynamic output virtual bool isRunning()=0; @@ -38,7 +39,7 @@ public: virtual void getThrust(float* out)=0; virtual void getTorque(float* out)=0; virtual void getGyro(float* out)=0; - virtual float getFuelFlow()=0; + virtual float getFuelFlow()=0; // in kg/s // Runtime instructions void setWind(float* wind); @@ -53,6 +54,7 @@ protected: float _throttle; float _mixture; bool _starter; // true=engaged, false=disengaged + bool _fuel; // true=available, false=out float _wind[3]; float _pressure; -- 2.39.5