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