JSBSim Flight Dynamics Model 1.0 (23 February 2013)
An Open Source Flight Dynamics and Control Software Library in C++

FGTank Class Reference

Models a fuel tank. More...

#include <FGTank.h>

Inheritance diagram for FGTank:
Collaboration diagram for FGTank:

List of all members.

Public Types

enum  GrainType { gtUNKNOWN, gtCYLINDRICAL, gtENDBURNING }
enum  TankType { ttUNKNOWN, ttFUEL, ttOXIDIZER }

Public Member Functions

 FGTank (FGFDMExec *exec, Element *el, int tank_number)
 Constructor.
 ~FGTank ()
 Destructor.
double Calculate (double dt, double TempC)
 Performs local, tanks-specific calculations, such as fuel temperature.
double Drain (double used)
 Removes fuel from the tank.
double Fill (double amount)
double GetCapacity (void) const
 Gets the capacity of the tank.
double GetCapacityGallons (void) const
 Gets the capacity of the tank.
double GetContents (void) const
 Gets the contents of the tank.
double GetContentsGallons (void) const
 Gets the contents of the tank.
double GetDensity (void) const
double GetExternalFlow (void) const
const GrainType GetGrainType (void) const
double GetIxx (void) const
double GetIyy (void) const
double GetIzz (void) const
double GetPctFull (void) const
 Gets the tank fill level.
int GetPriority (void) const
bool GetSelected (void) const
 If the tank is set to supply fuel, this function returns true.
double GetStandpipe (void) const
double GetTemperature (void) const
 Gets the temperature of the fuel.
double GetTemperature_degC (void) const
 Gets the temperature of the fuel.
int GetType (void) const
 Retrieves the type of tank: Fuel or Oxidizer.
FGColumnVector3 GetXYZ (void) const
double GetXYZ (int idx) const
double ProcessFuelName (const std::string &name)
 Returns the density of a named fuel type.
void ResetToIC (void)
 Resets the tank parameters to the initial conditions.
void SetContents (double amount)
void SetContentsGallons (double gallons)
void SetDensity (double d)
void SetExternalFlow (double f)
void SetPriority (int p)
void SetSelected (bool sel)
void SetStandpipe (double amount)
void SetTemperature (double temp)

Detailed Description

Fuel Temperature:

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.

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 volume of the tank is then 40(h)(h)(h). The area of the upper or lower surface is then 40(h)(h). The volume is also equal to the capacity divided by 49.368 lbs/cu-ft, for jet fuel. The surface area of one side can then be derived from the tank's capacity.

The heat capacity of jet fuel is assumed to be 900 Joules/lbm/K, and the heat transfer factor of the tank is 1.115 Watts/sq-ft/K.

Fuel Dump:

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 Transfer:

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 propulsion/tank[i]/contents-lbs, 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 propulsion/tank[i]/external-flow-rate-pps. 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.

Configuration File Format:

<tank type="{FUEL | OXIDIZER}">
  <grain_config type="{CYLINDRICAL | ENDBURNING}">
    <length unit="{IN | FT | M}"> {number} </radius>
  </grain_config>
  <location unit="{FT | M | IN}">
    <x> {number} </x>
    <y> {number} </y>
    <z> {number} </z>
  </location>
  <drain_location unit="{FT | M | IN}">
    <x> {number} </x>
    <y> {number} </y>
    <z> {number} </z>
  </drain_location>
  <radius unit="{IN | FT | M}"> {number} </radius>
  <capacity unit="{LBS | KG}"> {number} </capacity>
  <contents unit="{LBS | KG}"> {number} </contents>
  <temperature> {number} </temperature> <!-- must be degrees fahrenheit -->
  <standpipe unit="{LBS | KG"}> {number} </standpipe>
  <priority> {integer} </priority>
  <density unit="{KG/L | LBS/GAL}"> {number} </density>
  <type> {string} </type> <!-- will override previous density setting -->
</tank>

Definition of the tank configuration file parameters:

  • type - One of FUEL or OXIDIZER. This is required.
  • radius - Equivalent radius of tank for modeling slosh, defaults to inches.
  • grain_config type - One of CYLINDRICAL or ENDBURNING.
  • length - length of tank for modeling solid fuel propellant grain, defaults to inches.
  • capacity - Capacity, defaults to pounds.
  • contents - Initial contents, defaults to pounds.
  • temperature - Initial temperature, defaults to degrees Fahrenheit.
  • standpipe - Minimum contents to which tank can dump, defaults to pounds.
  • priority - Establishes feed sequence of tank. "1" is the highest priority.
  • density - Density of liquid tank contents.
  • 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:

  • x - Location of tank on aircraft's x-axis, defaults to inches.
  • y - Location of tank on aircraft's y-axis, defaults to inches.
  • z - Location of tank on aircraft's z-axis, defaults to inches.

