]> git.mxchange.org Git - flightgear.git/commitdiff
Initial revision.
authorcurt <curt>
Wed, 6 Sep 2000 15:45:43 +0000 (15:45 +0000)
committercurt <curt>
Wed, 6 Sep 2000 15:45:43 +0000 (15:45 +0000)
src/FDM/ps-10520c.cxx [new file with mode: 0644]

diff --git a/src/FDM/ps-10520c.cxx b/src/FDM/ps-10520c.cxx
new file mode 100644 (file)
index 0000000..78ffb24
--- /dev/null
@@ -0,0 +1,529 @@
+// 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 (philip@zedley.com)
+//
+// 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
+// 19/8/2000               PLS     Updated E-mail address - This version compiles
+//  19/8/2000              PLS          Set Max Prop blade angle to prevent prop exeeding 90
+// ------------------------------------------------------------------------
+// INCLUDES
+// ------------------------------------------------------------------------
+
+#include <iostream.h>
+// #include <stdio.h>
+#include <math.h>
+// #include "10520c.h"
+
+// ------------------------------------------------------------------------
+// CODE
+// ------------------------------------------------------------------------
+
+// prototype definitions
+// These should be in a header file 10520c.h
+
+float Density (float x);
+void  ShowRho (float x);
+
+float IAS_to_FPS (float x);
+void ShowFPS(float x);
+
+float Get_Throttle (float x);
+void Show_Throttle (float x);
+
+float Manifold_Pressure (float x, float z);
+void Show_Manifold_Pressure (float x);
+
+float CHT (float Fuel_Flow, float Mixture, float IAS);
+void Show_CHT (float x);
+
+float Oil_Temp (float x, float y);
+void Show_Oil_Temp (float x);
+
+float Oil_Press (float Oil_Temp, float Engine_RPM);
+void Show_Oil_Press (float x);
+
+int main()
+
+{
+    // Declare local variables
+    int num = 0; // Not used. Counting variables
+    int num2 = 100;  // Not used.
+    float ManXRPM = 0;
+    float Vo = 0;
+    float V1 = 0;
+
+
+       // Set up the new variables
+    float Blade_Station = 30;
+    float Rho =        0.002378;
+    float FGProp_Area = 1.405/3;
+    float PI = 3.1428571;
+
+    // Input Variables
+    float IAS = 0; 
+    cout << "Enter IAS  ";
+    // cin  >> IAS;
+    IAS = 85;
+    cout << endl;
+
+    // 0 = Closed, 100 = Fully Open
+    float FGEng1_Throttle_Lever_Pos = 75;
+    // 0 = Full Course 100 = Full Fine
+    float FGEng1_Propeller_Lever_Pos = 75;     
+    // 0 = Idle Cut Off 100 = Full Rich
+    float FGEng1_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 FGEng1_Fuel_Available = 1;
+    // Off = 0. Reduces power by 3 % for same throttle setting
+    int FGEng1_Alternate_Air_Pos =0;
+    // 1 = On.   Reduces power by 5 % for same power lever settings
+    int FGEng1_Magneto_Left = 1;
+    // 1 = On.  Ditto, Both of the above though do not alter fuel flow
+    int FGEng1_Magneto_Right = 1;
+
+    // There needs to be a section in here to trap silly values, like
+    // 0, otherwise they will crash the calculations
+
+    //  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 FGEng_Max_Manifold_Pressure = 29.50;
+    float FGEng_Max_RPM = 2700;
+    float FGEng_Min_RPM = 1000;
+    float FGEng_Max_Fuel_Flow = 130;
+    float FGEng_Mag_Derate_Percent = 5;
+    float FGEng_MaxHP = 285;
+    float FGEng_Gear_Ratio = 1;
+
+    // Initialise Engine Variables used by this instance
+    float FGEng1_Percentage_Power = 0;
+    float FGEng1_Manifold_Pressure = 29.00;     // Inches
+    float FGEng1_RPM = 500;
+    float FGEng1_Fuel_Flow = 0;                 // lbs/hour
+    float FGEng1_Torque = 0;
+    float FGEng1_CHT = 370;
+    float FGEng1_Mixture = 14;
+    float FGEng1_Oil_Pressure = 0;             // PSI
+    float FGEng1_Oil_Temp = 85;                        // Deg C
+    float FGEng1_HP = 0;
+    float FGEng1_RPS = 0;
+    float Torque_Imbalance = 0;
+    float FGEng1_Desired_RPM = 0;
+
+    // Initialise Propellor Variables used by this instance
+    float FGProp1_Angular_V = 0;
+    float FGProp1_Coef_Drag =  0.6;
+    float FGProp1_Torque = 0;
+    float FGProp1_Thrust = 0;
+    float FGProp1_RPS = 0;
+    float FGProp1_Coef_Lift = 0.1;
+    float Alpha1 = 13.5;
+    float FGProp1_Blade_Angle = 13.5;
+    float FGProp_Fine_Pitch_Stop = 13.5;
+    float FGProp_Course_Pitch_Stop = 55;
+
+    // cout << "Enter Blade Angle  ";
+    // cin  >> FGProp1_Blade_Angle;
+    // cout << endl;
+
+    cout << " Number of Iterations ";
+    // cin >> num2;
+    num2 = 100;
+    cout << endl;
+
+    cout << " Throttle % ";
+    // cin >> FGEng1_Throttle_Lever_Pos;
+    FGEng1_Throttle_Lever_Pos = 50;
+    cout << endl;
+
+    cout << " Prop % ";
+    // cin >> FGEng1_Propeller_Lever_Pos;
+    FGEng1_Propeller_Lever_Pos = 100;
+    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"
+    ShowRho(Rho);
+
+  
+    // Calculate Manifold Pressure (Engine 1) as set by throttle opening
+
+    FGEng1_Manifold_Pressure = Manifold_Pressure(FGEng1_Throttle_Lever_Pos,
+                                                FGEng1_Manifold_Pressure );
+    Show_Manifold_Pressure(FGEng1_Manifold_Pressure);
+
+    // Calculate Desired RPM as set by Prop Lever Position.
+    // Actual engine RPM may be different
+    // The governed max RPM at 100% Prop Lever Position =  FGEng_MaxRPM
+    // The governed minimum RPM at 0% Prop Lever Position = FGEng_Min_RPM
+    // The actual minimum RPM of the engine can be < FGEng_Min_RPM if there is insufficient 
+    //  engine torque to counter act the propeller torque at  FGProp_Fine_Pitch_Stop
+
+    FGEng1_RPM = (FGEng1_Propeller_Lever_Pos * (FGEng_Max_RPM - FGEng_Min_RPM) /100)
+       + FGEng_Min_RPM ;
+
+       // * ((FGEng_Max_RPM + FGEng_Min_RPM) / 100);
+    
+    if (FGEng1_RPM >= 2700) {
+       FGEng1_RPM = 2700;
+    }
+    FGEng1_Desired_RPM = FGEng1_RPM;
+
+    cout << "Desired RPM = " << FGEng1_Desired_RPM << endl;
+
+    //==================================================================
+    // Engine Power & Torque Calculations
+    
+    // Loop until stable - required for testing only
+    for (num = 1; num < num2; num++) {
+       cout << endl << "====================" << endl;
+       cout << "MP Inches = " << FGEng1_Manifold_Pressure << "\t";
+       cout << FGEng1_RPM << "  RPM" << "\t";
+
+       // For a givem Manifold Pressure and RPM calculate the % Power
+       // Multiply Manifold Pressure by RPM
+       ManXRPM = FGEng1_Manifold_Pressure * FGEng1_RPM;
+       cout << ManXRPM << endl;
+
+       //  Calculate % Power
+       FGEng1_Percentage_Power = (+ 7E-09 * ManXRPM * ManXRPM) 
+           + ( + 7E-04 * ManXRPM) - 0.1218;
+       cout << "percent power = " << FGEng1_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
+       FGEng1_Percentage_Power = FGEng1_Percentage_Power - (FG_ISA_VAR * 7 /120);
+       cout << " adjusted T = " << FGEng1_Percentage_Power <<  "%" << "\t";
+       
+       // Adjust for Altitude. In this version a linear variation is
+       // used. Decrease 1% for each 1000' increase in Altitde
+       FGEng1_Percentage_Power = FGEng1_Percentage_Power 
+           + (FG_Pressure_Ht * 12/10000);      
+       cout << " adjusted A = " << FGEng1_Percentage_Power <<  "%" << "\t";
+
+       // Now Calculate Fuel Flow based on % Power Best Power Mixture
+       FGEng1_Fuel_Flow = FGEng1_Percentage_Power
+           * FGEng_Max_Fuel_Flow / 100;
+       // cout << FGEng1_Fuel_Flow << " lbs/hr"<< endl;
+       
+       // Now Derate engine for the effects of Bad/Switched off magnetos
+       if (FGEng1_Magneto_Left == 0 && FGEng1_Magneto_Right == 0) {
+           // cout << "Both OFF\n";
+           FGEng1_Percentage_Power = 0;
+       } else if (FGEng1_Magneto_Left && FGEng1_Magneto_Right) {
+           // cout << "Both On    ";
+       } else if (FGEng1_Magneto_Left == 0 || FGEng1_Magneto_Right== 0) {
+           // cout << "1 Magneto Failed   ";
+                               
+           FGEng1_Percentage_Power = FGEng1_Percentage_Power * 
+               ((100 - FGEng_Mag_Derate_Percent)/100);
+           //  cout << FGEng1_Percentage_Power <<  "%" << "\t";
+       }       
+
+       // Calculate Engine Horsepower
+
+       FGEng1_HP = FGEng1_Percentage_Power * FGEng_MaxHP/100;
+
+       // Calculate Engine Torque
+
+       FGEng1_Torque = FGEng1_HP * 5252 / FGEng1_RPM;
+       cout << FGEng1_Torque << "Ft/lbs" << "\t";
+
+       // Calculate Cylinder Head Temperature
+       FGEng1_CHT = CHT (FGEng1_Fuel_Flow, FGEng1_Mixture, IAS);
+       // Show_CHT (FGEng1_CHT);
+
+       // Calculate Oil Pressure
+       FGEng1_Oil_Pressure = Oil_Press (FGEng1_Oil_Temp, FGEng1_RPM);
+       // Show_Oil_Press(FGEng1_Oil_Pressure);
+
+       
+       //==============================================================
+
+       // Now do the Propellor Calculations
+
+       // Revs per second
+       FGProp1_RPS = FGEng1_RPM * FGEng_Gear_Ratio/60;
+       // 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 << "Angular Velocity " << FGProp1_Angular_V << 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);
+       // ShowFPS ( Vo );
+
+       // cout << Vo << "Axial Velocity" << endl;
+
+       // Relative Velocity (V1)
+       V1 = sqrt((FGProp1_Angular_V * FGProp1_Angular_V) +
+                 (Vo * Vo));
+       cout << "Relative Velocity " << V1 << endl;
+    
+       if ( FGProp1_Blade_Angle >= FGProp_Course_Pitch_Stop )  {
+           FGProp1_Blade_Angle = FGProp_Course_Pitch_Stop;
+       }
+
+       cout << FGProp1_Blade_Angle << " Prop Blade Angle" << endl;
+
+       // Blade Angle of Attack (Alpha1)
+
+       Alpha1 = FGProp1_Blade_Angle -(atan(Vo / FGProp1_Angular_V) * (180/PI));
+       // cout << Alpha1 << " Alpha1" << endl;
+
+       cout << "  Alpha1 = " << Alpha1
+            << "  Blade angle = " << FGProp1_Blade_Angle
+            << "  Vo = " << Vo
+            << "  FGProp1_Angular_V = " << FGProp1_Angular_V << 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 << "Prop Torque = " << FGProp1_Torque << endl;
+
+       //  Calculate Prop Thrust
+       FGProp1_Thrust = 0.5 * Rho * (V1 * V1) * FGProp_Area
+           * ((FGProp1_Coef_Lift * cos(Alpha1 * PI / 180))
+              - (FGProp1_Coef_Drag * sin(Alpha1 * PI / 180)));
+       cout << " Prop Thrust = " << FGProp1_Thrust <<  endl;
+
+       // End of Propeller Calculations   
+       //==============================================================
+
+
+
+       Torque_Imbalance = FGProp1_Torque - FGEng1_Torque; 
+       //  cout <<  Torque_Imbalance << endl;
+
+       if (Torque_Imbalance > 20) {
+           FGEng1_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) {
+           FGEng1_RPM += 14.5;
+           // FGProp1_RPM += 25;
+           FGProp1_Blade_Angle += 0.75;
+       }
+
+       if (FGEng1_RPM >= 2700) {
+           FGEng1_RPM = 2700;
+       }
+
+
+       // cout << FGEng1_RPM << " Blade_Angle  " << FGProp1_Blade_Angle << endl << endl;
+
+    }
+
+
+    return (0);
+}
+
+
+
+
+// Functions
+
+// Calculate Air Density - Rho
+float Density ( float x )
+{
+    float y ;
+    y = ((9E-08 * x * x) - (7E-08 * x) + 0.0024);
+    return(y);
+}
+
+// Show Air Density Calculations
+void ShowRho (float x)
+{
+    cout << "Rho = ";
+    cout << x << endl;
+}
+
+
+
+
+
+// Calculate Speed in FPS given Knots CAS
+float IAS_to_FPS (float x)
+{
+    float y;
+    y = x * 1.68888888;
+    return (y);
+}
+
+// Show Feet per Second
+void ShowFPS (float x)
+{
+    cout << "Feet/sec = ";
+    cout << x << endl;
+}
+
+
+
+// Calculate Manifold Pressure based on Throttle lever Position
+
+float Manifold_Pressure ( float x, float z)
+{
+    float y;  
+    // if ( x < = 0 )
+    //   {
+    // x = 0.00001;
+    // }
+    y = x * z / 100;
+    return (y);
+}
+
+// Show Manifold Pressure
+void  Show_Manifold_Pressure (float x)
+{
+    cout << "Manifold Pressure  = ";
+    cout << x << endl;
+}
+
+// Calculate Oil Temperature
+
+float Oil_Temp (float Fuel_Flow, float Mixture, float IAS)
+{
+    float Oil_Temp = 85;
+       
+    return (Oil_Temp);
+}
+
+// Show Oil Temperature
+
+void Show_Oil_Temp (float x)
+{
+    cout << "Oil Temperature (F) = ";
+    cout << x << endl;
+}
+
+
+// Calculate Oil Pressure
+
+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);
+}
+
+// Show Oil Pressure
+void Show_Oil_Press (float x)
+{
+    cout << "Oil Pressure (PSI) = ";
+    cout << x << endl;
+}
+
+
+
+// Calculate Cylinder Head Temperature
+
+float CHT (float Fuel_Flow, float Mixture, float IAS)
+{
+    float CHT = 350;
+       
+    return (CHT);
+}
+
+// Show Cyl Head Temperature
+
+void Show_CHT (float x)
+{
+    cout << "CHT (F) = ";
+    cout << x << endl;
+}