]> git.mxchange.org Git - flightgear.git/commitdiff
Unified handling of (fuel-)tank properties
authorTorsten Dreyer <Torsten@t3r.de>
Sun, 6 Feb 2011 16:33:31 +0000 (17:33 +0100)
committerTorsten Dreyer <Torsten@t3r.de>
Sun, 6 Feb 2011 16:33:31 +0000 (17:33 +0100)
Ensure consistent properties for all fuel tanks

src/FDM/CMakeLists.txt
src/FDM/JSBSim/JSBSim.cxx
src/FDM/Makefile.am
src/FDM/TankProperties.cxx [new file with mode: 0644]
src/FDM/TankProperties.hxx [new file with mode: 0644]
src/FDM/YASim/FGFDM.cpp
src/FDM/YASim/YASim.cxx
src/FDM/fdm_shell.cxx
src/FDM/fdm_shell.hxx

index 72b685dc1447f9aaa6521fb4feade5178492e273..74d695f5067cd3b08d423223a0b4122505f711c6 100644 (file)
@@ -130,6 +130,7 @@ set(SOURCES
        fdm_shell.cxx
        flight.cxx
        flightProperties.cxx
+       TankProperties.cxx
        groundcache.cxx
        ${SP_FDM_SOURCES}
        ExternalNet/ExternalNet.cxx
index b1daa9cd3450e47ac7e07b163d3bfae27c4cfdb1..c6f19333645d2ea828249888173fa4b5c32b35d3 100644 (file)
@@ -212,15 +212,17 @@ FGJSBsim::FGJSBsim( double dt )
 
     // Set initial fuel levels if provided.
     for (unsigned int i = 0; i < Propulsion->GetNumTanks(); i++) {
+      double d;
       SGPropertyNode * node = fgGetNode("/consumables/fuel/tank", i, true);
-      if (node->getChild("level-gal_us", 0, false) != 0) {
-        Propulsion->GetTank(i)->SetContents(node->getDoubleValue("level-gal_us") * 6.6);
-      } else {
-        node->setDoubleValue("level-lbs", Propulsion->GetTank(i)->GetContents());
-        node->setDoubleValue("level-gal_us", Propulsion->GetTank(i)->GetContents() / 6.6);
-      }
-      node->setDoubleValue("capacity-gal_us",
-                           Propulsion->GetTank(i)->GetCapacity() / 6.6);
+      FGTank* tank = Propulsion->GetTank(i);
+
+      d = node->getNode( "density-ppg", true )->getDoubleValue();
+      if( d > 0.0 )
+        tank->SetDensity( d );
+
+      d = node->getNode( "level-lbs", true )->getDoubleValue();
+      if( d > 0.0 )
+        tank->SetContents( d );
     }
     Propulsion->SetFuelFreeze((fgGetNode("/sim/freeze/fuel",true))->getBoolValue());
 
@@ -676,8 +678,13 @@ bool FGJSBsim::copy_to_JSBsim()
     for (i = 0; i < Propulsion->GetNumTanks(); i++) {
       SGPropertyNode * node = fgGetNode("/consumables/fuel/tank", i, true);
       FGTank * tank = Propulsion->GetTank(i);
-      tank->SetContents(node->getDoubleValue("level-gal_us") * 6.6);
-//       tank->SetContents(node->getDoubleValue("level-lbs"));
+      double fuelDensity = node->getDoubleValue("density-ppg");
+
+      if (fuelDensity < 0.1)
+        fuelDensity = 6.0; // Use average fuel value
+
+      tank->SetDensity(fuelDensity);
+      tank->SetContents(node->getDoubleValue("level-lbs"));
     }
 
     Propulsion->SetFuelFreeze((fgGetNode("/sim/freeze/fuel",true))->getBoolValue());
@@ -915,7 +922,12 @@ bool FGJSBsim::copy_from_JSBsim()
         FGTank* tank = Propulsion->GetTank(i);
         double contents = tank->GetContents();
         double temp = tank->GetTemperature_degC();
-        node->setDoubleValue("level-gal_us", contents/6.6);
+        double fuelDensity = tank->GetDensity();
+
+        if (fuelDensity < 0.1)
+          fuelDensity = 6.0; // Use average fuel value
+
+        node->setDoubleValue("density-ppg" , fuelDensity);
         node->setDoubleValue("level-lbs", contents);
         if (temp != -9999.0) node->setDoubleValue("temperature_degC", temp);
       }
