--- /dev/null
+// 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
+// ------------------------------------------------------------------------
+
+#include <iostream.h>
+#include <math.h>
+
+#include "10520d.hxx"
+
+
+// ------------------------------------------------------------------------
+// CODE
+// ------------------------------------------------------------------------
+
+
+// Calculate Engine RPM based on Propellor Lever Position
+float FGEngine::Calc_Engine_RPM (float LeverPosition)
+{
+ // Calculate RPM as set by Prop Lever Position. Assumes engine
+ // will run at 1000 RPM at full course
+
+ float RPM;
+ RPM = LeverPosition * Max_RPM / 100.0;
+ // * ((FGEng_Max_RPM + FGEng_Min_RPM) / 100);
+
+ if ( RPM >= Max_RPM ) {
+ RPM = Max_RPM;
+ }
+
+ return RPM;
+}
+
+
+// Calculate Manifold Pressure based on Throttle lever Position
+static float Calc_Manifold_Pressure ( float LeverPosn, float MaxMan)
+{
+ float Inches;
+ // if ( x < = 0 ) {
+ // x = 0.00001;
+ // }
+ Inches = LeverPosn * MaxMan / 100;
+ return Inches;
+}
+
+
+// set initial default values
+void FGEngine::init() {
+ // Control and environment inputs
+ IAS = 0;
+ Throttle_Lever_Pos = 75;
+ Propeller_Lever_Pos = 75;
+ Mixture_Lever_Pos = 100;
+
+ // 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.
+ Max_Manifold_Pressure = 29.50;
+ Max_RPM = 2700;
+ Min_RPM = 1000;
+ Max_Fuel_Flow = 130;
+ Mag_Derate_Percent = 5;
+ MaxHP = 285;
+ Gear_Ratio = 1;
+
+ // Initialise Engine Variables used by this instance
+ Percentage_Power = 0;
+ Manifold_Pressure = 29.00; // Inches
+ RPM = 2700;
+ Fuel_Flow = 0; // lbs/hour
+ Torque = 0;
+ CHT = 370;
+ Mixture = 14;
+ Oil_Pressure = 0; // PSI
+ Oil_Temp = 85; // Deg C
+ HP = 0;
+ RPS = 0;
+ Torque_Imbalance = 0;
+ Desired_RPM = 0;
+
+ // Initialise Propellor Variables used by this instance
+ FGProp1_Angular_V = 0;
+ FGProp1_Coef_Drag = 0.6;
+ FGProp1_Torque = 0;
+ FGProp1_Thrust = 0;
+ FGProp1_RPS = 0;
+ FGProp1_Coef_Lift = 0.1;
+ Alpha1 = 13.5;
+ FGProp1_Blade_Angle = 13.5;
+ FGProp_Fine_Pitch_Stop = 13.5;
+
+ // Other internal values
+ Rho = 0.002378;
+}
+
+
+// Calculate Oil Pressure
+static float Oil_Press (float Oil_Temp, float Engine_RPM)
+{
+ float Oil_Pressure = 0; //PSI
+ float Oil_Press_Relief_Valve = 60; //PSI
+ float Oil_Press_RPM_Max = 1800;
+ float Design_Oil_Temp = 85; //Celsius
+ float Oil_Viscosity_Index = 0.25; // PSI/Deg C
+ float Temp_Deviation = 0; // Deg C
+
+ Oil_Pressure = (Oil_Press_Relief_Valve / Oil_Press_RPM_Max) * Engine_RPM;
+
+ // Pressure relief valve opens at Oil_Press_Relief_Valve PSI setting
+ if (Oil_Pressure >= Oil_Press_Relief_Valve)
+ {
+ Oil_Pressure = Oil_Press_Relief_Valve;
+ }
+
+ // Now adjust pressure according to Temp which affects the viscosity
+
+ Oil_Pressure += (Design_Oil_Temp - Oil_Temp) * Oil_Viscosity_Index;
+
+ return Oil_Pressure;
+}
+
+
+// Calculate Cylinder Head Temperature
+static float Calc_CHT (float Fuel_Flow, float Mixture, float IAS)
+{
+ float CHT = 350;
+
+ return CHT;
+}
+
+
+// Calculate Density Ratio
+static float Density_Ratio ( float x )
+{
+ float y ;
+ y = ((3E-10 * x * x) - (3E-05 * x) + 0.9998);
+ return(y);
+}
+
+
+// Calculate Air Density - Rho
+static float Density ( float x )
+{
+ float y ;
+ y = ((9E-08 * x * x) - (7E-08 * x) + 0.0024);
+ return(y);
+}
+
+
+// Calculate Speed in FPS given Knots CAS
+static float IAS_to_FPS (float x)
+{
+ float y;
+ y = x * 1.68888888;
+ return y;
+}
+
+
+// update the engine model based on current control positions
+void FGEngine::update() {
+ // Declare local variables
+ int num = 0;
+ const int num2 = 1; // default is 100, number if iterations to run
+ float ManXRPM = 0;
+ float Vo = 0;
+ float V1 = 0;
+
+
+ // Set up the new variables
+ float Blade_Station = 30;
+ float FGProp_Area = 1.405/3;
+ float PI = 3.1428571;
+
+ // Input Variables
+
+ // 0 = Closed, 100 = Fully Open
+ // float Throttle_Lever_Pos = 75;
+ // 0 = Full Course 100 = Full Fine
+ // float Propeller_Lever_Pos = 75;
+ // 0 = Idle Cut Off 100 = Full Rich
+ // float Mixture_Lever_Pos = 100;
+
+ // Environmental Variables
+
+ // Temp Variation from ISA (Deg F)
+ float FG_ISA_VAR = 0;
+ // Pressure Altitude 1000's of Feet
+ float FG_Pressure_Ht = 0;
+
+ // Parameters that alter the operation of the engine.
+ // Yes = 1. Is there Fuel Available. Calculated elsewhere
+ int Fuel_Available = 1;
+ // Off = 0. Reduces power by 3 % for same throttle setting
+ int Alternate_Air_Pos =0;
+ // 1 = On. Reduces power by 5 % for same power lever settings
+ int Magneto_Left = 1;
+ // 1 = On. Ditto, Both of the above though do not alter fuel flow
+ int Magneto_Right = 1;
+
+ // There needs to be a section in here to trap silly values, like
+ // 0, otherwise they will crash the calculations
+
+ // cout << " Number of Iterations ";
+ // cin >> num2;
+ // cout << endl;
+
+ // cout << " Throttle % ";
+ // cin >> Throttle_Lever_Pos;
+ // cout << endl;
+
+ // cout << " Prop % ";
+ // cin >> Propeller_Lever_Pos;
+ // cout << endl;
+
+ //==================================================================
+ // Engine & Environmental Inputs from elsewhere
+
+ // Calculate Air Density (Rho) - In FG this is calculated in
+ // FG_Atomoshere.cxx
+
+ Rho = Density(FG_Pressure_Ht); // In FG FG_Pressure_Ht is "h"
+ // cout << "Rho = " << Rho << endl;
+
+ // Calculate Manifold Pressure (Engine 1) as set by throttle opening
+
+ Manifold_Pressure =
+ Calc_Manifold_Pressure( Throttle_Lever_Pos, Max_Manifold_Pressure );
+ // cout << "manifold pressure = " << Manifold_Pressure << endl;
+
+
+ // Calculate Manifold Pressure (Engine 2) as set by throttle opening
+
+ // FGEng2_Manifold_Pressure = Manifold_Pressure(FGEng2_Throttle_Lever_Pos, FGEng2_Manifold_Pressure);
+ // Show_Manifold_Pressure(FGEng2_Manifold_Pressure);
+
+ RPM = Calc_Engine_RPM(Propeller_Lever_Pos);
+ // cout << "Engine RPM = " << RPM << endl;
+
+ Desired_RPM = RPM;
+
+ //==================================================================
+ // Engine Power & Torque Calculations
+
+ // Loop until stable - required for testing only
+ for (num = 0; num < num2; num++) {
+ // cout << Manifold_Pressure << " Inches" << "\t";
+ // cout << RPM << " RPM" << "\t";
+
+ // For a given Manifold Pressure and RPM calculate the % Power
+ // Multiply Manifold Pressure by RPM
+ ManXRPM = Manifold_Pressure * RPM;
+ // cout << ManXRPM;
+ // cout << endl;
+
+ // Calculate % Power
+ Percentage_Power = (+ 7E-09 * ManXRPM * ManXRPM)
+ + ( + 7E-04 * ManXRPM) - 0.1218;
+ // cout << Percentage_Power << "%" << "\t";
+
+ // Adjust for Temperature - Temperature above Standard decrease
+ // power % by 7/120 per degree F increase, and incease power for
+ // temps below at the same ratio
+ Percentage_Power = Percentage_Power - (FG_ISA_VAR * 7 /120);
+ // cout << Percentage_Power << "%" << "\t";
+
+ // Adjust for Altitude. In this version a linear variation is
+ // used. Decrease 1% for each 1000' increase in Altitde
+ Percentage_Power = Percentage_Power + (FG_Pressure_Ht * 12/10000);
+ // cout << Percentage_Power << "%" << "\t";
+
+ // Now Calculate Fuel Flow based on % Power Best Power Mixture
+ 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
+ if (Magneto_Left == 0 && Magneto_Right == 0) {
+ // cout << "Both OFF\n";
+ Percentage_Power = 0;
+ } else if (Magneto_Left && Magneto_Right) {
+ // cout << "Both On ";
+ } else if (Magneto_Left == 0 || Magneto_Right== 0) {
+ // cout << "1 Magneto Failed ";
+
+ Percentage_Power = Percentage_Power *
+ ((100.0 - Mag_Derate_Percent)/100.0);
+ // cout << FGEng1_Percentage_Power << "%" << "\t";
+ }
+
+ // Calculate Engine Horsepower
+
+ HP = Percentage_Power * MaxHP / 100.0;
+
+ // Calculate Engine Torque
+
+ Torque = HP * 5252 / RPM;
+ // cout << Torque << "Ft/lbs" << "\t";
+
+ // Calculate Cylinder Head Temperature
+ CHT = Calc_CHT( Fuel_Flow, Mixture, IAS);
+ // cout << "Cylinder Head Temp (F) = " << CHT << endl;
+
+ // Calculate Oil Pressure
+ Oil_Pressure = Oil_Press( Oil_Temp, RPM );
+ // cout << "Oil Pressure (PSI) = " << Oil_Pressure << endl;
+
+ //==============================================================
+
+ // Now do the Propellor Calculations
+
+ // Revs per second
+ FGProp1_RPS = RPM * Gear_Ratio / 60.0;
+ // cout << FGProp1_RPS << " RPS" << endl;
+
+ //Radial Flow Vector (V2) Ft/sec at Ref Blade Station (usually 30")
+ FGProp1_Angular_V = FGProp1_RPS * 2 * PI * (Blade_Station / 12);
+ // cout << FGProp1_Angular_V << "Angular Velocity " << endl;
+
+ // Axial Flow Vector (Vo) Ft/sec
+ // Some further work required here to allow for inflow at low speeds
+ // Vo = (IAS + 20) * 1.688888;
+ Vo = IAS_to_FPS(IAS + 20);
+ // cout << "Feet/sec = " << Vo << endl;
+
+ // cout << Vo << "Axial Velocity" << endl;
+
+ // Relative Velocity (V1)
+ V1 = sqrt((FGProp1_Angular_V * FGProp1_Angular_V) +
+ (Vo * Vo));
+ // cout << V1 << "Relative Velocity " << endl;
+
+ // cout << FGProp1_Blade_Angle << " Prop Blade Angle" << endl;
+
+ // Blade Angle of Attack (Alpha1)
+
+ cout << " Alpha1 = " << Alpha1
+ << " Blade angle = " << FGProp1_Blade_Angle
+ << " Vo = " << Vo
+ << " FGProp1_Angular_V = " << FGProp1_Angular_V << endl;
+ Alpha1 = FGProp1_Blade_Angle -(atan(Vo / FGProp1_Angular_V) * (180/PI));
+ // cout << Alpha1 << " Alpha1" << endl;
+
+ // Calculate Coefficient of Drag at Alpha1
+ FGProp1_Coef_Drag = (0.0005 * (Alpha1 * Alpha1)) + (0.0003 * Alpha1)
+ + 0.0094;
+ // cout << FGProp1_Coef_Drag << " Coef Drag" << endl;
+
+ // Calculate Coefficient of Lift at Alpha1
+ FGProp1_Coef_Lift = -(0.0026 * (Alpha1 * Alpha1)) + (0.1027 * Alpha1)
+ + 0.2295;
+ // cout << FGProp1_Coef_Lift << " Coef Lift " << endl;
+
+ // Covert Alplha1 to Radians
+ // Alpha1 = Alpha1 * PI / 180;
+
+ // Calculate Prop Torque
+ FGProp1_Torque = (0.5 * Rho * (V1 * V1) * FGProp_Area
+ * ((FGProp1_Coef_Lift * sin(Alpha1 * PI / 180))
+ + (FGProp1_Coef_Drag * cos(Alpha1 * PI / 180))))
+ * (Blade_Station/12);
+ // cout << FGProp1_Torque << " Prop Torque" << endl;
+
+ // Calculate Prop Thrust
+ // cout << " V1 = " << V1 << " Alpha1 = " << Alpha1 << endl;
+ FGProp1_Thrust = 0.5 * Rho * (V1 * V1) * FGProp_Area
+ * ((FGProp1_Coef_Lift * cos(Alpha1 * PI / 180))
+ - (FGProp1_Coef_Drag * sin(Alpha1 * PI / 180)));
+ // cout << FGProp1_Thrust << " Prop Thrust " << endl;
+
+ // End of Propeller Calculations
+ //==============================================================
+
+
+
+#if 0
+ Torque_Imbalance = FGProp1_Torque - Torque;
+ // cout << Torque_Imbalance << endl;
+
+ if (Torque_Imbalance > 20) {
+ RPM -= 14.5;
+ // FGProp1_RPM -= 25;
+ FGProp1_Blade_Angle -= 0.75;
+ }
+
+ if (FGProp1_Blade_Angle < FGProp_Fine_Pitch_Stop) {
+ FGProp1_Blade_Angle = FGProp_Fine_Pitch_Stop;
+ }
+ if (Torque_Imbalance < -20) {
+ RPM += 14.5;
+ // FGProp1_RPM += 25;
+ FGProp1_Blade_Angle += 0.75;
+ }
+
+ if (RPM >= 2700) {
+ RPM = 2700;
+ }
+#endif
+
+
+ // cout << FGEng1_RPM << " Blade_Angle " << FGProp1_Blade_Angle << endl << endl;
+
+ }
+}
+
+
+
+
+// Functions
+
+// Calculate Oil Temperature
+
+static float Oil_Temp (float Fuel_Flow, float Mixture, float IAS)
+{
+ float Oil_Temp = 85;
+
+ return (Oil_Temp);
+}
--- /dev/null
+// 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 _10520D_HXX_
+#define _10520D_HXX_
+
+
+#include <iostream.h>
+#include <math.h>
+
+
+class FGEngine {
+
+private:
+
+ // 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;
+ 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;
+ float Manifold_Pressure; // Inches
+ float RPM;
+ float Fuel_Flow; // lbs/hour
+ float Torque;
+ float CHT;
+ float Mixture;
+ float Oil_Pressure; // PSI
+ float Oil_Temp; // Deg C
+ float HP;
+ float RPS;
+ float Torque_Imbalance;
+ float Desired_RPM;
+
+ // 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;
+
+ // Other internal values
+ float Rho;
+
+ // Calculate Engine RPM based on Propellor Lever Position
+ float Calc_Engine_RPM (float Position);
+
+public:
+
+ // set initial default values
+ void init();
+
+ // 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;
+ }
+
+ // accessors
+ inline float get_RPM() const { return RPM; }
+ inline float get_FGProp1_Thrust() const { return FGProp1_Thrust; }
+
+ inline float get_Rho() const { return Rho; }
+};
+
+
+#endif _10520D_HXX_