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 + -
显示快捷键?