1 /*******************************************************************************
3 Module: FGCoefficient.cpp
6 Purpose: Encapsulates the stability derivative class FGCoefficient;
9 ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
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
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
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.
25 Further information about the GNU General Public License can also be found on
26 the world wide web at http://www.gnu.org.
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.
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:
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)>
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>
55 <... repeat above for each column of data in table ...>
57 As an example for the X-15, for the lift due to mach:
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.
100 See the header file FGCoefficient.h for the values of the identifiers.
103 --------------------------------------------------------------------------------
106 ********************************************************************************
108 *******************************************************************************/
110 #include "FGCoefficient.h"
111 #include "FGAtmosphere.h"
113 #include "FGFDMExec.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"
122 /*******************************************************************************
123 ************************************ CODE **************************************
124 *******************************************************************************/
126 FGCoefficient::FGCoefficient(FGFDMExec* 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();
143 FGCoefficient::FGCoefficient(FGFDMExec* fdex, string fname)
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();
159 ifstream coeffDefFile(fname.c_str());
162 if (!coeffDefFile.fail()) {
163 coeffDefFile >> name;
164 coeffDefFile >> description;
165 coeffDefFile >> method;
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;
173 if (type == 2 || type == 3) {
174 coeffDefFile >> rows;
176 coeffDefFile >> columns;
178 coeffDefFile >> LookupR;
182 coeffDefFile >> LookupC;
185 coeffDefFile >> multipliers;
188 if (multipliers & FG_QBAR) {
189 mult_idx[mult_count] = FG_QBAR;
192 if (multipliers & FG_WINGAREA) {
193 mult_idx[mult_count] = FG_WINGAREA;
196 if (multipliers & FG_WINGSPAN) {
197 mult_idx[mult_count] = FG_WINGSPAN;
200 if (multipliers & FG_CBAR) {
201 mult_idx[mult_count] = FG_CBAR;
204 if (multipliers & FG_ALPHA) {
205 mult_idx[mult_count] = FG_ALPHA;
208 if (multipliers & FG_ALPHADOT) {
209 mult_idx[mult_count] = FG_ALPHADOT;
212 if (multipliers & FG_BETA) {
213 mult_idx[mult_count] = FG_BETA;
216 if (multipliers & FG_BETADOT) {
217 mult_idx[mult_count] = FG_BETADOT;
220 if (multipliers & FG_PITCHRATE) {
221 mult_idx[mult_count] = FG_PITCHRATE;
224 if (multipliers & FG_ROLLRATE) {
225 mult_idx[mult_count] = FG_ROLLRATE;
228 if (multipliers & FG_YAWRATE) {
229 mult_idx[mult_count] = FG_YAWRATE;
232 if (multipliers & FG_ELEVATOR) {
233 mult_idx[mult_count] = FG_ELEVATOR;
236 if (multipliers & FG_AILERON) {
237 mult_idx[mult_count] = FG_AILERON;
240 if (multipliers & FG_RUDDER) {
241 mult_idx[mult_count] = FG_RUDDER;
244 if (multipliers & FG_MACH) {
245 mult_idx[mult_count] = FG_MACH;
248 if (multipliers & FG_ALTITUDE) {
249 mult_idx[mult_count] = FG_ALTITUDE;
255 coeffDefFile >> StaticValue;
260 for (r=1;r<=rows;r++) {
261 coeffDefFile >> Table3D[r][0];
262 coeffDefFile >> Table3D[r][1];
266 Allocate(rows, columns);
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];
279 cerr << "Empty file" << endl;
281 coeffDefFile.close();
286 FGCoefficient::FGCoefficient(FGFDMExec* fdex, int r, int c)
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();
305 FGCoefficient::FGCoefficient(FGFDMExec* fdex, int n)
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();
324 FGCoefficient::~FGCoefficient(void)
329 bool FGCoefficient::Allocate(int r, int c)
333 Table3D = new float*[r+1];
334 for (int i=0;i<=r;i++) Table3D[i] = new float[c+1];
339 bool FGCoefficient::Allocate(int n)
343 Table2D = new float[n+1];
348 float FGCoefficient::Value(float rVal, float cVal)
350 float rFactor, cFactor, col1temp, col2temp, Value;
353 if (rows < 2 || columns < 2) return 0.0;
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;
358 c = c < 2 ? 2 : (c > columns ? columns : c);
359 r = r < 2 ? 2 : (r > rows ? rows : r);
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]);
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];
367 Value = col1temp + cFactor*(col2temp - col1temp);
369 for (midx=0;midx<mult_count;midx++) {
370 Value *= GetCoeffVal(mult_idx[midx]);
377 float FGCoefficient::Value(float Val)
382 if (rows < 2) return 0.0;
384 for (r=1;r<=rows;r++) if (Table3D[r][0] >= Val) break;
385 r = r < 2 ? 2 : (r > rows ? rows : r);
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]);
393 Value = Factor*(Table3D[r][1] - Table3D[r-1][1]) + Table3D[r-1][1];
395 for (midx=0;midx<mult_count;midx++) {
396 Value *= GetCoeffVal(mult_idx[midx]);
403 float FGCoefficient::Value()
409 return (StaticValue);
411 return (Value(GetCoeffVal(LookupR)));
413 return (Value(GetCoeffVal(LookupR),GetCoeffVal(LookupC)));
420 float FGCoefficient::GetCoeffVal(int val_idx)
424 return State->Getqbar();
426 return Aircraft->GetWingArea();
428 return Aircraft->GetWingSpan();
430 return Aircraft->Getcbar();
432 return Translation->Getalpha();
434 return State->Getadot();
436 return Translation->Getbeta();
438 return State->Getbdot();
440 return Rotation->GetQ();
442 return Rotation->GetP();
444 return Rotation->GetR();
452 return State->GetMach();
454 return State->Geth();