// DCL 27/10/00 - Added first stab at cylinder head temperature model
// See the comment block in the code for details
//
-// DCL 02/11/00 - Modified EGT code to reduce values to those more representative of a sensor downstream
+// DCL 02/11/00 - Modified EGT code to reduce values to those more representative of a sensor downstream
+//
+// DCL 02/02/01 - Changed the prop model to one based on efficiency and co-efficient of power curves from McCormick instead of the
+// blade element method we were using previously. This works much better, and is similar to how Jon is doing it in JSBSim.
//
//////////////////////////////////////////////////////////////////////
float factor;
int i;
- int j;
- j = NUM_ELEMENTS; //This must be equal to the number of elements in the lookup table arrays
+ int j = NUM_ELEMENTS; //This must be equal to the number of elements in the lookup table arrays
for(i=0;i<j;i++)
{
Cp_air = 1005; // J/KgK
Cp_fuel = 1700; // J/KgK
calorific_value_fuel = 47.3e6; // W/Kg Note that this is only an approximate value
+ rho_fuel = 800; // kg/m^3 - an estimate for now
R_air = 287.3;
// Control and environment inputs
Percentage_Power = 0;
Manifold_Pressure = 29.00; // Inches
RPM = 600;
- Fuel_Flow = 0; // lbs/hour
+ Fuel_Flow_gals_hr = 0;
Torque = 0;
Torque_SI = 0;
CHT = 298.0; //deg Kelvin
//calculate ideal engine volume inducted per second
swept_volume = (displacement_SI * (RPM / 60)) / 2; //This equation is only valid for a four stroke engine
//calculate volumetric efficiency - for now we will just use 0.8, but actually it is a function of engine speed and the exhaust to manifold pressure ratio
+ //Note that this is cylinder vol eff - the throttle drop is already accounted for in the MAP calculation
volumetric_efficiency = 0.8;
//Now use volumetric efficiency to calculate actual air volume inducted per second
v_dot_air = swept_volume * volumetric_efficiency;
//Now calculate mass flow rate of air into engine
m_dot_air = v_dot_air * rho_air_manifold;
+ //cout << "air = " << m_dot_air;
// cout << "rho air manifold " << rho_air_manifold << '\n';
// cout << "Swept volume " << swept_volume << '\n';
//DCL - now calculate fuel flow into engine based on air flow and mixture lever position
//assume lever runs from no flow at fully out to thi = 1.6 at fully in at sea level
+ //***TODO*** - MUST try and get some real idea of the actual full rich sea level mixture - this is important !!!
//also assume that the injector linkage is ideal - hence the set mixture is maintained at a given altitude throughout the speed and load range
thi_sea_level = 1.6 * ( Mixture_Lever_Pos / 100.0 );
equivalence_ratio = thi_sea_level * p_amb_sea_level / p_amb; //ie as we go higher the mixture gets richer for a given lever position
m_dot_fuel = m_dot_air / 14.7 * equivalence_ratio;
+ Fuel_Flow_gals_hr = (m_dot_fuel / rho_fuel) * 264.172 * 3600.0; // Note this assumes US gallons
- // cout << "fuel " << m_dot_fuel;
- // cout << " air " << m_dot_air << '\n';
+ //cout << "fuel " << m_dot_fuel; << "kg/s " << Fuel_Flow_gals_hr << "gals/hr"
+ //cout << " air " << m_dot_air << '\n';
//***********************************************************************
//Engine power and torque calculations
//***DCL - FIXME - this needs altering - for instance going richer than full power mixture decreases the %power but increases the fuel flow
// Now Calculate Fuel Flow based on % Power Best Power Mixture
- Fuel_Flow = Percentage_Power * Max_Fuel_Flow / 100.0;
+// Fuel_Flow = Percentage_Power * Max_Fuel_Flow / 100.0;
// cout << Fuel_Flow << " lbs/hr"<< endl;
// Now Derate engine for the effects of Bad/Switched off magnetos
float Percentage_Power; // Power output as percentage of maximum power output
float Manifold_Pressure; // Inches
float RPM;
- float Fuel_Flow; // lbs/hour
+ float Fuel_Flow_gals_hr; // gals/hour
float Torque;
float CHT; // Cylinder head temperature deg K
float CHT_degF; // Ditto in deg Fahrenheit
float p_amb; // Pascals
float T_amb; // deg Kelvin
float calorific_value_fuel;
+ float rho_fuel; // kg/m^3
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
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); }
};
I_yy = 3.000000E+03;
I_zz = 3.530000E+03;
I_xz = 0.000000E+00;
+ //current_aircraft.fdm_state->set_Tank1Fuel(15.0);
+ //current_aircraft.fdm_state->set_Tank2Fuel(15.0);
+ //Tank1Fuel = 15.0;
+ //Tank2Fuel = 15.0;
}
FGLaRCsim::~FGLaRCsim(void) {
// update the engines interface
FGEngInterface e;
add_engine( e );
-
+
+ // Fill the fuel tanks
+ // Hardwired to C172 full tanks for now - need to fix this sometime
+ // Also note that this is the max quantity - the usable quantity
+ // is slightly less
+ set_Tank1Fuel(28.0);
+ set_Tank2Fuel(28.0);
// FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::init()" );
e->set_EGT( eng.get_EGT() );
e->set_CHT( eng.get_CHT() );
e->set_prop_thrust( eng.get_prop_thrust_SI() );
+ e->set_Fuel_Flow( eng.get_fuel_flow_gals_hr() );
+
+ //Assume we are using both tanks equally for now
+ reduce_Tank1Fuel( (eng.get_fuel_flow_gals_hr() / (2 * 3600))
+ * get_delta_t() );
+ reduce_Tank2Fuel( (eng.get_fuel_flow_gals_hr() / (2 * 3600))
+ * get_delta_t() );
#if 0
FG_LOG( FG_FLIGHT, FG_INFO, "Throttle = "
// outputs
double RPM;
- double Manifold_Pressure;
+ double Manifold_Pressure; //inches
double MaxHP;
- double Percentage_Power;
- double EGT;
- double CHT;
- double prop_thrust;
+ double Percentage_Power; //HP
+ double EGT; //deg F
+ double CHT; //deg F
+ double prop_thrust; //lbs
+ double Fuel_Flow; //Gals/hr
/* others...
double PercentN1,N1; //GE,CFM
inline double get_EGT() const { return EGT; }
inline double get_CHT() const { return CHT; }
inline double get_prop_thrust() const { return prop_thrust; }
+ inline double get_Fuel_Flow() const { return Fuel_Flow; }
inline void set_Throttle( double t ) { Throttle = t; }
inline void set_Mixture( double m ) { Mixture = m; }
inline void set_EGT( double e ) { EGT = e; }
inline void set_CHT( double c ) { CHT = c; }
inline void set_prop_thrust( double t ) { prop_thrust = t; }
+ inline void set_Fuel_Flow( double f ) { Fuel_Flow = f; }
};
double sin_longitude, cos_longitude;
double sin_latitude, cos_latitude;
double altitude_agl;
+ double Tank1Fuel; // Gals
+ double Tank2Fuel; // Gals
// Engine list
engine_list engines;
virtual void set_Velocities_Local_Airmass (double wnorth,
double weast,
double wdown );
-
+
+ // Consumables
+ inline void set_Tank1Fuel( double f ) { Tank1Fuel = f; }
+ inline void set_Tank2Fuel( double f ) { Tank2Fuel = f; }
+
+ inline void reduce_Tank1Fuel( double f ) {
+ Tank1Fuel -= f;
+ if(Tank1Fuel < 0)
+ Tank1Fuel = 0;
+ }
+ inline void reduce_Tank2Fuel( double f ) {
+ Tank2Fuel -= f;
+ if(Tank2Fuel < 0)
+ Tank2Fuel = 0;
+ }
+
// ========== Mass properties and geometry values ==========
return cos_latitude;
}
+ // Consumables
+ inline double get_Tank1Fuel() const { return Tank1Fuel; }
+ inline double get_Tank2Fuel() const { return Tank2Fuel; }
+
// engines
inline double get_num_engines() const {
return engines.size();
$(top_builddir)/src/Time/libTime.a \
$(WEATHER_LIBS) \
$(top_builddir)/src/Joystick/libJoystick.a \
- -lsgroute -lsgsky -lsgephem -lsgtiming -lsgio -lsgscreen -lsgmath \
- -lsgbucket -lsgdebug -lsgmagvar -lsgmisc -lsgxml \
+ -lsgroute -lsgsky -lsgephem -lsgmetar -lsgtiming -lsgio -lsgscreen \
+ -lsgmath -lsgbucket -lsgdebug -lsgmagvar -lsgmisc -lsgxml \
$(SERIAL_LIBS) \
-lplibpu -lplibfnt -lplibssg -lplibsg \
-lmk4 -lz \
fgTie("/engines/engine0/egt", getEGT);
fgTie("/engines/engine0/cht", getCHT);
fgTie("/engines/engine0/mp", getMP);
+ fgTie("/engines/engine0/fuel-flow", getFuelFlow);
+
+ //consumables
+ fgTie("/consumables/fuel/tank1/level", getTank1Fuel, setTank1Fuel, false);
+ fgTie("/consumables/fuel/tank2/level", getTank2Fuel, setTank2Fuel, false);
// Autopilot
fgTie("/autopilot/locks/altitude", getAPAltitudeLock, setAPAltitudeLock);
mktime(&new_time) - mktime(current_time) + globals->get_warp();
double lon = current_aircraft.fdm_state->get_Longitude();
double lat = current_aircraft.fdm_state->get_Latitude();
- double alt = current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER;
+ // double alt = current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER;
globals->set_warp(warp);
st->update(lon, lat, warp);
fgUpdateSkyAndLightingParams();
/**
- * Return the current engine0 CHT.
+ * Return the current engine0 Manifold Pressure.
*/
double
FGBFI::getMP ()
}
}
+/**
+ * Return the current engine0 fuel flow
+ */
+double
+FGBFI::getFuelFlow ()
+{
+ if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
+ return current_aircraft.fdm_state->get_engine(0)->get_Fuel_Flow();
+ } else {
+ return 0.0;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// Consumables
+////////////////////////////////////////////////////////////////////////
+
+/**
+ * Return the fuel level in tank 1
+ */
+double
+FGBFI::getTank1Fuel ()
+{
+ return current_aircraft.fdm_state->get_Tank1Fuel();
+}
+
+void
+FGBFI::setTank1Fuel ( double gals )
+{
+ current_aircraft.fdm_state->set_Tank1Fuel( gals );
+}
+
+/**
+ * Return the fuel level in tank 2
+ */
+double
+FGBFI::getTank2Fuel ()
+{
+ return current_aircraft.fdm_state->get_Tank2Fuel();
+}
+
+void
+FGBFI::setTank2Fuel ( double gals )
+{
+ current_aircraft.fdm_state->set_Tank2Fuel( gals );
+}
\f
////////////////////////////////////////////////////////////////////////
double
FGBFI::getFOV ()
{
- globals->get_current_view()->get_fov();
+ return globals->get_current_view()->get_fov();
}
void
static double getRPM (); // revolutions/minute
static void setRPM ( double rpm ); // revolutions/minute
- static double getEGT (); // [unit??]
- static double getCHT (); // [unit??]
- static double getMP (); // [unit??]
+ static double getEGT (); // deg Fahrenheit
+ static double getCHT (); // deg Fahrenheit
+ static double getMP (); // inches mercury
+ static double getFuelFlow (); // gals/hr
+
+ // Consumables
+ static double getTank1Fuel (); // gals
+ static void setTank1Fuel( double gals );
+ static double getTank2Fuel (); // gals
+ static void setTank2Fuel( double gals );
// Velocities
static double getAirspeed (); // knots