1 /***************************************************************************
5 ----------------------------------------------------------------------------
7 FUNCTION: aerodynamics model based on constant stability derivatives
9 ----------------------------------------------------------------------------
11 MODULE STATUS: developmental
13 ----------------------------------------------------------------------------
15 GENEALOGY: Based on data from:
16 Part 1 of Roskam's S&C text
17 The FAA type certificate data sheet for the 172
18 Various sources on the net
19 John D. Anderson's Intro to Flight text (NACA 2412 data)
20 UIUC's airfoil data web site
22 ----------------------------------------------------------------------------
24 DESIGNED BY: Tony Peden
28 MAINTAINED BY: Tony Peden
30 ----------------------------------------------------------------------------
35 6/10/99 Initial test release
38 ----------------------------------------------------------------------------
48 Croll,Cl rolling moment (yeah, I know. Shoot me.)
51 o constant i.e. not a function of alpha or beta
60 de elevator deflection
67 ----------------------------------------------------------------------------
71 ----------------------------------------------------------------------------
75 ----------------------------------------------------------------------------
79 ----------------------------------------------------------------------------
83 --------------------------------------------------------------------------*/
87 #include "ls_generic.h"
88 #include "ls_cockpit.h"
89 #include "ls_constants.h"
96 #define DYN_ON_SPEED 33 /*20 knots*/
100 #define NZ generic_.n_cg_body_v[2]
106 extern COCKPIT cockpit_;
109 SCALAR interp(SCALAR *y_table, SCALAR *x_table, int Ntable, SCALAR x)
116 /* if x is outside the table, return value at x[0] or x[Ntable-1]*/
120 /* printf("x smaller than x_table[0]: %g %g\n",x,x_table[0]); */
122 else if(x >= x_table[Ntable-1])
125 /* printf("x larger than x_table[N]: %g %g %d\n",x,x_table[NCL-1],Ntable-1); */
127 else /*x is within the table, interpolate linearly to find y value*/
130 while(x_table[i] <= x) {i++;}
131 slope=(y_table[i]-y_table[i-1])/(x_table[i]-x_table[i-1]);
132 /* printf("x: %g, i: %d, cl[i]: %g, cl[i-1]: %g, slope: %g\n",x,i,y_table[i],y_table[i-1],slope); */
133 y=slope*(x-x_table[i-1]) +y_table[i-1];
140 void aero( SCALAR dt, int Initialize ) {
146 static SCALAR trim_inc = 0.0002;
150 SCALAR elevator, aileron, rudder;
154 static SCALAR alpha_ind[NCL]={-0.087,0,0.175,0.209,0.24,0.262,0.278,0.303,0.314,0.332,0.367};
155 static SCALAR CLtable[NCL]={-0.14,0.31,1.21,1.376,1.51249,1.591,1.63,1.60878,1.53712,1.376,1.142};
160 /*Note that CLo,Cdo,Cmo will likely change with flap setting so
161 they may not be declared static in the future */
164 static SCALAR CLadot=1.7;
165 static SCALAR CLq=3.9;
166 static SCALAR CLde=0.43;
170 static SCALAR Cdo=0.031;
171 static SCALAR Cda=0.13; /*Not used*/
172 static SCALAR Cdde=0.06;
174 static SCALAR Cma=-0.89;
175 static SCALAR Cmadot=-5.2;
176 static SCALAR Cmq=-12.4;
177 static SCALAR Cmo=-0.062;
178 static SCALAR Cmde=-1.28;
180 static SCALAR Clbeta=-0.089;
181 static SCALAR Clp=-0.47;
182 static SCALAR Clr=0.096;
183 static SCALAR Clda=-0.178;
184 static SCALAR Cldr=0.0147;
186 static SCALAR Cnbeta=0.065;
187 static SCALAR Cnp=-0.03;
188 static SCALAR Cnr=-0.099;
189 static SCALAR Cnda=-0.053;
190 static SCALAR Cndr=-0.0657;
192 static SCALAR Cybeta=-0.31;
193 static SCALAR Cyp=-0.037;
194 static SCALAR Cyr=0.21;
195 static SCALAR Cyda=0.0;
196 static SCALAR Cydr=0.187;
198 /*nondimensionalization quantities*/
199 /*units here are ft and lbs */
200 static SCALAR cbar=4.9; /*mean aero chord ft*/
201 static SCALAR b=35.8; /*wing span ft */
202 static SCALAR Sw=174; /*wing planform surface area ft^2*/
203 static SCALAR rPiARe=0.054; /*reciprocal of Pi*AR*e*/
207 SCALAR CLwbh,CL,cm,cd,cn,cy,croll,cbar_2V,b_2V,qS,qScbar,qSb,ps,rs;
209 SCALAR F_X_wind,F_Y_wind,F_Z_wind,W_X,W_Y,W_Z;
229 Cl > 0 => Right wing down
232 elevator > 0 => AND -- aircraft nose down
233 aileron > 0 => right wing up
237 if(Aft_trim) long_trim = long_trim - trim_inc;
238 if(Fwd_trim) long_trim = long_trim + trim_inc;
240 /*scale pct control to degrees deflection*/
241 if ((Long_control+long_trim) <= 0)
242 elevator=(Long_control+long_trim)*28*DEG_TO_RAD;
244 elevator=(Long_control+long_trim)*23*DEG_TO_RAD;
246 aileron = Lat_control*17.5*DEG_TO_RAD;
247 rudder = Rudder_pedal*16*DEG_TO_RAD;
249 The aileron travel limits are 20 deg. TEU and 15 deg TED
250 but since we don't distinguish between left and right we'll
251 use the average here (17.5 deg)
255 /*calculate rate derivative nondimensionalization (is that a word?) factors */
256 /*hack to avoid divide by zero*/
257 /*the dynamic terms might be negligible at low ground speeds anyway*/
259 if(V_rel_wind > DYN_ON_SPEED)
261 cbar_2V=cbar/(2*V_rel_wind);
262 b_2V=b/(2*V_rel_wind);
271 /*calcuate the qS nondimensionalization factors*/
273 qS=Dynamic_pressure*Sw;
277 /*transform the aircraft rotation rates*/
278 ps=-P_body*Cos_alpha + R_body*Sin_alpha;
279 rs=-P_body*Sin_alpha + R_body*Cos_alpha;
281 /* printf("Wb: %7.4f, Ub: %7.4f, Alpha: %7.4f, elev: %7.4f, ail: %7.4f, rud: %7.4f\n",W_body,U_body,Alpha*RAD_TO_DEG,elevator*RAD_TO_DEG,aileron*RAD_TO_DEG,rudder*RAD_TO_DEG);
282 printf("Theta: %7.4f, Gamma: %7.4f, Beta: %7.4f, Phi: %7.4f, Psi: %7.4f\n",Theta*RAD_TO_DEG,Gamma_vert_rad*RAD_TO_DEG,Beta*RAD_TO_DEG,Phi*RAD_TO_DEG,Psi*RAD_TO_DEG);
285 /* sum coefficients */
286 CLwbh = interp(CLtable,alpha_ind,NCL,Alpha);
287 CL = CLo + CLwbh + (CLadot*Alpha_dot + CLq*Theta_dot)*cbar_2V + CLde*elevator;
288 cd = Cdo + rPiARe*CL*CL + Cdde*elevator;
289 cy = Cybeta*Beta + (Cyp*ps + Cyr*rs)*b_2V + Cyda*aileron + Cydr*rudder;
291 cm = Cmo + Cma*Alpha + (Cmq*Theta_dot + Cmadot*Alpha_dot)*cbar_2V + Cmde*(elevator+long_trim);
292 cn = Cnbeta*Beta + (Cnp*ps + Cnr*rs)*b_2V + Cnda*aileron + Cndr*rudder;
293 croll=Clbeta*Beta + (Clp*ps + Clr*rs)*b_2V + Clda*aileron + Cldr*rudder;
295 /* printf("CL: %7.4f, Cd: %7.4f, Cm: %7.4f, Cy: %7.4f, Cn: %7.4f, Cl: %7.4f\n",CL,cd,cm,cy,cn,croll);
296 */ /*calculate wind axes forces*/
301 /* printf("V_rel_wind: %7.4f, Fxwind: %7.4f Fywind: %7.4f Fzwind: %7.4f\n",V_rel_wind,F_X_wind,F_Y_wind,F_Z_wind);
303 /*calculate moments and body axis forces */
305 /*find body-axis components of weight*/
306 /*with earth axis to body axis transform */
308 W_Y=W*Sin_phi*Cos_theta;
309 W_Z=W*Cos_phi*Cos_theta;
311 /* requires ugly wind-axes to body-axes transform */
312 F_X_aero = W_X + F_X_wind*Cos_alpha*Cos_beta - F_Y_wind*Cos_alpha*Sin_beta - F_Z_wind*Sin_alpha;
313 F_Y_aero = W_Y + F_X_wind*Sin_beta + F_Y_wind*Cos_beta;
314 F_Z_aero = W_Z*NZ + F_X_wind*Sin_alpha*Cos_beta - F_Y_wind*Sin_alpha*Sin_beta + F_Z_wind*Cos_alpha;
316 /*no axes transform here */
317 M_l_aero = croll*qSb;
318 M_m_aero = cm*qScbar;
321 /* printf("I_yy: %7.4f, qScbar: %7.4f, qbar: %7.4f, Sw: %7.4f, cbar: %7.4f, 0.5*rho*V^2: %7.4f\n",I_yy,qScbar,Dynamic_pressure,Sw,cbar,0.5*0.0023081*V_rel_wind*V_rel_wind);
322 printf("Fxbody: %7.4f Fybody: %7.4f Fzbody: %7.4f Weight: %7.4f\n",F_X_wind,F_Y_wind,F_Z_wind,W);
323 printf("Maero: %7.4f Naero: %7.4f Raero: %7.4f\n",M_m_aero,M_n_aero,M_l_aero);