]> git.mxchange.org Git - flightgear.git/blob - src/FDM/UIUCModel/uiuc_engine.cpp
Fixed calibrated airspeed output so that it accounts for wind.
[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_Cl_beta_fac) {eta_q_Cl_beta *= eta_q * eta_q_Cl_beta_fac;}
143               if (eta_q_Cl_p_fac)    {eta_q_Cl_p    *= eta_q * eta_q_Cl_p_fac;}
144               if (eta_q_Cl_r_fac)    {eta_q_Cl_r    *= eta_q * eta_q_Cl_r_fac;}
145               if (eta_q_Cl_dr_fac)   {eta_q_Cl_dr   *= eta_q * eta_q_Cl_dr_fac;}
146               if (eta_q_CY_beta_fac) {eta_q_CY_beta *= eta_q * eta_q_CY_beta_fac;}
147               if (eta_q_CY_p_fac)    {eta_q_CY_p    *= eta_q * eta_q_CY_p_fac;}
148               if (eta_q_CY_r_fac)    {eta_q_CY_r    *= eta_q * eta_q_CY_r_fac;}
149               if (eta_q_CY_dr_fac)   {eta_q_CY_dr   *= eta_q * eta_q_CY_dr_fac;}
150               if (eta_q_Cn_beta_fac) {eta_q_Cn_beta *= eta_q * eta_q_Cn_beta_fac;}
151               if (eta_q_Cn_p_fac)    {eta_q_Cn_p    *= eta_q * eta_q_Cn_p_fac;}
152               if (eta_q_Cn_r_fac)    {eta_q_Cn_r    *= eta_q * eta_q_Cn_r_fac;}
153               if (eta_q_Cn_dr_fac)   {eta_q_Cn_dr   *= eta_q * eta_q_Cn_dr_fac;}
154             }
155             /* Need engineOmega for gyroscopic moments */
156             engineOmega = minOmega + Throttle[3] * (maxOmega - minOmega);
157             break;
158           }
159         case c172_flag:
160           {
161             //c172 engine lines ... looks like 0.83 is just a thrust increase
162             F_X_engine = Throttle[3] * 350 / 0.83;
163             F_Z_engine = Throttle[3] * 4.9 / 0.83;
164             M_m_engine = F_X_engine * 0.734 * cbar;
165             break;
166           }
167         case cherokee_flag:
168           {
169             static float
170               dP = (180.0-117.0)*745.7,   // Watts
171               dn = (2700.0-2350.0)/60.0,  // d_rpm (I mean d_rps, in seconds)
172               D  = 6.17*0.3048,           // prop diameter
173               dPh = (58.0-180.0)*745.7,   // change of power as function of height
174               dH = 25000.0*0.3048;
175
176             float
177               n,   // [rps]
178               H,   // altitude [m]
179               J,   // advance ratio (ratio of horizontal speed to prop tip speed)
180               T,   // thrust [N]
181               V,   // velocity [m/s]
182               P,   // power [W]
183               eta_engine; // engine efficiency
184
185             /* assumption -> 0.0 <= Throttle[3] <=1.0 */
186             P = fabs(Throttle[3]) * 180.0 * 745.7; /*180.0*745.7 ->max avail power [W]*/
187             n = dn/dP * (P-117.0*745.7) + 2350.0/60.0;
188
189             /*  V  [m/s]   */
190             V = (V_rel_wind < 10.0 ? 10.0 : V_rel_wind*0.3048);
191             J = V / n / D;
192
193             /* Propeller efficiency */
194             eta_engine = (J < 0.7 ? ((0.8-0.55)/(.7-.3)*(J-0.3) + 0.55) : 
195                           (J > 0.85 ? ((0.6-0.8)/(1.0-0.85)*(J-0.85) + 0.8) : 0.8));
196
197             /* power on Altitude */
198             H = Altitude * 0.3048;       /* H == Altitude [m] */
199             P *= (dPh/dH * H + 180.0*745.7) / (180.0*745.7);
200             T = eta_engine * P/V;        /* Thrust [N] */ 
201
202             /*assumption: Engine's line of thrust passes through cg */
203             F_X_engine = T * 0.2248;     /* F_X_engine in lb */
204             F_Y_engine = 0.0;
205             F_Z_engine = 0.0;
206             break;
207           }
208         case forcemom_flag:
209           {
210             double Xp_input_endTime = Xp_input_timeArray[Xp_input_ntime];
211             if (Simtime >= Xp_input_startTime && 
212                 Simtime <= (Xp_input_startTime + Xp_input_endTime))
213               {
214                 double time = Simtime - Xp_input_startTime;
215                 F_X_engine = uiuc_1Dinterpolation(Xp_input_timeArray,
216                                                   Xp_input_XpArray,
217                                                   Xp_input_ntime,
218                                                   time);
219               }
220             double Zp_input_endTime = Zp_input_timeArray[Zp_input_ntime];
221             if (Simtime >= Zp_input_startTime && 
222                 Simtime <= (Zp_input_startTime + Zp_input_endTime))
223               {
224                 double time = Simtime - Zp_input_startTime;
225                 F_Z_engine = uiuc_1Dinterpolation(Zp_input_timeArray,
226                                                   Zp_input_ZpArray,
227                                                   Zp_input_ntime,
228                                                   time);
229               }
230             double Mp_input_endTime = Mp_input_timeArray[Mp_input_ntime];
231             if (Simtime >= Mp_input_startTime && 
232                 Simtime <= (Mp_input_startTime + Mp_input_endTime))
233               {
234                 double time = Simtime - Mp_input_startTime;
235                 M_m_engine = uiuc_1Dinterpolation(Mp_input_timeArray,
236                                                   Mp_input_MpArray,
237                                                   Mp_input_ntime,
238                                                   time);
239               }
240           }
241         };
242     }
243   return;
244 }
245
246 // end uiuc_engine.cpp