drain_location:

  • x - Location of tank drain on aircraft's x-axis, defaults to inches.
  • y - Location of tank drain on aircraft's y-axis, defaults to inches.
  • z - Location of tank drain on aircraft's z-axis, defaults to inches.

Default values of the tank configuration file parameters:

  • type - ttUNKNOWN (causes a load error in the propulsion configuration)
  • location, drain_location - both optional, but a warning message will be printed to the console if the location is not given
  • x - 0.0 (both full and drained CG locations)
  • y - 0.0 (both full and drained CG locations)
  • z - 0.0 (both full and drained CG locations)
  • radius - 0.0
  • capacity - 0.00001 (tank capacity must not be zero)
  • contents - 0.0
  • temperature - -9999.0 (flag which indicates no temperature is set)
  • standpipe - 0.0 (all contents may be dumped)
  • priority - 1 (highest feed sequence priority)
  • density - 6.6
Author:
Jon Berndt, Dave Culp
See also:
Akbar, Raza et al. "A Simple Analysis of Fuel Addition to the CWT of 747", California Institute of Technology, 1998, http://www.galcit.caltech.edu/EDL/projects/JetA/reports/lumped.pdf

Definition at line 194 of file FGTank.h.


Constructor & Destructor Documentation

FGTank ( FGFDMExec exec,
Element el,
int  tank_number 
)

The constructor reads in the defining parameters from a configuration file.

Parameters:
execa pointer to the base FGFDMExec instance.
ela pointer to the Tank element.
tank_numberthe tank number (zero based).

Definition at line 57 of file FGTank.cpp.

