1
0
Fork 0

Basically complete support for piston engine startup, including power loss

due to single-magneto operation.  Seems to work.
This commit is contained in:
andy 2002-02-27 00:18:57 +00:00
parent 51587dbe75
commit d3cca375dc
4 changed files with 44 additions and 22 deletions

View file

@ -77,6 +77,8 @@ void ControlMap::addMapping(int input, int type, void* object, int options)
map->src0 = map->dst0 = 0; map->src0 = map->dst0 = 0;
if(type==FLAP0 || type==FLAP1 || type==STEER) if(type==FLAP0 || type==FLAP1 || type==STEER)
map->src0 = map->dst0 = -1; map->src0 = map->dst0 = -1;
if(type==MAGNETOS)
map->src1 = map->dst1 = 3;
// And add it to the approproate vectors. // And add it to the approproate vectors.
Vector* maps = (Vector*)_inputs.get(input); Vector* maps = (Vector*)_inputs.get(input);
@ -141,8 +143,8 @@ void ControlMap::applyControls()
switch(o->type) { switch(o->type) {
case THROTTLE: ((Thruster*)obj)->setThrottle(lval); break; case THROTTLE: ((Thruster*)obj)->setThrottle(lval); break;
case MIXTURE: ((Thruster*)obj)->setMixture(lval); break; case MIXTURE: ((Thruster*)obj)->setMixture(lval); break;
case STARTER: ((Thruster*)obj)->setStarter(bool(lval)); break; case STARTER: ((Thruster*)obj)->setStarter((bool)lval); break;
case MAGNETOS: ((PropEngine*)obj)->setMagnetos(int(lval)); break; case MAGNETOS: ((PropEngine*)obj)->setMagnetos((int)lval); break;
case ADVANCE: ((PropEngine*)obj)->setAdvance(lval); break; case ADVANCE: ((PropEngine*)obj)->setAdvance(lval); break;
case REHEAT: ((Jet*)obj)->setReheat(lval); break; case REHEAT: ((Jet*)obj)->setReheat(lval); break;
case VECTOR: ((Jet*)obj)->setRotation(lval); break; case VECTOR: ((Jet*)obj)->setRotation(lval); break;

View file

@ -5,6 +5,7 @@ namespace yasim {
const static float HP2W = 745.7; const static float HP2W = 745.7;
const static float CIN2CM = 1.6387064e-5; const static float CIN2CM = 1.6387064e-5;
const static float RPM2RADPS = 0.1047198;
PistonEngine::PistonEngine(float power, float speed) PistonEngine::PistonEngine(float power, float speed)
{ {
@ -71,9 +72,14 @@ void PistonEngine::setThrottle(float t)
_throttle = t; _throttle = t;
} }
void PistonEngine::setRunning(bool r)
{
_running = r;
}
void PistonEngine::setStarter(bool s) void PistonEngine::setStarter(bool s)
{ {
_starter = s; _cranking = s;
} }
void PistonEngine::setMagnetos(int m) void PistonEngine::setMagnetos(int m)
@ -123,19 +129,10 @@ float PistonEngine::getEGT()
void PistonEngine::calc(float pressure, float temp, float speed) void PistonEngine::calc(float pressure, float temp, float speed)
{ {
if (_magnetos == 0) { if(_magnetos == 0 || speed < 200*RPM2RADPS)
_running = false; _running = false;
_mp = pressure; else
_torque = 0; _running = true;
_fuelFlow = 0;
_egt = 80; // FIXME: totally made-up
return;
}
_running = true;
_cranking = false;
// TODO: degrade performance on single magneto
// Calculate manifold pressure as ambient pressure modified for // Calculate manifold pressure as ambient pressure modified for
// turbocharging and reduced by the throttle setting. According // turbocharging and reduced by the throttle setting. According
@ -178,11 +175,30 @@ void PistonEngine::calc(float pressure, float temp, float speed)
else else
burned = _fuelFlow + (burnable-_fuelFlow)*(r-.625)*(4.0/3.0); 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 // And finally the power is just the reference power scaled by the
// amount of fuel burned, and torque is that divided by RPM. // amount of fuel burned, and torque is that divided by RPM.
float power = _power0 * burned/_f0; float power = _power0 * burned/_f0;
_torque = power/speed; _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 // Now EGT. This one gets a little goofy. We can calculate the
// work done by an isentropically expanding exhaust gas as the // work done by an isentropically expanding exhaust gas as the
// mass of the gas times the specific heat times the change in // 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 specHeat = 1300;
float corr = 1.0/(Math::pow(_compression, 0.4) - 1); float corr = 1.0/(Math::pow(_compression, 0.4) - 1);
_egt = corr * (power * 1.1) / (massFlow * specHeat); _egt = corr * (power * 1.1) / (massFlow * specHeat);
if(_egt < temp) _egt = temp;
} }
}; // namespace yasim }; // namespace yasim

View file

@ -17,6 +17,9 @@ public:
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
// For solver use
void setRunning(bool r);
float getMaxPower(); // max sea-level power float getMaxPower(); // max sea-level power
void calc(float pressure, float temp, float speed); void calc(float pressure, float temp, float speed);

View file

@ -82,10 +82,11 @@ void PropEngine::stabilize()
{ {
float speed = -Math::dot3(_wind, _dir); float speed = -Math::dot3(_wind, _dir);
_eng->setThrottle(_throttle); _eng->setThrottle(_throttle);
_eng->setStarter(_starter);
_eng->setMagnetos(true); // FIXME: otherwise, an infinite loop
_eng->setMixture(_mixture); _eng->setMixture(_mixture);
_eng->setMagnetos(3);
_eng->setRunning(true);
if(_variable) { if(_variable) {
_omega = _minOmega + _advance * (_maxOmega - _minOmega); _omega = _minOmega + _advance * (_maxOmega - _minOmega);
_prop->modPitch(1e6); // Start at maximum pitch and move down _prop->modPitch(1e6); // Start at maximum pitch and move down
@ -117,6 +118,9 @@ void PropEngine::stabilize()
else _prop->modPitch(1-(step*0.005)); else _prop->modPitch(1-(step*0.005));
} }
} }
// ...and back off
_eng->setRunning(false);
} }
void PropEngine::integrate(float dt) void PropEngine::integrate(float dt)
@ -143,10 +147,6 @@ void PropEngine::integrate(float dt)
float rotacc = (engTorque-propTorque)/Math::abs(_moment); float rotacc = (engTorque-propTorque)/Math::abs(_moment);
_omega += dt * rotacc; _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 // Store the total angular momentum into _gyro
Math::mul3(_omega*_moment, _dir, _gyro); Math::mul3(_omega*_moment, _dir, _gyro);