diff --git a/src/FDM/CMakeLists.txt b/src/FDM/CMakeLists.txt index 72b685dc1..74d695f50 100644 --- a/src/FDM/CMakeLists.txt +++ b/src/FDM/CMakeLists.txt @@ -130,6 +130,7 @@ set(SOURCES fdm_shell.cxx flight.cxx flightProperties.cxx + TankProperties.cxx groundcache.cxx ${SP_FDM_SOURCES} ExternalNet/ExternalNet.cxx diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx index b1daa9cd3..c6f193336 100644 --- a/src/FDM/JSBSim/JSBSim.cxx +++ b/src/FDM/JSBSim/JSBSim.cxx @@ -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); } diff --git a/src/FDM/Makefile.am b/src/FDM/Makefile.am index e1e764c82..41bfe3f87 100644 --- a/src/FDM/Makefile.am +++ b/src/FDM/Makefile.am @@ -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 index 000000000..7bd24fb1e --- /dev/null +++ b/src/FDM/TankProperties.cxx @@ -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 +#endif + +#include "TankProperties.hxx" + +#include +#include
+ +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 index 000000000..27a2e9f40 --- /dev/null +++ b/src/FDM/TankProperties.hxx @@ -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 +#include + +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 > { +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 diff --git a/src/FDM/YASim/FGFDM.cpp b/src/FDM/YASim/FGFDM.cpp index b727d3c59..8ce87f528 100644 --- a/src/FDM/YASim/FGFDM.cpp +++ b/src/FDM/YASim/FGFDM.cpp @@ -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); diff --git a/src/FDM/YASim/YASim.cxx b/src/FDM/YASim/YASim.cxx index 70c7459d2..9635e7294 100644 --- a/src/FDM/YASim/YASim.cxx +++ b/src/FDM/YASim/YASim.cxx @@ -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++) { diff --git a/src/FDM/fdm_shell.cxx b/src/FDM/fdm_shell.cxx index ba661e8f7..dff0d40fe 100644 --- a/src/FDM/fdm_shell.cxx +++ b/src/FDM/fdm_shell.cxx @@ -49,6 +49,7 @@ #include #include + /* * 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) { diff --git a/src/FDM/fdm_shell.hxx b/src/FDM/fdm_shell.hxx index be0b1f859..759be1c9e 100644 --- a/src/FDM/fdm_shell.hxx +++ b/src/FDM/fdm_shell.hxx @@ -24,6 +24,7 @@ #define FG_FDM_SHELL_HXX #include +#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;