⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fgtank.cpp

📁 6 DOF Missle Simulation
💻 CPP
字号:
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Module:       FGTank.cpp Author:       Jon Berndt Date started: 01/21/99 Called by:    FGAircraft ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.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. 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. 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--------------------------------------------------------------------------------See header file.HISTORY--------------------------------------------------------------------------------01/21/99   JSB   Created%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%INCLUDES%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/#include "FGTank.h"using std::cerr;using std::endl;using std::cout;namespace JSBSim {static const char *IdSrc = "$Id$";static const char *IdHdr = ID_TANK;/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%CLASS IMPLEMENTATION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)                  : TankNumber(tank_number){  string token;  Element* element;  Element* element_Grain;  Area = 1.0;  Temperature = -9999.0;  Ixx = Iyy = Izz = 0.0;  Auxiliary = exec->GetAuxiliary();  Radius = Capacity = Contents = Standpipe = Length = InnerRadius = 0.0;  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("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");  Selected = true;  if (Capacity != 0) {    PctFull = 100.0*Contents/Capacity;            // percent full; 0 to 100.0  } else {    Contents = 0;    PctFull  = 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  }  char property_name[80];  snprintf(property_name, 80, "propulsion/tank[%d]/contents-lbs", TankNumber);  PropertyManager->Tie( property_name, (FGTank*)this, &FGTank::GetContents,                                       &FGTank::SetContents );  if (Temperature != -9999.0)  InitialTemperature = Temperature = FahrenheitToCelsius(Temperature);  Area = 40.0 * pow(Capacity/1975, 0.666666667);  Debug(0);}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%FGTank::~FGTank(){  Debug(1);}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%void FGTank::ResetToIC(void){  Temperature = InitialTemperature;  Standpipe = InitialStandpipe;  Contents = InitialContents;  PctFull = 100.0*Contents/Capacity;  Selected = true;}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%const FGColumnVector3 FGTank::GetXYZ(void){  return vXYZ_drain + (Contents/Capacity)*(vXYZ - vXYZ_drain);}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%const double FGTank::GetXYZ(int idx){  return vXYZ_drain(idx) + (Contents/Capacity)*(vXYZ(idx)-vXYZ_drain(idx));}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%double FGTank::Drain(double used){  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;    Selected = false;  }  if (grainType != gtUNKNOWN) CalculateInertias();  return remaining;}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%double FGTank::Fill(double amount){  double overage = 0.0;  Contents += amount;  if (Contents > Capacity) {    overage = Contents - Capacity;    Contents = Capacity;    PctFull = 100.0;  } else {    PctFull = Contents/Capacity*100.0;  }  return overage;}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%void FGTank::SetContents(double amount){  Contents = amount;  if (Contents > Capacity) {    Contents = Capacity;    PctFull = 100.0;  } else {    PctFull = Contents/Capacity*100.0;  }}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%double FGTank::Calculate(double dt){  if (Temperature == -9999.0) return 0.0;  double HeatCapacity = 900.0;        // Joules/lbm/C  double TempFlowFactor = 1.115;      // Watts/sqft/C  double TAT = Auxiliary->GetTAT_C();  double Tdiff = TAT - 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}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%//  This function calculates the moments of inertia for a solid propellant//  grain - either an end burning cylindrical grain or a bored cylindrical//  grain.void FGTank::CalculateInertias(void){  double Mass = Contents*lbtoslug;  double RadSumSqr;  double Rad2 = Radius*Radius;  Volume = (Contents*lbtoslug)/Density; // in^3  switch (grainType) {    case gtCYLINDRICAL:      InnerRadius = sqrt(Rad2 - Volume/(M_PI * Length));      RadSumSqr = (Rad2 + InnerRadius*InnerRadius)/144.0;      Ixx = 0.5*Mass*RadSumSqr;      Iyy = Mass*(3.0*RadSumSqr + Length*Length/144.0)/12.0;      break;    case gtENDBURNING:      Length = Volume/(M_PI*Rad2);      Ixx = 0.5*Mass*Rad2/144.0;      Iyy = Mass*(3.0*Rad2 + Length*Length)/(144.0*12.0);      break;  }  Izz  = Iyy;}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%//    The bitmasked value choices are as follows://    unset: In this case (the default) JSBSim would only print//       out the normally expected messages, essentially echoing//       the config files as they are read. If the environment//       variable is not set, debug_lvl is set to 1 internally//    0: This requests JSBSim not to output any messages//       whatsoever.//    1: This value explicity requests the normal JSBSim//       startup messages//    2: This value asks for a message to be printed out when//       a class is instantiated//    4: When this value is set, a message is displayed when a//       FGModel object executes its Run() method//    8: When this value is set, various runtime state variables//       are printed out periodically//    16: When set various parameters are sanity checked and//       a message is printed out when they go out of boundsvoid FGTank::Debug(int from){  if (debug_lvl <= 0) return;  if (debug_lvl & 1) { // Standard console startup message output    if (from == 0) { // Constructor      cout << "      " << type << " tank holds " << Capacity << " lbs. " << type << endl;      cout << "      currently at " << PctFull << "% of maximum capacity" << endl;      cout << "      Tank location (X, Y, Z): " << vXYZ(eX) << ", " << vXYZ(eY) << ", " << vXYZ(eZ) << endl;      cout << "      Effective radius: " << Radius << " inches" << endl;      cout << "      Initial temperature: " << Temperature << " Fahrenheit" << endl;    }  }  if (debug_lvl & 2 ) { // Instantiation/Destruction notification    if (from == 0) cout << "Instantiated: FGTank" << endl;    if (from == 1) cout << "Destroyed:    FGTank" << endl;  }  if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects  }  if (debug_lvl & 8 ) { // Runtime state variables  }  if (debug_lvl & 16) { // Sanity checking  }  if (debug_lvl & 64) {    if (from == 0) { // Constructor      cout << IdSrc << endl;      cout << IdHdr << endl;    }  }}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -