2001-12-06 18:13:24 +00:00
|
|
|
#include "Atmosphere.hpp"
|
|
|
|
#include "Math.hpp"
|
2001-12-01 06:22:24 +00:00
|
|
|
#include "PistonEngine.hpp"
|
|
|
|
namespace yasim {
|
|
|
|
|
|
|
|
PistonEngine::PistonEngine(float power, float speed)
|
|
|
|
{
|
|
|
|
// 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) 3.69e-07 kg/Ws.
|
|
|
|
_f0 = power * 3.69e-07;
|
|
|
|
|
2001-12-07 20:00:59 +00:00
|
|
|
_power0 = power;
|
2001-12-01 06:22:24 +00:00
|
|
|
_omega0 = speed;
|
|
|
|
|
|
|
|
// We must be at sea level under standard conditions
|
2001-12-06 18:13:24 +00:00
|
|
|
_rho0 = Atmosphere::getStdDensity(0);
|
2001-12-01 06:22:24 +00:00
|
|
|
|
|
|
|
// Further presume that takeoff is (duh) full throttle and
|
|
|
|
// peak-power, that means that by our efficiency function, we are
|
|
|
|
// at 11/8 of "ideal" fuel flow.
|
|
|
|
float realFlow = _f0 * (11.0/8.0);
|
|
|
|
_mixCoeff = realFlow * 1.1 / _omega0;
|
2001-12-06 18:13:24 +00:00
|
|
|
|
|
|
|
_turbo = 1;
|
|
|
|
_maxMP = 1e6; // No waste gate on non-turbo engines.
|
|
|
|
}
|
|
|
|
|
|
|
|
void PistonEngine::setTurboParams(float turbo, float maxMP)
|
|
|
|
{
|
|
|
|
_turbo = turbo;
|
|
|
|
_maxMP = maxMP;
|
|
|
|
|
|
|
|
// This changes the "sea level" manifold air density
|
|
|
|
float P0 = Atmosphere::getStdPressure(0);
|
|
|
|
float P = P0 * _turbo;
|
|
|
|
if(P > _maxMP) P = _maxMP;
|
|
|
|
float T = Atmosphere::getStdTemperature(0) * Math::pow(P/P0, 2./7.);
|
|
|
|
_rho0 = P / (287.1 * T);
|
|
|
|
}
|
|
|
|
|
|
|
|
float PistonEngine::getPower()
|
|
|
|
{
|
2001-12-07 20:00:59 +00:00
|
|
|
return _power0;
|
2001-12-01 06:22:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void PistonEngine::setThrottle(float t)
|
|
|
|
{
|
|
|
|
_throttle = t;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PistonEngine::setMixture(float m)
|
|
|
|
{
|
|
|
|
_mixture = m;
|
|
|
|
}
|
|
|
|
|
2001-12-06 18:13:24 +00:00
|
|
|
void PistonEngine::calc(float P, float T, float speed,
|
2001-12-01 06:22:24 +00:00
|
|
|
float* torqueOut, float* fuelFlowOut)
|
|
|
|
{
|
|
|
|
// The actual fuel flow
|
|
|
|
float fuel = _mixture * _mixCoeff * speed;
|
|
|
|
|
|
|
|
// manifold air density
|
2001-12-06 18:13:24 +00:00
|
|
|
if(_turbo != 1) {
|
|
|
|
float P1 = P * _turbo;
|
|
|
|
if(P1 > _maxMP) P1 = _maxMP;
|
|
|
|
T *= Math::pow(P1/P, 2./7.);
|
|
|
|
P = P1;
|
|
|
|
}
|
|
|
|
float density = P / (287.1 * T);
|
|
|
|
|
2001-12-01 06:22:24 +00:00
|
|
|
float rho = density * _throttle;
|
|
|
|
|
|
|
|
// How much fuel could be burned with ideal (i.e. uncorrected!)
|
|
|
|
// combustion.
|
|
|
|
float burnable = _f0 * (rho/_rho0) * (speed/_omega0);
|
|
|
|
|
|
|
|
// Calculate the fuel that actually burns to produce work. The
|
|
|
|
// idea is that less than 5/8 of ideal, we get complete
|
|
|
|
// combustion. We use up all the oxygen at 1 3/8 of ideal (that
|
|
|
|
// is, you need to waste fuel to use all your O2). In between,
|
|
|
|
// interpolate. This vaguely matches a curve I copied out of a
|
|
|
|
// book for a single engine. Shrug.
|
|
|
|
float burned;
|
|
|
|
float r = fuel/burnable;
|
|
|
|
if (burnable == 0) burned = 0;
|
|
|
|
else if(r < .625) burned = fuel;
|
|
|
|
else if(r > 1.375) burned = burnable;
|
|
|
|
else burned = fuel + (burnable-fuel)*(r-.625)*(4.0/3.0);
|
|
|
|
|
|
|
|
// And finally the power is just the reference power scaled by the
|
|
|
|
// amount of fuel burned.
|
2001-12-07 20:00:59 +00:00
|
|
|
float power = _power0 * burned/_f0;
|
2001-12-01 06:22:24 +00:00
|
|
|
|
|
|
|
*torqueOut = power/speed;
|
|
|
|
*fuelFlowOut = fuel;
|
|
|
|
}
|
|
|
|
|
|
|
|
}; // namespace yasim
|