]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/math/FGTable.h
PAtch by Andreas Gaeb to eliminate NaN's in the location code
[flightgear.git] / src / FDM / JSBSim / math / 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 (jon@jsbsim.org) --------------
8
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser 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 Lesser General Public License for more
17  details.
18
19  You should have received a copy of the GNU Lesser 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 Lesser 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 "FGParameter.h"
42 #include <iosfwd>
43 #include <vector>
44 #include <string>
45
46 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47 DEFINITIONS
48 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
49
50 #define ID_TABLE "$Id: FGTable.h,v 1.12 2010/09/16 11:01:24 jberndt Exp $"
51
52 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53 FORWARD DECLARATIONS
54 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
55
56 namespace JSBSim {
57
58 class FGPropertyManager;
59 class Element;
60
61 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62 CLASS DOCUMENTATION
63 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
64
65 /** Lookup table class.
66 Models a one, two, or three dimensional lookup table for use in aerodynamics
67 and function definitions.
68
69 For a single "vector" lookup table, the format is as follows:
70
71 @code
72 <table name="property_name">
73   <independentVar lookup="row"> property_name </independentVar>
74   <tableData>
75     key_1 value_1
76     key_2 value_2
77     ...  ...
78     key_n value_n
79   </tableData>
80 </table>
81 @endcode
82
83 The lookup="row" attribute in the independentVar element is option in this case;
84 it is assumed that the independentVar is a row variable.
85
86 A "real life" example is as shown here:
87
88 @code
89 <table>
90   <independentVar lookup="row"> aero/alpha-rad </independentVar>
91   <tableData>
92    -1.57  1.500
93    -0.26  0.033
94     0.00  0.025
95     0.26  0.033
96     1.57  1.500
97   </tableData>
98 </table>
99 @endcode
100
101 The first column in the data table represents the lookup index (or "key").  In
102 this case, the lookup index is aero/alpha-rad (angle of attack in radians).
103 If alpha is 0.26 radians, the value returned from the lookup table
104 would be 0.033.
105
106 The definition for a 2D table, is as follows:
107
108 @code
109 <table name="property_name">
110   <independentVar lookup="row"> property_name </independentVar>
111   <independentVar lookup="column"> property_name </independentVar>
112   <tableData>
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   </tableData>
119 </table>
120 @endcode
121
122 The data is in a gridded format.
123
124 A "real life" example is as shown below. Alpha in radians is the row lookup (alpha
125 breakpoints are arranged in the first column) and flap position in degrees is
126
127 @code
128 <table>
129   <independentVar lookup="row">aero/alpha-rad</independentVar>
130   <independentVar lookup="column">fcs/flap-pos-deg</independentVar>
131   <tableData>
132                 0.0         10.0        20.0         30.0
133     -0.0523599  8.96747e-05 0.00231942  0.0059252    0.00835082
134     -0.0349066  0.000313268 0.00567451  0.0108461    0.0140545
135     -0.0174533  0.00201318  0.0105059   0.0172432    0.0212346
136      0.0        0.0051894   0.0168137   0.0251167    0.0298909
137      0.0174533  0.00993967  0.0247521   0.0346492    0.0402205
138      0.0349066  0.0162201   0.0342207   0.0457119    0.0520802
139      0.0523599  0.0240308   0.0452195   0.0583047    0.0654701
140      0.0698132  0.0333717   0.0577485   0.0724278    0.0803902
141      0.0872664  0.0442427   0.0718077   0.088081     0.0968405
142   </tableData>
143 </table>
144 @endcode
145
146 The definition for a 3D table in a coefficient would be (for example):
147
148 @code
149 <table name="property_name">
150   <independentVar lookup="row"> property_name </independentVar>
151   <independentVar lookup="column"> property_name </independentVar>
152   <tableData breakpoint="table_1_key">
153                 {col_1_key   col_2_key   ...  col_n_key }
154     {row_1_key} {col_1_data  col_2_data  ...  col_n_data}
155     {row_2_key} {...         ...         ...  ...       }
156     { ...     } {...         ...         ...  ...       }
157     {row_n_key} {...         ...         ...  ...       }
158   </tableData>
159   <tableData breakpoint="table_2_key">
160                 {col_1_key   col_2_key   ...  col_n_key }
161     {row_1_key} {col_1_data  col_2_data  ...  col_n_data}
162     {row_2_key} {...         ...         ...  ...       }
163     { ...     } {...         ...         ...  ...       }
164     {row_n_key} {...         ...         ...  ...       }
165   </tableData>
166   ...
167   <tableData breakpoint="table_n_key">
168                 {col_1_key   col_2_key   ...  col_n_key }
169     {row_1_key} {col_1_data  col_2_data  ...  col_n_data}
170     {row_2_key} {...         ...         ...  ...       }
171     { ...     } {...         ...         ...  ...       }
172     {row_n_key} {...         ...         ...  ...       }
173   </tableData>
174 </table>
175 @endcode
176
177 [Note the "breakpoint" attribute in the tableData element, above.]
178
179 Here's an example:
180
181 @code
182 <table>
183   <independentVar lookup="row">fcs/row-value</independentVar>
184   <independentVar lookup="column">fcs/column-value</independentVar>
185   <independentVar lookup="table">fcs/table-value</independentVar>
186   <tableData breakPoint="-1.0">
187            -1.0     1.0
188     0.0     1.0000  2.0000
189     1.0     3.0000  4.0000
190   </tableData>
191   <tableData breakPoint="0.0000">
192             0.0     10.0
193     2.0     1.0000  2.0000
194     3.0     3.0000  4.0000
195   </tableData>
196   <tableData breakPoint="1.0">
197            0.0     10.0     20.0
198      2.0   1.0000   2.0000   3.0000
199      3.0   4.0000   5.0000   6.0000
200     10.0   7.0000   8.0000   9.0000
201   </tableData>
202 </table>
203 @endcode
204
205 In addition to using a Table for something like a coefficient, where all the
206 row and column elements are read in from a file, a Table could be created
207 and populated completely within program code:
208
209 @code
210 // First column is thi, second is neta (combustion efficiency)
211 Lookup_Combustion_Efficiency = new FGTable(12);
212
213 *Lookup_Combustion_Efficiency << 0.00 << 0.980;
214 *Lookup_Combustion_Efficiency << 0.90 << 0.980;
215 *Lookup_Combustion_Efficiency << 1.00 << 0.970;
216 *Lookup_Combustion_Efficiency << 1.05 << 0.950;
217 *Lookup_Combustion_Efficiency << 1.10 << 0.900;
218 *Lookup_Combustion_Efficiency << 1.15 << 0.850;
219 *Lookup_Combustion_Efficiency << 1.20 << 0.790;
220 *Lookup_Combustion_Efficiency << 1.30 << 0.700;
221 *Lookup_Combustion_Efficiency << 1.40 << 0.630;
222 *Lookup_Combustion_Efficiency << 1.50 << 0.570;
223 *Lookup_Combustion_Efficiency << 1.60 << 0.525;
224 *Lookup_Combustion_Efficiency << 2.00 << 0.345;
225 @endcode
226
227 The first column in the table, above, is thi (the lookup index, or key). The
228 second column is the output data - in this case, "neta" (the Greek letter
229 referring to combustion efficiency). Later on, the table is used like this:
230
231 @code
232 combustion_efficiency = Lookup_Combustion_Efficiency->GetValue(equivalence_ratio);
233 @endcode
234
235 @author Jon S. Berndt
236 @version $Id: FGTable.h,v 1.12 2010/09/16 11:01:24 jberndt Exp $
237 */
238
239 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
240 CLASS DECLARATION
241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
242
243 class FGTable : public FGParameter
244 {
245 public:
246   /// Destructor
247   ~FGTable();
248
249   /** This is the very important copy constructor.
250       @param table a const reference to a table.*/
251   FGTable(const FGTable& table);
252
253   /// The constructor for a table
254   FGTable (FGPropertyManager* propMan, Element* el);
255   FGTable (int );
256   FGTable (int, int);
257   double GetValue(void) const;
258   double GetValue(double key) const;
259   double GetValue(double rowKey, double colKey) const;
260   double GetValue(double rowKey, double colKey, double TableKey) const;
261   /** Read the table in.
262       Data in the config file should be in matrix format with the row
263       independents as the first column and the column independents in
264       the first row.  The implication of this layout is that there should
265       be no value in the upper left corner of the matrix e.g:
266       <pre>
267            0  10  20 30 ...
268       -5   1  2   3  4  ...
269        ...
270        </pre>
271
272        For multiple-table (i.e. 3D) data sets there is an additional number
273        key in the table definition. For example:
274
275       <pre>
276        0.0
277            0  10  20 30 ...
278       -5   1  2   3  4  ...
279        ...
280        </pre>
281        */
282
283   void operator<<(std::istream&);
284   FGTable& operator<<(const double n);
285   FGTable& operator<<(const int n);
286
287   inline double GetElement(int r, int c) {return Data[r][c];}
288   inline double GetElement(int r, int c, int t);
289
290   void SetRowIndexProperty(FGPropertyManager *node) {lookupProperty[eRow] = node;}
291   void SetColumnIndexProperty(FGPropertyManager *node) {lookupProperty[eColumn] = node;}
292
293   void Print(void);
294
295 private:
296   enum type {tt1D, tt2D, tt3D} Type;
297   enum axis {eRow=0, eColumn, eTable};
298   bool internal;
299   FGPropertyManager *lookupProperty[3];
300   double** Data;
301   std::vector <FGTable*> Tables;
302   unsigned int nRows, nCols, nTables, dimension;
303   int colCounter, rowCounter, tableCounter;
304   mutable int lastRowIndex, lastColumnIndex, lastTableIndex;
305   double** Allocate(void);
306   FGPropertyManager* const PropertyManager;
307   std::string Name;
308   void bind(void);
309
310   unsigned int FindNumColumns(const std::string&);
311   void Debug(int from);
312 };
313 }
314 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
315
316 #endif
317