// 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());
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());
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);
}
--- /dev/null
+// 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;
+}
+
+
--- /dev/null
+// 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