1 #include "Atmosphere.hpp"
3 #include "PistonEngine.hpp"
6 PistonEngine::PistonEngine(float power, float speed)
8 // Presume a BSFC (in lb/hour per HP) of 0.45. In SI that becomes
9 // (2.2 lb/kg, 745.7 W/hp, 3600 sec/hour) 3.69e-07 kg/Ws.
10 _f0 = power * 3.69e-07;
15 // We must be at sea level under standard conditions
16 _rho0 = Atmosphere::getStdDensity(0);
18 // Further presume that takeoff is (duh) full throttle and
19 // peak-power, that means that by our efficiency function, we are
20 // at 11/8 of "ideal" fuel flow.
21 float realFlow = _f0 * (11.0/8.0);
22 _mixCoeff = realFlow * 1.1 / _omega0;
25 _maxMP = 1e6; // No waste gate on non-turbo engines.
28 void PistonEngine::setTurboParams(float turbo, float maxMP)
33 // This changes the "sea level" manifold air density
34 float P0 = Atmosphere::getStdPressure(0);
35 float P = P0 * _turbo;
36 if(P > _maxMP) P = _maxMP;
37 float T = Atmosphere::getStdTemperature(0) * Math::pow(P/P0, 2./7.);
38 _rho0 = P / (287.1 * T);
41 float PistonEngine::getPower()
46 void PistonEngine::setThrottle(float t)
51 void PistonEngine::setMixture(float m)
56 void PistonEngine::calc(float P, float T, float speed,
57 float* torqueOut, float* fuelFlowOut)
59 // The actual fuel flow
60 float fuel = _mixture * _mixCoeff * speed;
62 // manifold air density
64 float P1 = P * _turbo;
65 if(P1 > _maxMP) P1 = _maxMP;
66 T *= Math::pow(P1/P, 2./7.);
69 float density = P / (287.1 * T);
71 float rho = density * _throttle;
73 // How much fuel could be burned with ideal (i.e. uncorrected!)
75 float burnable = _f0 * (rho/_rho0) * (speed/_omega0);
77 // Calculate the fuel that actually burns to produce work. The
78 // idea is that less than 5/8 of ideal, we get complete
79 // combustion. We use up all the oxygen at 1 3/8 of ideal (that
80 // is, you need to waste fuel to use all your O2). In between,
81 // interpolate. This vaguely matches a curve I copied out of a
82 // book for a single engine. Shrug.
84 float r = fuel/burnable;
85 if (burnable == 0) burned = 0;
86 else if(r < .625) burned = fuel;
87 else if(r > 1.375) burned = burnable;
88 else burned = fuel + (burnable-fuel)*(r-.625)*(4.0/3.0);
90 // And finally the power is just the reference power scaled by the
91 // amount of fuel burned.
92 float power = _power0 * burned/_f0;
94 *torqueOut = power/speed;