]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/FGCoefficient.cpp
First commit of properties code. JSBSim now has a basic property tree all
[flightgear.git] / src / FDM / JSBSim / FGCoefficient.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Module:       FGCoefficient.cpp
4  Author:       Jon S. Berndt
5  Date started: 12/28/98
6  Purpose:      Encapsulates the stability derivative class FGCoefficient;
7  Called by:    FGAircraft
8
9  ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
10
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
14  version.
15
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
19  details.
20
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.
24
25  Further information about the GNU General Public License can also be found on
26  the world wide web at http://www.gnu.org.
27
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.
32
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.
36
37 See the header file FGCoefficient.h for the values of the identifiers.
38
39 HISTORY
40 --------------------------------------------------------------------------------
41 12/28/98   JSB   Created
42
43 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
44 INCLUDES
45 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
46
47 #include "FGCoefficient.h"
48 #include "FGState.h"
49 #include "FGFDMExec.h"
50 #include "FGPropertyManager.h"
51
52 #ifndef FGFS
53 #  if defined(sgi) && !defined(__GNUC__)
54 #    include <iomanip.h>
55 #  else
56 #    include <iomanip>
57 #  endif
58 #else
59 #  include STL_IOMANIP
60 #endif
61
62 static const char *IdSrc = "$Id$";
63 static const char *IdHdr = ID_COEFFICIENT;
64
65 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66 CLASS IMPLEMENTATION
67 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
68
69 FGCoefficient::FGCoefficient( FGFDMExec* fdex )
70 {
71
72   FDMExec = fdex;
73   State   = FDMExec->GetState();
74   Table   = 0;
75   
76   PropertyManager = FDMExec->GetPropertyManager();
77   
78   bias=0;
79   gain=1;
80   
81   LookupR = LookupC = 0;
82   
83   totalValue = 0;
84
85   if (debug_lvl & 2) cout << "Instantiated: FGCoefficient" << endl;
86 }
87
88 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
89
90 FGCoefficient::~FGCoefficient()
91 {
92   if (Table) delete Table;
93   if (debug_lvl & 2) cout << "Destroyed:    FGCoefficient" << endl;
94 }
95
96 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
97
98 bool FGCoefficient::Load(FGConfigFile *AC_cfg)
99 {
100   int start, end, n;
101   string mult,prop;
102
103   if (AC_cfg) {
104     name = AC_cfg->GetValue("NAME");
105     method = AC_cfg->GetValue("TYPE");
106     AC_cfg->GetNextConfigLine();
107     *AC_cfg >> description;
108
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;
113     else                           type = UNKNOWN;
114
115     if (type == VECTOR || type == TABLE) {
116       *AC_cfg >> rows;
117       if (type == TABLE) {
118         *AC_cfg >> columns;
119         Table = new FGTable(rows, columns);
120       } else {
121         Table = new FGTable(rows);
122       }
123
124       *AC_cfg >> multparmsRow;
125       prop = State->GetPropertyName( State->GetParameterIndex(multparmsRow) );
126       LookupR = PropertyManager->GetNode( prop );
127     }
128
129     if (type == TABLE) {
130       *AC_cfg >> multparmsCol;
131       prop = State->GetPropertyName( State->GetParameterIndex(multparmsCol) );
132
133       LookupC = PropertyManager->GetNode( prop );
134     }
135
136     // Here, read in the line of the form (e.g.) FG_MACH|FG_QBAR|FG_ALPHA
137     // where each non-dimensionalizing parameter for this coefficient is
138     // separated by a | character
139
140     *AC_cfg >> multparms;
141
142     end   = multparms.length();
143     n     = multparms.find("|");
144     start = 0;
145
146     if (multparms != string("FG_NONE")) {
147       while (n < end && n >= 0) {
148         n -= start;
149         mult = multparms.substr(start,n);
150         prop= State->GetPropertyName( State->GetParameterIndex(mult) );
151         multipliers.push_back( PropertyManager->GetNode(prop) );
152         start += n+1;
153         n = multparms.find("|",start);
154       }
155       prop=State->GetPropertyName( 
156             State->GetParameterIndex( multparms.substr(start,n) ) );
157       mult = multparms.substr(start,n);
158       multipliers.push_back( PropertyManager->GetNode(prop) );
159       // End of non-dimensionalizing parameter read-in
160     }
161
162     if (type == VALUE) {
163       *AC_cfg >> StaticValue;
164     } else if (type == VECTOR || type == TABLE) {
165       *Table << *AC_cfg;
166     } else {
167       cerr << "Unimplemented coefficient type: " << type << endl;
168     }
169
170     AC_cfg->GetNextConfigLine();
171     FGCoefficient::Debug(2);
172
173     return true;
174   } else {
175     return false;
176   }  
177 }
178
179
180
181 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182
183 double FGCoefficient::Value(double rVal, double cVal)
184 {
185   double Value;
186   unsigned int midx;
187
188   SD = Value = gain*Table->GetValue(rVal, cVal) + bias;
189   
190
191   for (midx=0; midx < multipliers.size(); midx++) {
192       Value *= multipliers[midx]->getDoubleValue();
193   }
194   return Value;
195 }
196
197 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
198
199 double FGCoefficient::Value(double Val)
200 {
201   double Value;
202
203   SD = Value = gain*Table->GetValue(Val) + bias;
204   
205   for (unsigned int midx=0; midx < multipliers.size(); midx++) 
206       Value *= multipliers[midx]->getDoubleValue();
207   
208   return Value;
209 }
210
211 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
212
213 double FGCoefficient::Value(void)
214 {
215         double Value;
216
217   SD = Value = gain*StaticValue + bias;
218
219   for (unsigned int midx=0; midx < multipliers.size(); midx++)
220     Value *= multipliers[midx]->getDoubleValue();
221
222   return Value;
223 }
224
225 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
226
227 double FGCoefficient::TotalValue(void)
228 {
229   switch(type) {
230   case 0:
231     totalValue=-1;
232     return totalValue;
233   case 1:
234     totalValue=Value();
235     return totalValue;
236   case 2:
237     totalValue=Value( LookupR->getDoubleValue() );
238     return totalValue;
239   case 3:
240     totalValue=Value( LookupR->getDoubleValue(),
241                         LookupC->getDoubleValue() );
242     return totalValue;
243   case 4:
244     totalValue=0.0;
245     return totalValue;
246   }
247   return totalValue;
248 }
249
250 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
251
252 void FGCoefficient::DumpSD(void)
253 {
254   cout << "   " << name << ": " << SD << endl;
255 }
256
257 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
258
259 void FGCoefficient::DisplayCoeffFactors(void)
260 {
261   unsigned int i;
262
263   cout << "   Non-Dimensionalized by: ";
264
265   if (multipliers.size() == 0) {
266     cout << "none" << endl;
267   } else {
268     for (i=0; i<multipliers.size(); i++) 
269       cout << multipliers[i]->getName() << "  ";
270   }
271   cout << endl;
272 }
273
274 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
275
276 string FGCoefficient::GetCoefficientValues(void)
277 {
278   char buffer[10];
279   string value;
280
281   sprintf(buffer,"%9.6f",SD);
282   value = string(buffer);
283   return value;
284 }
285
286 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
287
288 void FGCoefficient::bind(FGPropertyManager *node) {
289   string mult;
290   unsigned i;
291   
292   FGCoefficient::node=node;
293   
294   node->SetString("description",description);
295   if(LookupR) node->SetString("row-parm",LookupR->getName() );
296   if(LookupC) node->SetString("column-parm",LookupC->getName() );
297   
298   mult="";
299   for (i=0; i<multipliers.size(); i++) {
300       mult += multipliers[i]->getName();
301       if( i < multipliers.size()-1 ) mult += "|"; 
302   }
303   node->SetString("multipliers",mult);
304   
305   node->Tie("SD-norm",this,&FGCoefficient::GetSD );
306   node->Tie("value-lbs",this,&FGCoefficient::GetValue );
307   
308   node->Tie("bias", this, &FGCoefficient::getBias,
309                           &FGCoefficient::setBias );
310                           
311   node->Tie("gain", this, &FGCoefficient::getGain,
312                           &FGCoefficient::setGain );
313
314 }
315
316 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
317
318 void FGCoefficient::unbind(void) {
319   node->Untie("SD-norm");
320   node->Untie("value-lbs"); 
321   node->Untie("bias");  
322   node->Untie("gain");
323 }  
324 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
325 //    The bitmasked value choices are as follows:
326 //    unset: In this case (the default) JSBSim would only print
327 //       out the normally expected messages, essentially echoing
328 //       the config files as they are read. If the environment
329 //       variable is not set, debug_lvl is set to 1 internally
330 //    0: This requests JSBSim not to output any messages
331 //       whatsoever.
332 //    1: This value explicity requests the normal JSBSim
333 //       startup messages
334 //    2: This value asks for a message to be printed out when
335 //       a class is instantiated
336 //    4: When this value is set, a message is displayed when a
337 //       FGModel object executes its Run() method
338 //    8: When this value is set, various runtime state variables
339 //       are printed out periodically
340 //    16: When set various parameters are sanity checked and
341 //       a message is printed out when they go out of bounds
342
343 void FGCoefficient::Debug(int from)
344 {
345   if (debug_lvl <= 0) return;
346
347   if (debug_lvl & 1) { // Standard console startup message output
348     
349     if (from == 2) { // Loading
350       cout << "\n   " << highint << underon << name << underoff << normint << endl;
351       cout << "   " << description << endl;
352       cout << "   " << method << endl;
353
354       if (type == VECTOR || type == TABLE) {
355         cout << "   Rows: " << rows << " ";
356         if (type == TABLE) {
357           cout << "Cols: " << columns;
358         }
359         cout << endl << "   Row indexing parameter: " << LookupR->getName() << endl;
360       }
361
362       if (type == TABLE) {
363         cout << "   Column indexing parameter: " << LookupC->getName() << endl;
364       }
365
366       if (type == VALUE) {
367         cout << "      Value = " << StaticValue << endl;
368       } else if (type == VECTOR || type == TABLE) {
369         Table->Print();
370       }
371
372       DisplayCoeffFactors();
373     }
374   }
375   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
376     if (from == 0) cout << "Instantiated: FGCoefficient" << endl;
377     if (from == 1) cout << "Destroyed:    FGCoefficient" << endl;
378   }
379   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
380   }
381   if (debug_lvl & 8 ) { // Runtime state variables
382   }
383   if (debug_lvl & 16) { // Sanity checking
384   }
385   if (debug_lvl & 64) {
386     if (from == 0) { // Constructor
387       cout << IdSrc << endl;
388       cout << IdHdr << endl;
389     }
390   }
391 }
392