References FGJSBBase::FahrenheitToCelsius(), Element::FindElement(), Element::FindElementTripletConvertTo(), Element::FindElementValue(), Element::FindElementValueAsNumber(), Element::FindElementValueAsNumberConvertTo(), Element::GetAttributeValue(), FGTank::GetContents(), FGTank::GetPctFull(), FGFDMExec::GetPropertyManager(), FGTank::ProcessFuelName(), and FGPropertyManager::Tie().

                  : TankNumber(tank_number), Exec(exec)
{
  string token, strFuelName;
  Element* element;
  Element* element_Grain;
  Area = 1.0;
  Density = 6.6;
  InitialTemperature = Temperature = -9999.0;
  Ixx = Iyy = Izz = 0.0;
  InertiaFactor = 1.0;
  Radius = Contents = Standpipe = Length = InnerRadius = 0.0;
  PreviousUsed = 0.0;
  ExternalFlow = 0.0;
  InitialStandpipe = 0.0;
  Capacity = 0.00001;
  Priority = InitialPriority = 1;
  PropertyManager = Exec->GetPropertyManager();
  vXYZ.InitMatrix();
  vXYZ_drain.InitMatrix();

  type = el->GetAttributeValue("type");
  if      (type == "FUEL")     Type = ttFUEL;
  else if (type == "OXIDIZER") Type = ttOXIDIZER;
  else                         Type = ttUNKNOWN;

  element = el->FindElement("location");
  if (element)  vXYZ = element->FindElementTripletConvertTo("IN");
  else          cerr << "No location found for this tank." << endl;

  vXYZ_drain = vXYZ; // Set initial drain location to initial tank CG

  element = el->FindElement("drain_location");
  if (element)  {
    vXYZ_drain = element->FindElementTripletConvertTo("IN");
  }

  if (el->FindElement("radius"))
    Radius = el->FindElementValueAsNumberConvertTo("radius", "IN");
  if (el->FindElement("inertia_factor"))
    InertiaFactor = el->FindElementValueAsNumber("inertia_factor");
  if (el->FindElement("capacity"))
    Capacity = el->FindElementValueAsNumberConvertTo("capacity", "LBS");
  if (el->FindElement("contents"))
    InitialContents = Contents = el->FindElementValueAsNumberConvertTo("contents", "LBS");
  if (el->FindElement("temperature"))
    InitialTemperature = Temperature = el->FindElementValueAsNumber("temperature");
  if (el->FindElement("standpipe"))
    InitialStandpipe = Standpipe = el->FindElementValueAsNumberConvertTo("standpipe", "LBS");
  if (el->FindElement("priority"))
    InitialPriority = Priority = (int)el->FindElementValueAsNumber("priority");
  if (el->FindElement("density"))
    Density = el->FindElementValueAsNumberConvertTo("density", "LBS/GAL");
  if (el->FindElement("type"))
    strFuelName = el->FindElementValue("type");


  SetPriority( InitialPriority );     // this will also set the Selected flag

  if (Capacity == 0) {
    cerr << "Tank capacity must not be zero. Reset to 0.00001 lbs!" << endl;
    Capacity = 0.00001;
    Contents = 0.0;
  }
  PctFull = 100.0*Contents/Capacity;            // percent full; 0 to 100.0

  // Check whether this is a solid propellant "tank". Initialize it if true.

  grainType = gtUNKNOWN; // This is the default
  
  element_Grain = el->FindElement("grain_config");
  if (element_Grain) {

    strGType = element_Grain->GetAttributeValue("type");
    if (strGType == "CYLINDRICAL")     grainType = gtCYLINDRICAL;
    else if (strGType == "ENDBURNING") grainType = gtENDBURNING;
    else                               cerr << "Unknown propellant grain type specified" << endl;

    if (element_Grain->FindElement("length"))
      Length = element_Grain->FindElementValueAsNumberConvertTo("length", "IN");
    if (element_Grain->FindElement("bore_diameter"))
      InnerRadius = element_Grain->FindElementValueAsNumberConvertTo("bore_diameter", "IN")/2.0;

    // Initialize solid propellant values for debug and runtime use.

    switch (grainType) {
      case gtCYLINDRICAL:
        if (Radius <= InnerRadius) {
          cerr << "The bore diameter should be smaller than the total grain diameter!" << endl;
          exit(-1);
        }
        Volume = M_PI * Length * (Radius*Radius - InnerRadius*InnerRadius); // cubic inches
        break;
      case gtENDBURNING:
        Volume = M_PI * Length * Radius * Radius; // cubic inches
        break;
      case gtUNKNOWN:
        cerr << "Unknown grain type found in this rocket engine definition." << endl;
        exit(-1);
    }
    Density = (Contents*lbtoslug)/Volume; // slugs/in^3
  }

    CalculateInertias();

  string property_name, base_property_name;
  base_property_name = CreateIndexedPropertyName("propulsion/tank", TankNumber);
  property_name = base_property_name + "/contents-lbs";
  PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetContents,
                                       &FGTank::SetContents );
  property_name = base_property_name + "/pct-full";
  PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetPctFull);

  property_name = base_property_name + "/priority";
  PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetPriority,
                                       &FGTank::SetPriority );
  property_name = base_property_name + "/external-flow-rate-pps";
  PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetExternalFlow,
                                       &FGTank::SetExternalFlow );

  if (Temperature != -9999.0)  InitialTemperature = Temperature = FahrenheitToCelsius(Temperature);
  Area = 40.0 * pow(Capacity/1975, 0.666666667);

  // A named fuel type will override a previous density value
  if (!strFuelName.empty()) Density = ProcessFuelName(strFuelName); 

  Debug(0);
}

Here is the call graph for this function:


Member Function Documentation

double Calculate ( double  dt,
double  TempC 
)

This function calculates the temperature of the fuel in the tank.

Parameters:
dtthe time step for this model.
TempCthe Total Air Temperature in degrees Celsius.
Returns:
the current temperature in degrees Celsius.

Definition at line 283 of file FGTank.cpp.

References FGTank::Drain().

{
  if(ExternalFlow < 0.) Drain( -ExternalFlow *dt);
  else Fill(ExternalFlow * dt);

  if (Temperature == -9999.0) return 0.0;
  double HeatCapacity = 900.0;        // Joules/lbm/C
  double TempFlowFactor = 1.115;      // Watts/sqft/C
  double Tdiff = TAT_C - Temperature;
  double dTemp = 0.0;                 // Temp change due to one surface
  if (fabs(Tdiff) > 0.1) {
    dTemp = (TempFlowFactor * Area * Tdiff * dt) / (Contents * HeatCapacity);
  }

  return Temperature += (dTemp + dTemp);    // For now, assume upper/lower the same
}

Here is the call graph for this function:

double Drain ( double  used)

This function removes fuel from a tank. If the tank empties, it is deselected.

