-// 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)
+// IO360.hxx - a piston engine model currently for the IO360 engine fitted to the C172
+// but with the potential to model other naturally aspirated piston engines
+// given appropriate config input.
+//
+// Written by David Luff, started 2000.
+// Based on code by Phil Schubert, started 1999.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
//
// 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
-// ------------------------------------------------------------------------
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
#ifndef _IO360_HXX_
#define _IO360_HXX_
-#define NEVS_PROP_MODEL
+#include <simgear/compiler.h>
-#ifndef NEVS_PROP_MODEL
-#define PHILS_PROP_MODEL
-#endif
-
-
-#include <iostream.h>
-#include <fstream.h>
#include <math.h>
+#include STL_IOSTREAM
+#include STL_FSTREAM
-class FGEngine {
-
-private:
+#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
+SG_USING_STD(ofstream);
+#endif
+class FGNewEngine {
+private:
- float CONVERT_HP_TO_WATTS;
+ // These constants should probably be moved eventually
float CONVERT_CUBIC_INCHES_TO_METERS_CUBED;
+ float CONVERT_HP_TO_WATTS;
- // Control and environment inputs
+ // Properties of working fluids
+ float Cp_air; // J/KgK
+ float Cp_fuel; // J/KgK
+ float calorific_value_fuel; // W/Kg
+ float rho_fuel; // kg/m^3
+ float rho_air; // kg/m^3
+
+ // environment inputs
+ float p_amb_sea_level; // Sea level ambient pressure in Pascals
+ float p_amb; // Ambient pressure at current altitude in Pascals
+ float T_amb; // ditto deg Kelvin
+
+ // Control inputs
+ float Throttle_Lever_Pos; // 0 = Closed, 100 = Fully Open
+ float Propeller_Lever_Pos; // 0 = Full Course 100 = Full Fine
+ float Mixture_Lever_Pos; // 0 = Idle Cut Off 100 = Full Rich
+ int mag_pos; // 0=off, 1=left, 2=right, 3=both.
+ bool starter;
+
+ //misc
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
+ double time_step;
+
+ // Engine Specific Variables that should be read in from a config file
+ float MaxHP; // Horsepower
+ float displacement; // Cubic inches
+ float displacement_SI; //m^3 (derived from above rather than read in)
+ float engine_inertia; //kg.m^2
+ float prop_inertia; //kg.m^2
+ float Max_Fuel_Flow; // Units??? Do we need this variable any more??
+
+ // Engine specific variables that maybe should be read in from config but are pretty generic and won't vary much for a naturally aspirated piston engine.
+ float Max_Manifold_Pressure; // inches Hg - typical manifold pressure at full throttle and typical max rpm
+ float Min_Manifold_Pressure; // inches Hg - typical manifold pressure at idle (closed throttle)
+ float Max_RPM; // rpm - this is really a bit of a hack and could be make redundant if the prop model works properly and takes tips at speed of sound into account.
+ float Min_RPM; // rpm - possibly redundant ???
+ float Mag_Derate_Percent; // Percentage reduction in power when mags are switched from 'both' to either 'L' or 'R'
+ float Gear_Ratio; // Gearing between engine and propellor
+ float n_R; // Number of cycles per power stroke - 2 for a 4 stroke engine.
+
+ // Engine Variables not read in from config file
+ float RPM; // rpm
float Percentage_Power; // Power output as percentage of maximum power output
- float Manifold_Pressure; // Inches
- float RPM;
- float Fuel_Flow; // lbs/hour
- float Torque;
- float CHT; // Cylinder head temperature
- float EGT; // Exhaust gas temperature
+ float Manifold_Pressure; // Inches Hg
+ float Fuel_Flow_gals_hr; // USgals/hour
+ float Torque_lbft; // lb-ft
+ float Torque_SI; // Nm
+ float CHT; // Cylinder head temperature deg K
+ float CHT_degF; // Ditto in deg Fahrenheit
float Mixture;
float Oil_Pressure; // PSI
float Oil_Temp; // Deg C
+ float current_oil_temp; // deg K
+ /**** one of these is superfluous !!!!***/
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;
- float Desired_RPM; // The RPM that we wish the constant speed prop to maintain if possible
- bool started; //flag to indicate the engine is running self sustaining
- bool cranking; //flag to indicate the engine is being cranked
-
- //DCL
+ float angular_velocity_SI; // rad/s
+ float Torque_FMEP; // The component of Engine torque due to FMEP (Nm)
+ float Torque_Imbalance; // difference between engine and prop torque
+ float EGT; // Exhaust gas temperature deg K
+ float EGT_degF; // Exhaust gas temperature deg Fahrenheit
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 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 equivalence_ratio; // ratio of stoichiometric AFR over actual AFR
+ float thi_sea_level; // the equivalence ratio we would be running at assuming sea level air denisity in the manifold
+ float v_dot_air; // volume flow rate of air into engine - m^3/s
+ float m_dot_air; // mass flow rate of air into engine - kg/s
+ float m_dot_fuel; // mass flow rate of fuel into engine - kg/s
+ float swept_volume; // total engine swept volume - m^3
+ /********* swept volume or the geometry used to calculate it should be in the config read section surely ??? ******/
+ float True_Manifold_Pressure; //in Hg - actual manifold gauge pressure
+ float rho_air_manifold; // denisty of air in the manifold - kg/m^3
+ float R_air; // Gas constant of air (287) UNITS???
+ float delta_T_exhaust; // Temperature change of exhaust this time step - degK
+ float heat_capacity_exhaust; // exhaust gas specific heat capacity - J/kgK
+ float enthalpy_exhaust; // Enthalpy at current exhaust gas conditions - UNITS???
+ float Percentage_of_best_power_mixture_power; // Current power as a percentage of what power we would have at the same conditions but at best power mixture
float abstract_mixture; //temporary hack
-
- // Initialise Propellor Variables used by this instance
- float FGProp1_Angular_V;
- float FGProp1_Coef_Drag;
- float FGProp1_Torque;
- float FGProp1_Thrust;
- float FGProp1_RPS;
- float FGProp1_Coef_Lift;
- float Alpha1;
- float FGProp1_Blade_Angle;
- float FGProp_Fine_Pitch_Stop;
-
-#ifdef NEVS_PROP_MODEL
- //Extra Propellor variables used by Nev's prop model
- float prop_fudge_factor;
- float prop_torque; //Nm
- float prop_thrust;
- float blade_length;
- float allowance_for_spinner;
- float num_elements;
- float distance;
- float number_of_blades;
- float forward_velocity;
- float angular_velocity_SI;
- float element;
- float element_drag;
- float element_lift;
- float element_torque;
- float rho_air;
- float prop_power_consumed_SI;
- float prop_power_consumed_HP;
- float theta[6]; //prop angle of each element
-#endif // NEVS_PROP_MODEL
-
- // Other internal values
- float Rho;
-
+ float angular_acceleration; //rad/s^2
+ float FMEP; //Friction Mean Effective Pressure (Pa)
+
+ // Various bits of housekeeping describing the engines state.
+ bool running; // flag to indicate the engine is running self sustaining
+ bool cranking; // flag to indicate the engine is being cranked
+ int crank_counter; // Number of iterations that the engine has been cranked non-stop
+ bool spark; // flag to indicate a spark is available
+ bool fuel; // flag to indicate fuel is available
+
+ // Propellor Variables
+ float FGProp1_RPS; // rps
+ float prop_torque; // Nm
+ float prop_thrust; // Newtons
+ double prop_diameter; // meters
+ double blade_angle; // degrees
+
+
+// MEMBER FUNCTIONS
+
// Calculate Engine RPM based on Propellor Lever Position
- float Calc_Engine_RPM (float 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);
// Calculate combustion efficiency based on equivalence ratio
float Lookup_Combustion_Efficiency(float thi_actual);
- // Calculate exhaust gas temperature rise
+ // Calculate percentage of best power mixture power based on equivalence ratio
+ float Power_Mixture_Correlation(float thi_actual);
+
+ // Calculate exhaust gas temperature change
float Calculate_Delta_T_Exhaust(void);
+ // Calculate cylinder head temperature
+ void Calc_CHT(void);
+
+ // Calculate exhaust gas temperature
+ void Calc_EGT(void);
+
+ // Calculate fuel flow in gals/hr
+ void Calc_Fuel_Flow_Gals_Hr(void);
+
+ // Calculate current percentage power
+ void Calc_Percentage_Power(bool mag_left, bool mag_right);
+
+ // Calculate Oil Temperature
+ float Calc_Oil_Temp (float oil_temp);
+
+ // Calculate Oil Pressure
+ float Calc_Oil_Press (float Oil_Temp, float Engine_RPM);
+
+ // Propeller calculations.
+ void Do_Prop_Calcs(void);
+
public:
- ofstream outfile;
+// ofstream outfile;
//constructor
- FGEngine() {
- outfile.open("FGEngine.dat", ios::out|ios::trunc);
+ FGNewEngine() {
+// outfile.open("FGNewEngine.dat", ios::out|ios::trunc);
}
//destructor
- ~FGEngine() {
- outfile.close();
+ ~FGNewEngine() {
+// outfile.close();
}
// set initial default values
- void init();
+ void init(double dt);
// update the engine model based on current control positions
void update();
inline void set_Mixture_Lever_Pos( float value ) {
Mixture_Lever_Pos = value;
}
+ // set the magneto switch position
+ inline void set_Magneto_Switch_Pos( int value ) {
+ mag_pos = value;
+ }
+ inline void setStarterFlag( bool flag ) {
+ starter = flag;
+ }
+ // 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
+ }
// accessors
inline float get_RPM() const { return RPM; }
- inline float get_Manifold_Pressure() const { return Manifold_Pressure; }
- 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; }
+ inline float get_Manifold_Pressure() const { return True_Manifold_Pressure; }
+ // inline float get_Rho() const { return Rho; }
inline float get_MaxHP() const { return MaxHP; }
inline float get_Percentage_Power() const { return Percentage_Power; }
- inline float get_EGT() const { return EGT; }
+ 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
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); }
+ inline float get_oil_temp() const { return ((current_oil_temp * 1.8) - 459.67); }
+ inline bool getRunningFlag() const { return running; }
+ inline bool getCrankingFlag() const { return cranking; }
+ inline bool getStarterFlag() const { return starter; }
};
-#endif // _10520D_HXX_
+#endif // _IO360_HXX_