1
0
Fork 0

Fuel consumption. Simple implementation without support for tank selection

or engine-specific feeds.
This commit is contained in:
andy 2002-11-30 06:12:20 +00:00
parent bcf9fa3695
commit 388d714fdc
8 changed files with 60 additions and 4 deletions

View file

@ -62,7 +62,28 @@ void Airplane::iterate(float dt)
_model.iterate(); _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() ControlMap* Airplane::getControlMap()
@ -189,6 +210,11 @@ float Airplane::getFuelDensity(int tank)
return ((Tank*)_tanks.get(tank))->density; return ((Tank*)_tanks.get(tank))->density;
} }
float Airplane::getTankCapacity(int tank)
{
return ((Tank*)_tanks.get(tank))->cap;
}
void Airplane::setWeight(float weight) void Airplane::setWeight(float weight)
{ {
_emptyWeight = weight; _emptyWeight = weight;
@ -298,6 +324,7 @@ void Airplane::setFuelFraction(float frac)
int i; int i;
for(i=0; i<_tanks.size(); i++) { for(i=0; i<_tanks.size(); i++) {
Tank* t = (Tank*)_tanks.get(i); Tank* t = (Tank*)_tanks.get(i);
t->fill = frac * t->cap;
_model.getBody()->setMass(t->handle, t->cap * frac); _model.getBody()->setMass(t->handle, t->cap * frac);
} }
} }

View file

@ -57,6 +57,7 @@ public:
void setFuelFraction(float frac); // 0-1, total amount of fuel void setFuelFraction(float frac); // 0-1, total amount of fuel
float getFuel(int tank); // in kg! float getFuel(int tank); // in kg!
float getFuelDensity(int tank); // kg/m^3 float getFuelDensity(int tank); // kg/m^3
float getTankCapacity(int tank);
void compile(); // generate point masses & such, then solve void compile(); // generate point masses & such, then solve
void initEngines(); void initEngines();

View file

