From d3cca375dcbe4fe8b5c66ef6449fe20c3f4ab129 Mon Sep 17 00:00:00 2001 From: andy Date: Wed, 27 Feb 2002 00:18:57 +0000 Subject: [PATCH] Basically complete support for piston engine startup, including power loss due to single-magneto operation. Seems to work. --- src/FDM/YASim/ControlMap.cpp | 6 +++-- src/FDM/YASim/PistonEngine.cpp | 45 +++++++++++++++++++++++----------- src/FDM/YASim/PistonEngine.hpp | 3 +++ src/FDM/YASim/PropEngine.cpp | 12 ++++----- 4 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/FDM/YASim/ControlMap.cpp b/src/FDM/YASim/ControlMap.cpp index 9cd985304..a023d91f3 100644 --- a/src/FDM/YASim/ControlMap.cpp +++ b/src/FDM/YASim/ControlMap.cpp @@ -77,6 +77,8 @@ void ControlMap::addMapping(int input, int type, void* object, int options) map->src0 = map->dst0 = 0; if(type==FLAP0 || type==FLAP1 || type==STEER) map->src0 = map->dst0 = -1; + if(type==MAGNETOS) + map->src1 = map->dst1 = 3; // And add it to the approproate vectors. Vector* maps = (Vector*)_inputs.get(input); @@ -141,8 +143,8 @@ void ControlMap::applyControls() switch(o->type) { case THROTTLE: ((Thruster*)obj)->setThrottle(lval); break; case MIXTURE: ((Thruster*)obj)->setMixture(lval); break; - case STARTER: ((Thruster*)obj)->setStarter(bool(lval)); break; - case MAGNETOS: ((PropEngine*)obj)->setMagnetos(int(lval)); break; + case STARTER: ((Thruster*)obj)->setStarter((bool)lval); break; + case MAGNETOS: ((PropEngine*)obj)->setMagnetos((int)lval); break; case ADVANCE: ((PropEngine*)obj)->setAdvance(lval); break; case REHEAT: ((Jet*)obj)->setReheat(lval); break; case VECTOR: ((Jet*)obj)->setRotation(lval); break; diff --git a/src/FDM/YASim/PistonEngine.cpp b/src/FDM/YASim/PistonEngine.cpp index 45db6e479..360c04a3f 100644 --- a/src/FDM/YASim/PistonEngine.cpp +++ b/src/FDM/YASim/PistonEngine.cpp @@ -5,6 +5,7 @@ namespace yasim { const static float HP2W = 745.7; const static float CIN2CM = 1.6387064e-5; +const static float RPM2RADPS = 0.1047198; PistonEngine::PistonEngine(float power, float speed) { @@ -71,9 +72,14 @@ void PistonEngine::setThrottle(float t) _throttle = t; } +void PistonEngine::setRunning(bool r) +{ + _running = r; +} + void PistonEngine::setStarter(bool s) { - _starter = s; + _cranking = s; } void PistonEngine::setMagnetos(int m) @@ -123,19 +129,10 @@ float PistonEngine::getEGT() void PistonEngine::calc(float pressure, float temp, float speed) { - if (_magnetos == 0) { - _running = false; - _mp = pressure; - _torque = 0; - _fuelFlow = 0; - _egt = 80; // FIXME: totally made-up - return; - } - - _running = true; - _cranking = false; - - // TODO: degrade performance on single magneto + if(_magnetos == 0 || speed < 200*RPM2RADPS) + _running = false; + else + _running = true; // Calculate manifold pressure as ambient pressure modified for // turbocharging and reduced by the throttle setting. According @@ -178,11 +175,30 @@ void PistonEngine::calc(float pressure, float temp, float speed) else burned = _fuelFlow + (burnable-_fuelFlow)*(r-.625)*(4.0/3.0); + // Correct for engine control state + if(!_running) + burned = 0; + if(_magnetos < 3) + burned *= 0.9; + // And finally the power is just the reference power scaled by the // amount of fuel burned, and torque is that divided by RPM. float power = _power0 * burned/_f0; _torque = power/speed; + // Figure that the starter motor produces 20% of the engine's + // cruise torque. + if(_cranking && !_running) + _torque += 0.20 * _power0/_omega0; + + // Also, add a negative torque of 10% of cruise, to represent + // internal friction. Propeller aerodynamic friction is too low + // at low RPMs to provide a good deceleration. Interpolate it + // away as we approach cruise RPMs, though, to prevent interaction + // with the power computations. Ugly. + if(speed > 0 && speed < _omega0) + _torque -= 0.05 * (_power0/_omega0) * (1 - speed/_omega0); + // Now EGT. This one gets a little goofy. We can calculate the // work done by an isentropically expanding exhaust gas as the // mass of the gas times the specific heat times the change in @@ -204,6 +220,7 @@ void PistonEngine::calc(float pressure, float temp, float speed) float specHeat = 1300; float corr = 1.0/(Math::pow(_compression, 0.4) - 1); _egt = corr * (power * 1.1) / (massFlow * specHeat); + if(_egt < temp) _egt = temp; } }; // namespace yasim diff --git a/src/FDM/YASim/PistonEngine.hpp b/src/FDM/YASim/PistonEngine.hpp index b8d4cb565..1e61da539 100644 --- a/src/FDM/YASim/PistonEngine.hpp +++ b/src/FDM/YASim/PistonEngine.hpp @@ -17,6 +17,9 @@ public: void setMixture(float mixture); void setBoost(float boost); // fraction of turbo-mul used + // For solver use + void setRunning(bool r); + float getMaxPower(); // max sea-level power void calc(float pressure, float temp, float speed); diff --git a/src/FDM/YASim/PropEngine.cpp b/src/FDM/YASim/PropEngine.cpp index b790cbeb9..0c5c5e34f 100644 --- a/src/FDM/YASim/PropEngine.cpp +++ b/src/FDM/YASim/PropEngine.cpp @@ -82,10 +82,11 @@ void PropEngine::stabilize() { float speed = -Math::dot3(_wind, _dir); _eng->setThrottle(_throttle); - _eng->setStarter(_starter); - _eng->setMagnetos(true); // FIXME: otherwise, an infinite loop _eng->setMixture(_mixture); + _eng->setMagnetos(3); + _eng->setRunning(true); + if(_variable) { _omega = _minOmega + _advance * (_maxOmega - _minOmega); _prop->modPitch(1e6); // Start at maximum pitch and move down @@ -117,6 +118,9 @@ void PropEngine::stabilize() else _prop->modPitch(1-(step*0.005)); } } + + // ...and back off + _eng->setRunning(false); } void PropEngine::integrate(float dt) @@ -143,10 +147,6 @@ void PropEngine::integrate(float dt) float rotacc = (engTorque-propTorque)/Math::abs(_moment); _omega += dt * rotacc; - // Clamp to a 500 rpm idle. This should probably be settable, and - // needs to go away when the startup code gets written. -// if(_omega < 52.3) _omega = 52.3; - // Store the total angular momentum into _gyro Math::mul3(_omega*_moment, _dir, _gyro);