]> git.mxchange.org Git - flightgear.git/blobdiff - src/FDM/JSBSim/models/FGPropulsion.cpp
Merge branch 'next' of http://git.gitorious.org/fg/flightgear into next
[flightgear.git] / src / FDM / JSBSim / models / FGPropulsion.cpp
index 35f420a5bc38632fabb030ba44e32b9b186db615..da82acf5103aac6884c20e1e9e7da87428b59565 100644 (file)
@@ -6,7 +6,7 @@
  Purpose:      Encapsulates the set of engines and tanks associated
                with this aircraft
 
- ------------- Copyright (C) 2000  Jon S. Berndt (jsb@hal-pc.org) -------------
+ ------------- Copyright (C) 2000  Jon S. Berndt (jon@jsbsim.org) -------------
 
  This program is free software; you can redistribute it and/or modify it under
  the terms of the GNU Lesser General Public License as published by the Free Software
@@ -45,19 +45,27 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGPropulsion.h"
-#include <models/propulsion/FGRocket.h>
-#include <models/propulsion/FGTurbine.h>
-#include <models/propulsion/FGPiston.h>
-#include <models/propulsion/FGElectric.h>
-#include <models/propulsion/FGTurboProp.h>
-#include <input_output/FGPropertyManager.h>
-#include <input_output/FGXMLParse.h>
-#include <math/FGColumnVector3.h>
+#include "models/FGFCS.h"
+#include "models/FGMassBalance.h"
+#include "models/propulsion/FGThruster.h"
+#include "models/propulsion/FGRocket.h"
+#include "models/propulsion/FGTurbine.h"
+#include "models/propulsion/FGPiston.h"
+#include "models/propulsion/FGElectric.h"
+#include "models/propulsion/FGTurboProp.h"
+#include "models/propulsion/FGTank.h"
+#include "input_output/FGPropertyManager.h"
+#include "input_output/FGXMLParse.h"
+#include "math/FGColumnVector3.h"
+#include <iostream>
 #include <sstream>
+#include <cstdlib>
+
+using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id$";
+static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.45 2011/02/13 00:42:45 jberndt Exp $";
 static const char *IdHdr = ID_PROPULSION;
 
 extern short debug_lvl;
@@ -71,12 +79,14 @@ FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec)
 {
   Name = "FGPropulsion";
 
+  InitializedEngines = 0;
   numSelectedFuelTanks = numSelectedOxiTanks = 0;
   numTanks = numEngines = 0;
   numOxiTanks = numFuelTanks = 0;
   ActiveEngine = -1; // -1: ALL, 0: Engine 1, 1: Engine 2 ...
   tankJ.InitMatrix();
-  refuel = false;
+  refuel = dump = false;
+  DumpRate = 0.0;
   fuel_freeze = false;
   TotalFuelQuantity = 0.0;
   IsBound =
@@ -85,6 +95,7 @@ FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec)
   HaveRocketEngine =
   HaveTurboPropEngine =
   HaveElectricEngine = false;
+  HasInitializedEngines = false;
 
   Debug(0);
 }