@ -148,7 +148,7 @@ void FGFDM::startElement(const char* name, const XMLAttributes &atts)
float n2max = attrf(a, "n2-max", 103); float n2max = attrf(a, "n2-max", 103);
j->setRPMs(n1min, n1max, n2min, n2max); 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("egt")) j->setEGT(attrf(a, "egt"));
if(a->hasAttribute("epr")) j->setEPR(attrf(a, "epr")); if(a->hasAttribute("epr")) j->setEPR(attrf(a, "epr"));
if(a->hasAttribute("exhaust-speed")) if(a->hasAttribute("exhaust-speed"))
@ -328,11 +328,22 @@ void FGFDM::setOutputProperties()
p->prop->setFloatValue(val); 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++) { for(i=0; i<_airplane.numTanks(); i++) {
fuelDensity = _airplane.getFuelDensity(i); fuelDensity = _airplane.getFuelDensity(i);
sprintf(buf, "/consumables/fuel/tank[%d]/level-gal_us", i); sprintf(buf, "/consumables/fuel/tank[%d]/level-gal_us", i);
fgSetFloat(buf, CM2GALS*_airplane.getFuel(i)/fuelDensity); 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++) { for(i=0; i<_thrusters.size(); i++) {

View file

@ -31,6 +31,7 @@ Jet::Jet()
// And sanify the remaining junk, just in case. // And sanify the remaining junk, just in case.
_running = true; _running = true;
_cranking = false; _cranking = false;
_fuel = true;
_epr = 1; _epr = 1;
_fuelFlow = 0; _fuelFlow = 0;
_egt = 273; _egt = 273;
@ -148,6 +149,12 @@ void Jet::integrate(float dt)
_pressureCorrect = statP/P0; _pressureCorrect = statP/P0;
_tempCorrect = Math::sqrt(statT/T0); _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 // Linearly taper maxThrust to zero at vMax
float vCorr = 1 - (speed/_vMax); float vCorr = 1 - (speed/_vMax);

View file

@ -12,6 +12,7 @@ PistonEngine::PistonEngine(float power, float speed)
_boost = 1; _boost = 1;
_running = false; _running = false;
_cranking = false; _cranking = false;
_fuel = true;
// Presume a BSFC (in lb/hour per HP) of 0.45. In SI that becomes // 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. // (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) if(_magnetos == 0 || speed < 200*RPM2RADPS)
_running = false; _running = false;
else if(_fuel == false)
_running = false;
else else
_running = true; _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 // mixture setting. Not all of this will burn with the same
// efficiency. // efficiency.
_fuelFlow = _mixture * speed * _mixCoeff; _fuelFlow = _mixture * speed * _mixCoeff;
if(_fuel == false) _fuelFlow = 0;
// How much fuel could be burned with ideal (i.e. uncorrected!) // How much fuel could be burned with ideal (i.e. uncorrected!)
// combustion. // combustion.

View file

@ -16,6 +16,7 @@ public:
void setMagnetos(int magnetos); void setMagnetos(int magnetos);
void setMixture(float mixture); void setMixture(float mixture);
void setBoost(float boost); // fraction of turbo-mul used void setBoost(float boost); // fraction of turbo-mul used
void setFuelState(bool hasFuel) { _fuel = hasFuel; }
// For solver use // For solver use
void setRunning(bool r); void setRunning(bool r);
@ -48,6 +49,7 @@ private:
int _magnetos; // 0=off, 1=right, 2=left, 3=both int _magnetos; // 0=off, 1=right, 2=left, 3=both
float _mixture; float _mixture;
float _boost; float _boost;
bool _fuel;
// Runtime state/output: // Runtime state/output:
bool _running; bool _running;

View file

@ -15,6 +15,7 @@ PropEngine::PropEngine(Propeller* prop, PistonEngine* eng, float moment)
_prop = prop; _prop = prop;
_eng = eng; _eng = eng;
_moment = moment; _moment = moment;
_fuel = true;
} }
PropEngine::~PropEngine() PropEngine::~PropEngine()
@ -140,6 +141,7 @@ void PropEngine::integrate(float dt)
_eng->setStarter(_starter); _eng->setStarter(_starter);
_eng->setMagnetos(_magnetos); _eng->setMagnetos(_magnetos);
_eng->setMixture(_mixture); _eng->setMixture(_mixture);
_eng->setFuelState(_fuel);
_prop->calc(_rho, speed, _omega, &thrust, &propTorque); _prop->calc(_rho, speed, _omega, &thrust, &propTorque);
_eng->calc(_pressure, _temp, _omega); _eng->calc(_pressure, _temp, _omega);

View file

@ -31,6 +31,7 @@ public:
void setThrottle(float throttle); void setThrottle(float throttle);
void setMixture(float mixture); void setMixture(float mixture);
void setStarter(bool starter); void setStarter(bool starter);
void setFuelState(bool hasFuel) { _fuel = hasFuel; }
// Dynamic output // Dynamic output
virtual bool isRunning()=0; virtual bool isRunning()=0;
@ -38,7 +39,7 @@ public:
virtual void getThrust(float* out)=0; virtual void getThrust(float* out)=0;
virtual void getTorque(float* out)=0; virtual void getTorque(float* out)=0;
virtual void getGyro(float* out)=0; virtual void getGyro(float* out)=0;
virtual float getFuelFlow()=0; virtual float getFuelFlow()=0; // in kg/s
// Runtime instructions // Runtime instructions
void setWind(float* wind); void setWind(float* wind);
@ -53,6 +54,7 @@ protected:
float _throttle; float _throttle;
float _mixture; float _mixture;
bool _starter; // true=engaged, false=disengaged bool _starter; // true=engaged, false=disengaged
bool _fuel; // true=available, false=out
float _wind[3]; float _wind[3];
float _pressure; float _pressure;