]> git.mxchange.org Git - flightgear.git/blob - src/FDM/UIUCModel/uiuc_engine.cpp
Updates from Rob 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 (Throttle_pct_input)
87     {
88       double Throttle_pct_input_endTime = Throttle_pct_input_timeArray[Throttle_pct_input_ntime];
89       if (Simtime >= Throttle_pct_input_startTime && 
90           Simtime <= (Throttle_pct_input_startTime + Throttle_pct_input_endTime))
91         {
92           double time = Simtime - Throttle_pct_input_startTime;
93           Throttle_pct = uiuc_1Dinterpolation(Throttle_pct_input_timeArray,
94                          Throttle_pct_input_dTArray,
95                          Throttle_pct_input_ntime,
96                          time);
97         }
98     }
99   
100   Throttle[3] = Throttle_pct;
101
102   command_list = engineParts -> getCommands();
103
104   /*
105   if (command_list.begin() == command_list.end())
106   {
107         cerr << "ERROR: Engine not specified. Aircraft cannot fly without the engine" << endl;
108         exit(-1);
109   }
110   */
111  
112   for (LIST command_line = command_list.begin(); command_line!=command_list.end(); ++command_line)
113     {
114       //cout << *command_line << endl;
115       
116       linetoken1 = engineParts -> getToken(*command_line, 1);
117       linetoken2 = engineParts -> getToken(*command_line, 2);
118       
119       switch(engine_map[linetoken2])
120         {
121         case simpleSingle_flag:
122           {
123             F_X_engine = Throttle[3] * simpleSingleMaxThrust;
124             break;
125           }
126         case simpleSingleModel_flag:
127           {
128             /* simple model based on Hepperle's equation
129              * exponent dtdvvt was computed in uiuc_menu.cpp */
130             F_X_engine = Throttle[3] * t_v0 * (1 - pow((V_rel_wind/v_t0),dtdvvt));
131             if (slipstream_effects) {
132               tc = F_X_engine/(Dynamic_pressure * LS_PI * propDia * propDia / 4);
133               w_induced = 0.5 *  V_rel_wind * (-1 + pow((1+tc),.5));
134               eta_q = (2* w_induced + V_rel_wind)*(2* w_induced + V_rel_wind)/(V_rel_wind * V_rel_wind);
135               /* add in a die-off function so that eta falls off w/ alfa and beta */
136               eta_q = Cos_alpha * Cos_alpha * Cos_beta * Cos_beta * eta_q;
137               /* determine the eta_q values for the respective coefficients */
138               if (eta_q_Cm_q_fac)    {eta_q_Cm_q    *= eta_q * eta_q_Cm_q_fac;}
139               if (eta_q_Cm_adot_fac) {eta_q_Cm_adot *= eta_q * eta_q_Cm_adot_fac;}
140               if (eta_q_Cmfade_fac)  {eta_q_Cmfade  *= eta_q * eta_q_Cmfade_fac;}
141               if (eta_q_Cl_beta_fac) {eta_q_Cl_beta *= eta_q * eta_q_Cl_beta_fac;}
142               if (eta_q_Cl_p_fac)    {eta_q_Cl_p    *= eta_q * eta_q_Cl_p_fac;}
143               if (eta_q_Cl_r_fac)    {eta_q_Cl_r    *= eta_q * eta_q_Cl_r_fac;}
144               if (eta_q_Cl_dr_fac)   {eta_q_Cl_dr   *= eta_q * eta_q_Cl_dr_fac;}
145               if (eta_q_CY_beta_fac) {eta_q_CY_beta *= eta_q * eta_q_CY_beta_fac;}
146               if (eta_q_CY_p_fac)    {eta_q_CY_p    *= eta_q * eta_q_CY_p_fac;}
147               if (eta_q_CY_r_fac)    {eta_q_CY_r    *= eta_q * eta_q_CY_r_fac;}
148               if (eta_q_CY_dr_fac)   {eta_q_CY_dr   *= eta_q * eta_q_CY_dr_fac;}
149               if (eta_q_Cn_beta_fac) {eta_q_Cn_beta *= eta_q * eta_q_Cn_beta_fac;}
150               if (eta_q_Cn_p_fac)    {eta_q_Cn_p    *= eta_q * eta_q_Cn_p_fac;}
151               if (eta_q_Cn_r_fac)    {eta_q_Cn_r    *= eta_q * eta_q_Cn_r_fac;}
152               if (eta_q_Cn_dr_fac)   {eta_q_Cn_dr   *= eta_q * eta_q_Cn_dr_fac;}
153             }
154             /* Need engineOmega for gyroscopic moments */
155             engineOmega = minOmega + Throttle[3] * (maxOmega - minOmega);
156             break;
157           }
158         case c172_flag:
159           {
160             //c172 engine lines ... looks like 0.83 is just a thrust increase
161             F_X_engine = Throttle[3] * 350 / 0.83;
162             F_Z_engine = Throttle[3] * 4.9 / 0.83;
163             M_m_engine = F_X_engine * 0.734 * cbar;
164             break;
165           }
166         case cherokee_flag:
167           {
168             static float
169               dP = (180.0-117.0)*745.7,   // Watts
170               dn = (2700.0-2350.0)/60.0,  // d_rpm (I mean d_rps, in seconds)
171               D  = 6.17*0.3048,           // prop diameter
172               dPh = (58.0-180.0)*745.7,   // change of power as function of height
173               dH = 25000.0*0.3048;
174
175             float
176               n,   // [rps]
177               H,   // altitude [m]
178               J,   // advance ratio (ratio of horizontal speed to prop tip speed)
179               T,   // thrust [N]
180               V,   // velocity [m/s]
181               P,   // power [W]
182               eta_engine; // engine efficiency
183
184             /* assumption -> 0.0 <= Throttle[3] <=1.0 */
185             P = fabs(Throttle[3]) * 180.0 * 745.7; /*180.0*745.7 ->max avail power [W]*/
186             n = dn/dP * (P-117.0*745.7) + 2350.0/60.0;
187
188             /*  V  [m/s]   */
189             V = (V_rel_wind < 10.0 ? 10.0 : V_rel_wind*0.3048);
190             J = V / n / D;
191
192             /* Propeller efficiency */
193             eta_engine = (J < 0.7 ? ((0.8-0.55)/(.7-.3)*(J-0.3) + 0.55) : 
194                           (J > 0.85 ? ((0.6-0.8)/(1.0-0.85)*(J-0.85) + 0.8) : 0.8));
195
196             /* power on Altitude */
197             H = Altitude * 0.3048;       /* H == Altitude [m] */
198             P *= (dPh/dH * H + 180.0*745.7) / (180.0*745.7);
199             T = eta_engine * P/V;        /* Thrust [N] */ 
200
201             /*assumption: Engine's line of thrust passes through cg */
202             F_X_engine = T * 0.2248;     /* F_X_engine in lb */
203             F_Y_engine = 0.0;
204             F_Z_engine = 0.0;
205             break;
206           }
207         case forcemom_flag:
208           {
209             double Xp_input_endTime = Xp_input_timeArray[Xp_input_ntime];
210             if (Simtime >= Xp_input_startTime && 
211                 Simtime <= (Xp_input_startTime + Xp_input_endTime))
212               {
213                 double time = Simtime - Xp_input_startTime;
214                 F_X_engine = uiuc_1Dinterpolation(Xp_input_timeArray,
215                                                   Xp_input_XpArray,
216                                                   Xp_input_ntime,
217                                                   time);
218               }
219             double Zp_input_endTime = Zp_input_timeArray[Zp_input_ntime];
220             if (Simtime >= Zp_input_startTime && 
221                 Simtime <= (Zp_input_startTime + Zp_input_endTime))
222               {
223                 double time = Simtime - Zp_input_startTime;
224                 F_Z_engine = uiuc_1Dinterpolation(Zp_input_timeArray,
225                                                   Zp_input_ZpArray,
226                                                   Zp_input_ntime,
227                                                   time);
228               }
229             double Mp_input_endTime = Mp_input_timeArray[Mp_input_ntime];
230             if (Simtime >= Mp_input_startTime && 
231                 Simtime <= (Mp_input_startTime + Mp_input_endTime))
232               {
233                 double time = Simtime - Mp_input_startTime;
234                 M_m_engine = uiuc_1Dinterpolation(Mp_input_timeArray,
235                                                   Mp_input_MpArray,
236                                                   Mp_input_ntime,
237                                                   time);
238               }
239           }
240         };
241     }
242   return;
243 }
244
245 // end uiuc_engine.cpp