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