]> git.mxchange.org Git - flightgear.git/blob - src/FDM/UIUCModel/uiuc_engine.cpp
Robert Deters:
[flightgear.git] / src / FDM / UIUCModel / uiuc_engine.cpp
1 /**********************************************************************
2
3  FILENAME:     uiuc_engine.cpp
4
5 ----------------------------------------------------------------------
6
7  DESCRIPTION:  determine the engine forces and moments
8                
9 ----------------------------------------------------------------------
10
11  STATUS:       alpha version
12
13 ----------------------------------------------------------------------
14
15  REFERENCES:   simple and c172 models based on portions of 
16                c172_engine.c, called from ls_model;
17                cherokee model based on cherokee_engine.c
18
19 ----------------------------------------------------------------------
20
21  HISTORY:      01/30/2000   initial release
22                06/18/2001   (RD) Added Throttle_pct_input.
23
24 ----------------------------------------------------------------------
25
26  AUTHOR(S):    Bipin Sehgal       <bsehgal@uiuc.edu>
27                Jeff Scott         <jscott@mail.com>
28                Robert Deters      <rdeters@uiuc.edu>
29                Michael Selig      <m-selig@uiuc.edu>
30
31 ----------------------------------------------------------------------
32
33  VARIABLES:
34
35 ----------------------------------------------------------------------
36
37  INPUTS:       -engine model
38
39 ----------------------------------------------------------------------
40
41  OUTPUTS:      -F_X_engine
42                -F_Z_engine
43                -M_m_engine
44
45 ----------------------------------------------------------------------
46
47  CALLED BY:   uiuc_wrapper.cpp 
48
49 ----------------------------------------------------------------------
50
51  CALLS TO:     none
52
53 ----------------------------------------------------------------------
54
55  COPYRIGHT:    (C) 2000 by Michael Selig
56
57  This program is free software; you can redistribute it and/or
58  modify it under the terms of the GNU General Public License
59  as published by the Free Software Foundation.
60
61  This program is distributed in the hope that it will be useful,
62  but WITHOUT ANY WARRANTY; without even the implied warranty of
63  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
64  GNU General Public License for more details.
65
66  You should have received a copy of the GNU General Public License
67  along with this program; if not, write to the Free Software
68  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
69  USA or view http://www.gnu.org/copyleft/gpl.html.
70
71 **********************************************************************/
72 #include <simgear/compiler.h>
73
74 #include "uiuc_engine.h"
75
76 #if !defined (SG_HAVE_NATIVE_SGI_COMPILERS)
77 SG_USING_STD(cerr);
78 #endif
79
80 void uiuc_engine() 
81 {
82   stack command_list;
83   string linetoken1;
84   string linetoken2;
85
86   if (outside_control == false)
87     pilot_throttle_no = false;
88   if (Throttle_pct_input)
89     {
90       double Throttle_pct_input_endTime = Throttle_pct_input_timeArray[Throttle_pct_input_ntime];
91       if (Simtime >= Throttle_pct_input_startTime && 
92           Simtime <= (Throttle_pct_input_startTime + Throttle_pct_input_endTime))
93         {
94           double time = Simtime - Throttle_pct_input_startTime;
95           Throttle_pct = uiuc_1Dinterpolation(Throttle_pct_input_timeArray,
96                          Throttle_pct_input_dTArray,
97                          Throttle_pct_input_ntime,
98                          time);
99           pilot_throttle_no = true;
100         }
101     }
102   
103   Throttle[3] = Throttle_pct;
104
105   command_list = engineParts -> getCommands();
106
107   /*
108   if (command_list.begin() == command_list.end())
109   {
110         cerr << "ERROR: Engine not specified. Aircraft cannot fly without the engine" << endl;
111         exit(-1);
112   }
113   */
114  
115   for (LIST command_line = command_list.begin(); command_line!=command_list.end(); ++command_line)
116     {
117       //cout << *command_line << endl;
118       
119       linetoken1 = engineParts -> getToken(*command_line, 1);
120       linetoken2 = engineParts -> getToken(*command_line, 2);
121       
122       switch(engine_map[linetoken2])
123         {
124         case simpleSingle_flag:
125           {
126             F_X_engine = Throttle[3] * simpleSingleMaxThrust;
127             break;
128           }
129         case simpleSingleModel_flag:
130           {
131             /* simple model based on Hepperle's equation
132              * exponent dtdvvt was computed in uiuc_menu.cpp */
133             F_X_engine = Throttle[3] * t_v0 * (1 - pow((V_rel_wind/v_t0),dtdvvt));
134             if (b_slipstreamEffects) {
135               tc = F_X_engine/(Dynamic_pressure * LS_PI * propDia * propDia / 4);
136               w_induced = 0.5 *  V_rel_wind * (-1 + pow((1+tc),.5));
137               eta_q = (2* w_induced + V_rel_wind)*(2* w_induced + V_rel_wind)/(V_rel_wind * V_rel_wind);
138               /* add in a die-off function so that eta falls off w/ alfa and beta */
139               eta_q = Cos_alpha * Cos_alpha * Cos_beta * Cos_beta * eta_q;
140               /* determine the eta_q values for the respective coefficients */
141               if (eta_q_Cm_q_fac)    {eta_q_Cm_q    *= eta_q * eta_q_Cm_q_fac;}
142               if (eta_q_Cm_adot_fac) {eta_q_Cm_adot *= eta_q * eta_q_Cm_adot_fac;}
143               if (eta_q_Cmfade_fac)  {eta_q_Cmfade  *= eta_q * eta_q_Cmfade_fac;}
144               if (eta_q_Cl_beta_fac) {eta_q_Cl_beta *= eta_q * eta_q_Cl_beta_fac;}
145               if (eta_q_Cl_p_fac)    {eta_q_Cl_p    *= eta_q * eta_q_Cl_p_fac;}
146               if (eta_q_Cl_r_fac)    {eta_q_Cl_r    *= eta_q * eta_q_Cl_r_fac;}
147               if (eta_q_Cl_dr_fac)   {eta_q_Cl_dr   *= eta_q * eta_q_Cl_dr_fac;}
148               if (eta_q_CY_beta_fac) {eta_q_CY_beta *= eta_q * eta_q_CY_beta_fac;}
149               if (eta_q_CY_p_fac)    {eta_q_CY_p    *= eta_q * eta_q_CY_p_fac;}
150               if (eta_q_CY_r_fac)    {eta_q_CY_r    *= eta_q * eta_q_CY_r_fac;}
151               if (eta_q_CY_dr_fac)   {eta_q_CY_dr   *= eta_q * eta_q_CY_dr_fac;}
152               if (eta_q_Cn_beta_fac) {eta_q_Cn_beta *= eta_q * eta_q_Cn_beta_fac;}
153               if (eta_q_Cn_p_fac)    {eta_q_Cn_p    *= eta_q * eta_q_Cn_p_fac;}
154               if (eta_q_Cn_r_fac)    {eta_q_Cn_r    *= eta_q * eta_q_Cn_r_fac;}
155               if (eta_q_Cn_dr_fac)   {eta_q_Cn_dr   *= eta_q * eta_q_Cn_dr_fac;}
156             }
157             /* Need engineOmega for gyroscopic moments */
158             engineOmega = minOmega + Throttle[3] * (maxOmega - minOmega);
159             break;
160           }
161         case c172_flag:
162           {
163             //c172 engine lines ... looks like 0.83 is just a thrust increase
164             F_X_engine = Throttle[3] * 350 / 0.83;
165             F_Z_engine = Throttle[3] * 4.9 / 0.83;
166             M_m_engine = F_X_engine * 0.734 * cbar;
167             break;
168           }
169         case cherokee_flag:
170           {
171             static float
172               dP = (180.0-117.0)*745.7,   // Watts
173               dn = (2700.0-2350.0)/60.0,  // d_rpm (I mean d_rps, in seconds)
174               D  = 6.17*0.3048,           // prop diameter
175               dPh = (58.0-180.0)*745.7,   // change of power as function of height
176               dH = 25000.0*0.3048;
177
178             float
179               n,   // [rps]
180               H,   // altitude [m]
181               J,   // advance ratio (ratio of horizontal speed to prop tip speed)
182               T,   // thrust [N]
183               V,   // velocity [m/s]
184               P,   // power [W]
185               eta_engine; // engine efficiency
186
187             /* assumption -> 0.0 <= Throttle[3] <=1.0 */
188             P = fabs(Throttle[3]) * 180.0 * 745.7; /*180.0*745.7 ->max avail power [W]*/
189             n = dn/dP * (P-117.0*745.7) + 2350.0/60.0;
190
191             /*  V  [m/s]   */
192             V = (V_rel_wind < 10.0 ? 10.0 : V_rel_wind*0.3048);
193             J = V / n / D;
194
195             /* Propeller efficiency */
196             eta_engine = (J < 0.7 ? ((0.8-0.55)/(.7-.3)*(J-0.3) + 0.55) : 
197                           (J > 0.85 ? ((0.6-0.8)/(1.0-0.85)*(J-0.85) + 0.8) : 0.8));
198
199             /* power on Altitude */
200             H = Altitude * 0.3048;       /* H == Altitude [m] */
201             P *= (dPh/dH * H + 180.0*745.7) / (180.0*745.7);
202             T = eta_engine * P/V;        /* Thrust [N] */ 
203
204             /*assumption: Engine's line of thrust passes through cg */
205             F_X_engine = T * 0.2248;     /* F_X_engine in lb */
206             F_Y_engine = 0.0;
207             F_Z_engine = 0.0;
208             break;
209           }
210         case forcemom_flag:
211           {
212             double Xp_input_endTime = Xp_input_timeArray[Xp_input_ntime];
213             if (Simtime >= Xp_input_startTime && 
214                 Simtime <= (Xp_input_startTime + Xp_input_endTime))
215               {
216                 double time = Simtime - Xp_input_startTime;
217                 F_X_engine = uiuc_1Dinterpolation(Xp_input_timeArray,
218                                                   Xp_input_XpArray,
219                                                   Xp_input_ntime,
220                                                   time);
221               }
222             double Zp_input_endTime = Zp_input_timeArray[Zp_input_ntime];
223             if (Simtime >= Zp_input_startTime && 
224                 Simtime <= (Zp_input_startTime + Zp_input_endTime))
225               {
226                 double time = Simtime - Zp_input_startTime;
227                 F_Z_engine = uiuc_1Dinterpolation(Zp_input_timeArray,
228                                                   Zp_input_ZpArray,
229                                                   Zp_input_ntime,
230                                                   time);
231               }
232             double Mp_input_endTime = Mp_input_timeArray[Mp_input_ntime];
233             if (Simtime >= Mp_input_startTime && 
234                 Simtime <= (Mp_input_startTime + Mp_input_endTime))
235               {
236                 double time = Simtime - Mp_input_startTime;
237                 M_m_engine = uiuc_1Dinterpolation(Mp_input_timeArray,
238                                                   Mp_input_MpArray,
239                                                   Mp_input_ntime,
240                                                   time);
241               }
242           }
243         };
244     }
245   return;
246 }
247
248 // end uiuc_engine.cpp