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 --------------------------------------------------------------------------------
107 --------------------------------------------------------------------------------
110 ********************************************************************************
112 *******************************************************************************/
118 #include "FGAircraft.h"
119 #include "FGCoefficient.h"
121 /*******************************************************************************
122 ************************************ CODE **************************************
123 *******************************************************************************/
125 FGCoefficient::FGCoefficient(void)
131 FGCoefficient::FGCoefficient(char* fname)
136 ifstream coeffDefFile(fname);
139 if (!coeffDefFile.fail()) {
140 coeffDefFile >> name;
141 coeffDefFile >> description;
142 coeffDefFile >> method;
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;
150 if (type == 2 || type == 3) {
151 coeffDefFile >> rows;
153 coeffDefFile >> columns;
155 coeffDefFile >> LookupR;
159 coeffDefFile >> LookupC;
162 coeffDefFile >> multipliers;
165 if (multipliers & FG_QBAR) {
166 mult_idx[mult_count] = FG_QBAR;
169 if (multipliers & FG_WINGAREA) {
170 mult_idx[mult_count] = FG_WINGAREA;
173 if (multipliers & FG_WINGSPAN) {
174 mult_idx[mult_count] = FG_WINGSPAN;
177 if (multipliers & FG_CBAR) {
178 mult_idx[mult_count] = FG_CBAR;
181 if (multipliers & FG_ALPHA) {
182 mult_idx[mult_count] = FG_ALPHA;
185 if (multipliers & FG_ALPHADOT) {
186 mult_idx[mult_count] = FG_ALPHADOT;
189 if (multipliers & FG_BETA) {
190 mult_idx[mult_count] = FG_BETA;
193 if (multipliers & FG_BETADOT) {
194 mult_idx[mult_count] = FG_BETADOT;
197 if (multipliers & FG_PITCHRATE) {
198 mult_idx[mult_count] = FG_PITCHRATE;
201 if (multipliers & FG_ROLLRATE) {
202 mult_idx[mult_count] = FG_ROLLRATE;
205 if (multipliers & FG_YAWRATE) {
206 mult_idx[mult_count] = FG_YAWRATE;
209 if (multipliers & FG_ELEVATOR) {
210 mult_idx[mult_count] = FG_ELEVATOR;
213 if (multipliers & FG_AILERON) {
214 mult_idx[mult_count] = FG_AILERON;
217 if (multipliers & FG_RUDDER) {
218 mult_idx[mult_count] = FG_RUDDER;
221 if (multipliers & FG_MACH) {
222 mult_idx[mult_count] = FG_MACH;
225 if (multipliers & FG_ALTITUDE) {
226 mult_idx[mult_count] = FG_ALTITUDE;
232 coeffDefFile >> StaticValue;
237 for (r=1;r<=rows;r++) {
238 coeffDefFile >> Table3D[r][0];
239 coeffDefFile >> Table3D[r][1];
243 Allocate(rows, columns);
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];
256 cerr << "Empty file" << endl;
258 coeffDefFile.close();
263 FGCoefficient::FGCoefficient(int r, int c)
271 FGCoefficient::FGCoefficient(int n)
279 FGCoefficient::~FGCoefficient(void)
284 bool FGCoefficient::Allocate(int r, int c)
288 Table3D = new float*[r+1];
289 for (int i=0;i<=r;i++) Table3D[i] = new float[c+1];
294 bool FGCoefficient::Allocate(int n)
298 Table2D = new float[n+1];
303 float FGCoefficient::Value(float rVal, float cVal)
305 float rFactor, cFactor, col1temp, col2temp, Value;
308 if (rows < 2 || columns < 2) return 0.0;
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;
313 c = c < 2 ? 2 : (c > columns ? columns : c);
314 r = r < 2 ? 2 : (r > rows ? rows : r);
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]);
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];
322 Value = col1temp + cFactor*(col2temp - col1temp);
324 for (midx=0;midx<mult_count;midx++) {
325 Value *= GetCoeffVal(mult_idx[midx]);
332 float FGCoefficient::Value(float Val)
337 if (rows < 2) return 0.0;
339 for (r=1;r<=rows;r++) if (Table3D[r][0] >= Val) break;
340 r = r < 2 ? 2 : (r > rows ? rows : r);
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]);
348 Value = Factor*(Table3D[r][1] - Table3D[r-1][1]) + Table3D[r-1][1];
350 for (midx=0;midx<mult_count;midx++) {
351 Value *= GetCoeffVal(mult_idx[midx]);
358 float FGCoefficient::Value()
364 return (StaticValue);
366 return (Value(GetCoeffVal(LookupR)));
368 return (Value(GetCoeffVal(LookupR),GetCoeffVal(LookupC)));
375 float FGCoefficient::GetCoeffVal(int val_idx)
379 return State->Getqbar();
381 return Aircraft->GetWingArea();
383 return Aircraft->GetWingSpan();
385 return Aircraft->Getcbar();
387 return State->Getalpha();
389 return State->Getadot();
391 return State->Getbeta();
393 return State->Getbdot();
395 return State->GetQ();
397 return State->GetP();
399 return State->GetR();
407 return State->GetMach();
409 return State->Geth();