]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/FGCoefficient.cpp
Initial revision
[flightgear.git] / src / FDM / JSBSim / FGCoefficient.cpp
1 /*******************************************************************************
2
3  Module:       FGCoefficient.cpp
4  Author:       Jon S. Berndt
5  Date started: 12/28/98
6  Purpose:      Encapsulates the stability derivative class FGCoefficient;
7  Called by:    FGAircraft
8
9  ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
10
11  This program is free software; you can redistribute it and/or modify it under
12  the terms of the GNU General Public License as published by the Free Software
13  Foundation; either version 2 of the License, or (at your option) any later
14  version.
15
16  This program is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
19  details.
20
21  You should have received a copy of the GNU General Public License along with
22  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
23  Place - Suite 330, Boston, MA  02111-1307, USA.
24
25  Further information about the GNU General Public License can also be found on
26  the world wide web at http://www.gnu.org.
27
28 FUNCTIONAL DESCRIPTION
29 --------------------------------------------------------------------------------
30 This class models the stability derivative coefficient lookup tables or
31 equations. Note that the coefficients need not be calculated each delta-t.
32
33 The coefficient files are located in the axis subdirectory for each aircraft.
34 For instance, for the X-15, you would find subdirectories under the
35 aircraft/X-15/ directory named CLIFT, CDRAG, CSIDE, CROLL, CPITCH, CYAW. Under
36 each of these directories would be files named a, a0, q, and so on. The file
37 named "a" under the CLIFT directory would contain data for the stability
38 derivative modeling lift due to a change in alpha. See the FGAircraft.cpp file
39 for additional information. The coefficient files have the following format:
40
41 <name of coefficient>
42 <short description of coefficient with no embedded spaces>
43 <method used in calculating the coefficient: TABLE | EQUATION | VECTOR | VALUE>
44   <parameter identifier for table row (if required)>
45   <parameter identifier for table column (if required)>
46 <OR'ed list of parameter identifiers needed to turn this coefficient into a force>
47 <number of rows in table (if required)>
48 <number of columns in table (if required)>
49
50 <value of parameter indexing into the column of a table or vector - or value
51   itself for a VALUE coefficient>
52 <values of parameter indexing into row of a table if TABLE type> <Value of
53   coefficient at this row and column>
54
55 <... repeat above for each column of data in table ...>
56
57 As an example for the X-15, for the lift due to mach:
58
59 CLa0
60 Lift_at_zero_alpha
61 Table 8 3
62 16384
63 32768
64 16387
65
66 0.00
67 0.0 0.0
68 0.5 0.4
69 0.9 0.9
70 1.0 1.6
71 1.1 1.3
72 1.4 1.0
73 2.0 0.5
74 3.0 0.5
75
76 30000.00
77 0.0 0.0
78 0.5 0.5
79 0.9 1.0
80 1.0 1.7
81 1.1 1.4
82 1.4 1.1
83 2.0 0.6
84 3.0 0.6
85
86 70000.00
87 0.0 0.0
88 0.5 0.6
89 0.9 1.1
90 1.0 1.7
91 1.1 1.5
92 1.4 1.2
93 2.0 0.7
94 3.0 0.7
95
96 Note that the values in a row which index into the table must be the same value
97 for each column of data, so the first column of numbers for each altitude are
98 seen to be equal, and there are the same number of values for each altitude.
99
100 See the header file FGCoefficient.h for the values of the identifiers.
101
102 HISTORY
103 --------------------------------------------------------------------------------
104 12/28/98   JSB   Created
105
106 ********************************************************************************
107 INCLUDES
108 *******************************************************************************/
109
110 #include "FGCoefficient.h"
111 #include "FGAtmosphere.h"
112 #include "FGState.h"
113 #include "FGFDMExec.h"
114 #include "FGFCS.h"
115 #include "FGAircraft.h"
116 #include "FGTranslation.h"
117 #include "FGRotation.h"
118 #include "FGPosition.h"
119 #include "FGAuxiliary.h"
120 #include "FGOutput.h"
121
122 /*******************************************************************************
123 ************************************ CODE **************************************
124 *******************************************************************************/
125
126 FGCoefficient::FGCoefficient(FGFDMExec* fdex, ifstream& coeffDefFile)
127 {
128   int r, c;
129   float ftrashcan;
130   string strashcan;
131
132   FDMExec     = fdex;
133   State       = FDMExec->GetState();
134   Atmosphere  = FDMExec->GetAtmosphere();
135   FCS         = FDMExec->GetFCS();
136   Aircraft    = FDMExec->GetAircraft();
137   Translation = FDMExec->GetTranslation();
138   Rotation    = FDMExec->GetRotation();
139   Position    = FDMExec->GetPosition();
140   Auxiliary   = FDMExec->GetAuxiliary();
141   Output      = FDMExec->GetOutput();
142
143   if (coeffDefFile) {
144     if (!coeffDefFile.fail()) {
145       coeffDefFile >> name;
146       cout << "   " << name << endl;
147       coeffDefFile >> strashcan;
148       coeffDefFile >> description;
149       cout << "   " << description << endl;
150       coeffDefFile >> method;
151       cout << "   " << method << endl;
152
153       if      (method == "EQUATION") type = EQUATION;
154       else if (method == "TABLE")    type = TABLE;
155       else if (method == "VECTOR")   type = VECTOR;
156       else if (method == "VALUE")    type = VALUE;
157       else                           type = UNKNOWN;
158
159       if (type == VECTOR || type == TABLE) {
160         coeffDefFile >> rows;
161         cout << "   Rows: " << rows << " ";
162         if (type == TABLE) {
163           coeffDefFile >> columns;
164           cout << "Cols: " << columns;
165         }
166         coeffDefFile >> LookupR;
167         cout << endl;
168         cout << "   Row indexing parameter: " << LookupR << endl;
169       }
170
171       if (type == TABLE) {
172         coeffDefFile >> LookupC;
173         cout << "   Column indexing parameter: " << LookupC << endl;
174       }
175
176       coeffDefFile >> multipliers;
177       cout << "   Non-Dimensionalized by: ";
178       
179       mult_count = 0;
180       if (multipliers & FG_QBAR) {
181         mult_idx[mult_count] = FG_QBAR;
182         mult_count++;
183         cout << "qbar ";
184       }
185       if (multipliers & FG_WINGAREA) {
186         mult_idx[mult_count] = FG_WINGAREA;
187         mult_count++;
188         cout << "S ";
189       }
190       if (multipliers & FG_WINGSPAN) {
191         mult_idx[mult_count] = FG_WINGSPAN;
192         mult_count++;
193         cout << "b ";
194       }
195       if (multipliers & FG_CBAR) {
196         mult_idx[mult_count] = FG_CBAR;
197         mult_count++;
198         cout << "c ";
199       }
200       if (multipliers & FG_ALPHA) {
201         mult_idx[mult_count] = FG_ALPHA;
202         mult_count++;
203         cout << "alpha ";
204       }
205       if (multipliers & FG_ALPHADOT) {
206         mult_idx[mult_count] = FG_ALPHADOT;
207         mult_count++;
208         cout << "alphadot ";
209       }
210       if (multipliers & FG_BETA) {
211         mult_idx[mult_count] = FG_BETA;
212         mult_count++;
213         cout << "beta ";
214       }
215       if (multipliers & FG_BETADOT) {
216         mult_idx[mult_count] = FG_BETADOT;
217         mult_count++;
218         cout << "betadot ";
219       }
220       if (multipliers & FG_PITCHRATE) {
221         mult_idx[mult_count] = FG_PITCHRATE;
222         mult_count++;
223         cout << "q ";
224       }
225       if (multipliers & FG_ROLLRATE) {
226         mult_idx[mult_count] = FG_ROLLRATE;
227         mult_count++;
228         cout << "p ";
229       }
230       if (multipliers & FG_YAWRATE) {
231         mult_idx[mult_count] = FG_YAWRATE;
232         mult_count++;
233         cout << "r ";
234       }
235       if (multipliers & FG_ELEVATOR) {
236         mult_idx[mult_count] = FG_ELEVATOR;
237         mult_count++;
238         cout << "De ";
239       }
240       if (multipliers & FG_AILERON) {
241         mult_idx[mult_count] = FG_AILERON;
242         mult_count++;
243         cout << "Da ";
244       }
245       if (multipliers & FG_RUDDER) {
246         mult_idx[mult_count] = FG_RUDDER;
247         mult_count++;
248         cout << "Dr ";
249       }
250       if (multipliers & FG_MACH) {
251         mult_idx[mult_count] = FG_MACH;
252         mult_count++;
253         cout << "Mach ";
254       }
255       if (multipliers & FG_ALTITUDE) {
256         mult_idx[mult_count] = FG_ALTITUDE;
257         mult_count++;
258         cout << "h ";
259       }
260                         cout << endl;
261                         
262       switch(type) {
263       case VALUE:
264         coeffDefFile >> StaticValue;
265         break;
266       case VECTOR:
267         Allocate(rows,2);
268
269         for (r=1;r<=rows;r++) {
270           coeffDefFile >> Table3D[r][0];
271           coeffDefFile >> Table3D[r][1];
272         }
273
274         for (r=0;r<=rows;r++) {
275                 cout << "       ";
276                 for (c=0;c<=columns;c++) {
277                         cout << Table3D[r][c] << "      ";
278                 }
279                 cout << endl;
280         }
281
282         break;
283       case TABLE:
284         Allocate(rows, columns);
285
286         for (c=1;c<=columns;c++) {
287           coeffDefFile >> Table3D[0][c];
288           for (r=1;r<=rows;r++) {
289             if ( c==1 ) coeffDefFile >> Table3D[r][0];
290             else coeffDefFile >> ftrashcan;
291             coeffDefFile >> Table3D[r][c];
292           }
293         }
294
295         for (r=0;r<=rows;r++) {
296                 cout << "       ";
297                 for (c=0;c<=columns;c++) {
298                         cout << Table3D[r][c] << "      ";
299                 }
300                 cout << endl;
301         }
302         
303         break;
304       }
305     } else {
306       cerr << "Empty file" << endl;
307     }
308   }
309 }
310
311
312 FGCoefficient::~FGCoefficient(void)
313 {
314 }
315
316
317 bool FGCoefficient::Allocate(int r, int c)
318 {
319   rows = r;
320   columns = c;
321   Table3D = new float*[r+1];
322   for (int i=0;i<=r;i++) Table3D[i] = new float[c+1];
323   return true;
324 }
325
326
327 bool FGCoefficient::Allocate(int n)
328 {
329   rows = n;
330   columns = 0;
331   Table2D = new float[n+1];
332   return true;
333 }
334
335
336 float FGCoefficient::Value(float rVal, float cVal)
337 {
338   float rFactor, cFactor, col1temp, col2temp, Value;
339   int r, c, midx;
340
341   if (rows < 2 || columns < 2) return 0.0;
342
343   for (r=1;r<=rows;r++) if (Table3D[r][0] >= rVal) break;
344   for (c=1;c<=columns;c++) if (Table3D[0][c] >= cVal) break;
345
346   c = c < 2 ? 2 : (c > columns ? columns : c);
347   r = r < 2 ? 2 : (r > rows    ? rows    : r);
348
349   rFactor = (rVal - Table3D[r-1][0]) / (Table3D[r][0] - Table3D[r-1][0]);
350   cFactor = (cVal - Table3D[0][c-1]) / (Table3D[0][c] - Table3D[0][c-1]);
351
352   col1temp = rFactor*(Table3D[r][c-1] - Table3D[r-1][c-1]) + Table3D[r-1][c-1];
353   col2temp = rFactor*(Table3D[r][c] - Table3D[r-1][c]) + Table3D[r-1][c];
354
355   Value = col1temp + cFactor*(col2temp - col1temp);
356   
357 //cout << "Value for " << description << " is " << Value;
358  
359   for (midx=0;midx<mult_count;midx++) {
360     Value *= GetCoeffVal(mult_idx[midx]);
361   }
362
363 //cout << " after multipliers it is: " << Value << endl;
364
365   return Value;
366 }
367
368
369 float FGCoefficient::Value(float Val)
370 {
371   float Factor, Value;
372   int r, midx;
373
374   if (rows < 2) return 0.0;
375   
376   for (r=1;r<=rows;r++) if (Table3D[r][0] >= Val) break;
377   r = r < 2 ? 2 : (r > rows    ? rows    : r);
378
379   // make sure denominator below does not go to zero.
380   if (Table3D[r][0] != Table3D[r-1][0]) {
381     Factor = (Val - Table3D[r-1][0]) / (Table3D[r][0] - Table3D[r-1][0]);
382   } else {
383     Factor = 1.0;
384   }
385
386   Value = Factor*(Table3D[r][1] - Table3D[r-1][1]) + Table3D[r-1][1];
387
388 // cout << "Value for " << description << " is " << Value;
389  
390   for (midx=0;midx<mult_count;midx++) {
391     Value *= GetCoeffVal(mult_idx[midx]);
392   }
393
394 //cout << " after multipliers it is: " << Value << endl;
395
396   return Value;
397 }
398
399
400 float FGCoefficient::Value(void)
401 {
402         float Value;
403         int midx;
404         
405         Value = StaticValue;
406
407 // cout << "Value for " << description << " is " << Value << endl;
408  
409   for (midx=0;midx<mult_count;midx++) {
410     Value *= GetCoeffVal(mult_idx[midx]);
411   }
412
413 // cout << " after multipliers it is: " << Value << endl;
414
415   return Value;
416 }
417
418 float FGCoefficient::TotalValue()
419 {
420   switch(type) {
421   case 0:
422     return -1;
423   case 1:
424     return (Value());
425   case 2:
426     return (Value(GetCoeffVal(LookupR)));
427   case 3:
428     return (Value(GetCoeffVal(LookupR),GetCoeffVal(LookupC)));
429   case 4:
430     return 0.0;
431   }
432   return 0;
433 }
434
435 float FGCoefficient::GetCoeffVal(int val_idx)
436 {
437   switch(val_idx) {
438   case FG_QBAR:
439 //cout << "Qbar: " << State->Getqbar() << endl;
440     return State->Getqbar();
441   case FG_WINGAREA:
442 //cout << "S: " << Aircraft->GetWingArea() << endl;  
443     return Aircraft->GetWingArea();
444   case FG_WINGSPAN:
445 //cout << "b: " << Aircraft->GetWingSpan() << endl;
446     return Aircraft->GetWingSpan();
447   case FG_CBAR:
448 //cout << "Cbar: " << Aircraft->Getcbar() << endl;
449     return Aircraft->Getcbar();
450   case FG_ALPHA:
451 //cout << "Alpha: " << Translation->Getalpha() << endl;
452     return Translation->Getalpha();
453   case FG_ALPHADOT:
454 //cout << "Adot: " << State->Getadot() << endl;
455     return State->Getadot();
456   case FG_BETA:
457 //cout << "Beta: " << Translation->Getbeta() << endl;
458     return Translation->Getbeta();
459   case FG_BETADOT:
460 //cout << "Bdot: " << State->Getbdot() << endl;
461     return State->Getbdot();
462   case FG_PITCHRATE:
463 //cout << "Q: " << Rotation->GetQ() << endl;
464     return Rotation->GetQ();
465   case FG_ROLLRATE:
466 //cout << "P: " << Rotation->GetP() << endl;
467     return Rotation->GetP();
468   case FG_YAWRATE:
469 //cout << "R: " << Rotation->GetR() << endl;
470     return Rotation->GetR();
471   case FG_ELEVATOR:
472 //cout << "De: " << FCS->GetDe() << endl;
473     return FCS->GetDe();
474   case FG_AILERON:
475 //cout << "Da: " << FCS->GetDa() << endl;
476     return FCS->GetDa();
477   case FG_RUDDER:
478 //cout << "Dr: " << FCS->GetDr() << endl;
479     return FCS->GetDr();
480   case FG_MACH:
481 //cout << "Mach: " << State->GetMach() << endl;
482     return State->GetMach();
483   case FG_ALTITUDE:
484 //cout << "h: " << State->Geth() << endl;
485     return State->Geth();
486   }
487   return 0;
488 }