index e1e764c8243ed18b297dd501bb17761fdfeb80ae..41bfe3f8765eae47101c042dd6776213eab45a31 100644 (file)
@@ -13,6 +13,7 @@ libFlight_a_SOURCES = \
        flight.cxx flight.hxx \
        fdm_shell.cxx fdm_shell.hxx \
        flightProperties.cxx flightProperties.hxx \
+       TankProperties.cxx TankProperties.hxx \
        groundcache.cxx groundcache.hxx \
        UFO.cxx UFO.hxx \
        NullFDM.cxx NullFDM.hxx
diff --git a/src/FDM/TankProperties.cxx b/src/FDM/TankProperties.cxx
new file mode 100644 (file)
index 0000000..7bd24fb
--- /dev/null
@@ -0,0 +1,241 @@
+// TankProperties.cxx -- expose (fuel)-tank properties 
+//
+// Written by Torsten Dreyer, started January 2011.
+//
+// Copyright (C) 2011  Torsten Dreyer - Torsten (at) t3r _dot_ de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "TankProperties.hxx"
+
+#include <simgear/math/SGMath.hxx>
+#include <Main/fg_props.hxx>
+
+static const double LBS_PER_KG = 2.20462262;
+static const double KG_PER_LBS = 1.0/LBS_PER_KG;
+static const double USGAL_PER_M3 = 1000.0/3.785411784;
+static const double M3_PER_USGAL = 1.0/USGAL_PER_M3;
+static const double IMPGAL_PER_M3 = 1000.0/4.54609;
+static const double M3_PER_IMPGAL = 1.0/IMPGAL_PER_M3;
+
+TankProperties::TankProperties(SGPropertyNode_ptr rootNode ) :
+  _content_kg(0.0),
+  _density_kgpm3(755.0), // avg. AVGAS density (more or less)
+  _capacity_m3(0.0)
+{
+  _tiedProperties.setRoot( rootNode );
+  _tiedProperties.Tie("level-kg", this, &TankProperties::getContent_kg, &TankProperties::setContent_kg );
+  _tiedProperties.Tie("density-kgpm3", this, &TankProperties::getDensity_kgpm3, &TankProperties::setDensity_kgpm3 );
+  _tiedProperties.Tie("capacity-m3", this, &TankProperties::getCapacity_m3, &TankProperties::setCapacity_m3 );
+  _tiedProperties.Tie("level-m3", this, &TankProperties::getContent_m3, &TankProperties::setContent_m3 );
+  _tiedProperties.Tie("level-norm", this, &TankProperties::getContent_norm, &TankProperties::setContent_norm );
+
+  _tiedProperties.Tie("density-ppg", this, &TankProperties::getDensity_ppg, &TankProperties::setDensity_ppg );
+  _tiedProperties.Tie("level-lbs", this, &TankProperties::getContent_lbs, &TankProperties::setContent_lbs );
+  _tiedProperties.Tie("level-gal_us", this, &TankProperties::getContent_gal_us, &TankProperties::setContent_gal_us );
+  _tiedProperties.Tie("level-gal_imp", this, &TankProperties::getContent_gal_imp, &TankProperties::setContent_gal_imp );
+  _tiedProperties.Tie("capacity-gal_us", this, &TankProperties::getCapacity_gal_us, &TankProperties::setCapacity_gal_us );
+  _tiedProperties.Tie("capacity-gal_imp", this, &TankProperties::getCapacity_gal_imp, &TankProperties::setCapacity_gal_imp );
+}
+
+TankProperties::~TankProperties()
+{
+}
+
+double TankProperties::getContent_kg() const
+{
+  return _content_kg;
+}
+
+void TankProperties::setContent_kg( double value )
+{
+  _content_kg = value;
+}
+
+double TankProperties::getDensity_kgpm3() const
+{
+  return _density_kgpm3;
+}
+
+void TankProperties::setDensity_kgpm3( double value )
+{
+  _density_kgpm3 = value;
+}
+
+double TankProperties::getDensity_ppg() const
+{
+  return _density_kgpm3 * LBS_PER_KG / USGAL_PER_M3;
+}
+
+void TankProperties::setDensity_ppg( double value )
+{
+  _density_kgpm3 = value * KG_PER_LBS / M3_PER_USGAL;
+}
+
+double TankProperties::getContent_lbs() const
+{
+  return _content_kg * LBS_PER_KG;
+}
+
+void TankProperties::setContent_lbs( double value )
+{
+  _content_kg = value * KG_PER_LBS;
+}
+
+double TankProperties::getContent_m3() const
+{
+  return _density_kgpm3 > SGLimitsd::min() ? _content_kg / _density_kgpm3 : 0.0;
+}
+
+void TankProperties::setContent_m3( double value )
+{
+  _content_kg = value * _density_kgpm3;
+}
+
+double TankProperties::getContent_gal_us() const
+{
+  return getContent_m3() * USGAL_PER_M3;
+}
+
+void TankProperties::setContent_gal_us( double value )
+{
+  setContent_m3( value * M3_PER_USGAL );
+}
+
+double TankProperties::getContent_gal_imp() const
+{
+  return getContent_m3() * IMPGAL_PER_M3;
+}
+
+void TankProperties::setContent_gal_imp( double value )
+{
+  setContent_m3( value * M3_PER_IMPGAL );
+}
+
+double TankProperties::getCapacity_m3() const
+{
+  return _capacity_m3;
+}
+
+void TankProperties::setCapacity_m3( double value )
+{
+  _capacity_m3 = value;
+}
+
+double TankProperties::getCapacity_gal_us() const
+{
+  return _capacity_m3 * USGAL_PER_M3;
+}
+
+void TankProperties::setCapacity_gal_us( double value )
+{
+  _capacity_m3 = value * M3_PER_USGAL;
+}
+
+double TankProperties::getCapacity_gal_imp() const
+{
+  return _capacity_m3 * IMPGAL_PER_M3;
+}
+
+void TankProperties::setCapacity_gal_imp( double value )
+{
+  _capacity_m3 = value * M3_PER_IMPGAL;
+}
+
+double TankProperties::getContent_norm() const
+{
+  return  _capacity_m3 > SGLimitsd::min() ? getContent_m3() / _capacity_m3 : 0.0;
+}
+
+void TankProperties::setContent_norm( double value )
+{
+  setContent_m3(_capacity_m3 * value);
+}
+
+TankPropertiesList::TankPropertiesList( SGPropertyNode_ptr rootNode )
+{
+  // we don't have a global rule how many tanks we support, so I assume eight.
+  // Because hard coded values suck, make it settable by a property
+  size_type n = rootNode->getIntValue( "numtanks", 8 );
+  for( size_type i = 0; i < n; i++ ) {
+    push_back( new TankProperties( rootNode->getChild( "tank", i, true ) ) );
+  }
+
+  _tiedProperties.setRoot( rootNode );
+  _tiedProperties.Tie("total-fuel-kg", this, &TankPropertiesList::getTotalContent_kg );
+  _tiedProperties.Tie("total-fuel-lbs", this, &TankPropertiesList::getTotalContent_lbs );
+  _tiedProperties.Tie("total-fuel-gal_us", this, &TankPropertiesList::getTotalContent_gal_us );
+  _tiedProperties.Tie("total-fuel-gals", this, &TankPropertiesList::getTotalContent_gal_us );
+  _tiedProperties.Tie("total-fuel-gal_imp", this, &TankPropertiesList::getTotalContent_gal_imp );
+  _tiedProperties.Tie("total-fuel-norm", this, &TankPropertiesList::getTotalContent_norm );
+}
+
+double TankPropertiesList::getTotalContent_lbs() const
+{
+  double value = 0.0;
+  for( const_iterator it = begin(); it != end(); ++it )
+    value += (*it)->getContent_lbs();
+  return value;
+}
+
+double TankPropertiesList::getTotalContent_kg() const
+{
+  double value = 0.0;
+  for( const_iterator it = begin(); it != end(); ++it )
+    value += (*it)->getContent_kg();
+  return value;
+}
+
+double TankPropertiesList::getTotalContent_gal_us() const
+{
+  double value = 0.0;
+  for( const_iterator it = begin(); it != end(); ++it )
+    value += (*it)->getContent_gal_us();
+  return value;
+}
+
+double TankPropertiesList::getTotalContent_gal_imp() const
+{
+  double value = 0.0;
+  for( const_iterator it = begin(); it != end(); ++it )
+    value += (*it)->getContent_gal_imp();
+  return value;
+}
+
+double TankPropertiesList::getTotalContent_m3() const
+{
+  double value = 0.0;
+  for( const_iterator it = begin(); it != end(); ++it )
+    value += (*it)->getContent_m3();
+  return value;
+}
+
+double TankPropertiesList::getTotalContent_norm() const
+{
+  double content = 0.0;
+  double capacity = 0.0;
+  for( const_iterator it = begin(); it != end(); ++it ) {
+    content += (*it)->getContent_m3();
+    capacity += (*it)->getCapacity_m3();
+  }
+  return capacity > SGLimitsd::min() ? content / capacity : 0.0;
+}
+
+
diff --git a/src/FDM/TankProperties.hxx b/src/FDM/TankProperties.hxx
new file mode 100644 (file)
index 0000000..27a2e9f
--- /dev/null
@@ -0,0 +1,93 @@
+// TankProperties.hxx -- expose (fuel)-tank properties 
+//
+// Written by Torsten Dreyer, started January 2011.
+//
+// Copyright (C) 2011  Torsten Dreyer - Torsten (at) t3r _dot_ de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+
+#ifndef __TANK_PROPERTIES_HXX
+#define __TANK_PROPERTIES_HXX
+
+#include <simgear/props/props.hxx>
+#include <simgear/props/tiedpropertylist.hxx>
+
+class TankProperties : public SGReferenced
+{
+public:
+  TankProperties(SGPropertyNode_ptr rootNode );
+  virtual ~TankProperties();
+
+  TankProperties( const TankProperties & );
+  const TankProperties & operator = ( const TankProperties & );
+
+  double getContent_kg() const;
+  void setContent_kg( double value );
+
+  double getDensity_kgpm3() const;
+  void setDensity_kgpm3( double value );
+
+  double getDensity_ppg() const;
+  void setDensity_ppg( double value );
+
+  double getContent_lbs() const;
+  void setContent_lbs( double value );
+
+  double getContent_m3() const;
+  void setContent_m3( double value );
+
+  double getContent_gal_us() const;
+  void setContent_gal_us( double value );
+
+  double getContent_gal_imp() const;
+  void setContent_gal_imp( double value );
+
+  double getCapacity_m3() const;
+  void setCapacity_m3( double value );
+
+  double getCapacity_gal_us() const;
+  void setCapacity_gal_us( double value );
+
+  double getCapacity_gal_imp() const;
+  void setCapacity_gal_imp( double value );
+
+  double getContent_norm() const;
+  void setContent_norm( double value );
+
+protected:
+  simgear::TiedPropertyList _tiedProperties;
+
+  double _content_kg;
+  double _density_kgpm3;
+  double _capacity_m3;
+};
+
+class TankPropertiesList : std::vector<SGSharedPtr<TankProperties> > {
+public:
+  TankPropertiesList( SGPropertyNode_ptr rootNode );
+
+  double getTotalContent_lbs() const;
+  double getTotalContent_kg() const;
+  double getTotalContent_gal_us() const;
+  double getTotalContent_gal_imp() const;
+  double getTotalContent_m3() const;
+  double getTotalContent_norm() const;
+
+private:
+  simgear::TiedPropertyList _tiedProperties;
+};
+
+#endif // __TANK_PROPERTIES_HXX
index b727d3c594424fd4e7e008b64caba13844f8c46b..8ce87f528df272617a8577f750870056bbac90b9 100644 (file)
@@ -132,8 +132,9 @@ void FGFDM::init()
         sprintf(buf, "/consumables/fuel/tank[%d]/density-ppg", i);
         fgSetDouble(buf, density * (KG2LBS/CM2GALS));
 
