]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBsim/FGCoefficient.cpp
source tree reorganization prior to flightgear 0.7
[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 Note that the values in a row which index into the table must be the same value
34 for each column of data, so the first column of numbers for each altitude are
35 seen to be equal, and there are the same number of values for each altitude.
36
37 See the header file FGCoefficient.h for the values of the identifiers.
38
39 HISTORY
40 --------------------------------------------------------------------------------
41 12/28/98   JSB   Created
42
43 ********************************************************************************
44 INCLUDES
45 *******************************************************************************/
46
47 #include "FGCoefficient.h"
48 #include "FGAtmosphere.h"
49 #include "FGState.h"
50 #include "FGFDMExec.h"
51 #include "FGFCS.h"
52 #include "FGAircraft.h"
53 #include "FGTranslation.h"
54 #include "FGRotation.h"
55 #include "FGPosition.h"
56 #include "FGAuxiliary.h"
57 #include "FGOutput.h"
58
59 /*******************************************************************************
60 ************************************ CODE **************************************
61 *******************************************************************************/
62
63 FGCoefficient::FGCoefficient(FGFDMExec* fdex, ifstream& coeffDefFile)
64 {
65   int r, c, start, end, n;
66   float ftrashcan;
67   string strashcan;
68
69   coeffdef["FG_QBAR"]      = 1;
70   coeffdef["FG_WINGAREA"]  = 2;
71   coeffdef["FG_WINGSPAN"]  = 4;
72   coeffdef["FG_CBAR"]      = 8;
73   coeffdef["FG_ALPHA"]     = 16;
74   coeffdef["FG_ALPHADOT"]  = 32;
75   coeffdef["FG_BETA"]      = 64;
76   coeffdef["FG_BETADOT"]   = 128;
77   coeffdef["FG_PITCHRATE"] = 256;
78   coeffdef["FG_ROLLRATE"]  = 512;
79   coeffdef["FG_YAWRATE"]   = 1024;
80   coeffdef["FG_ELEVATOR"]  = 2048;
81   coeffdef["FG_AILERON"]   = 4096;
82   coeffdef["FG_RUDDER"]    = 8192;
83   coeffdef["FG_MACH"]      = 16384;
84   coeffdef["FG_ALTITUDE"]  = 32768L;
85   coeffdef["FG_BI2VEL"]    = 65536L;
86   coeffdef["FG_CI2VEL"]    = 131072L;
87
88   FDMExec     = fdex;
89   State       = FDMExec->GetState();
90   Atmosphere  = FDMExec->GetAtmosphere();
91   FCS         = FDMExec->GetFCS();
92   Aircraft    = FDMExec->GetAircraft();
93   Translation = FDMExec->GetTranslation();
94   Rotation    = FDMExec->GetRotation();
95   Position    = FDMExec->GetPosition();
96   Auxiliary   = FDMExec->GetAuxiliary();
97   Output      = FDMExec->GetOutput();
98
99   if (coeffDefFile) {
100     if (!coeffDefFile.fail()) {
101       coeffDefFile >> name;
102       cout << "   " << name << endl;
103       coeffDefFile >> strashcan;
104       coeffDefFile >> description;
105       cout << "   " << description << endl;
106       coeffDefFile >> method;
107       cout << "   " << method << endl;
108
109       if      (method == "EQUATION") type = EQUATION;
110       else if (method == "TABLE")    type = TABLE;
111       else if (method == "VECTOR")   type = VECTOR;
112       else if (method == "VALUE")    type = VALUE;
113       else                           type = UNKNOWN;
114
115       if (type == VECTOR || type == TABLE) {
116         coeffDefFile >> rows;
117         cout << "   Rows: " << rows << " ";
118         if (type == TABLE) {
119           coeffDefFile >> columns;
120           cout << "Cols: " << columns;
121         }
122
123         cout << endl;
124
125         coeffDefFile >> strashcan;
126         if (strashcan.substr(0,1) == "F") {
127           LookupR = coeffdef[strashcan.c_str()];
128           cout << "   Row indexing parameter: " << strashcan << endl;
129         } else {
130           LookupR = atoi(strashcan.c_str());
131           cout << "   Row indexing parameter: " << LookupR << endl;
132         }
133
134       }
135
136       if (type == TABLE) {
137         coeffDefFile >> strashcan;
138         if (strashcan.substr(0,1) == "F") {
139           LookupC = coeffdef[strashcan.c_str()];
140           cout << "   Column indexing parameter: " << strashcan << endl;
141         } else {
142           LookupC = atoi(strashcan.c_str());
143           cout << "   Column indexing parameter: " << LookupC << endl;
144         }
145       }
146
147       coeffDefFile >> strashcan;
148
149       end   = strashcan.length();
150       n     = strashcan.find("|");
151       start = 0;
152       multipliers = 0;
153       if (strashcan.substr(0,1) == "F") {
154         while(n < end && n >= 0) {
155           n -= start;
156           multipliers += coeffdef[strashcan.substr(start,n).c_str()];
157           start += n+1;
158           n = strashcan.find("|",start);
159         }
160         multipliers += coeffdef[strashcan.substr(start,end).c_str()];
161       } else {
162         multipliers = atoi(strashcan.c_str());
163       }
164
165       cout << "   Non-Dimensionalized by: ";
166
167       mult_count = 0;
168       if (multipliers & FG_QBAR) {
169         mult_idx[mult_count] = FG_QBAR;
170         mult_count++;
171         cout << "qbar ";
172       }
173       if (multipliers & FG_WINGAREA) {
174         mult_idx[mult_count] = FG_WINGAREA;
175         mult_count++;
176         cout << "S ";
177       }
178       if (multipliers & FG_WINGSPAN) {
179         mult_idx[mult_count] = FG_WINGSPAN;
180         mult_count++;
181         cout << "b ";
182       }
183       if (multipliers & FG_CBAR) {
184         mult_idx[mult_count] = FG_CBAR;
185         mult_count++;
186         cout << "c ";
187       }
188       if (multipliers & FG_ALPHA) {
189         mult_idx[mult_count] = FG_ALPHA;
190         mult_count++;
191         cout << "alpha ";
192       }
193       if (multipliers & FG_ALPHADOT) {
194         mult_idx[mult_count] = FG_ALPHADOT;
195         mult_count++;
196         cout << "alphadot ";
197       }
198       if (multipliers & FG_BETA) {
199         mult_idx[mult_count] = FG_BETA;
200         mult_count++;
201         cout << "beta ";
202       }
203       if (multipliers & FG_BETADOT) {
204         mult_idx[mult_count] = FG_BETADOT;
205         mult_count++;
206         cout << "betadot ";
207       }
208       if (multipliers & FG_PITCHRATE) {
209         mult_idx[mult_count] = FG_PITCHRATE;
210         mult_count++;
211         cout << "q ";
212       }
213       if (multipliers & FG_ROLLRATE) {
214         mult_idx[mult_count] = FG_ROLLRATE;
215         mult_count++;
216         cout << "p ";
217       }
218       if (multipliers & FG_YAWRATE) {
219         mult_idx[mult_count] = FG_YAWRATE;
220         mult_count++;
221         cout << "r ";
222       }
223       if (multipliers & FG_ELEVATOR) {
224         mult_idx[mult_count] = FG_ELEVATOR;
225         mult_count++;
226         cout << "De ";
227       }
228       if (multipliers & FG_AILERON) {
229         mult_idx[mult_count] = FG_AILERON;
230         mult_count++;
231         cout << "Da ";
232       }
233       if (multipliers & FG_RUDDER) {
234         mult_idx[mult_count] = FG_RUDDER;
235         mult_count++;
236         cout << "Dr ";
237       }
238       if (multipliers & FG_MACH) {
239         mult_idx[mult_count] = FG_MACH;
240         mult_count++;
241         cout << "Mach ";
242       }
243       if (multipliers & FG_ALTITUDE) {
244         mult_idx[mult_count] = FG_ALTITUDE;
245         mult_count++;
246         cout << "h ";
247       }
248       if (multipliers & FG_BI2VEL) {
249         mult_idx[mult_count] = FG_BI2VEL;
250         mult_count++;
251         cout << "b /(2*Vt) ";
252       }
253       if (multipliers & FG_CI2VEL) {
254         mult_idx[mult_count] = FG_CI2VEL;
255         mult_count++;
256         cout << "c /(2*Vt) ";
257       }
258                         cout << endl;
259
260       switch(type) {
261       case VALUE:
262         coeffDefFile >> StaticValue;
263         cout << "      Value = " << StaticValue << endl;
264         break;
265       case VECTOR:
266         Allocate(rows,2);
267
268         for (r=1;r<=rows;r++) {
269           coeffDefFile >> Table3D[r][0];
270           coeffDefFile >> Table3D[r][1];
271         }
272
273         for (r=0;r<=rows;r++) {
274                 cout << "       ";
275                 for (c=0;c<=columns;c++) {
276                         cout << Table3D[r][c] << "      ";
277                 }
278                 cout << endl;
279         }
280
281         break;
282       case TABLE:
283         Allocate(rows, columns);
284
285         Table3D[0][0] = 0.0;
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   for (midx=0;midx<mult_count;midx++) {
358     Value *= GetCoeffVal(mult_idx[midx]);
359   }
360
361   return Value;
362 }
363
364
365 float FGCoefficient::Value(float Val)
366 {
367   float Factor, Value;
368   int r, midx;
369
370   if (rows < 2) return 0.0;
371
372   for (r=1;r<=rows;r++) if (Table3D[r][0] >= Val) break;
373   r = r < 2 ? 2 : (r > rows    ? rows    : r);
374
375   // make sure denominator below does not go to zero.
376   if (Table3D[r][0] != Table3D[r-1][0]) {
377     Factor = (Val - Table3D[r-1][0]) / (Table3D[r][0] - Table3D[r-1][0]);
378   } else {
379     Factor = 1.0;
380   }
381
382   Value = Factor*(Table3D[r][1] - Table3D[r-1][1]) + Table3D[r-1][1];
383
384   for (midx=0;midx<mult_count;midx++) {
385     Value *= GetCoeffVal(mult_idx[midx]);
386   }
387
388   return Value;
389 }
390
391
392 float FGCoefficient::Value(void)
393 {
394         float Value;
395         int midx;
396         
397         Value = StaticValue;
398
399   for (midx=0;midx<mult_count;midx++) {
400     Value *= GetCoeffVal(mult_idx[midx]);
401   }
402
403   return Value;
404 }
405
406 float FGCoefficient::TotalValue()
407 {
408   switch(type) {
409   case 0:
410     return -1;
411   case 1:
412     return (Value());
413   case 2:
414     return (Value(GetCoeffVal(LookupR)));
415   case 3:
416     return (Value(GetCoeffVal(LookupR),GetCoeffVal(LookupC)));
417   case 4:
418     return 0.0;
419   }
420   return 0;
421 }
422
423 float FGCoefficient::GetCoeffVal(int val_idx)
424 {
425   switch(val_idx) {
426   case FG_QBAR:
427     return State->Getqbar();
428   case FG_WINGAREA:
429     return Aircraft->GetWingArea();
430   case FG_WINGSPAN:
431     return Aircraft->GetWingSpan();
432   case FG_CBAR:
433     return Aircraft->Getcbar();
434   case FG_ALPHA:
435     return Translation->Getalpha();
436   case FG_ALPHADOT:
437     return State->Getadot();
438   case FG_BETA:
439     return Translation->Getbeta();
440   case FG_BETADOT:
441     return State->Getbdot();
442   case FG_PITCHRATE:
443     return Rotation->GetQ();
444   case FG_ROLLRATE:
445     return Rotation->GetP();
446   case FG_YAWRATE:
447     return Rotation->GetR();
448   case FG_ELEVATOR:
449     return FCS->GetDe();
450   case FG_AILERON:
451     return FCS->GetDa();
452   case FG_RUDDER:
453     return FCS->GetDr();
454   case FG_MACH:
455     return State->GetMach();
456   case FG_ALTITUDE:
457     return State->Geth();
458   case FG_BI2VEL:
459     return Aircraft->GetWingSpan()/(2.0 * State->GetVt());
460   case FG_CI2VEL:
461     return Aircraft->Getcbar()/(2.0 * State->GetVt());
462   }
463   return 0;
464 }
465