The starter isn't working yet, so the engine just springs to life.
void* obj = o->object;
switch(o->type) {
- case THROTTLE: ((Thruster*)obj)->setThrottle(lval); break;
- case MIXTURE: ((Thruster*)obj)->setMixture(lval); break;
- case ADVANCE: ((PropEngine*)obj)->setAdvance(lval); break;
- case REHEAT: ((Jet*)obj)->setReheat(lval); break;
- case VECTOR: ((Jet*)obj)->setRotation(lval); break;
- case BRAKE: ((Gear*)obj)->setBrake(lval); break;
- case STEER: ((Gear*)obj)->setRotation(lval); break;
- case EXTEND: ((Gear*)obj)->setExtension(lval); break;
- case SLAT: ((Wing*)obj)->setSlat(lval); break;
- case FLAP0: ((Wing*)obj)->setFlap0(lval, rval); break;
- case FLAP1: ((Wing*)obj)->setFlap1(lval, rval); break;
- case SPOILER: ((Wing*)obj)->setSpoiler(lval, rval); break;
+ 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 ADVANCE: ((PropEngine*)obj)->setAdvance(lval); break;
+ case REHEAT: ((Jet*)obj)->setReheat(lval); break;
+ case VECTOR: ((Jet*)obj)->setRotation(lval); break;
+ case BRAKE: ((Gear*)obj)->setBrake(lval); break;
+ case STEER: ((Gear*)obj)->setRotation(lval); break;
+ case EXTEND: ((Gear*)obj)->setExtension(lval); break;
+ case SLAT: ((Wing*)obj)->setSlat(lval); break;
+ case FLAP0: ((Wing*)obj)->setFlap0(lval, rval); break;
+ case FLAP1: ((Wing*)obj)->setFlap1(lval, rval); break;
+ case SPOILER: ((Wing*)obj)->setSpoiler(lval, rval); break;
case BOOST:
((Thruster*)obj)->getPistonEngine()->setBoost(lval);
break;
public:
~ControlMap();
- enum OutputType { THROTTLE, MIXTURE, ADVANCE, REHEAT, PROP,
+ enum OutputType { THROTTLE, MIXTURE, STARTER, MAGNETOS,
+ ADVANCE, REHEAT, PROP,
BRAKE, STEER, EXTEND,
INCIDENCE, FLAP0, FLAP1, SLAT, SPOILER, VECTOR,
BOOST };
{
if(eq(name, "THROTTLE")) return ControlMap::THROTTLE;
if(eq(name, "MIXTURE")) return ControlMap::MIXTURE;
+ if(eq(name, "STARTER")) return ControlMap::STARTER;
+ if(eq(name, "MAGNETOS")) return ControlMap::MAGNETOS;
if(eq(name, "ADVANCE")) return ControlMap::ADVANCE;
if(eq(name, "REHEAT")) return ControlMap::REHEAT;
if(eq(name, "BOOST")) return ControlMap::BOOST;
_n2 = _n2Min;
// And sanify the remaining junk, just in case.
+ _running = true;
+ _cranking = false;
_epr = 1;
_fuelFlow = 0;
_egt = 273;
_rotControl = rot;
}
-
float Jet::getN1()
{
return _n1 * _tempCorrect;
_egt = T0 + beta*ibeta0 * (_egt0 - T0);
}
+bool Jet::isRunning()
+{
+ return _running;
+}
+
+bool Jet::isCranking()
+{
+ return _cranking;
+}
+
void Jet::getThrust(float* out)
{
Math::mul3(_thrust, _dir, out);
float getEGT();
// From Thruster:
+ virtual bool isRunning();
+ virtual bool isCranking();
virtual void getThrust(float* out);
virtual void getTorque(float* out);
virtual void getGyro(float* out);
float _n2Min; // N2 at ground idle
float _n2Max; // N2 at takeoff thrust
+ bool _running; // Is the engine running?
+ bool _cranking; // Is the engine cranking?
float _thrust; // Current thrust
float _epr; // Current EPR
float _n1; // Current UNCORRECTED N1 (percent)
PistonEngine::PistonEngine(float power, float speed)
{
_boost = 1;
+ _running = false;
+ _cranking = false;
// 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.
_throttle = t;
}
+void PistonEngine::setStarter(bool s)
+{
+ _starter = s;
+}
+
+void PistonEngine::setMagnetos(int m)
+{
+ _magnetos = m;
+}
+
void PistonEngine::setMixture(float m)
{
_mixture = m;
_boost = boost;
}
+bool PistonEngine::isRunning()
+{
+ return _running;
+}
+
+bool PistonEngine::isCranking()
+{
+ return _cranking;
+}
+
float PistonEngine::getTorque()
{
return _torque;
void PistonEngine::calc(float pressure, float temp, float speed)
{
+ if (_magnetos == 0) {
+ _running = false;
+ _mp = _rho0;
+ _torque = 0;
+ _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
// turbocharging and reduced by the throttle setting. According
// to Dave Luff, minimum throttle at sea level corresponds to 6"
void setCompression(float c);
void setThrottle(float throttle);
+ void setStarter(bool starter);
+ void setMagnetos(int magnetos);
void setMixture(float mixture);
void setBoost(float boost); // fraction of turbo-mul used
float getMaxPower(); // max sea-level power
void calc(float pressure, float temp, float speed);
+ bool isRunning();
+ bool isCranking();
float getTorque();
float getFuelFlow();
float getMP();
// Runtime settables:
float _throttle;
+ bool _starter; // true=engaged, false=disengaged
+ int _magnetos; // 0=off, 1=right, 2=left, 3=both
float _mixture;
float _boost;
// Runtime state/output:
+ bool _running;
+ bool _cranking;
float _mp;
float _torque;
float _fuelFlow;
delete _eng;
}
+void PropEngine::setMagnetos(int pos)
+{
+ _magnetos = pos;
+}
+
void PropEngine::setAdvance(float advance)
{
_advance = Math::clamp(advance, 0, 1);
_maxOmega = max;
}
+bool PropEngine::isRunning()
+{
+ return _eng->isRunning();
+}
+
+bool PropEngine::isCranking()
+{
+ return _eng->isCranking();
+}
+
float PropEngine::getOmega()
{
return _omega;
{
float speed = -Math::dot3(_wind, _dir);
_eng->setThrottle(_throttle);
+ _eng->setStarter(_starter);
+ _eng->setMagnetos(true); // FIXME: otherwise, an infinite loop
_eng->setMixture(_mixture);
if(_variable) {
float propTorque, engTorque, thrust;
_eng->setThrottle(_throttle);
+ _eng->setStarter(_starter);
+ _eng->setMagnetos(_magnetos);
_eng->setMixture(_mixture);
_prop->calc(_rho, speed, _omega, &thrust, &propTorque);
// 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;
+// if(_omega < 52.3) _omega = 52.3;
// Store the total angular momentum into _gyro
Math::mul3(_omega*_moment, _dir, _gyro);
PropEngine(Propeller* prop, PistonEngine* eng, float moment);
virtual ~PropEngine();
+ void setMagnetos(int magnetos);
void setAdvance(float advance);
void setVariableProp(float min, float max);
virtual Propeller* getPropeller() { return _prop; }
// Dynamic output
+ virtual bool isRunning();
+ virtual bool isCranking();
virtual void getThrust(float* out);
virtual void getTorque(float* out);
virtual void getGyro(float* out);
PistonEngine* _eng;
bool _variable;
+ int _magnetos; // 0=off, 1=right, 2=left, 3=both
float _advance; // control input, 0-1
float _maxOmega;
float _minOmega;
_thrust = thrust;
}
+bool SimpleJet::isRunning()
+{
+ return true;
+}
+
+bool SimpleJet::isCranking()
+{
+ return false;
+}
+
void SimpleJet::getThrust(float* out)
{
Math::mul3(_thrust * _throttle, _dir, out);
public:
SimpleJet();
void setThrust(float thrust);
+ virtual bool isRunning();
+ virtual bool isCranking();
virtual void getThrust(float* out);
virtual void getTorque(float* out);
virtual void getGyro(float* out);
for(i=0; i<3; i++) _pos[i] = _wind[i] = 0;
_throttle = 0;
_mixture = 0;
+ _starter = false;
_pressure = _temp = _rho = 0;
}
_mixture = Math::clamp(mixture, 0, 1);
}
+void Thruster::setStarter(bool starter)
+{
+ _starter = starter;
+}
+
void Thruster::setWind(float* wind)
{
int i;
// Controls
void setThrottle(float throttle);
void setMixture(float mixture);
+ void setStarter(bool starter);
// Dynamic output
+ virtual bool isRunning()=0;
+ virtual bool isCranking()=0;
virtual void getThrust(float* out)=0;
virtual void getTorque(float* out)=0;
virtual void getGyro(float* out)=0;
float _dir[3];
float _throttle;
float _mixture;
+ bool _starter; // true=engaged, false=disengaged
float _wind[3];
float _pressure;
SGPropertyNode * node = fgGetNode("engines/engine", i, true);
Thruster* t = model->getThruster(i);
- node->setBoolValue("running", true);
- node->setBoolValue("cranking", false);
+ node->setBoolValue("running", t->isRunning());
+ node->setBoolValue("cranking", t->isCranking());
// Note: assumes all tanks have the same fuel density!
node->setDoubleValue("fuel-flow-gph", CM2GALS * t->getFuelFlow()