From: ehofman Date: Fri, 11 Jul 2008 14:11:54 +0000 (+0000) Subject: add a reference for memset() X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=ce7f695ea238bf9d484dbd8c8eb56587ff3d2df4;p=flightgear.git add a reference for memset() --- diff --git a/src/FDM/JSBSim/input_output/FGfdmSocket.cpp b/src/FDM/JSBSim/input_output/FGfdmSocket.cpp index 33ac21d26..0797b69fc 100644 --- a/src/FDM/JSBSim/input_output/FGfdmSocket.cpp +++ b/src/FDM/JSBSim/input_output/FGfdmSocket.cpp @@ -39,6 +39,7 @@ INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ #include "FGfdmSocket.h" +#include namespace JSBSim { diff --git a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp index bf9375f49..8e300b944 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp @@ -3,6 +3,7 @@ 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 @@ -73,11 +74,13 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number) Cycles = 2; IdleRPM = 600; + MaxRPM = 2800; Displacement = 360; SparkFailDrop = 1.0; MaxHP = 200; MinManifoldPressure_inHg = 6.5; MaxManifoldPressure_inHg = 28.5; + BSFC = 0.45; // These are internal program variables @@ -129,19 +132,52 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number) *Lookup_Combustion_Efficiency << 2.00 << 0.345; Power_Mixture_Correlation = new FGTable(13); - *Power_Mixture_Correlation << (14.7/1.6) << 78.0; - *Power_Mixture_Correlation << 10 << 86.0; - *Power_Mixture_Correlation << 11 << 93.5; - *Power_Mixture_Correlation << 12 << 98.0; - *Power_Mixture_Correlation << 13 << 100.0; - *Power_Mixture_Correlation << 14 << 99.0; - *Power_Mixture_Correlation << 15 << 96.4; - *Power_Mixture_Correlation << 16 << 92.5; - *Power_Mixture_Correlation << 17 << 88.0; - *Power_Mixture_Correlation << 18 << 83.0; - *Power_Mixture_Correlation << 19 << 78.5; - *Power_Mixture_Correlation << 20 << 74.0; - *Power_Mixture_Correlation << (14.7/0.6) << 58; + *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 1 +0 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 +1000 0.7778 0.8212 0.8647 0.9081 0.9516 0.9950 +2000 0.5556 0.6424 0.7293 0.8162 0.9031 0.9900 +3000 0.3333 0.4637 0.5940 0.7243 0.8547 0.9850 +4000 0.2000 0.2849 0.4587 0.6324 0.8062 0.9800 +5000 0.2000 0.2000 0.3233 0.5406 0.7578 0.9750 +6000 0.2000 0.2000 0.2000 0.4487 0.7093 0.9700 +7000 0.2000 0.2000 0.2000 0.2000 0.4570 0.7611 +8000 0.2000 0.2000 0.2000 0.2000 0.2047 0.5522 +*/ // Read inputs from engine data file where present. @@ -159,10 +195,14 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number) 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->FindElementValueAsNumber("bsfc"); if (el->FindElement("numboostspeeds")) { // Turbo- and super-charging parameters BoostSpeeds = (int)el->FindElementValueAsNumber("numboostspeeds"); if (el->FindElement("boostoverride")) @@ -194,6 +234,12 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number) if (el->FindElement("ratedaltitude3")) RatedAltitude[2] = el->FindElementValueAsNumberConvertTo("ratedaltitude3", "FT"); } + char property_name[80]; + snprintf(property_name, 80, "/engines/engine[%d]/power_hp", engine_number); + PropertyManager->Tie(property_name, &HP); + snprintf(property_name, 80, "/engines/engine[%d]/bsfc", engine_number); + PropertyManager->Tie(property_name, &BSFC); + minMAP = MinManifoldPressure_inHg * inhgtopa; // inHg to Pa maxMAP = MaxManifoldPressure_inHg * inhgtopa; StarterHP = sqrt(MaxHP) * 0.4; @@ -244,7 +290,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number) 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 } @@ -252,8 +298,15 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number) FGPiston::~FGPiston() { + char property_name[80]; + snprintf(property_name, 80, "/engines/engine[%d]/power_hp", EngineNumber); + PropertyManager->Untie(property_name); + snprintf(property_name, 80, "/engines/engine[%d]/bsfc", EngineNumber); + PropertyManager->Untie(property_name); + delete Lookup_Combustion_Efficiency; delete Power_Mixture_Correlation; + delete Mixture_Efficiency_Correlation; Debug(1); // Call Debug() routine from constructor if needed } @@ -281,6 +334,7 @@ double FGPiston::Calculate(void) if (FuelFlow_gph > 0.0) ConsumeFuel(); Throttle = FCS->GetThrottlePos(EngineNumber); + ThrottlePos = MinThrottle+((MaxThrottle-MinThrottle)*Throttle ); Mixture = FCS->GetMixturePos(EngineNumber); // @@ -305,10 +359,13 @@ double FGPiston::Calculate(void) //Assume lean limit at 22 AFR for now - thats a thi of 0.668 //This might be a bit generous, but since there's currently no audiable warning of impending //cutout in the form of misfiring and/or rough running its probably reasonable for now. - if (equivalence_ratio < 0.668) - Running = false; +// if (equivalence_ratio < 0.668) +// Running = false; doEnginePower(); +if(HP<0.1250) + Running = false; + doEGT(); doCHT(); doOilTemperature(); @@ -385,10 +442,10 @@ void FGPiston::doEngineStartup(void) if (!Running && spark && fuel) { // start the engine if revs high enough if (Cranking) { - if ((RPM > 450) && (crank_counter > 175)) // Add a little delay to startup + if ((RPM > IdleRPM*0.8) && (crank_counter > 175)) // Add a little delay to startup Running = true; // on the starter } else { - if (RPM > 450) // This allows us to in-air start + if (RPM > IdleRPM*0.8) // This allows us to in-air start Running = true; // when windmilling } } @@ -402,7 +459,7 @@ void FGPiston::doEngineStartup(void) if (Running) { if (RPM == 0) { Running = false; - } else if ((RPM <= 480) && (Cranking)) { + } else if ((RPM <= IdleRPM *0.8 ) && (Cranking)) { Running = false; } } @@ -456,10 +513,9 @@ void FGPiston::doBoostControl(void) void FGPiston::doMAP(void) { - if(RPM > 10) { - // Naturally aspirated - MAP = minMAP + (Throttle * (maxMAP - minMAP)); - MAP *= p_amb / p_amb_sea_level; + suction_loss = pow( ThrottlePos*0.98, RPM/MaxRPM ); + MAP = p_amb * suction_loss; + if(Boosted) { // If takeoff boost is fitted, we currently assume the following throttle map: // (In throttle % - actual input is 0 -> 1) @@ -484,7 +540,7 @@ void FGPiston::doMAP(void) } } // Boost the manifold pressure. - MAP *= BoostMul[BoostSpeed]; + MAP += MAP * BoostMul[BoostSpeed] * RPM/MaxRPM; // Now clip the manifold pressure to BCV or Wastegate setting. if(bTakeoffPos) { if(MAP > TakeoffMAP[BoostSpeed]) { @@ -496,11 +552,6 @@ void FGPiston::doMAP(void) } } } - } else { - // rpm < 10 - effectively stopped. - // TODO - add a better variation of MAP with engine speed - MAP = Atmosphere->GetPressure() * psftopa; - } // And set the value in American units as well ManifoldPressure_inHg = MAP / inhgtopa; @@ -513,7 +564,7 @@ void FGPiston::doMAP(void) * (used in CHT calculation for air-cooled engines). * * Inputs: p_amb, R_air, T_amb, MAP, Displacement, - * RPM, volumetric_efficiency + * RPM, volumetric_efficiency, ThrottlePos * * TODO: Model inlet manifold air temperature. * @@ -522,11 +573,13 @@ void FGPiston::doMAP(void) void FGPiston::doAirFlow(void) { - rho_air = p_amb / (R_air * T_amb); - double rho_air_manifold = MAP / (R_air * T_amb); + +rho_air = p_amb / (R_air * T_amb); double displacement_SI = Displacement * in3tom3; double swept_volume = (displacement_SI * (RPM/60)) / 2; double v_dot_air = swept_volume * volumetric_efficiency; + + double rho_air_manifold = MAP / (R_air * T_amb); m_dot_air = v_dot_air * rho_air_manifold; } @@ -541,13 +594,15 @@ void FGPiston::doAirFlow(void) void FGPiston::doFuelFlow(void) { - double thi_sea_level = 1.3 * Mixture; - equivalence_ratio = thi_sea_level * p_amb_sea_level / p_amb; - m_dot_fuel = m_dot_air / 14.7 * equivalence_ratio; + double thi_sea_level = 1.3 * Mixture; // Allows an AFR of infinity:1 to 11.3075:1 + equivalence_ratio = thi_sea_level; // * p_amb_sea_level / p_amb; + double AFR = 10+(12*(1-Mixture));// mixture 10:1 to 22:1 + m_dot_fuel = m_dot_air / AFR; FuelFlow_gph = m_dot_fuel * 3600 // seconds to hours * 2.2046 // kg to lb - / 6.6; // lb to gal_us of kerosene + / 6.0; // lb to gal_us of gasoline +// / 6.6; // lb to gal_us of kerosene } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -559,8 +614,8 @@ void FGPiston::doFuelFlow(void) * When tested with sufficient RPM, it has no trouble reaching * 200HP. * - * Inputs: ManifoldPressure_inHg, p_amb, p_amb_sea_level, RPM, T_amb, - * equivalence_ratio, Cycles, MaxHP + * Inputs: ManifoldPressure_inHg, p_amb, RPM, T_amb, + * Mixture_Efficiency_Correlation, Cycles, MaxHP * * Outputs: Percentage_Power, HP */ @@ -572,43 +627,15 @@ void FGPiston::doEnginePower(void) double T_amb_sea_lev_degF = KelvinToFahrenheit(288); // FIXME: this needs to be generalized - double ManXRPM; // Convienience term for use in the calculations - if(Boosted) { - // Currently a simple linear fit. - // The zero crossing is moved up the speed-load range to reduce the idling power. - // This will change! - double zeroOffset = (minMAP / 2.0) * (IdleRPM / 2.0); - ManXRPM = MAP * (RPM > RatedRPM[BoostSpeed] ? RatedRPM[BoostSpeed] : RPM); - // The speed clip in the line above is deliberate. - Percentage_Power = ((ManXRPM - zeroOffset) / ((RatedMAP[BoostSpeed] * RatedRPM[BoostSpeed]) - zeroOffset)) * 107.0; - Percentage_Power -= 7.0; // Another idle power reduction offset - see line above with 107. - if (Percentage_Power < 0.0) Percentage_Power = 0.0; - // Note that %power is allowed to go over 100 for boosted powerplants - // such as for the BCV-override or takeoff power settings. - // TODO - currently no altitude effect (temperature & exhaust back-pressure) modelled - // for boosted engines. - } else { - ManXRPM = ManifoldPressure_inHg * RPM; // Note that inHg must be used for the following correlation. - Percentage_Power = (6e-9 * ManXRPM * ManXRPM) + (8e-4 * ManXRPM) - 1.0; -// Percentage_Power += ((T_amb_sea_lev_degF - T_amb_degF) * 7 /120); - Percentage_Power += ((T_amb_sea_lev_degF - T_amb_degF) * 7 * dt); - if (Percentage_Power < 0.0) Percentage_Power = 0.0; - else if (Percentage_Power > 100.0) Percentage_Power = 100.0; - } - - double Percentage_of_best_power_mixture_power = - Power_Mixture_Correlation->GetValue(14.7 / equivalence_ratio); - - Percentage_Power *= Percentage_of_best_power_mixture_power / 100.0; + double ManXRPM, ME, Adjusted_BSFC; // Convienience term for use in the calculations + ME = Mixture_Efficiency_Correlation->GetValue(m_dot_fuel/m_dot_air); + Adjusted_BSFC = (1/ThrottlePos) * BSFC; + Percentage_Power = 1.000; if( Magnetos != 3 ) Percentage_Power *= SparkFailDrop; - if (Boosted) { - HP = Percentage_Power * RatedPower[BoostSpeed] / 100.0; - } else { - HP = Percentage_Power * MaxHP / 100.0; - } + HP = (FuelFlow_gph * 6.0 / Adjusted_BSFC )* ME * suction_loss * Percentage_Power; } else { @@ -616,8 +643,8 @@ void FGPiston::doEnginePower(void) if (Cranking) { if (RPM < 10) { HP = StarterHP; - } else if (RPM < 480) { - HP = StarterHP + ((480 - RPM) / 8.0); + } else if (RPM < IdleRPM*0.8) { + HP = StarterHP + ((IdleRPM*0.8 - RPM) / 8.0); // This is a guess - would be nice to find a proper starter moter torque curve } else { HP = StarterHP; @@ -657,7 +684,7 @@ void FGPiston::doEGT(void) heat_capacity_exhaust = (Cp_air * m_dot_air) + (Cp_fuel * m_dot_fuel); delta_T_exhaust = enthalpy_exhaust / heat_capacity_exhaust; ExhaustGasTemp_degK = T_amb + delta_T_exhaust; - ExhaustGasTemp_degK *= 0.444 + ((0.544 - 0.444) * Percentage_Power / 100.0); + ExhaustGasTemp_degK *= 0.444 + ((0.544 - 0.444) * Percentage_Power); } else { // Drop towards ambient - guess an appropriate time constant for now combustion_efficiency = 0; dEGTdt = (RankineToKelvin(Atmosphere->GetTemperature()) - ExhaustGasTemp_degK) / 100.0; @@ -714,7 +741,7 @@ void FGPiston::doCHT(void) void FGPiston::doOilTemperature(void) { - double idle_percentage_power = 2.3; // approximately + double idle_percentage_power = 0.023; // approximately double target_oil_temp; // Steady state oil temp at the current engine conditions double time_constant; // The time constant for the differential equation @@ -747,7 +774,7 @@ void FGPiston::doOilTemperature(void) void FGPiston::doOilPressure(void) { double Oil_Press_Relief_Valve = 60; // FIXME: may vary by engine - double Oil_Press_RPM_Max = 1800; // FIXME: may vary by engine + double Oil_Press_RPM_Max = MaxRPM * 0.75; // 75% of max rpm FIXME: may vary by engine double Design_Oil_Temp = 358; // degK; FIXME: may vary by engine double Oil_Viscosity_Index = 0.25; @@ -837,6 +864,11 @@ void FGPiston::Debug(int from) Power_Mixture_Correlation->Print(); cout << endl; + cout << endl; + cout << " Mixture Efficiency Correlation table:" << endl; + Mixture_Efficiency_Correlation->Print(); + cout << endl; + } } if (debug_lvl & 2 ) { // Instantiation/Destruction notification diff --git a/src/FDM/JSBSim/models/propulsion/FGPiston.h b/src/FDM/JSBSim/models/propulsion/FGPiston.h index 554ece829..14d86e3b0 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPiston.h +++ b/src/FDM/JSBSim/models/propulsion/FGPiston.h @@ -199,6 +199,10 @@ public: double getOilTemp_degF (void) {return KelvinToFahrenheit(OilTemp_degK);} double getRPM(void) {return RPM;} +protected: + double ThrottlePos; + + private: int crank_counter; @@ -236,6 +240,7 @@ private: FGTable *Lookup_Combustion_Efficiency; FGTable *Power_Mixture_Correlation; + FGTable *Mixture_Efficiency_Correlation; // // Configuration @@ -247,7 +252,8 @@ private: double SparkFailDrop; // drop of power due to spark failure double Cycles; // cycles/power stroke double IdleRPM; // revolutions per minute - double StarterHP; // initial horsepower of starter motor + double MaxRPM; // revolutions per minute + double StarterHP; // initial horsepower of starter motor int BoostSpeeds; // Number of super/turbocharger boost speeds - zero implies no turbo/supercharging. int BoostSpeed; // The current boost-speed (zero-based). bool Boosted; // Set true for boosted engine. @@ -273,6 +279,7 @@ private: double minMAP; // Pa double maxMAP; // Pa double MAP; // Pa + double BSFC; // unitless // // Inputs (in addition to those in FGEngine). @@ -286,11 +293,13 @@ private: bool Magneto_Right; int Magnetos; + // // Outputs (in addition to those in FGEngine). // double rho_air; double volumetric_efficiency; + double suction_loss; double m_dot_air; double equivalence_ratio; double m_dot_fuel;