]> git.mxchange.org Git - flightgear.git/blobdiff - src/FDM/YASim/PropEngine.cpp
FGPUIDialog: fix reading from already free'd memory.
[flightgear.git] / src / FDM / YASim / PropEngine.cpp
index 0213358fc43d8ceacdb67754634504a51ccc64dc..c6581f4453e03980c5dab72ae38ad42e9594a02a 100644 (file)
@@ -17,6 +17,7 @@ PropEngine::PropEngine(Propeller* prop, Engine* eng, float moment)
     _eng = eng;
     _moment = moment;
     _fuel = true;
+    _contra = false;
 }
 
 PropEngine::~PropEngine()
@@ -41,6 +42,12 @@ void PropEngine::setPropPitch(float proppitch)
     _prop->setPropPitch(proppitch);
 }
 
+void PropEngine::setPropFeather(int state)
+{
+    // toggle prop feathering on/off
+    _prop->setPropFeather(state);
+}
+
 void PropEngine::setVariableProp(float min, float max)
 {
     _variable = true;
@@ -99,6 +106,8 @@ void PropEngine::stabilize()
 
     _eng->setStarter(false);
     _eng->setMagnetos(3);
+
+    bool running_state = _eng->isRunning();
     _eng->setRunning(true);
 
     if(_variable) {
@@ -110,14 +119,27 @@ void PropEngine::stabilize()
 
     bool goingUp = false;
     float step = 10;
-    while(true) {
+
+    // If we cannot manage this in 100 iterations, give up.
+    for (int n = 0; n < 100; n++) {
        float ptau, thrust;
        _prop->calc(_rho, speed, _omega * _gearRatio, &thrust, &ptau);
        _eng->calc(_pressure, _temp, _omega);
         _eng->stabilize();
 
-        // Compute torque as seen by the engine's end of the
-        // gearbox.
+        // Do it again -- the turbo sets the target MP in the first
+        // run, stabilize sets the current to the target, then we need
+        // to run again to get the correct output torque.  Clumsy, but
+        // it works without side effects (other than solver
+        // performance).  In the future, the Engine objects should
+        // store state to allow them to do the work themselves.
+       _eng->calc(_pressure, _temp, _omega);
+
+        // Compute torque as seen by the engine's end of the gearbox.
+        // The propeller will be moving more slowly (for gear ratios
+        // less than one), so it's torque will be higher than the
+        // engine's, so multiply by _gearRatio to get the engine-side
+        // value.
         ptau *= _gearRatio;
         float etau = _eng->getTorque();
        float tdiff = etau - ptau;
@@ -141,7 +163,7 @@ void PropEngine::stabilize()
     }
 
     // ...and back off
-    _eng->setRunning(false);
+    _eng->setRunning(running_state);
 }
 
 void PropEngine::init()
@@ -164,6 +186,9 @@ void PropEngine::integrate(float dt)
     _eng->setFuelState(_fuel);
     
     _prop->calc(_rho, speed, _omega * _gearRatio, &thrust, &propTorque);
+    if(_omega == 0.0)
+        _omega = 0.001; // hack to get around reports of NaNs somewhere...
+    propTorque *= _gearRatio;
     _eng->calc(_pressure, _temp, _omega);
     _eng->integrate(dt);
     engTorque = _eng->getTorque();
@@ -184,16 +209,20 @@ void PropEngine::integrate(float dt)
         _omega = 0 - _omega;    // don't allow negative RPM
                                 // FIXME: introduce proper windmilling
 
-    // Store the total angular momentum into _gyro
-    Math::mul3(_omega*momt, _dir, _gyro);
+    // Store the total angular momentum into _gyro, unless the
+    // propeller is a counter-rotating pair (which has zero net
+    // angular momentum, even though it *does* have an MoI for
+    // acceleration purposes).
+    Math::mul3(_contra ? 0 : _omega*momt, _dir, _gyro);
 
     // Accumulate the engine torque, it acts on the body as a whole.
     // (Note: engine torque, not propeller torque.  They can be
     // different, but the difference goes to accelerating the
     // rotation.  It is the engine torque that is felt at the shaft
-    // and works on the body.)
+    // and works on the body.) (Note 2: contra-rotating propellers do
+    // not exert net torque on the aircraft).
     float tau = _moment < 0 ? engTorque : -engTorque;
-    Math::mul3(tau, _dir, _torque);
+    Math::mul3(_contra ? 0 : tau, _dir, _torque);
 
     // Iterate the propeller governor, if we have one.  Since engine
     // torque is basically constant with RPM, we want to make the
@@ -203,7 +232,8 @@ void PropEngine::integrate(float dt)
     // _current_ RPM.  Seek to that.  This is sort of a continuous
     // Newton-Raphson, basically.
     if(_variable) {
-       float targetOmega = _minOmega + _advance*(_maxOmega-_minOmega);
+       float targetPropSpd = _minOmega + _advance*(_maxOmega-_minOmega);
+        float targetOmega = targetPropSpd / _gearRatio; // -> "engine omega"
        float ratio2 = (_omega*_omega)/(targetOmega*targetOmega);
        float targetTorque = engTorque * ratio2;