1
0
Fork 0
flightgear/src/FDM/IO360.hxx

247 lines
8.7 KiB
C++
Raw Normal View History

2000-09-26 23:37:26 +00:00
// Module: 10520c.c
// Author: Phil Schubert
// Date started: 12/03/99
// Purpose: Models a Continental IO-520-M Engine
// Called by: FGSimExec
//
// Copyright (C) 1999 Philip L. Schubert (philings@ozemail.com.au)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU 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
// General Public License for more details.
//
// You should have received a copy of the GNU 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 General Public License can also
// be found on the world wide web at http://www.gnu.org.
//
// FUNCTIONAL DESCRIPTION
// ------------------------------------------------------------------------
// Models a Continental IO-520-M engine. This engine is used in Cessna
// 210, 310, Beechcraft Bonaza and Baron C55. The equations used below
// were determined by a first and second order curve fits using Excel.
// The data is from the Cessna Aircraft Corporations Engine and Flight
// Computer for C310. Part Number D3500-13
//
// ARGUMENTS
// ------------------------------------------------------------------------
//
//
// HISTORY
// ------------------------------------------------------------------------
// 12/03/99 PLS Created
// 07/03/99 PLS Added Calculation of Density, and Prop_Torque
// 07/03/99 PLS Restructered Variables to allow easier implementation
// of Classes
// 15/03/99 PLS Added Oil Pressure, Oil Temperature and CH Temp
// ------------------------------------------------------------------------
// INCLUDES
// ------------------------------------------------------------------------
#ifndef _IO360_HXX_
#define _IO360_HXX_
#include <simgear/compiler.h>
2000-09-26 23:37:26 +00:00
#include <math.h>
2001-03-26 18:22:31 +00:00
#include STL_IOSTREAM
#include STL_FSTREAM
#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
2001-03-23 22:59:18 +00:00
SG_USING_STD(ofstream);
2001-03-26 18:22:31 +00:00
#endif
2000-09-26 23:37:26 +00:00
class FGNewEngine {
2000-09-26 23:37:26 +00:00
private:
float CONVERT_HP_TO_WATTS;
float CONVERT_CUBIC_INCHES_TO_METERS_CUBED;
// Control and environment inputs
float IAS;
// 0 = Closed, 100 = Fully Open
float Throttle_Lever_Pos;
// 0 = Full Course 100 = Full Fine
float Propeller_Lever_Pos;
// 0 = Idle Cut Off 100 = Full Rich
float Mixture_Lever_Pos;
// Engine Specific Variables used by this program that have limits.
// Will be set in a parameter file to be read in to create
// and instance for each engine.
float Max_Manifold_Pressure; //will be lower than ambient pressure for a non turbo/super charged engine due to losses through the throttle. This is the sea level full throttle value.
float Min_Manifold_Pressure; //Closed throttle valueat idle - governed by the idle bypass valve
float Max_RPM;
float Min_RPM;
float Max_Fuel_Flow;
float Mag_Derate_Percent;
float MaxHP;
float Gear_Ratio;
// Initialise Engine Variables used by this instance
float Percentage_Power; // Power output as percentage of maximum power output
float Manifold_Pressure; // Inches
float RPM;
float Fuel_Flow_gals_hr; // gals/hour
2000-09-26 23:37:26 +00:00
float Torque;
This is a somewhat rough first attempt at modelling cylinder head temperature. The cylinder head is assumed to be at uniform temperature. Obviously this is incorrect, but it simplifies things a lot, and we're just looking for the behaviour of CHT to be correct. Energy transfer to the cylinder head is assumed to be one third of the energy released by combustion at all conditions. This is a reasonable estimate, although obviously in real life it varies with different conditions and possibly with CHT itself. I've split energy transfer from the cylinder head into 2 terms - free convection - ie convection to stationary air, and forced convection, ie convection into flowing air. The basic free convection equation is: dqdt = -hAdT Since we don't know A and are going to set h quite arbitarily anyway I've knocked A out and just wrapped it up in h - the only real significance is that the units of h will be different but that dosn't really matter to us anyway. In addition, we have the problem that the prop model I'm currently using dosn't model the backwash from the prop which will add to the velocity of the cooling air when the prop is turning, so I've added an extra term to try and cope with this. In real life, forced convection equations are genarally empirically derived, and are quite complicated and generally contain such things as the Reynolds and Nusselt numbers to various powers. The best course of action would probably to find an empirical correlation from the literature for a similar situation and try and get it to fit well. However, for now I am using my own made up very simple correlation for the energy transfer from the cylinder head: dqdt = -(h1.dT) -(h2.m_dot.dT) -(h3.rpm.dT) where dT is the temperature different between the cylinder head and the surrounding air, m_dot is the mass flow rate of cooling air through an arbitary volume, rpm is the engine speed in rpm (this is the backwash term), and h1, h2, h3 are co-efficients which we can play with to attempt to get the CHT behaviour to match real life. In order to change the values of CHT that the engine settles down at at various conditions, have a play with h1, h2 and h3. In order to change the rate of heating/cooling without affecting equilibrium values alter the cylinder head mass, which is really quite arbitary. Bear in mind that altering h1, h2 and h3 will also alter the rate of heating or cooling as well as equilibrium values, but altering the cylinder head mass will only alter the rate. It would I suppose be better to read the values from file to avoid the necessity for re-compilation every time I change them.
2000-10-27 21:33:07 +00:00
float CHT; // Cylinder head temperature deg K
float CHT_degF; // Ditto in deg Fahrenheit
float EGT; // Exhaust gas temperature deg K
float EGT_degF; // Exhaust gas temperature deg Fahrenheit
2000-09-26 23:37:26 +00:00
float Mixture;
float Oil_Pressure; // PSI
float Oil_Temp; // Deg C
float HP; // Current power output in HP
float Power_SI; // Current power output in Watts
float Torque_SI; // Torque in Nm
float RPS;
float Torque_Imbalance;
bool started; //flag to indicate the engine is running self sustaining
bool cranking; //flag to indicate the engine is being cranked
//DCL
float volumetric_efficiency;
float combustion_efficiency;
float equivalence_ratio;
float v_dot_air;
float m_dot_air;
float m_dot_fuel;
float swept_volume;
float True_Manifold_Pressure; //in Hg
float rho_air_manifold;
float R_air;
float p_amb_sea_level; // Pascals
float p_amb; // Pascals
float T_amb; // deg Kelvin
float calorific_value_fuel;
float rho_air;
float rho_fuel; // kg/m^3
2000-09-26 23:37:26 +00:00
float thi_sea_level;
float delta_T_exhaust;
float displacement; // Engine displacement in cubic inches - to be read in from config file for each engine
float displacement_SI; // ditto in meters cubed
float Cp_air; // J/KgK
float Cp_fuel; // J/KgK
float heat_capacity_exhaust;
float enthalpy_exhaust;
float Percentage_of_best_power_mixture_power;
float abstract_mixture; //temporary hack
float engine_inertia; //kg.m^2
float prop_inertia; //kg.m^2
float angular_acceleration; //rad/s^2
double time_step;
2000-09-26 23:37:26 +00:00
// Propellor Variables
2000-09-26 23:37:26 +00:00
float FGProp1_Thrust;
float FGProp1_RPS;
float FGProp1_Blade_Angle;
float prop_torque; // Nm
float prop_thrust; // Newtons
float blade_length; // meters
float forward_velocity; // m/s
float angular_velocity_SI; // rad/s
float prop_power_consumed_SI; // Watts
float prop_power_consumed_HP; // HP
double prop_diameter; // meters
double J; // advance ratio - dimensionless
double Cp_20; // coefficient of power for 20 degree blade angle
double Cp_25; // coefficient of power for 25 degree blade angle
double Cp; // Our actual coefficient of power
double blade_angle; // degrees
double neta_prop_20;
double neta_prop_25;
double neta_prop; // prop efficiency
2000-09-26 23:37:26 +00:00
// Calculate Engine RPM based on Propellor Lever Position
float Calc_Engine_RPM(float Position);
// Calculate Manifold Pressure based on throttle lever position
// Note that this is simplistic and needs altering to include engine speed effects
float Calc_Manifold_Pressure( float LeverPosn, float MaxMan, float MinMan);
2000-09-26 23:37:26 +00:00
// Calculate combustion efficiency based on equivalence ratio
float Lookup_Combustion_Efficiency(float thi_actual);
// Calculate percentage of best power mixture power based on equivalence ratio
float Power_Mixture_Correlation(float thi_actual);
2000-09-26 23:37:26 +00:00
// Calculate exhaust gas temperature rise
float Calculate_Delta_T_Exhaust(void);
// Calculate Oil Temperature
float Calc_Oil_Temp (float Fuel_Flow, float Mixture, float IAS);
// Calculate Oil Pressure
float Calc_Oil_Press (float Oil_Temp, float Engine_RPM);
2000-09-26 23:37:26 +00:00
public:
ofstream outfile;
//constructor
FGNewEngine() {
This is a somewhat rough first attempt at modelling cylinder head temperature. The cylinder head is assumed to be at uniform temperature. Obviously this is incorrect, but it simplifies things a lot, and we're just looking for the behaviour of CHT to be correct. Energy transfer to the cylinder head is assumed to be one third of the energy released by combustion at all conditions. This is a reasonable estimate, although obviously in real life it varies with different conditions and possibly with CHT itself. I've split energy transfer from the cylinder head into 2 terms - free convection - ie convection to stationary air, and forced convection, ie convection into flowing air. The basic free convection equation is: dqdt = -hAdT Since we don't know A and are going to set h quite arbitarily anyway I've knocked A out and just wrapped it up in h - the only real significance is that the units of h will be different but that dosn't really matter to us anyway. In addition, we have the problem that the prop model I'm currently using dosn't model the backwash from the prop which will add to the velocity of the cooling air when the prop is turning, so I've added an extra term to try and cope with this. In real life, forced convection equations are genarally empirically derived, and are quite complicated and generally contain such things as the Reynolds and Nusselt numbers to various powers. The best course of action would probably to find an empirical correlation from the literature for a similar situation and try and get it to fit well. However, for now I am using my own made up very simple correlation for the energy transfer from the cylinder head: dqdt = -(h1.dT) -(h2.m_dot.dT) -(h3.rpm.dT) where dT is the temperature different between the cylinder head and the surrounding air, m_dot is the mass flow rate of cooling air through an arbitary volume, rpm is the engine speed in rpm (this is the backwash term), and h1, h2, h3 are co-efficients which we can play with to attempt to get the CHT behaviour to match real life. In order to change the values of CHT that the engine settles down at at various conditions, have a play with h1, h2 and h3. In order to change the rate of heating/cooling without affecting equilibrium values alter the cylinder head mass, which is really quite arbitary. Bear in mind that altering h1, h2 and h3 will also alter the rate of heating or cooling as well as equilibrium values, but altering the cylinder head mass will only alter the rate. It would I suppose be better to read the values from file to avoid the necessity for re-compilation every time I change them.
2000-10-27 21:33:07 +00:00
// outfile.open("FGNewEngine.dat", ios::out|ios::trunc);
2000-09-26 23:37:26 +00:00
}
//destructor
~FGNewEngine() {
// outfile.close();
2000-09-26 23:37:26 +00:00
}
// set initial default values
void init(double dt);
2000-09-26 23:37:26 +00:00
// update the engine model based on current control positions
void update();
inline void set_IAS( float value ) { IAS = value; }
inline void set_Throttle_Lever_Pos( float value ) {
Throttle_Lever_Pos = value;
}
inline void set_Propeller_Lever_Pos( float value ) {
Propeller_Lever_Pos = value;
}
inline void set_Mixture_Lever_Pos( float value ) {
Mixture_Lever_Pos = value;
}
// set ambient pressure - takes pounds per square foot
inline void set_p_amb( float value ) {
p_amb = value * 47.88026;
// Convert to Pascals
}
// set ambient temperature - takes degrees Rankine
inline void set_T_amb( float value ) {
T_amb = value * 0.555555555556;
// Convert to degrees Kelvin
}
2000-09-26 23:37:26 +00:00
// accessors
inline float get_RPM() const { return RPM; }
inline float get_Manifold_Pressure() const { return True_Manifold_Pressure; }
2000-09-26 23:37:26 +00:00
inline float get_FGProp1_Thrust() const { return FGProp1_Thrust; }
inline float get_FGProp1_Blade_Angle() const { return FGProp1_Blade_Angle; }
// inline float get_Rho() const { return Rho; }
2000-09-26 23:37:26 +00:00
inline float get_MaxHP() const { return MaxHP; }
inline float get_Percentage_Power() const { return Percentage_Power; }
inline float get_EGT() const { return EGT_degF; } // Returns EGT in Fahrenheit
inline float get_CHT() const { return CHT_degF; } // Note this returns CHT in Fahrenheit
2000-09-26 23:37:26 +00:00
inline float get_prop_thrust_SI() const { return prop_thrust; }
inline float get_prop_thrust_lbs() const { return (prop_thrust * 0.2248); }
inline float get_fuel_flow_gals_hr() const { return (Fuel_Flow_gals_hr); }
2000-09-26 23:37:26 +00:00
};
#endif // _IO360_HXX_