Unified handling of (fuel-)tank properties
Ensure consistent properties for all fuel tanks
This commit is contained in:
parent
d1b35578c8
commit
717ffe584f
9 changed files with 369 additions and 15 deletions
|
@ -130,6 +130,7 @@ set(SOURCES
|
|||
fdm_shell.cxx
|
||||
flight.cxx
|
||||
flightProperties.cxx
|
||||
TankProperties.cxx
|
||||
groundcache.cxx
|
||||
${SP_FDM_SOURCES}
|
||||
ExternalNet/ExternalNet.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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
241
src/FDM/TankProperties.cxx
Normal file
241
src/FDM/TankProperties.cxx
Normal file
|
@ -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;
|
||||
}
|
||||
|
||||
|
93
src/FDM/TankProperties.hxx
Normal file
93
src/FDM/TankProperties.hxx
Normal file
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue