]> git.mxchange.org Git - flightgear.git/blob - src/FDM/UIUCModel/uiuc_engine.cpp
set new FSF address (the whole paragraph is taken from
[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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
69
70 **********************************************************************/
71 #include <simgear/compiler.h>
72
73 #include "uiuc_engine.h"
74
75 SG_USING_STD(cerr);
76
77 void uiuc_engine() 
78 {
79   stack command_list;
80   string linetoken1;
81   string linetoken2;
82
83   if (outside_control == false)
84     pilot_throttle_no = false;
85   if (Throttle_pct_input)
86     {
87       double Throttle_pct_input_endTime = Throttle_pct_input_timeArray[Throttle_pct_input_ntime];
88       if (Simtime >= Throttle_pct_input_startTime && 
89           Simtime <= (Throttle_pct_input_startTime + Throttle_pct_input_endTime))
90         {
91           double time = Simtime - Throttle_pct_input_startTime;
92           Throttle_pct = uiuc_1Dinterpolation(Throttle_pct_input_timeArray,
93                          Throttle_pct_input_dTArray,
94                          Throttle_pct_input_ntime,
95                          time);
96           pilot_throttle_no = true;
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             F_Y_engine = 0.0;
125             F_Z_engine = 0.0;
126             M_l_engine = 0.0;
127             M_m_engine = 0.0;
128             M_n_engine = 0.0;
129             break;
130           }
131         case simpleSingleModel_flag:
132           {
133             /* simple model based on Hepperle's equation
134              * exponent dtdvvt was computed in uiuc_menu.cpp */
135             F_X_engine = Throttle[3] * t_v0 * (1 - pow((V_rel_wind/v_t0),dtdvvt));
136             F_Y_engine = 0.0;
137             F_Z_engine = 0.0;
138             M_l_engine = 0.0;
139             M_m_engine = 0.0;
140             M_n_engine = 0.0;
141             if (b_slipstreamEffects) {
142               tc = F_X_engine/(Dynamic_pressure * LS_PI * propDia * propDia / 4);
143               w_induced = 0.5 *  V_rel_wind * (-1 + pow((1+tc),.5));
144               eta_q = (2* w_induced + V_rel_wind)*(2* w_induced + V_rel_wind)/(V_rel_wind * V_rel_wind);
145               /* add in a die-off function so that eta falls off w/ alfa and beta */
146               eta_q = Cos_alpha * Cos_alpha * Cos_beta * Cos_beta * eta_q;
147               /* determine the eta_q values for the respective coefficients */
148               if (eta_q_Cm_q_fac)    {eta_q_Cm_q    *= eta_q * eta_q_Cm_q_fac;}
149               if (eta_q_Cm_adot_fac) {eta_q_Cm_adot *= eta_q * eta_q_Cm_adot_fac;}
150               if (eta_q_Cmfade_fac)  {eta_q_Cmfade  *= eta_q * eta_q_Cmfade_fac;}
151               if (eta_q_Cm_de_fac)   {eta_q_Cm_de   *= eta_q * eta_q_Cm_de_fac;}
152               if (eta_q_Cl_beta_fac) {eta_q_Cl_beta *= eta_q * eta_q_Cl_beta_fac;}
153               if (eta_q_Cl_p_fac)    {eta_q_Cl_p    *= eta_q * eta_q_Cl_p_fac;}
154               if (eta_q_Cl_r_fac)    {eta_q_Cl_r    *= eta_q * eta_q_Cl_r_fac;}
155               if (eta_q_Cl_dr_fac)   {eta_q_Cl_dr   *= eta_q * eta_q_Cl_dr_fac;}
156               if (eta_q_CY_beta_fac) {eta_q_CY_beta *= eta_q * eta_q_CY_beta_fac;}
157               if (eta_q_CY_p_fac)    {eta_q_CY_p    *= eta_q * eta_q_CY_p_fac;}
158               if (eta_q_CY_r_fac)    {eta_q_CY_r    *= eta_q * eta_q_CY_r_fac;}
159               if (eta_q_CY_dr_fac)   {eta_q_CY_dr   *= eta_q * eta_q_CY_dr_fac;}
160               if (eta_q_Cn_beta_fac) {eta_q_Cn_beta *= eta_q * eta_q_Cn_beta_fac;}
161               if (eta_q_Cn_p_fac)    {eta_q_Cn_p    *= eta_q * eta_q_Cn_p_fac;}
162               if (eta_q_Cn_r_fac)    {eta_q_Cn_r    *= eta_q * eta_q_Cn_r_fac;}
163               if (eta_q_Cn_dr_fac)   {eta_q_Cn_dr   *= eta_q * eta_q_Cn_dr_fac;}
164             }
165             /* Need engineOmega for gyroscopic moments */
166             engineOmega = minOmega + Throttle[3] * (maxOmega - minOmega);
167             break;
168           }
169         case c172_flag:
170           {
171             //c172 engine lines ... looks like 0.83 is just a thrust increase
172             F_X_engine = Throttle[3] * 350 / 0.83;
173             F_Z_engine = Throttle[3] * 4.9 / 0.83;
174             M_m_engine = F_X_engine * 0.734 * cbar;
175             break;
176           }
177         case cherokee_flag:
178           {
179             static float
180               dP = (180.0-117.0)*745.7,   // Watts
181               dn = (2700.0-2350.0)/60.0,  // d_rpm (I mean d_rps, in seconds)
182               D  = 6.17*0.3048,           // prop diameter
183               dPh = (58.0-180.0)*745.7,   // change of power as function of height
184               dH = 25000.0*0.3048;
185
186             float
187               n,   // [rps]
188               H,   // altitude [m]
189               J,   // advance ratio (ratio of horizontal speed to prop tip speed)
190               T,   // thrust [N]
191               V,   // velocity [m/s]
192               P,   // power [W]
193               eta_engine; // engine efficiency
194
195             /* assumption -> 0.0 <= Throttle[3] <=1.0 */
196             P = fabs(Throttle[3]) * 180.0 * 745.7; /*180.0*745.7 ->max avail power [W]*/
197             n = dn/dP * (P-117.0*745.7) + 2350.0/60.0;
198
199             /*  V  [m/s]   */
200             V = (V_rel_wind < 10.0 ? 10.0 : V_rel_wind*0.3048);
201             J = V / n / D;
202
203             /* Propeller efficiency */
204             eta_engine = (J < 0.7 ? ((0.8-0.55)/(.7-.3)*(J-0.3) + 0.55) : 
205                           (J > 0.85 ? ((0.6-0.8)/(1.0-0.85)*(J-0.85) + 0.8) : 0.8));
206
207             /* power on Altitude */
208             H = Altitude * 0.3048;       /* H == Altitude [m] */
209             P *= (dPh/dH * H + 180.0*745.7) / (180.0*745.7);
210             T = eta_engine * P/V;        /* Thrust [N] */ 
211
212             /*assumption: Engine's line of thrust passes through cg */
213             F_X_engine = T * 0.2248;     /* F_X_engine in lb */
214             F_Y_engine = 0.0;
215             F_Z_engine = 0.0;
216             break;
217           }
218         case forcemom_flag:
219           {
220             double Xp_input_endTime = Xp_input_timeArray[Xp_input_ntime];
221             if (Simtime >= Xp_input_startTime && 
222                 Simtime <= (Xp_input_startTime + Xp_input_endTime))
223               {
224                 double time = Simtime - Xp_input_startTime;
225                 F_X_engine = uiuc_1Dinterpolation(Xp_input_timeArray,
226                                                   Xp_input_XpArray,
227                                                   Xp_input_ntime,
228                                                   time);
229               }
230             double Zp_input_endTime = Zp_input_timeArray[Zp_input_ntime];
231             if (Simtime >= Zp_input_startTime && 
232                 Simtime <= (Zp_input_startTime + Zp_input_endTime))
233               {
234                 double time = Simtime - Zp_input_startTime;
235                 F_Z_engine = uiuc_1Dinterpolation(Zp_input_timeArray,
236                                                   Zp_input_ZpArray,
237                                                   Zp_input_ntime,
238                                                   time);
239               }
240             double Mp_input_endTime = Mp_input_timeArray[Mp_input_ntime];
241             if (Simtime >= Mp_input_startTime && 
242                 Simtime <= (Mp_input_startTime + Mp_input_endTime))
243               {
244                 double time = Simtime - Mp_input_startTime;
245                 M_m_engine = uiuc_1Dinterpolation(Mp_input_timeArray,
246                                                   Mp_input_MpArray,
247                                                   Mp_input_ntime,
248                                                   time);
249               }
250           }
251         };
252     }
253   return;
254 }
255
256 // end uiuc_engine.cpp