Parameters:
usedthe amount of fuel used in lbs.
Returns:
the remaining contents of the tank in lbs.

Definition at line 221 of file FGTank.cpp.

Referenced by FGTank::Calculate().

{
//  double AmountToDrain = 2.0*used - PreviousUsed;
  double remaining = Contents - used;

  if (remaining >= 0) { // Reduce contents by amount used.

    Contents -= used;
    PctFull = 100.0*Contents/Capacity;

  } else { // This tank must be empty.

    Contents = 0.0;
    PctFull = 0.0;
  }
//  PreviousUsed = AmountToDrain;
  if (grainType != gtUNKNOWN) CalculateInertias();

  return remaining;
}

Here is the caller graph for this function:

double GetCapacity ( void  ) const [inline]
Returns:
the capacity of the tank in pounds.

Definition at line 244 of file FGTank.h.

{return Capacity;}
double GetCapacityGallons ( void  ) const [inline]
Returns:
the capacity of the tank in gallons.

Definition at line 248 of file FGTank.h.

{return Capacity/Density;}
double GetContents ( void  ) const [inline]
Returns:
the contents of the tank in pounds.

Definition at line 252 of file FGTank.h.

Referenced by FGTank::FGTank().

{return Contents;}

Here is the caller graph for this function:

double GetContentsGallons ( void  ) const [inline]
Returns:
the contents of the tank in gallons.

Definition at line 256 of file FGTank.h.

{return Contents/Density;}
double GetPctFull ( void  ) const [inline]
Returns:
the fill level in percent, from 0 to 100.

Definition at line 240 of file FGTank.h.

Referenced by FGTank::FGTank().

{return PctFull;}

Here is the caller graph for this function:

bool GetSelected ( void  ) const [inline]
Returns:
true if this tank is set to a non-zero priority.

Definition at line 236 of file FGTank.h.

{return Selected;}
double GetTemperature ( void  ) const [inline]

The temperature of the fuel is calculated if an initial tempearture is given in the configuration file.

Returns:
the temperature of the fuel in degrees F IF an initial temperature is given, otherwise 32 degrees F is returned.

Definition at line 270 of file FGTank.h.

References FGJSBBase::CelsiusToFahrenheit().

{return CelsiusToFahrenheit(Temperature);}

Here is the call graph for this function:

double GetTemperature_degC ( void  ) const [inline]

The temperature of the fuel is calculated if an initial tempearture is given in the configuration file.

Returns:
the temperature of the fuel in degrees C IF an initial temperature is given, otherwise 0.0 C is returned.

Definition at line 263 of file FGTank.h.

{return Temperature;}
int GetType ( void  ) const [inline]
Returns:
the tank type, 0 for undefined, 1 for fuel, and 2 for oxidizer.

Definition at line 229 of file FGTank.h.

{return Type;}
double ProcessFuelName ( const std::string &  name)
Returns:
the density, in lbs/gal, or 6.6 if name cannot be resolved.

Definition at line 362 of file FGTank.cpp.

Referenced by FGTank::FGTank().

{
   if      (name == "AVGAS")    return 6.02; 
   else if (name == "JET-A")    return 6.74;
   else if (name == "JET-A1")   return 6.74;
   else if (name == "JET-B")    return 6.48;
   else if (name == "JP-1")     return 6.76;
   else if (name == "JP-2")     return 6.38;
   else if (name == "JP-3")     return 6.34;
   else if (name == "JP-4")     return 6.48;
   else if (name == "JP-5")     return 6.81;
   else if (name == "JP-6")     return 6.55;
   else if (name == "JP-7")     return 6.61;
   else if (name == "JP-8")     return 6.66;
   else if (name == "JP-8+100") return 6.66;
 //else if (name == "JP-9")     return 6.74;
 //else if (name == "JPTS")     return 6.74;
   else if (name == "RP-1")     return 6.73;
   else if (name == "T-1")      return 6.88;
   else if (name == "ETHANOL")  return 6.58;
   else if (name == "HYDRAZINE")return 8.61;
   else if (name == "F-34")     return 6.66;
   else if (name == "F-35")     return 6.74;
   else if (name == "F-40")     return 6.48;
   else if (name == "F-44")     return 6.81;
   else if (name == "AVTAG")    return 6.48;
   else if (name == "AVCAT")    return 6.81;
   else {
     cerr << "Unknown fuel type specified: "<< name << endl;
   } 

   return 6.6;
}

Here is the caller graph for this function:


The documentation for this class was generated from the following files: