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