[JSBSim] Takes into account the amount of unusable fuel.
Properties /consumable/fuel/tank[*]/unusable-* supplied in the -set.xml file are propagated to the aircraft model and accounted for in the tanks management.
This commit is contained in:
parent
466fb0979d
commit
e704d589f2
5 changed files with 115 additions and 64 deletions
|
@ -273,19 +273,29 @@ FGJSBsim::FGJSBsim( double dt )
|
|||
double d;
|
||||
SGPropertyNode * node = fgGetNode("/consumables/fuel/tank", i, true);
|
||||
FGTank* tank = Propulsion->GetTank(i);
|
||||
SGPropertyNode * prop = node->getNode( "density-ppg", true );
|
||||
|
||||
d = node->getNode( "density-ppg", true )->getDoubleValue();
|
||||
d = prop->getDoubleValue();
|
||||
if( d > 0.0 ) {
|
||||
tank->SetDensity( d );
|
||||
} else {
|
||||
node->getNode( "density-ppg", true )->setDoubleValue( SG_MAX2<double>(tank->GetDensity(), 0.1) );
|
||||
prop->setDoubleValue( SG_MAX2<double>(tank->GetDensity(), 0.1) );
|
||||
}
|
||||
|
||||
d = node->getNode( "level-lbs", true )->getDoubleValue();
|
||||
prop = node->getNode( "level-lbs", true );
|
||||
d = prop->getDoubleValue();
|
||||
if( d > 0.0 ) {
|
||||
tank->SetContents( d );
|
||||
} else {
|
||||
node->getNode( "level-lbs", true )->setDoubleValue( tank->GetContents() );
|
||||
prop->setDoubleValue( tank->GetContents() );
|
||||
}
|
||||
|
||||
prop = node->getNode( "unusable-gal_us", true );
|
||||
d = prop->getDoubleValue();
|
||||
if ( d > 0.0 ) {
|
||||
tank->SetUnusableVolume( d );
|
||||
} else {
|
||||
prop->setDoubleValue(tank->GetUnusableVolume());
|
||||
}
|
||||
/* Capacity is read-only in FGTank and can't be overwritten from FlightGear */
|
||||
node->getNode("capacity-gal_us", true )->setDoubleValue( tank->GetCapacityGallons() );
|
||||
|
|
|
@ -8,33 +8,27 @@
|
|||
------------- Copyright (C) 2001 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
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
the terms of the GNU Lesser 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 Lesser General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Further information about the GNU Lesser General Public License can also be found on
|
||||
the world wide web at http://www.gnu.org.
|
||||
Further information about the GNU Lesser General Public License can also be
|
||||
found on the world wide web at http://www.gnu.org.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "FGXMLElement.h"
|
||||
#include "string_utilities.h"
|
||||
#include "FGJSBBase.h"
|
||||
|
||||
using namespace std;
|
||||
|
@ -91,6 +85,12 @@ Element::Element(const string& nm)
|
|||
convert["FT3"]["M3"] = 1.0/convert["M3"]["FT3"];
|
||||
convert["LTR"]["IN3"] = 61.0237441;
|
||||
convert["IN3"]["LTR"] = 1.0/convert["LTR"]["IN3"];
|
||||
convert["GAL"]["FT3"] = 0.133681;
|
||||
convert["FT3"]["GAL"] = 1.0/convert["GAL"]["FT3"];
|
||||
convert["IN3"]["GAL"] = convert["IN3"]["FT3"]*convert["FT3"]["GAL"];
|
||||
convert["LTR"]["GAL"] = convert["LTR"]["IN3"]*convert["IN3"]["GAL"];
|
||||
convert["M3"]["GAL"] = 1000.*convert["LTR"]["GAL"];
|
||||
convert["CC"]["GAL"] = convert["CC"]["IN3"]*convert["IN3"]["GAL"];
|
||||
// Mass & Weight
|
||||
convert["LBS"]["KG"] = 0.45359237;
|
||||
convert["KG"]["LBS"] = 1.0/convert["LBS"]["KG"];
|
||||
|
@ -177,6 +177,7 @@ Element::Element(const string& nm)
|
|||
convert["M3"]["M3"] = 1.0;
|
||||
convert["FT3"]["FT3"] = 1.0;
|
||||
convert["LTR"]["LTR"] = 1.0;
|
||||
convert["GAL"]["GAL"] = 1.0;
|
||||
// Mass & Weight
|
||||
convert["KG"]["KG"] = 1.00;
|
||||
convert["LBS"]["LBS"] = 1.00;
|
||||
|
|
|
@ -204,7 +204,7 @@ void FGPropulsion::ConsumeFuel(FGEngine* engine)
|
|||
if (TankPriority != 0) {
|
||||
switch(Tank->GetType()) {
|
||||
case FGTank::ttFUEL:
|
||||
if ((Tank->GetContents() > 0.0) && Tank->GetSelected() && (TankPriority == CurrentFuelTankPriority)) {
|
||||
if ((Tank->GetContents() > Tank->GetUnusable()) && Tank->GetSelected() && (TankPriority == CurrentFuelTankPriority)) {
|
||||
TanksWithFuel++;
|
||||
Starved = false;
|
||||
FeedListFuel.push_back(TankId);
|
||||
|
@ -236,7 +236,7 @@ void FGPropulsion::ConsumeFuel(FGEngine* engine)
|
|||
break;
|
||||
case FGTank::ttOXIDIZER:
|
||||
hasOxTanks = true;
|
||||
if (Tank->GetContents() > 0.0 && Tank->GetSelected() && TankPriority == CurrentOxidizerTankPriority) {
|
||||
if (Tank->GetContents() > Tank->GetUnusable() && Tank->GetSelected() && TankPriority == CurrentOxidizerTankPriority) {
|
||||
TanksWithOxidizer++;
|
||||
if (TanksWithFuel > 0) Starved = false;
|
||||
FeedListOxi.push_back(TankId);
|
||||
|
|
|
@ -63,7 +63,7 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
|
|||
Radius = Contents = Standpipe = Length = InnerRadius = 0.0;
|
||||
ExternalFlow = 0.0;
|
||||
InitialStandpipe = 0.0;
|
||||
Capacity = 0.00001;
|
||||
Capacity = 0.00001; UnusableVol = 0.0;
|
||||
Priority = InitialPriority = 1;
|
||||
vXYZ.InitMatrix();
|
||||
vXYZ_drain.InitMatrix();
|
||||
|
@ -95,6 +95,8 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
|
|||
Capacity = el->FindElementValueAsNumberConvertTo("capacity", "LBS");
|
||||
if (el->FindElement("contents"))
|
||||
InitialContents = Contents = el->FindElementValueAsNumberConvertTo("contents", "LBS");
|
||||
if (el->FindElement("unusable-volume"))
|
||||
UnusableVol = el->FindElementValueAsNumberConvertTo("unusable-volume", "GAL");
|
||||
if (el->FindElement("temperature"))
|
||||
InitialTemperature = Temperature = el->FindElementValueAsNumber("temperature");
|
||||
if (el->FindElement("standpipe"))
|
||||
|
@ -115,6 +117,13 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
|
|||
Capacity = 0.00001;
|
||||
Contents = 0.0;
|
||||
}
|
||||
if (Capacity <= GetUnusable()) {
|
||||
cerr << el->ReadFrom() << "Tank capacity (" << Capacity
|
||||
<< " lbs) is lower than the amount of unusable fuel (" << GetUnusable()
|
||||
<< " lbs) for tank " << tank_number
|
||||
<< "! Did you accidentally swap unusable and capacity?" << endl;
|
||||
throw("tank definition error");
|
||||
}
|
||||
if (Contents > Capacity) {
|
||||
cerr << el->ReadFrom() << "Tank content (" << Contents
|
||||
<< " lbs) is greater than tank capacity (" << Capacity
|
||||
|
@ -122,6 +131,11 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
|
|||
<< "! Did you accidentally swap contents and capacity?" << endl;
|
||||
throw("tank definition error");
|
||||
}
|
||||
if (Contents < GetUnusable()) {
|
||||
cerr << el->ReadFrom() << "Tank content (" << Contents
|
||||
<< " lbs) is lower than the amount of unusable fuel (" << GetUnusable()
|
||||
<< " lbs) for tank " << tank_number << endl;
|
||||
}
|
||||
|
||||
PctFull = 100.0*Contents/Capacity; // percent full; 0 to 100.0
|
||||
|
||||
|
@ -253,17 +267,16 @@ double FGTank::Drain(double used)
|
|||
{
|
||||
double remaining = Contents - used;
|
||||
|
||||
if (remaining >= 0) { // Reduce contents by amount used.
|
||||
|
||||
if (remaining >= GetUnusable()) { // Reduce contents by amount used.
|
||||
Contents -= used;
|
||||
PctFull = 100.0*Contents/Capacity;
|
||||
|
||||
} else { // This tank must be empty.
|
||||
if (Contents > GetUnusable())
|
||||
Contents = GetUnusable();
|
||||
|
||||
Contents = 0.0;
|
||||
PctFull = 0.0;
|
||||
remaining = Contents;
|
||||
}
|
||||
|
||||
PctFull = 100.0*Contents/Capacity;
|
||||
CalculateInertias();
|
||||
|
||||
return remaining;
|
||||
|
@ -443,6 +456,9 @@ void FGTank::bind(FGPropertyManager* PropertyManager)
|
|||
property_name = base_property_name + "/contents-lbs";
|
||||
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetContents,
|
||||
&FGTank::SetContents );
|
||||
property_name = base_property_name + "/unusable-volume-gal";
|
||||
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetUnusableVolume,
|
||||
&FGTank::SetUnusableVolume );
|
||||
property_name = base_property_name + "/pct-full";
|
||||
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetPctFull);
|
||||
|
||||
|
|
|
@ -7,21 +7,21 @@
|
|||
------------- Copyright (C) 1999 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
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
the terms of the GNU Lesser 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 Lesser General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Further information about the GNU Lesser General Public License can also be found on
|
||||
the world wide web at http://www.gnu.org.
|
||||
Further information about the GNU Lesser General Public License can also be
|
||||
found on the world wide web at http://www.gnu.org.
|
||||
|
||||
FUNCTIONAL DESCRIPTION
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -46,8 +46,6 @@ INCLUDES
|
|||
|
||||
#include "FGJSBBase.h"
|
||||
#include "math/FGColumnVector3.h"
|
||||
#include "math/FGFunction.h"
|
||||
#include <string>
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -58,6 +56,7 @@ namespace JSBSim {
|
|||
class Element;
|
||||
class FGPropertyManager;
|
||||
class FGFDMExec;
|
||||
class FGFunction;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DOCUMENTATION
|
||||
|
@ -69,8 +68,8 @@ CLASS DOCUMENTATION
|
|||
|
||||
Fuel temperature is calculated using the following assumptions:
|
||||
|
||||
Fuel temperature will only be calculated for tanks which have an initial fuel
|
||||
temperature specified in the configuration file.
|
||||
Fuel temperature will only be calculated for tanks which have an initial
|
||||
fuel temperature specified in the configuration file.
|
||||
|
||||
The surface area of the tank is estimated from the capacity in pounds. It
|
||||
is assumed that the tank is a wing tank with dimensions h by 4h by 10h. The
|
||||
|
@ -84,27 +83,30 @@ CLASS DOCUMENTATION
|
|||
|
||||
<h3>Fuel Dump:</h3>
|
||||
|
||||
Fuel dumping is handled by the FGPropulsion class. A standpipe can be defined
|
||||
here for each tank which sets the level of contents (in pounds) which is not dumpable.
|
||||
Default standpipe level is zero, making all contents dumpable.
|
||||
Fuel dumping is handled by the FGPropulsion class. A standpipe can be
|
||||
defined here for each tank which sets the level of contents (in pounds)
|
||||
which is not dumpable. Default standpipe level is zero, making all contents
|
||||
dumpable.
|
||||
|
||||
<h3>Fuel Transfer:</h3>
|
||||
|
||||
Fuel transfer is handled by the FGPropulsion class, however the contents of tanks
|
||||
may be manipulated directly using the SetContents() function here, or via the property
|
||||
tree at <tt>propulsion/tank[i]/contents-lbs</tt>, where i is the tank number (Tanks
|
||||
are automatically numbered, starting at zero, in the order in which they are read in
|
||||
the aircraft configuration file). The latter method allows one to use a system of FCS
|
||||
components to control tank contents.
|
||||
Fuel transfer is handled by the FGPropulsion class, however the contents of
|
||||
tanks may be manipulated directly using the SetContents() function here, or
|
||||
via the property tree at <tt>propulsion/tank[i]/contents-lbs</tt>, where i
|
||||
is the tank number (Tanks are automatically numbered, starting at zero, in
|
||||
the order in which they are read in the aircraft configuration file). The
|
||||
latter method allows one to use a system of FCS components to control tank
|
||||
contents.
|
||||
|
||||
There is also a property <tt>propulsion/tank[i]/external-flow-rate-pps</tt>. Setting
|
||||
this property to a positive value causes the tank to fill at the rate specified.
|
||||
Setting a negative number causes the tank to drain. The value is the rate in pounds
|
||||
of fuel per second. The tank will not fill past 100% full and will not drain below 0%.
|
||||
Fuel may be transfered between two tanks by setting the source tank's external flow rate
|
||||
to a negative value and the destination's external flow rate to the same positive value.
|
||||
Care must be taken to stop fuel flow before the source tank becomes empty to prevent
|
||||
phantom fuel being created.
|
||||
There is also a property
|
||||
<tt>propulsion/tank[i]/external-flow-rate-pps</tt>. Setting this property to
|
||||
a positive value causes the tank to fill at the rate specified. Setting a
|
||||
negative number causes the tank to drain. The value is the rate in pounds of
|
||||
fuel per second. The tank will not fill past 100% full and will not drain
|
||||
below 0%. Fuel may be transfered between two tanks by setting the source
|
||||
tank's external flow rate to a negative value and the destination's external
|
||||
flow rate to the same positive value. Care must be taken to stop fuel flow
|
||||
before the source tank becomes empty to prevent phantom fuel being created.
|
||||
|
||||
<h3>Configuration File Format:</h3>
|
||||
|
||||
|
@ -133,6 +135,7 @@ CLASS DOCUMENTATION
|
|||
<contents unit="{LBS | KG}"> {number} </contents>
|
||||
<temperature> {number} </temperature> <!-- must be degrees fahrenheit -->
|
||||
<standpipe unit="{LBS | KG"}> {number} </standpipe>
|
||||
<unusable unit="{LBS | KG}"> {number} </unusable>
|
||||
<priority> {integer} </priority>
|
||||
<density unit="{KG/L | LBS/GAL}"> {number} </density>
|
||||
<type> {string} </type> <!-- will override previous density setting -->
|
||||
|
@ -144,16 +147,19 @@ CLASS DOCUMENTATION
|
|||
- \b type - One of FUEL or OXIDIZER. This is required.
|
||||
- \b radius - Equivalent radius of tank for modeling slosh, defaults to inches.
|
||||
- \b grain_config type - One of CYLINDRICAL or ENDBURNING.
|
||||
- \b length - length of tank for modeling solid fuel propellant grain, defaults to inches.
|
||||
- \b length - length of tank for modeling solid fuel propellant grain, defaults
|
||||
to inches.
|
||||
- \b capacity - Capacity, defaults to pounds.
|
||||
- \b contents - Initial contents, defaults to pounds.
|
||||
- \b temperature - Initial temperature, defaults to degrees Fahrenheit.
|
||||
- \b standpipe - Minimum contents to which tank can dump, defaults to pounds.
|
||||
- \b unusable - Contents that cannot be used for combustion in the engine,
|
||||
defaults to pounds.
|
||||
- \b priority - Establishes feed sequence of tank. "1" is the highest priority.
|
||||
- \b density - Density of liquid tank contents.
|
||||
- \b type - Named fuel type. One of AVGAS, JET-A, JET-A1, JET-B, JP-1, JP-2, JP-3,
|
||||
- \b JP-4, JP-5, JP-6, JP-7, JP-8, JP-8+100, RP-1, T-1, ETHANOL, HYDRAZINE,
|
||||
- \b F-34, F-35, F-40, F-44, AVTAG, AVCAT
|
||||
- \b type - Named fuel type. One of AVGAS, JET-A, JET-A1, JET-B, JP-1, JP-2,
|
||||
JP-3, JP-4, JP-5, JP-6, JP-7, JP-8, JP-8+100, RP-1, T-1, ETHANOL,
|
||||
HYDRAZINE, F-34, F-35, F-40, F-44, AVTAG, AVCAT
|
||||
|
||||
location:
|
||||
- \b x - Location of tank on aircraft's x-axis, defaults to inches.
|
||||
|
@ -178,6 +184,7 @@ be printed to the console if the location is not given
|
|||
- \b contents - 0.0
|
||||
- \b temperature - -9999.0 (flag which indicates no temperature is set)
|
||||
- \b standpipe - 0.0 (all contents may be dumped)
|
||||
- \b unusable - 0.0 (all contents may be burnt)
|
||||
- \b priority - 1 (highest feed sequence priority)
|
||||
- \b density - 6.6
|
||||
|
||||
|
@ -195,7 +202,8 @@ class FGTank : public FGJSBBase
|
|||
{
|
||||
public:
|
||||
/** Constructor.
|
||||
The constructor reads in the defining parameters from a configuration file.
|
||||
The constructor reads in the defining parameters from a configuration
|
||||
file.
|
||||
@param exec a pointer to the base FGFDMExec instance.
|
||||
@param el a pointer to the Tank element.
|
||||
@param tank_number the tank number (zero based).
|
||||
|
@ -271,7 +279,19 @@ public:
|
|||
|
||||
/** Returns the density of a named fuel type.
|
||||
@return the density, in lbs/gal, or 6.6 if name cannot be resolved. */
|
||||
double ProcessFuelName(const std::string& name);
|
||||
double ProcessFuelName(const std::string& name);
|
||||
|
||||
/** Returns the amount of unusable fuel in the tank.
|
||||
@return the amount in lbs. */
|
||||
double GetUnusable(void) const {return UnusableVol*Density;}
|
||||
|
||||
/** Returns the unusable volume of fuel in the tank.
|
||||
@return the volume in gal. */
|
||||
double GetUnusableVolume(void) const {return UnusableVol;}
|
||||
|
||||
/** Sets the volume of unusable fuel in the tank.
|
||||
@param amount the amount of unusable fuel in gal. */
|
||||
void SetUnusableVolume(double volume) {UnusableVol = volume;}
|
||||
|
||||
double GetIxx(void) const {return Ixx;}
|
||||
double GetIyy(void) const {return Iyy;}
|
||||
|
@ -289,7 +309,11 @@ public:
|
|||
int GetPriority(void) const {return Priority;}
|
||||
void SetPriority(int p) { Priority = p; Selected = p>0 ? true:false; }
|
||||
|
||||
/** Returns the fuel density.
|
||||
@return the density in lbs/gal. */
|
||||
double GetDensity(void) const {return Density;}
|
||||
/** Sets the fuel density.
|
||||
@param d the density in lbs/gal. */
|
||||
void SetDensity(double d) { Density = d; }
|
||||
|
||||
double GetExternalFlow(void) const {return ExternalFlow;}
|
||||
|
@ -298,7 +322,7 @@ public:
|
|||
FGColumnVector3 GetXYZ(void) const;
|
||||
double GetXYZ(int idx) const;
|
||||
|
||||
const GrainType GetGrainType(void) const {return grainType;}
|
||||
GrainType GetGrainType(void) const {return grainType;}
|
||||
|
||||
double Fill(double amount);
|
||||
void SetContents(double amount);
|
||||
|
@ -321,7 +345,7 @@ private:
|
|||
FGFunction* function_ixx;
|
||||
FGFunction* function_iyy;
|
||||
FGFunction* function_izz;
|
||||
double Capacity;
|
||||
double Capacity, UnusableVol;
|
||||
double Radius;
|
||||
double InnerRadius;
|
||||
double Length;
|
||||
|
|
Loading…
Add table
Reference in a new issue