@@ -95,12 +106,51 @@ FGPropulsion::~FGPropulsion()
 {
   for (unsigned int i=0; i<Engines.size(); i++) delete Engines[i];
   Engines.clear();
-  unbind();
+  for (unsigned int i=0; i<Tanks.size(); i++) delete Tanks[i];
+  Tanks.clear();
   Debug(1);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+bool FGPropulsion::InitModel(void)
+{
+  bool result = true;
+
+  if (!FGModel::InitModel()) return false;
+
+  for (unsigned int i=0; i<numTanks; i++) Tanks[i]->ResetToIC();
+
+  for (unsigned int i=0; i<numEngines; i++) {
+    switch (Engines[i]->GetType()) {
+      case FGEngine::etPiston:
+        ((FGPiston*)Engines[i])->ResetToIC();
+        try {
+          if (HasInitializedEngines && (InitializedEngines & i)) InitRunning(i);
+        } catch (string str) {
+          cerr << str << endl;
+          result = false;
+        }
+        break;
+      case FGEngine::etTurbine:
+        ((FGTurbine*)Engines[i])->ResetToIC();
+        try {
+          if (HasInitializedEngines && (InitializedEngines & i)) InitRunning(i);
+        } catch (string str) {
+          cerr << str << endl;
+          result = false;
+        }
+        break;
+      default:
+        break;
+    }
+  }
+
+  return result;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 bool FGPropulsion::Run(void)
 {
   unsigned int i;
@@ -108,7 +158,9 @@ bool FGPropulsion::Run(void)
   if (FGModel::Run()) return true;
   if (FDMExec->Holding()) return false;
 
-  double dt = State->Getdt();
+  RunPreFunctions();
+
+  double dt = FDMExec->GetDeltaT();
 
   vForces.InitMatrix();
   vMoments.InitMatrix();
@@ -128,6 +180,9 @@ bool FGPropulsion::Run(void)
   }
 
   if (refuel) DoRefuel( dt * rate );
+  if (dump) DumpFuel( dt * rate );
+
+  RunPostFunctions();
 
   return false;
 }
@@ -136,35 +191,46 @@ bool FGPropulsion::Run(void)
 
 bool FGPropulsion::GetSteadyState(void)
 {
-  double currentThrust = 0, lastThrust=-1;
-  int steady_count,j=0;
-  bool steady=false;
+  double currentThrust = 0, lastThrust = -1;
+  int steady_count = 0, j = 0;
+  bool steady = false;
+  bool TrimMode = FDMExec->GetTrimStatus();
 
   vForces.InitMatrix();
   vMoments.InitMatrix();
 
   if (!FGModel::Run()) {
+    FDMExec->SetTrimStatus(true);
+
     for (unsigned int i=0; i<numEngines; i++) {
-      Engines[i]->SetTrimMode(true);
+//      cout << "  Finding steady state for engine " << i << endl;
       steady=false;
       steady_count=0;
+      j=0;
       while (!steady && j < 6000) {
         Engines[i]->Calculate();
         lastThrust = currentThrust;
-        currentThrust = Engines[i]->GetThrust();
+        currentThrust = Engines[i]->GetThruster()->GetThrust();
         if (fabs(lastThrust-currentThrust) < 0.0001) {
           steady_count++;
-          if (steady_count > 120) { steady=true; }
+          if (steady_count > 120) {
+            steady=true;
+//            cout << "    Steady state found at thrust: " << currentThrust << " lbs." << endl;
+          }
         } else {
           steady_count=0;
         }
         j++;
       }
+//      if (j >= 6000) {
+//        cout << "    Could not find a steady state for this engine." << endl;
+//      }
       vForces  += Engines[i]->GetBodyForces();  // sum body frame forces
       vMoments += Engines[i]->GetMoments();     // sum body frame moments
-      Engines[i]->SetTrimMode(false);
     }
 
+    FDMExec->SetTrimStatus(TrimMode);
+
     return false;
   } else {
     return true;
@@ -173,25 +239,33 @@ bool FGPropulsion::GetSteadyState(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGPropulsion::ICEngineStart(void)
+void FGPropulsion::InitRunning(int n)
 {
-  int j;
+  if (n >= 0) { // A specific engine is supposed to be initialized
 
-  vForces.InitMatrix();
-  vMoments.InitMatrix();
+    if (n >= (int)GetNumEngines() ) {
+      throw(string("Tried to initialize a non-existent engine!"));
+    }
+    FDMExec->GetFCS()->SetThrottleCmd(n,1);
+    FDMExec->GetFCS()->SetMixtureCmd(n,1);
+    GetEngine(n)->InitRunning();
+    GetSteadyState();
 
-  for (unsigned int i=0; i<numEngines; i++) {
-    Engines[i]->SetTrimMode(true);
-    j=0;
-    while (!Engines[i]->GetRunning() && j < 2000) {
-      Engines[i]->Calculate();
-      j++;
+    InitializedEngines = 1 << n;
+    HasInitializedEngines = true;
+
+  } else if (n < 0) { // -1 refers to "All Engines"
+
+    for (unsigned int i=0; i<GetNumEngines(); i++) {
+      FDMExec->GetFCS()->SetThrottleCmd(i,1);
+      FDMExec->GetFCS()->SetMixtureCmd(i,1);
+      GetEngine(i)->InitRunning();
     }
-    vForces  += Engines[i]->GetBodyForces();  // sum body frame forces
-    vMoments += Engines[i]->GetMoments();     // sum body frame moments
-    Engines[i]->SetTrimMode(false);
+    GetSteadyState();
+    InitializedEngines = -1;
+    HasInitializedEngines = true;
+
   }
-  return true;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -199,14 +273,26 @@ bool FGPropulsion::ICEngineStart(void)
 bool FGPropulsion::Load(Element* el)
 {
   string type, engine_filename;
-  int Feed;
   bool ThrottleAdded = false;
-  Element* document;
-  FGXMLParse engine_file_parser;
-  ifstream* engine_file;
 
   Debug(2);
 
+  FGModel::Load(el); // Perform base class Load.
+
+  // Process tank definitions first to establish the number of fuel tanks
+
+  Element* tank_element = el->FindElement("tank");
+  while (tank_element) {
+    Tanks.push_back(new FGTank(FDMExec, tank_element, numTanks));
+    if (Tanks.back()->GetType() == FGTank::ttFUEL) numFuelTanks++;
+    else if (Tanks.back()->GetType() == FGTank::ttOXIDIZER) numOxiTanks++;
+    else {cerr << "Unknown tank type specified." << endl; return false;}
+    numTanks++;
+    tank_element = el->FindNextElement("tank");
+  }
+  numSelectedFuelTanks = numFuelTanks;
+  numSelectedOxiTanks  = numOxiTanks;
+
   Element* engine_element = el->FindElement("engine");
   while (engine_element) {
     engine_filename = engine_element->GetAttributeValue("file");
@@ -217,86 +303,79 @@ bool FGPropulsion::Load(Element* el)
     }
 
     engine_filename = FindEngineFullPathname(engine_filename);
-    readXML(engine_filename, engine_file_parser);
-    document = engine_file_parser.GetDocument(); // document holds the engine description
+    document = LoadXMLDocument(engine_filename);
     document->SetParent(engine_element);
 
     type = document->GetName();
-    if (type == "piston_engine") {
-      HavePistonEngine = true;
-      if (!IsBound) bind();
-      Engines.push_back(new FGPiston(FDMExec, document, numEngines));
-    } else if (type == "turbine_engine") {
-      HaveTurbineEngine = true;
-      if (!IsBound) bind();
-      Engines.push_back(new FGTurbine(FDMExec, document, numEngines));
-    } else if (type == "turboprop_engine") {
-      HaveTurboPropEngine = true;
-      if (!IsBound) bind();
-      Engines.push_back(new FGTurboProp(FDMExec, document, numEngines));
-    } else if (type == "rocket_engine") {
-      HaveRocketEngine = true;
-      if (!IsBound) bind();
-      Engines.push_back(new FGRocket(FDMExec, document, numEngines));
-    } else if (type == "electric_engine") {
-      HaveElectricEngine = true;
-      if (!IsBound) bind();
-      Engines.push_back(new FGElectric(FDMExec, document, numEngines));
-    } else {
-      cerr << "Unknown engine type: " << type << endl;
-      exit(-5);
+    try {
+      if (type == "piston_engine") {
+        HavePistonEngine = true;
+        if (!IsBound) bind();
+        Engines.push_back(new FGPiston(FDMExec, document, numEngines));
+      } else if (type == "turbine_engine") {
+        HaveTurbineEngine = true;
+        if (!IsBound) bind();
+        Engines.push_back(new FGTurbine(FDMExec, document, numEngines));
+      } else if (type == "turboprop_engine") {
+        HaveTurboPropEngine = true;
+        if (!IsBound) bind();
+        Engines.push_back(new FGTurboProp(FDMExec, document, numEngines));
+      } else if (type == "rocket_engine") {
+        HaveRocketEngine = true;
+        if (!IsBound) bind();
+        Engines.push_back(new FGRocket(FDMExec, document, numEngines));
+      } else if (type == "electric_engine") {
+        HaveElectricEngine = true;
+        if (!IsBound) bind();
+        Engines.push_back(new FGElectric(FDMExec, document, numEngines));
+      } else {
+        cerr << "Unknown engine type: " << type << endl;
+        exit(-5);
+      }
+    } catch (std::string str) {
+      cerr << endl << fgred << str << reset << endl;
+      return false;
     }
 
-    FCS->AddThrottle();
+    FDMExec->GetFCS()->AddThrottle();
     ThrottleAdded = true;
 
     numEngines++;
 
     engine_element = el->FindNextElement("engine");
-    engine_file_parser.reset();
+    ResetParser();
   }
 
-  // Process tank definitions
+  CalculateTankInertias();
+  if (!ThrottleAdded) FDMExec->GetFCS()->AddThrottle(); // need to have at least one throttle
 
-  Element* tank_element = el->FindElement("tank");
-  while (tank_element) {
-    Tanks.push_back(new FGTank(FDMExec, tank_element));
-    if (Tanks.back()->GetType() == FGTank::ttFUEL) numFuelTanks++;
-    else if (Tanks.back()->GetType() == FGTank::ttOXIDIZER) numOxiTanks++;
-    else {cerr << "Unknown tank type specified." << endl; return false;}
-    numTanks++;
-    tank_element = el->FindNextElement("tank");
-  }
-  numSelectedFuelTanks = numFuelTanks;
-  numSelectedOxiTanks  = numOxiTanks;
+  // Process fuel dump rate
+  if (el->FindElement("dump-rate"))
+    DumpRate = el->FindElementValueAsNumberConvertTo("dump-rate", "LBS/MIN");
 
-  CalculateTankInertias();
-  if (!ThrottleAdded) FCS->AddThrottle(); // need to have at least one throttle
+  PostLoad(el, PropertyManager);
 
   return true;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-string FGPropulsion::FindEngineFullPathname(string engine_filename)
+string FGPropulsion::FindEngineFullPathname(const string& engine_filename)
 {
   string fullpath, localpath;
   string enginePath = FDMExec->GetEnginePath();
   string aircraftPath = FDMExec->GetFullAircraftPath();
-  ifstream* engine_file = new ifstream();
+  ifstream engine_file;
 
   string separator = "/";
-# ifdef macintosh
-  separator = ";";
-# endif
 
   fullpath = enginePath + separator;
   localpath = aircraftPath + separator + "Engines" + separator;
 
-  engine_file->open(string(fullpath + engine_filename + ".xml").c_str());
-  if ( !engine_file->is_open()) {
-    engine_file->open(string(localpath + engine_filename + ".xml").c_str());
-      if ( !engine_file->is_open()) {
+  engine_file.open(string(fullpath + engine_filename + ".xml").c_str());
+  if ( !engine_file.is_open()) {
+    engine_file.open(string(localpath + engine_filename + ".xml").c_str());
+      if ( !engine_file.is_open()) {
         cerr << " Could not open engine file: " << engine_filename << " in path "
              << fullpath << " or " << localpath << endl;
         return string("");
@@ -309,7 +388,7 @@ string FGPropulsion::FindEngineFullPathname(string engine_filename)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-ifstream* FGPropulsion::FindEngineFile(string engine_filename)
+ifstream* FGPropulsion::FindEngineFile(const string& engine_filename)
 {
   string fullpath, localpath;
   string enginePath = FDMExec->GetEnginePath();
@@ -317,9 +396,6 @@ ifstream* FGPropulsion::FindEngineFile(string engine_filename)
   ifstream* engine_file = new ifstream();
 
   string separator = "/";
-# ifdef macintosh
-  separator = ";";
-# endif
 
   fullpath = enginePath + separator;
   localpath = aircraftPath + separator + "Engines" + separator;
@@ -337,7 +413,7 @@ ifstream* FGPropulsion::FindEngineFile(string engine_filename)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-string FGPropulsion::GetPropulsionStrings(string delimeter)
+string FGPropulsion::GetPropulsionStrings(const string& delimiter) const
 {
   unsigned int i;
 
@@ -347,13 +423,13 @@ string FGPropulsion::GetPropulsionStrings(string delimeter)
 
   for (i=0; i<Engines.size(); i++) {
     if (firstime)  firstime = false;
-    else           PropulsionStrings += delimeter;
+    else           PropulsionStrings += delimiter;
 
-    PropulsionStrings += Engines[i]->GetEngineLabels(delimeter);
+    PropulsionStrings += Engines[i]->GetEngineLabels(delimiter);
   }
   for (i=0; i<Tanks.size(); i++) {
-    if (Tanks[i]->GetType() == FGTank::ttFUEL) buf << delimeter << "Fuel Tank " << i;
-    else if (Tanks[i]->GetType() == FGTank::ttOXIDIZER) buf << delimeter << "Oxidizer Tank " << i;
+    if (Tanks[i]->GetType() == FGTank::ttFUEL) buf << delimiter << "Fuel Tank " << i;
+    else if (Tanks[i]->GetType() == FGTank::ttOXIDIZER) buf << delimiter << "Oxidizer Tank " << i;
   }
 
   return PropulsionStrings;
@@ -361,7 +437,7 @@ string FGPropulsion::GetPropulsionStrings(string delimeter)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-string FGPropulsion::GetPropulsionValues(string delimeter)
+string FGPropulsion::GetPropulsionValues(const string& delimiter) const
 {
   unsigned int i;
 
@@ -371,12 +447,12 @@ string FGPropulsion::GetPropulsionValues(string delimeter)
 
   for (i=0; i<Engines.size(); i++) {
     if (firstime)  firstime = false;
-    else           PropulsionValues += delimeter;
+    else           PropulsionValues += delimiter;
 
-    PropulsionValues += Engines[i]->GetEngineValues(delimeter);
+    PropulsionValues += Engines[i]->GetEngineValues(delimiter);
   }
   for (i=0; i<Tanks.size(); i++) {
-    buf << delimeter;
+    buf << delimiter;
     buf << Tanks[i]->GetContents();
   }
 
@@ -387,13 +463,11 @@ string FGPropulsion::GetPropulsionValues(string delimeter)
 
 FGColumnVector3& FGPropulsion::GetTanksMoment(void)
 {
-  iTank = Tanks.begin();
   vXYZtank_arm.InitMatrix();
-  while (iTank < Tanks.end()) {
-    vXYZtank_arm(eX) += (*iTank)->GetXYZ(eX)*(*iTank)->GetContents();
-    vXYZtank_arm(eY) += (*iTank)->GetXYZ(eY)*(*iTank)->GetContents();
-    vXYZtank_arm(eZ) += (*iTank)->GetXYZ(eZ)*(*iTank)->GetContents();
-    iTank++;
+  for (unsigned int i=0; i<Tanks.size(); i++) {
+    vXYZtank_arm(eX) += Tanks[i]->GetXYZ(eX) * Tanks[i]->GetContents();
+    vXYZtank_arm(eY) += Tanks[i]->GetXYZ(eY) * Tanks[i]->GetContents();
+    vXYZtank_arm(eZ) += Tanks[i]->GetXYZ(eZ) * Tanks[i]->GetContents();
   }
   return vXYZtank_arm;
 }
@@ -404,11 +478,8 @@ double FGPropulsion::GetTanksWeight(void)
 {
   double Tw = 0.0;
 
-  iTank = Tanks.begin();
-  while (iTank < Tanks.end()) {
-    Tw += (*iTank)->GetContents();
-    iTank++;
-  }
+  for (unsigned int i=0; i<Tanks.size(); i++) Tw += Tanks[i]->GetContents();
+
   return Tw;
 }
 
@@ -423,9 +494,13 @@ FGMatrix33& FGPropulsion::CalculateTankInertias(void)
 
   tankJ = FGMatrix33();
 
-  for (unsigned int i=0; i<size; i++)
-    tankJ += MassBalance->GetPointmassInertia( lbtoslug * Tanks[i]->GetContents(),
+  for (unsigned int i=0; i<size; i++) {
+    tankJ += FDMExec->GetMassBalance()->GetPointmassInertia( lbtoslug * Tanks[i]->GetContents(),
                                                Tanks[i]->GetXYZ() );
+    tankJ(1,1) += Tanks[i]->GetIxx();
+    tankJ(2,2) += Tanks[i]->GetIyy();
+    tankJ(3,3) += Tanks[i]->GetIzz();
+  }
 
   return tankJ;
 }
@@ -488,7 +563,7 @@ void FGPropulsion::SetCutoff(int setting)
 
 void FGPropulsion::SetActiveEngine(int engine)
 {
-  if (engine >= Engines.size() || engine < 0)
+  if (engine >= (int)Engines.size() || engine < 0)
     ActiveEngine = -1;
   else
     ActiveEngine = engine;
@@ -536,6 +611,28 @@ void FGPropulsion::DoRefuel(double time_slice)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+void FGPropulsion::DumpFuel(double time_slice)
+{
+  unsigned int i;
+  int TanksDumping = 0;
+
+  for (i=0; i<numTanks; i++) {
+    if (Tanks[i]->GetContents() > Tanks[i]->GetStandpipe()) ++TanksDumping;
+  }
+
+  if (TanksDumping == 0) return;
+
+  double dump_rate_per_tank = DumpRate / 60.0 * time_slice / TanksDumping;
+
+  for (i=0; i<numTanks; i++) {
+    if (Tanks[i]->GetContents() > Tanks[i]->GetStandpipe()) {
+      Transfer(i, -1, dump_rate_per_tank);
+    }
+  }
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 void FGPropulsion::SetFuelFreeze(bool f)
 {
   fuel_freeze = f;
@@ -552,38 +649,37 @@ void FGPropulsion::bind(void)
   typedef int (FGPropulsion::*iPMF)(void) const;
 
   IsBound = true;
-
+  PropertyManager->Tie("propulsion/set-running", this, (iPMF)0, &FGPropulsion::InitRunning, false);
   if (HaveTurbineEngine) {
-    PropertyManager->Tie("propulsion/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter,  true);
-    PropertyManager->Tie("propulsion/cutoff_cmd", this,  (iPMF)0, &FGPropulsion::SetCutoff,   true);
+    PropertyManager->Tie("propulsion/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter,  false);
+    PropertyManager->Tie("propulsion/cutoff_cmd", this,  (iPMF)0, &FGPropulsion::SetCutoff,   false);
   }
 
   if (HavePistonEngine) {
-    PropertyManager->Tie("propulsion/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter,  true);
-    PropertyManager->Tie("propulsion/magneto_cmd", this, (iPMF)0, &FGPropulsion::SetMagnetos, true);
+    PropertyManager->Tie("propulsion/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter,  false);
+    PropertyManager->Tie("propulsion/magneto_cmd", this, (iPMF)0, &FGPropulsion::SetMagnetos, false);
   }
 
   PropertyManager->Tie("propulsion/active_engine", this, (iPMF)&FGPropulsion::GetActiveEngine,
                         &FGPropulsion::SetActiveEngine, true);
   PropertyManager->Tie("propulsion/total-fuel-lbs", this, &FGPropulsion::GetTotalFuelQuantity);
-}
+  PropertyManager->Tie("propulsion/refuel", this, &FGPropulsion::GetRefuel,
+                        &FGPropulsion::SetRefuel, true);
+  PropertyManager->Tie("propulsion/fuel_dump", this, &FGPropulsion::GetFuelDump,
+                        &FGPropulsion::SetFuelDump, true);
+  PropertyManager->Tie("forces/fbx-prop-lbs", this,1,
+                       (PMF)&FGPropulsion::GetForces);
+  PropertyManager->Tie("forces/fby-prop-lbs", this,2,
+                       (PMF)&FGPropulsion::GetForces);
+  PropertyManager->Tie("forces/fbz-prop-lbs", this,3,
+                       (PMF)&FGPropulsion::GetForces);
+  PropertyManager->Tie("moments/l-prop-lbsft", this,1,
+                       (PMF)&FGPropulsion::GetMoments);
+  PropertyManager->Tie("moments/m-prop-lbsft", this,2,
+                       (PMF)&FGPropulsion::GetMoments);
+  PropertyManager->Tie("moments/n-prop-lbsft", this,3,
+                       (PMF)&FGPropulsion::GetMoments);
 
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGPropulsion::unbind(void)
-{
-  if (!IsBound) return;
-
-  if (HaveTurbineEngine) {
-    PropertyManager->Untie("propulsion/starter_cmd");
-    PropertyManager->Untie("propulsion/cutoff_cmd");
-  }
-  if (HavePistonEngine) {
-    PropertyManager->Untie("propulsion/starter_cmd");
-    PropertyManager->Untie("propulsion/magneto_cmd");
-  }
-  PropertyManager->Untie("propulsion/active_engine");
-  PropertyManager->Untie("propulsion/total-fuel-lbs");
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%