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, ifstream& coeffDefFile)
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();
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;
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;
159 if (type == VECTOR || type == TABLE) {
160 coeffDefFile >> rows;
161 cout << " Rows: " << rows << " ";
163 coeffDefFile >> columns;
164 cout << "Cols: " << columns;
166 coeffDefFile >> LookupR;
168 cout << " Row indexing parameter: " << LookupR << endl;
172 coeffDefFile >> LookupC;
173 cout << " Column indexing parameter: " << LookupC << endl;
176 coeffDefFile >> multipliers;
177 cout << " Non-Dimensionalized by: ";
180 if (multipliers & FG_QBAR) {
181 mult_idx[mult_count] = FG_QBAR;
185 if (multipliers & FG_WINGAREA) {
186 mult_idx[mult_count] = FG_WINGAREA;
190 if (multipliers & FG_WINGSPAN) {
191 mult_idx[mult_count] = FG_WINGSPAN;
195 if (multipliers & FG_CBAR) {
196 mult_idx[mult_count] = FG_CBAR;
200 if (multipliers & FG_ALPHA) {
201 mult_idx[mult_count] = FG_ALPHA;
205 if (multipliers & FG_ALPHADOT) {
206 mult_idx[mult_count] = FG_ALPHADOT;
210 if (multipliers & FG_BETA) {
211 mult_idx[mult_count] = FG_BETA;
215 if (multipliers & FG_BETADOT) {
216 mult_idx[mult_count] = FG_BETADOT;
220 if (multipliers & FG_PITCHRATE) {
221 mult_idx[mult_count] = FG_PITCHRATE;
225 if (multipliers & FG_ROLLRATE) {
226 mult_idx[mult_count] = FG_ROLLRATE;
230 if (multipliers & FG_YAWRATE) {
231 mult_idx[mult_count] = FG_YAWRATE;
235 if (multipliers & FG_ELEVATOR) {
236 mult_idx[mult_count] = FG_ELEVATOR;
240 if (multipliers & FG_AILERON) {
241 mult_idx[mult_count] = FG_AILERON;
245 if (multipliers & FG_RUDDER) {
246 mult_idx[mult_count] = FG_RUDDER;
250 if (multipliers & FG_MACH) {
251 mult_idx[mult_count] = FG_MACH;
255 if (multipliers & FG_ALTITUDE) {
256 mult_idx[mult_count] = FG_ALTITUDE;
264 coeffDefFile >> StaticValue;
269 for (r=1;r<=rows;r++) {
270 coeffDefFile >> Table3D[r][0];
271 coeffDefFile >> Table3D[r][1];
274 for (r=0;r<=rows;r++) {
276 for (c=0;c<=columns;c++) {
277 cout << Table3D[r][c] << " ";
284 Allocate(rows, columns);
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];
295 for (r=0;r<=rows;r++) {
297 for (c=0;c<=columns;c++) {
298 cout << Table3D[r][c] << " ";
306 cerr << "Empty file" << endl;
312 FGCoefficient::~FGCoefficient(void)
317 bool FGCoefficient::Allocate(int r, int c)
321 Table3D = new float*[r+1];
322 for (int i=0;i<=r;i++) Table3D[i] = new float[c+1];
327 bool FGCoefficient::Allocate(int n)
331 Table2D = new float[n+1];
336 float FGCoefficient::Value(float rVal, float cVal)
338 float rFactor, cFactor, col1temp, col2temp, Value;
341 if (rows < 2 || columns < 2) return 0.0;
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;
346 c = c < 2 ? 2 : (c > columns ? columns : c);
347 r = r < 2 ? 2 : (r > rows ? rows : r);
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]);
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];
355 Value = col1temp + cFactor*(col2temp - col1temp);
357 //cout << "Value for " << description << " is " << Value;
359 for (midx=0;midx<mult_count;midx++) {
360 Value *= GetCoeffVal(mult_idx[midx]);
363 //cout << " after multipliers it is: " << Value << endl;
369 float FGCoefficient::Value(float Val)
374 if (rows < 2) return 0.0;
376 for (r=1;r<=rows;r++) if (Table3D[r][0] >= Val) break;
377 r = r < 2 ? 2 : (r > rows ? rows : r);
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]);
386 Value = Factor*(Table3D[r][1] - Table3D[r-1][1]) + Table3D[r-1][1];
388 // cout << "Value for " << description << " is " << Value;
390 for (midx=0;midx<mult_count;midx++) {
391 Value *= GetCoeffVal(mult_idx[midx]);
394 //cout << " after multipliers it is: " << Value << endl;
400 float FGCoefficient::Value(void)
407 // cout << "Value for " << description << " is " << Value << endl;
409 for (midx=0;midx<mult_count;midx++) {
410 Value *= GetCoeffVal(mult_idx[midx]);
413 // cout << " after multipliers it is: " << Value << endl;
418 float FGCoefficient::TotalValue()
426 return (Value(GetCoeffVal(LookupR)));
428 return (Value(GetCoeffVal(LookupR),GetCoeffVal(LookupC)));
435 float FGCoefficient::GetCoeffVal(int val_idx)
439 //cout << "Qbar: " << State->Getqbar() << endl;
440 return State->Getqbar();
442 //cout << "S: " << Aircraft->GetWingArea() << endl;
443 return Aircraft->GetWingArea();
445 //cout << "b: " << Aircraft->GetWingSpan() << endl;
446 return Aircraft->GetWingSpan();
448 //cout << "Cbar: " << Aircraft->Getcbar() << endl;
449 return Aircraft->Getcbar();
451 //cout << "Alpha: " << Translation->Getalpha() << endl;
452 return Translation->Getalpha();
454 //cout << "Adot: " << State->Getadot() << endl;
455 return State->Getadot();
457 //cout << "Beta: " << Translation->Getbeta() << endl;
458 return Translation->Getbeta();
460 //cout << "Bdot: " << State->Getbdot() << endl;
461 return State->Getbdot();
463 //cout << "Q: " << Rotation->GetQ() << endl;
464 return Rotation->GetQ();
466 //cout << "P: " << Rotation->GetP() << endl;
467 return Rotation->GetP();
469 //cout << "R: " << Rotation->GetR() << endl;
470 return Rotation->GetR();
472 //cout << "De: " << FCS->GetDe() << endl;
475 //cout << "Da: " << FCS->GetDa() << endl;
478 //cout << "Dr: " << FCS->GetDr() << endl;
481 //cout << "Mach: " << State->GetMach() << endl;
482 return State->GetMach();
484 //cout << "h: " << State->Geth() << endl;
485 return State->Geth();