]> git.mxchange.org Git - flightgear.git/blob - JSBsim/FGCoefficient.cpp
da5bfbe33624ba8fb747dd7ffe563827bc0ee60d
[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 ARGUMENTS
103 --------------------------------------------------------------------------------
104
105
106 HISTORY
107 --------------------------------------------------------------------------------
108 12/28/98   JSB   Created
109
110 ********************************************************************************
111 INCLUDES
112 *******************************************************************************/
113
114 class FGCoefficient;
115 #include <stdio.h>
116 #include <stdlib.h>
117 #include "FGFCS.h"
118 #include "FGAircraft.h"
119 #include "FGCoefficient.h"
120
121 /*******************************************************************************
122 ************************************ CODE **************************************
123 *******************************************************************************/
124
125 FGCoefficient::FGCoefficient(void)
126 {
127   rows = columns = 0;
128 }
129
130
131 FGCoefficient::FGCoefficient(char* fname)
132 {
133   int r, c;
134   float ftrashcan;
135
136   ifstream coeffDefFile(fname);
137
138   if (coeffDefFile) {
139     if (!coeffDefFile.fail()) {
140       coeffDefFile >> name;
141       coeffDefFile >> description;
142       coeffDefFile >> method;
143
144       if (strcmp(method,"EQUATION") == 0) type = 4;
145       else if (strcmp(method,"TABLE") == 0) type = 3;
146       else if (strcmp(method,"VECTOR") == 0) type = 2;
147       else if (strcmp(method,"VALUE") == 0) type = 1;
148       else type = 0;
149
150       if (type == 2 || type == 3) {
151         coeffDefFile >> rows;
152         if (type == 3) {
153           coeffDefFile >> columns;
154         }
155         coeffDefFile >> LookupR;
156       }
157
158       if (type == 3) {
159         coeffDefFile >> LookupC;
160       }
161
162       coeffDefFile >> multipliers;
163
164       mult_count = 0;
165       if (multipliers & FG_QBAR) {
166         mult_idx[mult_count] = FG_QBAR;
167         mult_count++;
168       }
169       if (multipliers & FG_WINGAREA) {
170         mult_idx[mult_count] = FG_WINGAREA;
171         mult_count++;
172       }
173       if (multipliers & FG_WINGSPAN) {
174         mult_idx[mult_count] = FG_WINGSPAN;
175         mult_count++;
176       }
177       if (multipliers & FG_CBAR) {
178         mult_idx[mult_count] = FG_CBAR;
179         mult_count++;
180       }
181       if (multipliers & FG_ALPHA) {
182         mult_idx[mult_count] = FG_ALPHA;
183         mult_count++;
184       }
185       if (multipliers & FG_ALPHADOT) {
186         mult_idx[mult_count] = FG_ALPHADOT;
187         mult_count++;
188       }
189       if (multipliers & FG_BETA) {
190         mult_idx[mult_count] = FG_BETA;
191         mult_count++;
192       }
193       if (multipliers & FG_BETADOT) {
194         mult_idx[mult_count] = FG_BETADOT;
195         mult_count++;
196       }
197       if (multipliers & FG_PITCHRATE) {
198         mult_idx[mult_count] = FG_PITCHRATE;
199         mult_count++;
200       }
201       if (multipliers & FG_ROLLRATE) {
202         mult_idx[mult_count] = FG_ROLLRATE;
203         mult_count++;
204       }
205       if (multipliers & FG_YAWRATE) {
206         mult_idx[mult_count] = FG_YAWRATE;
207         mult_count++;
208       }
209       if (multipliers & FG_ELEVATOR) {
210         mult_idx[mult_count] = FG_ELEVATOR;
211         mult_count++;
212       }
213       if (multipliers & FG_AILERON) {
214         mult_idx[mult_count] = FG_AILERON;
215         mult_count++;
216       }
217       if (multipliers & FG_RUDDER) {
218         mult_idx[mult_count] = FG_RUDDER;
219         mult_count++;
220       }
221       if (multipliers & FG_MACH) {
222         mult_idx[mult_count] = FG_MACH;
223         mult_count++;
224       }
225       if (multipliers & FG_ALTITUDE) {
226         mult_idx[mult_count] = FG_ALTITUDE;
227         mult_count++;
228       }
229
230       switch(type) {
231       case 1:
232         coeffDefFile >> StaticValue;
233         break;
234       case 2:
235         Allocate(rows,2);
236
237         for (r=1;r<=rows;r++) {
238           coeffDefFile >> Table3D[r][0];
239           coeffDefFile >> Table3D[r][1];
240         }
241         break;
242       case 3:
243         Allocate(rows, columns);
244
245         for (c=1;c<=columns;c++) {
246           coeffDefFile >> Table3D[0][c];
247           for (r=1;r<=rows;r++) {
248             if ( c==1 ) coeffDefFile >> Table3D[r][0];
249             else coeffDefFile >> ftrashcan;
250             coeffDefFile >> Table3D[r][c];
251           }
252         }
253         break;
254       }
255     } else {
256       cerr << "Empty file" << endl;
257     }
258     coeffDefFile.close();
259   }
260 }
261
262
263 FGCoefficient::FGCoefficient(int r, int c)
264 {
265   rows = r;
266   columns = c;
267   Allocate(r,c);
268 }
269
270
271 FGCoefficient::FGCoefficient(int n)
272 {
273   rows = n;
274   columns = 0;
275   Allocate(n);
276 }
277
278
279 FGCoefficient::~FGCoefficient(void)
280 {
281 }
282
283
284 bool FGCoefficient::Allocate(int r, int c)
285 {
286   rows = r;
287   columns = c;
288   Table3D = new float*[r+1];
289   for (int i=0;i<=r;i++) Table3D[i] = new float[c+1];
290   return true;
291 }
292
293
294 bool FGCoefficient::Allocate(int n)
295 {
296   rows = n;
297   columns = 0;
298   Table2D = new float[n+1];
299   return true;
300 }
301
302
303 float FGCoefficient::Value(float rVal, float cVal)
304 {
305   float rFactor, cFactor, col1temp, col2temp, Value;
306   int r, c, midx;
307
308   if (rows < 2 || columns < 2) return 0.0;
309
310   for (r=1;r<=rows;r++) if (Table3D[r][0] >= rVal) break;
311   for (c=1;c<=columns;c++) if (Table3D[0][c] >= cVal) break;
312
313   c = c < 2 ? 2 : (c > columns ? columns : c);
314   r = r < 2 ? 2 : (r > rows    ? rows    : r);
315
316   rFactor = (rVal - Table3D[r-1][0]) / (Table3D[r][0] - Table3D[r-1][0]);
317   cFactor = (cVal - Table3D[0][c-1]) / (Table3D[0][c] - Table3D[0][c-1]);
318
319   col1temp = rFactor*(Table3D[r][c-1] - Table3D[r-1][c-1]) + Table3D[r-1][c-1];
320   col2temp = rFactor*(Table3D[r][c] - Table3D[r-1][c]) + Table3D[r-1][c];
321
322   Value = col1temp + cFactor*(col2temp - col1temp);
323
324   for (midx=0;midx<mult_count;midx++) {
325     Value *= GetCoeffVal(mult_idx[midx]);
326   }
327
328   return Value;
329 }
330
331
332 float FGCoefficient::Value(float Val)
333 {
334   float Factor, Value;
335   int r, midx;
336
337   if (rows < 2) return 0.0;
338   
339   for (r=1;r<=rows;r++) if (Table3D[r][0] >= Val) break;
340   r = r < 2 ? 2 : (r > rows    ? rows    : r);
341
342   // make sure denominator below does not go to zero.
343   if (Table3D[r][0] != Table3D[r-1][0]) {
344     Factor = (Val - Table3D[r-1][0]) / (Table3D[r][0] - Table3D[r-1][0]);
345   } else {
346     Factor = 1.0;
347   }
348   Value = Factor*(Table3D[r][1] - Table3D[r-1][1]) + Table3D[r-1][1];
349
350   for (midx=0;midx<mult_count;midx++) {
351     Value *= GetCoeffVal(mult_idx[midx]);
352   }
353
354   return Value;
355 }
356
357
358 float FGCoefficient::Value()
359 {
360   switch(type) {
361   case 0:
362     return -1;
363   case 1:
364     return (StaticValue);
365   case 2:
366     return (Value(GetCoeffVal(LookupR)));
367   case 3:
368     return (Value(GetCoeffVal(LookupR),GetCoeffVal(LookupC)));
369   case 4:
370     return 0.0;
371   }
372   return 0;
373 }
374
375 float FGCoefficient::GetCoeffVal(int val_idx)
376 {
377   switch(val_idx) {
378   case FG_QBAR:
379     return State->Getqbar();
380   case FG_WINGAREA:
381     return Aircraft->GetWingArea();
382   case FG_WINGSPAN:
383     return Aircraft->GetWingSpan();
384   case FG_CBAR:
385     return Aircraft->Getcbar();
386   case FG_ALPHA:
387     return State->Getalpha();
388   case FG_ALPHADOT:
389     return State->Getadot();
390   case FG_BETA:
391     return State->Getbeta();
392   case FG_BETADOT:
393     return State->Getbdot();
394   case FG_PITCHRATE:
395     return State->GetQ();
396   case FG_ROLLRATE:
397     return State->GetP();
398   case FG_YAWRATE:
399     return State->GetR();
400   case FG_ELEVATOR:
401     return FCS->GetDe();
402   case FG_AILERON:
403     return FCS->GetDa();
404   case FG_RUDDER:
405     return FCS->GetDr();
406   case FG_MACH:
407     return State->GetMach();
408   case FG_ALTITUDE:
409     return State->Geth();
410   }
411   return 0;
412 }