]> git.mxchange.org Git - flightgear.git/blob - JSBsim/FGCoefficient.cpp
Added initial support for native SGI compilers.
[flightgear.git] / 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)
127 {
128   FDMExec     = fdex;
129   State       = FDMExec->GetState();
130   Atmosphere  = FDMExec->GetAtmosphere();
131   FCS         = FDMExec->GetFCS();
132   Aircraft    = FDMExec->GetAircraft();
133   Translation = FDMExec->GetTranslation();
134   Rotation    = FDMExec->GetRotation();
135   Position    = FDMExec->GetPosition();
136   Auxiliary   = FDMExec->GetAuxiliary();
137   Output      = FDMExec->GetOutput();
138
139   rows = columns = 0;
140 }
141
142
143 FGCoefficient::FGCoefficient(FGFDMExec* fdex, string fname)
144 {
145   int r, c;
146   float ftrashcan;
147
148   FDMExec     = fdex;
149   State       = FDMExec->GetState();
150   Atmosphere  = FDMExec->GetAtmosphere();
151   FCS         = FDMExec->GetFCS();
152   Aircraft    = FDMExec->GetAircraft();
153   Translation = FDMExec->GetTranslation();
154   Rotation    = FDMExec->GetRotation();
155   Position    = FDMExec->GetPosition();
156   Auxiliary   = FDMExec->GetAuxiliary();
157   Output      = FDMExec->GetOutput();
158
159   ifstream coeffDefFile(fname.c_str());
160
161   if (coeffDefFile) {
162     if (!coeffDefFile.fail()) {
163       coeffDefFile >> name;
164       coeffDefFile >> description;
165       coeffDefFile >> method;
166
167       if      (method == "EQUATION") type = 4;
168       else if (method == "TABLE")    type = 3;
169       else if (method == "VECTOR")   type = 2;
170       else if (method == "VALUE")    type = 1;
171       else                           type = 0;
172
173       if (type == 2 || type == 3) {
174         coeffDefFile >> rows;
175         if (type == 3) {
176           coeffDefFile >> columns;
177         }
178         coeffDefFile >> LookupR;
179       }
180
181       if (type == 3) {
182         coeffDefFile >> LookupC;
183       }
184
185       coeffDefFile >> multipliers;
186
187       mult_count = 0;
188       if (multipliers & FG_QBAR) {
189         mult_idx[mult_count] = FG_QBAR;
190         mult_count++;
191       }
192       if (multipliers & FG_WINGAREA) {
193         mult_idx[mult_count] = FG_WINGAREA;
194         mult_count++;
195       }
196       if (multipliers & FG_WINGSPAN) {
197         mult_idx[mult_count] = FG_WINGSPAN;
198         mult_count++;
199       }
200       if (multipliers & FG_CBAR) {
201         mult_idx[mult_count] = FG_CBAR;
202         mult_count++;
203       }
204       if (multipliers & FG_ALPHA) {
205         mult_idx[mult_count] = FG_ALPHA;
206         mult_count++;
207       }
208       if (multipliers & FG_ALPHADOT) {
209         mult_idx[mult_count] = FG_ALPHADOT;
210         mult_count++;
211       }
212       if (multipliers & FG_BETA) {
213         mult_idx[mult_count] = FG_BETA;
214         mult_count++;
215       }
216       if (multipliers & FG_BETADOT) {
217         mult_idx[mult_count] = FG_BETADOT;
218         mult_count++;
219       }
220       if (multipliers & FG_PITCHRATE) {
221         mult_idx[mult_count] = FG_PITCHRATE;
222         mult_count++;
223       }
224       if (multipliers & FG_ROLLRATE) {
225         mult_idx[mult_count] = FG_ROLLRATE;
226         mult_count++;
227       }
228       if (multipliers & FG_YAWRATE) {
229         mult_idx[mult_count] = FG_YAWRATE;
230         mult_count++;
231       }
232       if (multipliers & FG_ELEVATOR) {
233         mult_idx[mult_count] = FG_ELEVATOR;
234         mult_count++;
235       }
236       if (multipliers & FG_AILERON) {
237         mult_idx[mult_count] = FG_AILERON;
238         mult_count++;
239       }
240       if (multipliers & FG_RUDDER) {
241         mult_idx[mult_count] = FG_RUDDER;
242         mult_count++;
243       }
244       if (multipliers & FG_MACH) {
245         mult_idx[mult_count] = FG_MACH;
246         mult_count++;
247       }
248       if (multipliers & FG_ALTITUDE) {
249         mult_idx[mult_count] = FG_ALTITUDE;
250         mult_count++;
251       }
252
253       switch(type) {
254       case 1:
255         coeffDefFile >> StaticValue;
256         break;
257       case 2:
258         Allocate(rows,2);
259
260         for (r=1;r<=rows;r++) {
261           coeffDefFile >> Table3D[r][0];
262           coeffDefFile >> Table3D[r][1];
263         }
264         break;
265       case 3:
266         Allocate(rows, columns);
267
268         for (c=1;c<=columns;c++) {
269           coeffDefFile >> Table3D[0][c];
270           for (r=1;r<=rows;r++) {
271             if ( c==1 ) coeffDefFile >> Table3D[r][0];
272             else coeffDefFile >> ftrashcan;
273             coeffDefFile >> Table3D[r][c];
274           }
275         }
276         break;
277       }
278     } else {
279       cerr << "Empty file" << endl;
280     }
281     coeffDefFile.close();
282   }
283 }
284
285
286 FGCoefficient::FGCoefficient(FGFDMExec* fdex, int r, int c)
287 {
288   FDMExec     = fdex;
289   State       = FDMExec->GetState();
290   Atmosphere  = FDMExec->GetAtmosphere();
291   FCS         = FDMExec->GetFCS();
292   Aircraft    = FDMExec->GetAircraft();
293   Translation = FDMExec->GetTranslation();
294   Rotation    = FDMExec->GetRotation();
295   Position    = FDMExec->GetPosition();
296   Auxiliary   = FDMExec->GetAuxiliary();
297   Output      = FDMExec->GetOutput();
298
299   rows = r;
300   columns = c;
301   Allocate(r,c);
302 }
303
304
305 FGCoefficient::FGCoefficient(FGFDMExec* fdex, int n)
306 {
307   FDMExec     = fdex;
308   State       = FDMExec->GetState();
309   Atmosphere  = FDMExec->GetAtmosphere();
310   FCS         = FDMExec->GetFCS();
311   Aircraft    = FDMExec->GetAircraft();
312   Translation = FDMExec->GetTranslation();
313   Rotation    = FDMExec->GetRotation();
314   Position    = FDMExec->GetPosition();
315   Auxiliary   = FDMExec->GetAuxiliary();
316   Output      = FDMExec->GetOutput();
317
318   rows = n;
319   columns = 0;
320   Allocate(n);
321 }
322
323
324 FGCoefficient::~FGCoefficient(void)
325 {
326 }
327
328
329 bool FGCoefficient::Allocate(int r, int c)
330 {
331   rows = r;
332   columns = c;
333   Table3D = new float*[r+1];
334   for (int i=0;i<=r;i++) Table3D[i] = new float[c+1];
335   return true;
336 }
337
338
339 bool FGCoefficient::Allocate(int n)
340 {
341   rows = n;
342   columns = 0;
343   Table2D = new float[n+1];
344   return true;
345 }
346
347
348 float FGCoefficient::Value(float rVal, float cVal)
349 {
350   float rFactor, cFactor, col1temp, col2temp, Value;
351   int r, c, midx;
352
353   if (rows < 2 || columns < 2) return 0.0;
354
355   for (r=1;r<=rows;r++) if (Table3D[r][0] >= rVal) break;
356   for (c=1;c<=columns;c++) if (Table3D[0][c] >= cVal) break;
357
358   c = c < 2 ? 2 : (c > columns ? columns : c);
359   r = r < 2 ? 2 : (r > rows    ? rows    : r);
360
361   rFactor = (rVal - Table3D[r-1][0]) / (Table3D[r][0] - Table3D[r-1][0]);
362   cFactor = (cVal - Table3D[0][c-1]) / (Table3D[0][c] - Table3D[0][c-1]);
363
364   col1temp = rFactor*(Table3D[r][c-1] - Table3D[r-1][c-1]) + Table3D[r-1][c-1];
365   col2temp = rFactor*(Table3D[r][c] - Table3D[r-1][c]) + Table3D[r-1][c];
366
367   Value = col1temp + cFactor*(col2temp - col1temp);
368
369   for (midx=0;midx<mult_count;midx++) {
370     Value *= GetCoeffVal(mult_idx[midx]);
371   }
372
373   return Value;
374 }
375
376
377 float FGCoefficient::Value(float Val)
378 {
379   float Factor, Value;
380   int r, midx;
381
382   if (rows < 2) return 0.0;
383   
384   for (r=1;r<=rows;r++) if (Table3D[r][0] >= Val) break;
385   r = r < 2 ? 2 : (r > rows    ? rows    : r);
386
387   // make sure denominator below does not go to zero.
388   if (Table3D[r][0] != Table3D[r-1][0]) {
389     Factor = (Val - Table3D[r-1][0]) / (Table3D[r][0] - Table3D[r-1][0]);
390   } else {
391     Factor = 1.0;
392   }
393   Value = Factor*(Table3D[r][1] - Table3D[r-1][1]) + Table3D[r-1][1];
394
395   for (midx=0;midx<mult_count;midx++) {
396     Value *= GetCoeffVal(mult_idx[midx]);
397   }
398
399   return Value;
400 }
401
402
403 float FGCoefficient::Value()
404 {
405   switch(type) {
406   case 0:
407     return -1;
408   case 1:
409     return (StaticValue);
410   case 2:
411     return (Value(GetCoeffVal(LookupR)));
412   case 3:
413     return (Value(GetCoeffVal(LookupR),GetCoeffVal(LookupC)));
414   case 4:
415     return 0.0;
416   }
417   return 0;
418 }
419
420 float FGCoefficient::GetCoeffVal(int val_idx)
421 {
422   switch(val_idx) {
423   case FG_QBAR:
424     return State->Getqbar();
425   case FG_WINGAREA:
426     return Aircraft->GetWingArea();
427   case FG_WINGSPAN:
428     return Aircraft->GetWingSpan();
429   case FG_CBAR:
430     return Aircraft->Getcbar();
431   case FG_ALPHA:
432     return Translation->Getalpha();
433   case FG_ALPHADOT:
434     return State->Getadot();
435   case FG_BETA:
436     return Translation->Getbeta();
437   case FG_BETADOT:
438     return State->Getbdot();
439   case FG_PITCHRATE:
440     return Rotation->GetQ();
441   case FG_ROLLRATE:
442     return Rotation->GetP();
443   case FG_YAWRATE:
444     return Rotation->GetR();
445   case FG_ELEVATOR:
446     return FCS->GetDe();
447   case FG_AILERON:
448     return FCS->GetDa();
449   case FG_RUDDER:
450     return FCS->GetDr();
451   case FG_MACH:
452     return State->GetMach();
453   case FG_ALTITUDE:
454     return State->Geth();
455   }
456   return 0;
457 }