-        sprintf(buf, "/consumables/fuel/tank[%d]/level-gal_us", i);
-        fgSetDouble(buf, _airplane.getFuel(i) * CM2GALS / density);
+// set in TankProperties class
+//        sprintf(buf, "/consumables/fuel/tank[%d]/level-gal_us", i);
+//        fgSetDouble(buf, _airplane.getFuel(i) * CM2GALS / density);
 
         sprintf(buf, "/consumables/fuel/tank[%d]/capacity-gal_us", i);
         fgSetDouble(buf, CM2GALS * _airplane.getTankCapacity(i)/density);
index 70c7459d2fabba8d304638c191ac435c5ee3fa81..9635e7294ce6cba9d80c3dfa068d65834fec482f 100644 (file)
@@ -95,9 +95,10 @@ void YASim::bind()
     // Run the superclass bind to set up a bunch of property ties
     FGInterface::bind();
 
+//Torsten Dreyer: we shouldn't do this anymore because we don't set these values nomore
     // Now UNtie the ones that we are going to set ourselves.
-    fgUntie("/consumables/fuel/tank[0]/level-gal_us");
-    fgUntie("/consumables/fuel/tank[1]/level-gal_us");
+//    fgUntie("/consumables/fuel/tank[0]/level-gal_us");
+//    fgUntie("/consumables/fuel/tank[1]/level-gal_us");
 
     char buf[256];
     for(int i=0; i<_fdm->getAirplane()->getModel()->numThrusters(); i++) {
index ba661e8f70f8a897792765fb4ea1adad5cc6ddf0..dff0d40fe4844a2156ba968159a02a95d20d8796 100644 (file)
@@ -49,6 +49,7 @@
 #include <FDM/NullFDM.hxx>
 #include <FDM/YASim/YASim.hxx>
 
+
 /*
  * Evil global variable required by Network/FGNative,
  * see that class for more information
@@ -56,6 +57,7 @@
 FGInterface* evil_global_fdm_state = NULL;
 
 FDMShell::FDMShell() :
+  _tankProperties( fgGetNode("/consumables/fuel", true) ),
   _impl(NULL),
   _dataLogging(false)
 {
index be0b1f85925965c949afab0de5e19f68ece71ec4..759be1c9e79d1f2fd6d122ee8a6aef6da3f59ae5 100644 (file)
@@ -24,6 +24,7 @@
 #define FG_FDM_SHELL_HXX
 
 #include <simgear/structure/subsystem_mgr.hxx>
+#include "TankProperties.hxx"
 
 // forward decls
 class FGInterface;
@@ -54,6 +55,7 @@ private:
 
   void createImplementation();
   
+  TankPropertiesList _tankProperties;
   FGInterface* _impl;
   SGPropertyNode* _props; // root property tree for this FDM instance
   bool _dataLogging;