]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/FGTable.h
Mathias Fröhlich:
[flightgear.git] / src / FDM / JSBSim / FGTable.h
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Header:       FGTable.h
4  Author:       Jon S. Berndt
5  Date started: 1/9/2001
6
7  ------------- Copyright (C) 2001  Jon S. Berndt (jsb@hal-pc.org) --------------
8
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17  details.
18
19  You should have received a copy of the GNU General Public License along with
20  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21  Place - Suite 330, Boston, MA  02111-1307, USA.
22
23  Further information about the GNU General Public License can also be found on
24  the world wide web at http://www.gnu.org.
25
26 HISTORY
27 --------------------------------------------------------------------------------
28 JSB  1/9/00          Created
29
30 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31 SENTRY
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
33
34 #ifndef FGTABLE_H
35 #define FGTABLE_H
36
37 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 INCLUDES
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
40
41 #include "FGConfigFile.h"
42 #include "FGJSBBase.h"
43 #include <vector>
44
45 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
46 DEFINITIONS
47 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
48
49 #define ID_TABLE "$Id$"
50
51 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 FORWARD DECLARATIONS
53 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
54
55 using std::vector;
56
57 namespace JSBSim {
58
59 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60 CLASS DOCUMENTATION
61 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
62
63 /** Lookup table class.
64     Models a one, two, or three dimensional lookup table for use in FGCoefficient,
65     FGPropeller, etc.  A one-dimensional table is called a "VECTOR" in a coefficient
66     definition. For example:
67 <pre>
68     \<COEFFICIENT NAME="{short name}" TYPE="VECTOR">
69       {name}
70       {number of rows}
71       {row lookup property}
72       {non-dimensionalizing properties}
73       {row_1_key} {col_1_data}
74       {row_2_key} {...       }
75       { ...     } {...       }
76       {row_n_key} {...       }
77     \</COEFFICIENT>
78 </pre>
79     A "real life" example is as shown here:
80 <pre>
81     \<COEFFICIENT NAME="CLDf" TYPE="VECTOR">
82       Delta_lift_due_to_flap_deflection
83       4
84       fcs/flap-pos-deg
85       aero/qbar-psf | metrics/Sw-sqft
86       0   0
87       10  0.20
88       20  0.30
89       30  0.35
90     \</COEFFICIENT>
91 </pre>
92     The first column in the data table represents the lookup index (or "key").  In
93     this case, the lookup index is fcs/flap-pos-deg (flap extension in degrees).
94     If the flap position is 10 degrees, the value returned from the lookup table
95     would be 0.20.  This value would be multiplied by qbar (aero/qbar-psf) and wing
96     area (metrics/Sw-sqft) to get the total lift force that is a result of flap
97     deflection (measured in pounds force).  If the value of the flap-pos-deg property
98     was 15 (degrees), the value output by the table routine would be 0.25 - an
99     interpolation.  If the flap position in degrees ever went below 0.0, or above
100     30 (degrees), the output from the table routine would be 0 and 0.35, respectively.
101     That is, there is no _extrapolation_ to values outside the range of the lookup
102     index.  This is why it is important to chose the data for the table wisely.
103
104     The definition for a 2D table - referred to simply as a TABLE, is as follows:
105 <pre>
106     \<COEFFICIENT NAME="{short name}" TYPE="TABLE">
107       {name}
108       {number of rows}
109       {number of columns}
110       {row lookup property}
111       {column lookup property}
112       {non-dimensionalizing}
113                   {col_1_key   col_2_key   ...  col_n_key }
114       {row_1_key} {col_1_data  col_2_data  ...  col_n_data}
115       {row_2_key} {...         ...         ...  ...       }
116       { ...     } {...         ...         ...  ...       }
117       {row_n_key} {...         ...         ...  ...       }
118     \</COEFFICIENT>
119 </pre>
120     A "real life" example is as shown here:
121 <pre>
122     \<COEFFICIENT NAME="CYb" TYPE="TABLE">
123       Side_force_due_to_beta
124       3
125       2
126       aero/beta-rad
127       fcs/flap-pos-deg
128       aero/qbar-psf | metrics/Sw-sqft
129                0     30
130       -0.349   0.137  0.106
131        0       0      0
132        0.349  -0.137 -0.106
133     \</COEFFICIENT>
134 </pre>
135     The definition for a 3D table in a coefficient would be (for example):
136 <pre>
137     \<COEFFICIENT NAME="{short name}" TYPE="TABLE3D">
138       {name}
139       {number of rows}
140       {number of columns}
141       {number of tables}
142       {row lookup property}
143       {column lookup property}
144       {table lookup property}
145       {non-dimensionalizing}
146       {first table key}
147                   {col_1_key   col_2_key   ...  col_n_key }
148       {row_1_key} {col_1_data  col_2_data  ...  col_n_data}
149       {row_2_key} {...         ...         ...  ...       }
150       { ...     } {...         ...         ...  ...       }
151       {row_n_key} {...         ...         ...  ...       }
152
153       {second table key}
154                   {col_1_key   col_2_key   ...  col_n_key }
155       {row_1_key} {col_1_data  col_2_data  ...  col_n_data}
156       {row_2_key} {...         ...         ...  ...       }
157       { ...     } {...         ...         ...  ...       }
158       {row_n_key} {...         ...         ...  ...       }
159
160       ...
161
162     \</COEFFICIENT>
163 </pre>
164     [At the present time, all rows and columns for each table must have the
165     same dimension.]
166
167     In addition to using a Table for something like a coefficient, where all the
168     row and column elements are read in from a file, a Table could be created
169     and populated completely within program code:
170 <pre>
171     // First column is thi, second is neta (combustion efficiency)
172     Lookup_Combustion_Efficiency = new FGTable(12);
173     *Lookup_Combustion_Efficiency << 0.00 << 0.980;
174     *Lookup_Combustion_Efficiency << 0.90 << 0.980;
175     *Lookup_Combustion_Efficiency << 1.00 << 0.970;
176     *Lookup_Combustion_Efficiency << 1.05 << 0.950;
177     *Lookup_Combustion_Efficiency << 1.10 << 0.900;
178     *Lookup_Combustion_Efficiency << 1.15 << 0.850;
179     *Lookup_Combustion_Efficiency << 1.20 << 0.790;
180     *Lookup_Combustion_Efficiency << 1.30 << 0.700;
181     *Lookup_Combustion_Efficiency << 1.40 << 0.630;
182     *Lookup_Combustion_Efficiency << 1.50 << 0.570;
183     *Lookup_Combustion_Efficiency << 1.60 << 0.525;
184     *Lookup_Combustion_Efficiency << 2.00 << 0.345;
185 </pre>
186     The first column in the table, above, is thi (the lookup index, or key). The
187     second column is the output data - in this case, "neta" (the Greek letter
188     referring to combustion efficiency). Later on, the table is used like this:
189
190     combustion_efficiency = Lookup_Combustion_Efficiency->GetValue(equivalence_ratio);
191
192     @author Jon S. Berndt
193     @version $Id$
194     @see FGCoefficient
195     @see FGPropeller
196 */
197
198 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
199 CLASS DECLARATION
200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
201
202 class FGTable : public FGJSBBase
203 {
204 public:
205   /// Destructor
206   ~FGTable();
207
208   /** This is the very important copy constructor.
209       @param table a const reference to a table.*/
210   FGTable(const FGTable& table);
211
212   /** The constructor for a VECTOR table
213       @param nRows the number of rows in this VECTOR table. */
214   FGTable(int nRows);
215   FGTable(int nRows, int nCols);
216   FGTable(int nRows, int nCols, int numTables);
217   double GetValue(double key);
218   double GetValue(double rowKey, double colKey);
219   double GetValue(double rowKey, double colKey, double TableKey);
220   /** Read the table in.
221       Data in the config file should be in matrix format with the row
222       independents as the first column and the column independents in
223       the first row.  The implication of this layout is that there should
224       be no value in the upper left corner of the matrix e.g:
225       <pre>
226            0  10  20 30 ...
227       -5   1  2   3  4  ...
228        ...
229        </pre>
230
231        For multiple-table (i.e. 3D) data sets there is an additional number
232        key in the table definition. For example:
233
234       <pre>
235        0.0
236            0  10  20 30 ...
237       -5   1  2   3  4  ...
238        ...
239        </pre>
240        */
241
242   void operator<<(FGConfigFile&);
243   FGTable& operator<<(const double n);
244   FGTable& operator<<(const int n);
245   inline double GetElement(int r, int c) {return Data[r][c];}
246   inline double GetElement(int r, int c, int t);
247   void Print(int spaces=0);
248
249 private:
250   enum type {tt1D, tt2D, tt3D} Type;
251   double** Data;
252   vector <FGTable> Tables;
253   int nRows, nCols, nTables;
254   int colCounter, rowCounter, tableCounter;
255   int lastRowIndex, lastColumnIndex, lastTableIndex;
256   double** Allocate(void);
257   void Debug(int from);
258 };
259 }
260 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261
262 #endif
263