]> git.mxchange.org Git - flightgear.git/blob - src/FDM/UIUCModel/uiuc_coefficients.cpp
UIUC flight model contribution. This is based on LaRCsim, but can read
[flightgear.git] / src / FDM / UIUCModel / uiuc_coefficients.cpp
1 /**********************************************************************
2
3  FILENAME:     uiuc_coefficients.cpp
4
5 ----------------------------------------------------------------------
6
7  DESCRIPTION:  computes aggregated aerodynamic coefficients
8
9 ----------------------------------------------------------------------
10
11  STATUS:       alpha version
12
13 ----------------------------------------------------------------------
14
15  REFERENCES:   Roskam, Jan.  Airplane Flight Dynamics and Automatic
16                Flight Controls, Part I.  Lawrence, KS: DARcorporation,
17                1995.
18
19 ----------------------------------------------------------------------
20
21  HISTORY:      01/29/2000   initial release
22                02/01/2000   (JS) changed map name from aeroData to 
23                             aeroPart
24                02/18/2000   (JS) added calls to 1Dinterpolation 
25                             function from CLfa and CDfa switches
26                02/24/2000   added icing model functions
27                02/29/2000   (JS) added calls to 2Dinterpolation 
28                             function from CLfade, CDfade, Cmfade, 
29                             CYfada, CYfbetadr, Clfada, Clfbetadr, 
30                             Cnfada, and Cnfbetadr switches
31
32 ----------------------------------------------------------------------
33
34  AUTHOR(S):    Bipin Sehgal       <bsehgal@uiuc.edu>
35                Jeff Scott         <jscott@mail.com>
36
37 ----------------------------------------------------------------------
38
39  VARIABLES:
40
41 ----------------------------------------------------------------------
42
43  INPUTS:       -Alpha
44                -aileron
45                -elevator
46                -rudder
47                -coefficient components
48
49 ----------------------------------------------------------------------
50
51  OUTPUTS:      -CL
52                -CD
53                -Cm
54                -CY
55                -Cl
56                -Cn
57
58 ----------------------------------------------------------------------
59
60  CALLED BY:    ?
61
62 ----------------------------------------------------------------------
63
64  CALLS TO:     uiuc_1Dinterpolation
65                uiuc_2Dinterpolation
66                uiuc_ice
67
68 ----------------------------------------------------------------------
69
70  COPYRIGHT:    (C) 2000 by Michael Selig
71
72  This program is free software; you can redistribute it and/or
73  modify it under the terms of the GNU General Public License
74  as published by the Free Software Foundation.
75
76  This program is distributed in the hope that it will be useful,
77  but WITHOUT ANY WARRANTY; without even the implied warranty of
78  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
79  GNU General Public License for more details.
80
81  You should have received a copy of the GNU General Public License
82  along with this program; if not, write to the Free Software
83  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
84  USA or view http://www.gnu.org/copyleft/gpl.html.
85
86 **********************************************************************/
87
88 #include "uiuc_coefficients.h"
89
90
91 /* set speed at which dynamic pressure terms will be accounted for
92    since if velocity is too small, coefficients will go to infinity */
93
94 #define ON_VELOCITY 33 /* 20 kts */
95
96
97 void uiuc_coefficients()
98 {
99   string linetoken1;
100   string linetoken2;
101   stack command_list;
102   double cbar_2U = 0, b_2U = 0;
103   double slope = 0;
104   bool ice_on = false;
105   
106   // determine if speed is sufficient to compute dynamic pressure
107   if (U_body > ON_VELOCITY)
108     {
109       cbar_2U = cbar / (2.0 * U_body);
110       b_2U = bw / (2.0 * U_body);
111     }
112   else
113     {
114       cbar_2U = 0.0;
115       b_2U = 0.0;
116     }
117
118   //check to see if icing model engaged and set flag
119   if (Simtime >= iceTime)
120     {
121       ice_on = true;
122     }
123
124   // slowly increase icing severity over period of transientTime
125   if (Simtime >= iceTime && Simtime < (iceTime + transientTime))
126     {
127       slope = eta_final / transientTime;
128       eta = slope * (Simtime - iceTime);
129     }
130   else
131     {
132       eta = eta_final;
133     }
134
135   CL = CD = Cm = CY = Cl = Cn = 0.0;
136   command_list = aeroParts -> getCommands();
137   
138   
139   for (LIST command_line = command_list.begin(); command_line!=command_list.end(); ++command_line)
140     {
141       linetoken1 = aeroParts -> getToken(*command_line, 1); // function parameters gettoken(string,tokenNo);
142       linetoken2 = aeroParts -> getToken(*command_line, 2); // 2 represents token No 2
143
144       switch (Keyword_map[linetoken1])
145         {
146         case CD_flag:
147           {
148             switch(CD_map[linetoken2])
149               {
150               case CDo_flag:
151                 {
152                   if (ice_on == true)
153                     {
154                       CDo = uiuc_ice(CDo_clean,kCDo,eta);
155                     }
156                   CD += CDo;
157                   break;
158                 }
159               case CDK_flag:
160                 {
161                   if (ice_on == true)
162                     {
163                       CDK = uiuc_ice(CDK_clean,kCDK,eta);
164                     }
165                   CD += CDK * CL * CL;
166                   break;
167                 }
168               case CD_a_flag:
169                 {
170                   if (ice_on == true)
171                     {
172                       CD_a = uiuc_ice(CD_a_clean,kCD_a,eta);
173                     }
174                   CD += CD_a * Alpha;
175                   break;
176                 }
177               case CD_de_flag:
178                 {
179                   if (ice_on == true)
180                     {
181                       CD_de = uiuc_ice(CD_de_clean,kCD_de,eta);
182                     }
183                   CD += CD_de * elevator;
184                   break;
185                 }
186               case CDfa_flag:
187                 {
188                   CDfaI = uiuc_1Dinterpolation(CDfa_aArray,
189                                                CDfa_CDArray,
190                                                CDfa_nAlpha,
191                                                Alpha);
192                   CD += CDfaI;
193                   break;
194                 }
195               case CDfade_flag:
196                 {
197                   CDfadeI = uiuc_2Dinterpolation(CDfade_aArray,
198                                                  CDfade_deArray,
199                                                  CDfade_CDArray,
200                                                  CDfade_nAlphaArray,
201                                                  CDfade_nde,
202                                                  Alpha,
203                                                  elevator);
204                   CD += CDfadeI;
205                   break;
206                 }
207               };
208             break;
209           } // end CD map
210         case CL_flag:
211           {
212             switch(CL_map[linetoken2])
213               {
214               case CLo_flag:
215                 {
216                   if (ice_on == true)
217                     {
218                       CLo = uiuc_ice(CLo_clean,kCLo,eta);
219                     }
220                   CL += CLo;
221                   break;
222                 }
223               case CL_a_flag:
224                 {
225                   if (ice_on == true)
226                     {
227                       CL_a = uiuc_ice(CL_a_clean,kCL_a,eta);
228                     }
229                   CL += CL_a * Alpha;
230                   break;
231                 }
232               case CL_adot_flag:
233                 {
234                   if (ice_on == true)
235                     {
236                       CL_adot = uiuc_ice(CL_adot_clean,kCL_a,eta);
237                     }
238                   /* CL_adot must be mulitplied by cbar/2U 
239                      (see Roskam Control book, Part 1, pg. 147) */
240                   CL += CL_adot * Alpha_dot * cbar_2U;
241                   break;
242                 }
243               case CL_q_flag:
244                 {
245                   if (ice_on == true)
246                     {
247                       CL_q = uiuc_ice(CL_q_clean,kCL_q,eta);
248                     }
249                   /* CL_q must be mulitplied by cbar/2U 
250                      (see Roskam Control book, Part 1, pg. 147) */
251                   /* why multiply by Theta_dot instead of Q_body?
252                      that is what is done in c172_aero.c; assume it 
253                      has something to do with axes systems */
254                   CL += CL_q * Theta_dot * cbar_2U;
255                   break;
256                 }
257               case CL_de_flag:
258                 {
259                   if (ice_on == true)
260                     {
261                       CL_de = uiuc_ice(CL_de_clean,kCL_de,eta);
262                     }
263                   CL += CL_de * elevator;
264                   break;
265                 }
266               case CLfa_flag:
267                 {
268                   CLfaI = uiuc_1Dinterpolation(CLfa_aArray,
269                                                CLfa_CLArray,
270                                                CLfa_nAlpha,
271                                                Alpha);
272                   CL += CLfaI;
273                   break;
274                 }
275               case CLfade_flag:
276                 {
277                   CLfadeI = uiuc_2Dinterpolation(CLfade_aArray,
278                                                  CLfade_deArray,
279                                                  CLfade_CLArray,
280                                                  CLfade_nAlphaArray,
281                                                  CLfade_nde,
282                                                  Alpha,
283                                                  elevator);
284                   CL += CLfadeI;
285                   break;
286                 }
287               };
288             break;
289           } // end CL map
290         case Cm_flag:
291           {
292             switch(Cm_map[linetoken2])
293               {
294               case Cmo_flag:
295                 {
296                   if (ice_on == true)
297                     {
298                       Cmo = uiuc_ice(Cmo_clean,kCmo,eta);
299                     }
300                   Cm += Cmo;
301                   break;
302                 }
303               case Cm_a_flag:
304                 {
305                   if (ice_on == true)
306                     {
307                       Cm_a = uiuc_ice(Cm_a_clean,kCm_a,eta);
308                     }
309                   Cm += Cm_a * Alpha;
310                   break;
311                 }
312               case Cm_adot_flag:
313                 {
314                   if (ice_on == true)
315                     {
316                       Cm_adot = uiuc_ice(Cm_adot_clean,kCm_a,eta);
317                     }
318                   /* Cm_adot must be mulitplied by cbar/2U 
319                      (see Roskam Control book, Part 1, pg. 147) */
320                   Cm += Cm_adot * Alpha_dot * cbar_2U;
321                   break;
322                 }
323               case Cm_q_flag:
324                 {
325                   if (ice_on == true)
326                     {
327                       Cm_q = uiuc_ice(Cm_q_clean,kCm_q,eta);
328                     }
329                   /* Cm_q must be mulitplied by cbar/2U 
330                      (see Roskam Control book, Part 1, pg. 147) */
331                   Cm += Cm_q * Q_body * cbar_2U;
332                   break;
333                 }
334               case Cm_de_flag:
335                 {
336                   if (ice_on == true)
337                     {
338                       Cm_de = uiuc_ice(Cm_de_clean,kCm_de,eta);
339                     }
340                   Cm += Cm_de * elevator;
341                   break;
342                 }
343               case Cmfade_flag:
344                 {
345                   CmfadeI = uiuc_2Dinterpolation(Cmfade_aArray,
346                                                  Cmfade_deArray,
347                                                  Cmfade_CmArray,
348                                                  Cmfade_nAlphaArray,
349                                                  Cmfade_nde,
350                                                  Alpha,
351                                                  elevator);
352                   Cm += CmfadeI;
353                   break;
354                 }
355               };
356             break;
357           } // end Cm map
358         case CY_flag:
359           {
360             switch(CY_map[linetoken2])
361               {
362               case CYo_flag:
363                 {
364                   if (ice_on == true)
365                     {
366                       CYo = uiuc_ice(CYo_clean,kCYo,eta);
367                     }
368                   CY += CYo;
369                   break;
370                 }
371               case CY_beta_flag:
372                 {
373                   if (ice_on == true)
374                     {
375                       CY_beta = uiuc_ice(CY_beta_clean,kCY_beta,eta);
376                     }
377                   CY += CY_beta * Beta;
378                   break;
379                 }
380               case CY_p_flag:
381                 {
382                   if (ice_on == true)
383                     {
384                       CY_p = uiuc_ice(CY_p_clean,kCY_p,eta);
385                     }
386                   /* CY_p must be mulitplied by b/2U 
387                      (see Roskam Control book, Part 1, pg. 147) */
388                   CY += CY_p * P_body * b_2U;
389                   break;
390                 }
391               case CY_r_flag:
392                 {
393                   if (ice_on == true)
394                     {
395                       CY_r = uiuc_ice(CY_r_clean,kCY_r,eta);
396                     }
397                   /* CY_r must be mulitplied by b/2U 
398                      (see Roskam Control book, Part 1, pg. 147) */
399                   CY += CY_r * R_body * b_2U;
400                   break;
401                 }
402               case CY_da_flag:
403                 {
404                   if (ice_on == true)
405                     {
406                       CY_da = uiuc_ice(CY_da_clean,kCY_da,eta);
407                     }
408                   CY += CY_da * aileron;
409                   break;
410                 }
411               case CY_dr_flag:
412                 {
413                   if (ice_on == true)
414                     {
415                       CY_dr = uiuc_ice(CY_dr_clean,kCY_dr,eta);
416                     }
417                   CY += CY_dr * rudder;
418                   break;
419                 }
420               case CYfada_flag:
421                 {
422                   CYfadaI = uiuc_2Dinterpolation(CYfada_aArray,
423                                                  CYfada_daArray,
424                                                  CYfada_CYArray,
425                                                  CYfada_nAlphaArray,
426                                                  CYfada_nda,
427                                                  Alpha,
428                                                  aileron);
429                   CY += CYfadaI;
430                   break;
431                 }
432               case CYfbetadr_flag:
433                 {
434                   CYfbetadrI = uiuc_2Dinterpolation(CYfbetadr_betaArray,
435                                                     CYfbetadr_drArray,
436                                                     CYfbetadr_CYArray,
437                                                     CYfbetadr_nBetaArray,
438                                                     CYfbetadr_ndr,
439                                                     Beta,
440                                                     rudder);
441                   CY += CYfbetadrI;
442                   break;
443                 }
444               };
445             break;
446           } // end CY map
447         case Cl_flag:
448           {
449             switch(Cl_map[linetoken2])
450               {
451               case Clo_flag:
452                 {
453                   if (ice_on == true)
454                     {
455                       Clo = uiuc_ice(Clo_clean,kClo,eta);
456                     }
457                   Cl += Clo;
458                   break;
459                 }
460               case Cl_beta_flag:
461                 {
462                   if (ice_on == true)
463                     {
464                       Cl_beta = uiuc_ice(Cl_beta_clean,kCl_beta,eta);
465                     }
466                   Cl += Cl_beta * Beta;
467                   break;
468                 }
469               case Cl_p_flag:
470                 {
471                   if (ice_on == true)
472                     {
473                       Cl_p = uiuc_ice(Cl_p_clean,kCl_p,eta);
474                     }
475                   /* Cl_p must be mulitplied by b/2U 
476                      (see Roskam Control book, Part 1, pg. 147) */
477                   Cl += Cl_p * P_body * b_2U;
478                   break;
479                 }
480               case Cl_r_flag:
481                 {
482                   if (ice_on == true)
483                     {
484                       Cl_r = uiuc_ice(Cl_r_clean,kCl_r,eta);
485                     }
486                   /* Cl_r must be mulitplied by b/2U 
487                      (see Roskam Control book, Part 1, pg. 147) */
488                   Cl += Cl_r * R_body * b_2U;
489                   break;
490                 }
491               case Cl_da_flag:
492                 {
493                   if (ice_on == true)
494                     {
495                       Cl_da = uiuc_ice(Cl_da_clean,kCl_da,eta);
496                     }
497                   Cl += Cl_da * aileron;
498                   break;
499                 }
500               case Cl_dr_flag:
501                 {
502                   if (ice_on == true)
503                     {
504                       Cl_dr = uiuc_ice(Cl_dr_clean,kCl_dr,eta);
505                     }
506                   Cl += Cl_dr * rudder;
507                   break;
508                 }
509               case Clfada_flag:
510                 {
511                   ClfadaI = uiuc_2Dinterpolation(Clfada_aArray,
512                                                  Clfada_daArray,
513                                                  Clfada_ClArray,
514                                                  Clfada_nAlphaArray,
515                                                  Clfada_nda,
516                                                  Alpha,
517                                                  aileron);
518                   Cl += ClfadaI;
519                   break;
520                 }
521               case Clfbetadr_flag:
522                 {
523                   ClfbetadrI = uiuc_2Dinterpolation(Clfbetadr_betaArray,
524                                                     Clfbetadr_drArray,
525                                                     Clfbetadr_ClArray,
526                                                     Clfbetadr_nBetaArray,
527                                                     Clfbetadr_ndr,
528                                                     Beta,
529                                                     rudder);
530                   Cl += ClfbetadrI;
531                   break;
532                 }
533               };
534             break;
535           } // end Cl map
536         case Cn_flag:
537           {
538             switch(Cn_map[linetoken2])
539               {
540               case Cno_flag:
541                 {
542                   if (ice_on == true)
543                     {
544                       Cno = uiuc_ice(Cno_clean,kCno,eta);
545                     }
546                   Cn += Cno;
547                   break;
548                 }
549               case Cn_beta_flag:
550                 {
551                   if (ice_on == true)
552                     {
553                       Cn_beta = uiuc_ice(Cn_beta_clean,kCn_beta,eta);
554                     }
555                   Cn += Cn_beta * Beta;
556                   break;
557                 }
558               case Cn_p_flag:
559                 {
560                   if (ice_on == true)
561                     {
562                       Cn_p = uiuc_ice(Cn_p_clean,kCn_p,eta);
563                     }
564                   /* Cn_p must be mulitplied by b/2U 
565                      (see Roskam Control book, Part 1, pg. 147) */
566                   Cn += Cn_p * P_body * b_2U;
567                   break;
568                 }
569               case Cn_r_flag:
570                 {
571                   if (ice_on == true)
572                     {
573                       Cn_r = uiuc_ice(Cn_r_clean,kCn_r,eta);
574                     }
575                   /* Cn_r must be mulitplied by b/2U 
576                      (see Roskam Control book, Part 1, pg. 147) */
577                   Cn += Cn_r * R_body * b_2U;
578                   break;
579                 }
580               case Cn_da_flag:
581                 {
582                   if (ice_on == true)
583                     {
584                       Cn_da = uiuc_ice(Cn_da_clean,kCn_da,eta);
585                     }
586                   Cn += Cn_da * aileron;
587                   break;
588                 }
589               case Cn_dr_flag:
590                 {
591                   if (ice_on == true)
592                     {
593                       Cn_dr = uiuc_ice(Cn_dr_clean,kCn_dr,eta);
594                     }
595                   Cn += Cn_dr * rudder;
596                   break;
597                 }
598               case Cnfada_flag:
599                 {
600                   CnfadaI = uiuc_2Dinterpolation(Cnfada_aArray,
601                                                  Cnfada_daArray,
602                                                  Cnfada_CnArray,
603                                                  Cnfada_nAlphaArray,
604                                                  Cnfada_nda,
605                                                  Alpha,
606                                                  aileron);
607                   Cn += CnfadaI;
608                   break;
609                 }
610               case Cnfbetadr_flag:
611                 {
612                   CnfbetadrI = uiuc_2Dinterpolation(Cnfbetadr_betaArray,
613                                                     Cnfbetadr_drArray,
614                                                     Cnfbetadr_CnArray,
615                                                     Cnfbetadr_nBetaArray,
616                                                     Cnfbetadr_ndr,
617                                                     Beta,
618                                                     rudder);
619                   Cn += CnfbetadrI;
620                   break;
621                 }
622               };
623             break;
624           } // end Cn map
625         };
626     } // end keyword map
627
628   return;
629 }
630
631 // end uiuc_coefficients.cpp