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 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.
37 See the header file FGCoefficient.h for the values of the identifiers.
40 --------------------------------------------------------------------------------
43 ********************************************************************************
45 *******************************************************************************/
47 #include "FGCoefficient.h"
48 #include "FGAtmosphere.h"
50 #include "FGFDMExec.h"
52 #include "FGAircraft.h"
53 #include "FGTranslation.h"
54 #include "FGRotation.h"
55 #include "FGPosition.h"
56 #include "FGAuxiliary.h"
59 /*******************************************************************************
60 ************************************ CODE **************************************
61 *******************************************************************************/
63 FGCoefficient::FGCoefficient(FGFDMExec* fdex, ifstream& coeffDefFile)
65 int r, c, start, end, n;
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;
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();
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;
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;
115 if (type == VECTOR || type == TABLE) {
116 coeffDefFile >> rows;
117 cout << " Rows: " << rows << " ";
119 coeffDefFile >> columns;
120 cout << "Cols: " << columns;
125 coeffDefFile >> strashcan;
126 if (strashcan.substr(0,1) == "F") {
127 LookupR = coeffdef[strashcan.c_str()];
128 cout << " Row indexing parameter: " << strashcan << endl;
130 LookupR = atoi(strashcan.c_str());
131 cout << " Row indexing parameter: " << LookupR << endl;
137 coeffDefFile >> strashcan;
138 if (strashcan.substr(0,1) == "F") {
139 LookupC = coeffdef[strashcan.c_str()];
140 cout << " Column indexing parameter: " << strashcan << endl;
142 LookupC = atoi(strashcan.c_str());
143 cout << " Column indexing parameter: " << LookupC << endl;
147 coeffDefFile >> strashcan;
149 end = strashcan.length();
150 n = strashcan.find("|");
153 if (strashcan.substr(0,1) == "F") {
154 while(n < end && n >= 0) {
156 multipliers += coeffdef[strashcan.substr(start,n).c_str()];
158 n = strashcan.find("|",start);
160 multipliers += coeffdef[strashcan.substr(start,end).c_str()];
162 multipliers = atoi(strashcan.c_str());
165 cout << " Non-Dimensionalized by: ";
168 if (multipliers & FG_QBAR) {
169 mult_idx[mult_count] = FG_QBAR;
173 if (multipliers & FG_WINGAREA) {
174 mult_idx[mult_count] = FG_WINGAREA;
178 if (multipliers & FG_WINGSPAN) {
179 mult_idx[mult_count] = FG_WINGSPAN;
183 if (multipliers & FG_CBAR) {
184 mult_idx[mult_count] = FG_CBAR;
188 if (multipliers & FG_ALPHA) {
189 mult_idx[mult_count] = FG_ALPHA;
193 if (multipliers & FG_ALPHADOT) {
194 mult_idx[mult_count] = FG_ALPHADOT;
198 if (multipliers & FG_BETA) {
199 mult_idx[mult_count] = FG_BETA;
203 if (multipliers & FG_BETADOT) {
204 mult_idx[mult_count] = FG_BETADOT;
208 if (multipliers & FG_PITCHRATE) {
209 mult_idx[mult_count] = FG_PITCHRATE;
213 if (multipliers & FG_ROLLRATE) {
214 mult_idx[mult_count] = FG_ROLLRATE;
218 if (multipliers & FG_YAWRATE) {
219 mult_idx[mult_count] = FG_YAWRATE;
223 if (multipliers & FG_ELEVATOR) {
224 mult_idx[mult_count] = FG_ELEVATOR;
228 if (multipliers & FG_AILERON) {
229 mult_idx[mult_count] = FG_AILERON;
233 if (multipliers & FG_RUDDER) {
234 mult_idx[mult_count] = FG_RUDDER;
238 if (multipliers & FG_MACH) {
239 mult_idx[mult_count] = FG_MACH;
243 if (multipliers & FG_ALTITUDE) {
244 mult_idx[mult_count] = FG_ALTITUDE;
248 if (multipliers & FG_BI2VEL) {
249 mult_idx[mult_count] = FG_BI2VEL;
251 cout << "b /(2*Vt) ";
253 if (multipliers & FG_CI2VEL) {
254 mult_idx[mult_count] = FG_CI2VEL;
256 cout << "c /(2*Vt) ";
262 coeffDefFile >> StaticValue;
263 cout << " Value = " << StaticValue << endl;
268 for (r=1;r<=rows;r++) {
269 coeffDefFile >> Table3D[r][0];
270 coeffDefFile >> Table3D[r][1];
273 for (r=0;r<=rows;r++) {
275 for (c=0;c<=columns;c++) {
276 cout << Table3D[r][c] << " ";
283 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 for (midx=0;midx<mult_count;midx++) {
358 Value *= GetCoeffVal(mult_idx[midx]);
365 float FGCoefficient::Value(float Val)
370 if (rows < 2) return 0.0;
372 for (r=1;r<=rows;r++) if (Table3D[r][0] >= Val) break;
373 r = r < 2 ? 2 : (r > rows ? rows : r);
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]);
382 Value = Factor*(Table3D[r][1] - Table3D[r-1][1]) + Table3D[r-1][1];
384 for (midx=0;midx<mult_count;midx++) {
385 Value *= GetCoeffVal(mult_idx[midx]);
392 float FGCoefficient::Value(void)
399 for (midx=0;midx<mult_count;midx++) {
400 Value *= GetCoeffVal(mult_idx[midx]);
406 float FGCoefficient::TotalValue()
414 return (Value(GetCoeffVal(LookupR)));
416 return (Value(GetCoeffVal(LookupR),GetCoeffVal(LookupC)));
423 float FGCoefficient::GetCoeffVal(int val_idx)
427 return State->Getqbar();
429 return Aircraft->GetWingArea();
431 return Aircraft->GetWingSpan();
433 return Aircraft->Getcbar();
435 return Translation->Getalpha();
437 return State->Getadot();
439 return Translation->Getbeta();
441 return State->Getbdot();
443 return Rotation->GetQ();
445 return Rotation->GetP();
447 return Rotation->GetR();
455 return State->GetMach();
457 return State->Geth();
459 return Aircraft->GetWingSpan()/(2.0 * State->GetVt());
461 return Aircraft->Getcbar()/(2.0 * State->GetVt());