fgpiston.cpp

来自「6 DOF Missle Simulation」· C++ 代码 · 共 910 行 · 第 1/3 页

CPP
910
字号
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Module:       FGPiston.cpp Author:       Jon S. Berndt, JSBSim framework               Dave Luff, Piston engine model               Ronald Jensen, Piston engine model Date started: 09/12/2000 Purpose:      This module models a Piston engine ------------- Copyright (C) 2000  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--------------------------------------------------------------------------------This class descends from the FGEngine class and models a Piston engine based onparameters given in the engine config file for this classHISTORY--------------------------------------------------------------------------------09/12/2000  JSB  Created%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%INCLUDES%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/#include <sstream>#include "FGPiston.h"#include <models/FGPropulsion.h>#include "FGPropeller.h"namespace JSBSim {static const char *IdSrc = "$Id$";static const char *IdHdr = ID_PISTON;/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%CLASS IMPLEMENTATION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)  : FGEngine(exec, el, engine_number),  R_air(287.3),                  // Gas constant for air J/Kg/K  rho_fuel(800),                 // estimate  calorific_value_fuel(47.3e6),  Cp_air(1005),                  // Specific heat (constant pressure) J/Kg/K  Cp_fuel(1700){  string token;  // Defaults and initializations  Type = etPiston;  dt = State->Getdt();  // These items are read from the configuration file  Cycles = 2;  IdleRPM = 600;  MaxRPM = 2800;  Displacement = 360;  SparkFailDrop = 1.0;  MaxHP = 200;  MinManifoldPressure_inHg = 6.5;  MaxManifoldPressure_inHg = 28.5;  BSFC = -1;  // Initialisation  volumetric_efficiency = 0.8;  // Actually f(speed, load) but this will get us running  // These are internal program variables  crank_counter = 0;  Magnetos = 0;  minMAP = 21950;  maxMAP = 96250;  ResetToIC();  // Supercharging  BoostSpeeds = 0;  // Default to no supercharging  BoostSpeed = 0;  Boosted = false;  BoostOverride = 0;  bBoostOverride = false;  bTakeoffBoost = false;  TakeoffBoost = 0.0;   // Default to no extra takeoff-boost  int i;  for (i=0; i<FG_MAX_BOOST_SPEEDS; i++) {    RatedBoost[i] = 0.0;    RatedPower[i] = 0.0;    RatedAltitude[i] = 0.0;    BoostMul[i] = 1.0;    RatedMAP[i] = 100000;    RatedRPM[i] = 2500;    TakeoffMAP[i] = 100000;  }  for (i=0; i<FG_MAX_BOOST_SPEEDS-1; i++) {    BoostSwitchAltitude[i] = 0.0;    BoostSwitchPressure[i] = 0.0;  }  // First column is thi, second is neta (combustion efficiency)  Lookup_Combustion_Efficiency = new FGTable(12);  *Lookup_Combustion_Efficiency << 0.00 << 0.980;  *Lookup_Combustion_Efficiency << 0.90 << 0.980;  *Lookup_Combustion_Efficiency << 1.00 << 0.970;  *Lookup_Combustion_Efficiency << 1.05 << 0.950;  *Lookup_Combustion_Efficiency << 1.10 << 0.900;  *Lookup_Combustion_Efficiency << 1.15 << 0.850;  *Lookup_Combustion_Efficiency << 1.20 << 0.790;  *Lookup_Combustion_Efficiency << 1.30 << 0.700;  *Lookup_Combustion_Efficiency << 1.40 << 0.630;  *Lookup_Combustion_Efficiency << 1.50 << 0.570;  *Lookup_Combustion_Efficiency << 1.60 << 0.525;  *Lookup_Combustion_Efficiency << 2.00 << 0.345;  Power_Mixture_Correlation = new FGTable(13);  *Power_Mixture_Correlation << (14.7/1.6) << 0.780;  *Power_Mixture_Correlation << 10 <<  0.860;  *Power_Mixture_Correlation << 11 <<  0.935;  *Power_Mixture_Correlation << 12 <<  0.980;  *Power_Mixture_Correlation << 13 <<  1.000;  *Power_Mixture_Correlation << 14 <<  0.990;  *Power_Mixture_Correlation << 15 <<  0.964;  *Power_Mixture_Correlation << 16 <<  0.925;  *Power_Mixture_Correlation << 17 <<  0.880;  *Power_Mixture_Correlation << 18 <<  0.830;  *Power_Mixture_Correlation << 19 <<  0.785;  *Power_Mixture_Correlation << 20 <<  0.740;  *Power_Mixture_Correlation << (14.7/0.6) << 0.58;  Mixture_Efficiency_Correlation = new FGTable(15);  *Mixture_Efficiency_Correlation << 0.05000 << 0.00000;  *Mixture_Efficiency_Correlation << 0.05137 << 0.00862;  *Mixture_Efficiency_Correlation << 0.05179 << 0.21552;  *Mixture_Efficiency_Correlation << 0.05430 << 0.48276;  *Mixture_Efficiency_Correlation << 0.05842 << 0.70690;  *Mixture_Efficiency_Correlation << 0.06312 << 0.83621;  *Mixture_Efficiency_Correlation << 0.06942 << 0.93103;  *Mixture_Efficiency_Correlation << 0.07786 << 1.00000;  *Mixture_Efficiency_Correlation << 0.08845 << 1.00000;  *Mixture_Efficiency_Correlation << 0.09270 << 0.98276;  *Mixture_Efficiency_Correlation << 0.10120 << 0.93103;  *Mixture_Efficiency_Correlation << 0.11455 << 0.72414;  *Mixture_Efficiency_Correlation << 0.12158 << 0.45690;  *Mixture_Efficiency_Correlation << 0.12435 << 0.23276;  *Mixture_Efficiency_Correlation << 0.12500 << 0.00000;/*Manifold_Pressure_Lookup = new        0       0.2      0.4      0.6      0.8     10        1.0000    1.0000    1.0000    1.0000    1.0000    1.00001000    0.7778    0.8212    0.8647    0.9081    0.9516    0.99502000    0.5556    0.6424    0.7293    0.8162    0.9031    0.99003000    0.3333    0.4637    0.5940    0.7243    0.8547    0.98504000    0.2000    0.2849    0.4587    0.6324    0.8062    0.98005000    0.2000    0.2000    0.3233    0.5406    0.7578    0.97506000    0.2000    0.2000    0.2000    0.4487    0.7093    0.97007000    0.2000    0.2000    0.2000    0.2000    0.4570    0.76118000    0.2000    0.2000    0.2000    0.2000    0.2047    0.5522*/  // Read inputs from engine data file where present.  if (el->FindElement("minmp")) // Should have ELSE statement telling default value used?    MinManifoldPressure_inHg = el->FindElementValueAsNumberConvertTo("minmp","INHG");  if (el->FindElement("maxmp"))    MaxManifoldPressure_inHg = el->FindElementValueAsNumberConvertTo("maxmp","INHG");  if (el->FindElement("displacement"))    Displacement = el->FindElementValueAsNumberConvertTo("displacement","IN3");  if (el->FindElement("maxhp"))    MaxHP = el->FindElementValueAsNumberConvertTo("maxhp","HP");  if (el->FindElement("sparkfaildrop"))    SparkFailDrop = Constrain(0, 1 - el->FindElementValueAsNumber("sparkfaildrop"), 1);  if (el->FindElement("cycles"))    Cycles = el->FindElementValueAsNumber("cycles");  if (el->FindElement("idlerpm"))    IdleRPM = el->FindElementValueAsNumber("idlerpm");  if (el->FindElement("maxrpm"))    MaxRPM = el->FindElementValueAsNumber("maxrpm");  if (el->FindElement("maxthrottle"))    MaxThrottle = el->FindElementValueAsNumber("maxthrottle");  if (el->FindElement("minthrottle"))    MinThrottle = el->FindElementValueAsNumber("minthrottle");  if (el->FindElement("bsfc"))    BSFC = el->FindElementValueAsNumberConvertTo("bsfc", "LBS/HP*HR");  if (el->FindElement("volumetric-efficiency"))    volumetric_efficiency = el->FindElementValueAsNumber("volumetric-efficiency");  if (el->FindElement("numboostspeeds")) { // Turbo- and super-charging parameters    BoostSpeeds = (int)el->FindElementValueAsNumber("numboostspeeds");    if (el->FindElement("boostoverride"))      BoostOverride = (int)el->FindElementValueAsNumber("boostoverride");    if (el->FindElement("takeoffboost"))      TakeoffBoost = el->FindElementValueAsNumberConvertTo("takeoffboost", "PSI");    if (el->FindElement("ratedboost1"))      RatedBoost[0] = el->FindElementValueAsNumberConvertTo("ratedboost1", "PSI");    if (el->FindElement("ratedboost2"))      RatedBoost[1] = el->FindElementValueAsNumberConvertTo("ratedboost2", "PSI");    if (el->FindElement("ratedboost3"))      RatedBoost[2] = el->FindElementValueAsNumberConvertTo("ratedboost3", "PSI");    if (el->FindElement("ratedpower1"))      RatedPower[0] = el->FindElementValueAsNumberConvertTo("ratedpower1", "HP");    if (el->FindElement("ratedpower2"))      RatedPower[1] = el->FindElementValueAsNumberConvertTo("ratedpower2", "HP");    if (el->FindElement("ratedpower3"))      RatedPower[2] = el->FindElementValueAsNumberConvertTo("ratedpower3", "HP");    if (el->FindElement("ratedrpm1"))      RatedRPM[0] = el->FindElementValueAsNumber("ratedrpm1");    if (el->FindElement("ratedrpm2"))      RatedRPM[1] = el->FindElementValueAsNumber("ratedrpm2");    if (el->FindElement("ratedrpm3"))      RatedRPM[2] = el->FindElementValueAsNumber("ratedrpm3");    if (el->FindElement("ratedaltitude1"))      RatedAltitude[0] = el->FindElementValueAsNumberConvertTo("ratedaltitude1", "FT");    if (el->FindElement("ratedaltitude2"))      RatedAltitude[1] = el->FindElementValueAsNumberConvertTo("ratedaltitude2", "FT");    if (el->FindElement("ratedaltitude3"))      RatedAltitude[2] = el->FindElementValueAsNumberConvertTo("ratedaltitude3", "FT");  }  // Create a BSFC to match the engine if not provided  if (BSFC < 0) {      BSFC = ( Displacement * MaxRPM * volumetric_efficiency ) / (9411 * MaxHP);  }  char property_name[80];  snprintf(property_name, 80, "propulsion/engine[%d]/power-hp", EngineNumber);  PropertyManager->Tie(property_name, &HP);  snprintf(property_name, 80, "propulsion/engine[%d]/bsfc-lbs_hphr", EngineNumber);  PropertyManager->Tie(property_name, &BSFC);  snprintf(property_name, 80, "propulsion/engine[%d]/volumetric-efficiency", EngineNumber);  PropertyManager->Tie(property_name, &volumetric_efficiency);  minMAP = MinManifoldPressure_inHg * inhgtopa;  // inHg to Pa  maxMAP = MaxManifoldPressure_inHg * inhgtopa;  StarterHP = sqrt(MaxHP) * 0.4;  // Set up and sanity-check the turbo/supercharging configuration based on the input values.  if (TakeoffBoost > RatedBoost[0]) bTakeoffBoost = true;  for (i=0; i<BoostSpeeds; ++i) {    bool bad = false;    if (RatedBoost[i] <= 0.0) bad = true;    if (RatedPower[i] <= 0.0) bad = true;    if (RatedAltitude[i] < 0.0) bad = true;  // 0.0 is deliberately allowed - this corresponds to unregulated supercharging.    if (i > 0 && RatedAltitude[i] < RatedAltitude[i - 1]) bad = true;    if (bad) {      // We can't recover from the above - don't use this supercharger speed.      BoostSpeeds--;      // TODO - put out a massive error message!      break;    }    // Now sanity-check stuff that is recoverable.    if (i < BoostSpeeds - 1) {      if (BoostSwitchAltitude[i] < RatedAltitude[i]) {        // TODO - put out an error message        // But we can also make a reasonable estimate, as below.        BoostSwitchAltitude[i] = RatedAltitude[i] + 1000;      }      BoostSwitchPressure[i] = Atmosphere->GetPressure(BoostSwitchAltitude[i]) * psftopa;      //cout << "BoostSwitchAlt = " << BoostSwitchAltitude[i] << ", pressure = " << BoostSwitchPressure[i] << '\n';      // Assume there is some hysteresis on the supercharger gear switch, and guess the value for now      BoostSwitchHysteresis = 1000;    }    // Now work out the supercharger pressure multiplier of this speed from the rated boost and altitude.    RatedMAP[i] = Atmosphere->GetPressureSL() * psftopa + RatedBoost[i] * 6895;  // psi*6895 = Pa.    // Sometimes a separate BCV setting for takeoff or extra power is fitted.    if (TakeoffBoost > RatedBoost[0]) {      // Assume that the effect on the BCV is the same whichever speed is in use.      TakeoffMAP[i] = RatedMAP[i] + ((TakeoffBoost - RatedBoost[0]) * 6895);      bTakeoffBoost = true;    } else {      TakeoffMAP[i] = RatedMAP[i];      bTakeoffBoost = false;    }    BoostMul[i] = RatedMAP[i] / (Atmosphere->GetPressure(RatedAltitude[i]) * psftopa);  }  if (BoostSpeeds > 0) {    Boosted = true;    BoostSpeed = 0;  }  bBoostOverride = (BoostOverride == 1 ? true : false);  if (MinThrottle < 0.001) MinThrottle = 0.001;  //MinThrottle is a denominator in a power equation so it can't be zero  Debug(0); // Call Debug() routine from constructor if needed}

⌨️ 快捷键说明

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