]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/FGCoefficient.cpp
Member variable initialization fixes from Cameron Moore
[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   FDMExec = fdex;
72   State   = FDMExec->GetState();
73   Table   = 0;
74   
75   PropertyManager = FDMExec->GetPropertyManager();
76   
77   Table = (FGTable*)0L;
78   LookupR = LookupC = 0;
79   numInstances = 0;
80   rows = columns = 0;
81
82   StaticValue  = 0.0;
83   totalValue   = 0.0;
84   bias = 0.0;
85   gain = 1.0;
86   SD = 0.0;
87
88   filename.erase();
89   description.erase();
90   name.erase();
91   method.erase();
92   multparms.erase();
93   multparmsRow.erase();
94   multparmsCol.erase();
95
96   Debug(0);
97 }
98
99 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
100
101 FGCoefficient::~FGCoefficient()
102 {
103   if (Table) delete Table;
104   Debug(1);
105 }
106
107 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108
109 bool FGCoefficient::Load(FGConfigFile *AC_cfg)
110 {
111   int start, end, n;
112   string mult,prop;
113
114   if (AC_cfg) {
115     name = AC_cfg->GetValue("NAME");
116     method = AC_cfg->GetValue("TYPE");
117     AC_cfg->GetNextConfigLine();
118     *AC_cfg >> description;
119
120     if      (method == "EQUATION") type = EQUATION;
121     else if (method == "TABLE")    type = TABLE;
122     else if (method == "VECTOR")   type = VECTOR;
123     else if (method == "VALUE")    type = VALUE;
124     else                           type = UNKNOWN;
125
126     if (type == VECTOR || type == TABLE) {
127       *AC_cfg >> rows;
128       if (type == TABLE) {
129         *AC_cfg >> columns;
130         Table = new FGTable(rows, columns);
131       } else {
132         Table = new FGTable(rows);
133       }
134
135       *AC_cfg >> multparmsRow;
136       prop = State->GetPropertyName( multparmsRow );
137       LookupR = PropertyManager->GetNode( prop );
138     }
139
140     if (type == TABLE) {
141       *AC_cfg >> multparmsCol;
142       prop = State->GetPropertyName( multparmsCol );
143
144       LookupC = PropertyManager->GetNode( prop );
145     }
146
147     // Here, read in the line of the form (e.g.) FG_MACH|FG_QBAR|FG_ALPHA
148     // where each non-dimensionalizing parameter for this coefficient is
149     // separated by a | character
150
151     *AC_cfg >> multparms;
152
153     end   = multparms.length();
154     n     = multparms.find("|");
155     start = 0;
156
157     if (multparms != string("FG_NONE")) {
158       while (n < end && n >= 0) {
159         n -= start;
160         mult = multparms.substr(start,n);
161         prop= State->GetPropertyName( mult );
162         multipliers.push_back( PropertyManager->GetNode(prop) );
163         start += n+1;
164         n = multparms.find("|",start);
165       }
166       prop=State->GetPropertyName( multparms.substr(start,n) );
167       mult = multparms.substr(start,n);
168       multipliers.push_back( PropertyManager->GetNode(prop) );
169       // End of non-dimensionalizing parameter read-in
170     }
171
172     if (type == VALUE) {
173       *AC_cfg >> StaticValue;
174     } else if (type == VECTOR || type == TABLE) {
175       *Table << *AC_cfg;
176     } else {
177       cerr << "Unimplemented coefficient type: " << type << endl;
178     }
179
180     AC_cfg->GetNextConfigLine();
181     FGCoefficient::Debug(2);
182
183     return true;
184   } else {
185     return false;
186   }  
187 }
188
189
190
191 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
192
193 double FGCoefficient::Value(double rVal, double cVal)
194 {
195   double Value;
196   unsigned int midx;
197
198   SD = Value = gain*Table->GetValue(rVal, cVal) + bias;
199
200   for (midx=0; midx < multipliers.size(); midx++) {
201       Value *= multipliers[midx]->getDoubleValue();
202   }
203   return Value;
204 }
205
206 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
207
208 double FGCoefficient::Value(double Val)
209 {
210   double Value;
211
212   SD = Value = gain*Table->GetValue(Val) + bias;
213   
214   for (unsigned int midx=0; midx < multipliers.size(); midx++) 
215       Value *= multipliers[midx]->getDoubleValue();
216   
217   return Value;
218 }
219
220 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221
222 double FGCoefficient::Value(void)
223 {
224         double Value;
225
226   SD = Value = gain*StaticValue + bias;
227
228   for (unsigned int midx=0; midx < multipliers.size(); midx++)
229     Value *= multipliers[midx]->getDoubleValue();
230
231   return Value;
232 }
233
234 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235
236 double FGCoefficient::TotalValue(void)
237 {
238   switch(type) {
239
240   case UNKNOWN:
241     totalValue = -1;
242     break;
243
244   case VALUE:
245     totalValue = Value();
246     break;
247
248   case VECTOR:
249     totalValue = Value( LookupR->getDoubleValue() );
250     break;
251
252   case TABLE:
253     totalValue = Value( LookupR->getDoubleValue(),
254                       LookupC->getDoubleValue() );
255     break;
256
257   case EQUATION:
258     totalValue = 0.0;
259     break;
260   }
261   return totalValue;
262 }
263
264 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
265
266 void FGCoefficient::DisplayCoeffFactors(void)
267 {
268   unsigned int i;
269
270   cout << "   Non-Dimensionalized by: ";
271
272   if (multipliers.size() == 0) {
273     cout << "none" << endl;
274   } else {
275     for (i=0; i<multipliers.size(); i++) 
276       cout << multipliers[i]->getName() << "  ";
277   }
278   cout << endl;
279 }
280
281 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
282
283 string FGCoefficient::GetSDstring(void)
284 {
285   char buffer[10];
286   string value;
287
288   sprintf(buffer,"%9.6f",SD);
289   value = string(buffer);
290   return value;
291 }
292
293 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
294
295 void FGCoefficient::bind(FGPropertyManager *parent)
296 {
297   string mult;
298   unsigned i;
299   
300   node=parent->GetNode(name,true);
301   
302   node->SetString("description",description);
303   if (LookupR) node->SetString("row-parm",LookupR->getName() );
304   if (LookupC) node->SetString("column-parm",LookupC->getName() );
305   
306   mult="";
307   if (multipliers.size() == 0) 
308     mult="none";
309     
310   for (i=0; i<multipliers.size(); i++) {
311       mult += multipliers[i]->getName();
312       if ( i < multipliers.size()-1 ) mult += " "; 
313   }
314   node->SetString("multipliers",mult);
315   
316   node->Tie("SD-norm",this,&FGCoefficient::GetSD );
317   node->Tie("value-lbs",this,&FGCoefficient::GetValue );
318   
319   node->Tie("bias", this, &FGCoefficient::getBias,
320                           &FGCoefficient::setBias );
321                           
322   node->Tie("gain", this, &FGCoefficient::getGain,
323                           &FGCoefficient::setGain );
324
325 }
326
327 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
328
329 void FGCoefficient::unbind(void)
330 {
331   node->Untie("SD-norm");
332   node->Untie("value-lbs"); 
333   node->Untie("bias");  
334   node->Untie("gain");
335 }
336   
337 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
338 //    The bitmasked value choices are as follows:
339 //    unset: In this case (the default) JSBSim would only print
340 //       out the normally expected messages, essentially echoing
341 //       the config files as they are read. If the environment
342 //       variable is not set, debug_lvl is set to 1 internally
343 //    0: This requests JSBSim not to output any messages
344 //       whatsoever.
345 //    1: This value explicity requests the normal JSBSim
346 //       startup messages
347 //    2: This value asks for a message to be printed out when
348 //       a class is instantiated
349 //    4: When this value is set, a message is displayed when a
350 //       FGModel object executes its Run() method
351 //    8: When this value is set, various runtime state variables
352 //       are printed out periodically
353 //    16: When set various parameters are sanity checked and
354 //       a message is printed out when they go out of bounds
355
356 void FGCoefficient::Debug(int from)
357 {
358   if (debug_lvl <= 0) return;
359
360   if (debug_lvl & 1) { // Standard console startup message output
361     
362     if (from == 2) { // Loading
363       cout << "\n   " << highint << underon << name << underoff << normint << endl;
364       cout << "   " << description << endl;
365       cout << "   " << method << endl;
366
367       if (type == VECTOR || type == TABLE) {
368         cout << "   Rows: " << rows << " ";
369         if (type == TABLE) {
370           cout << "Cols: " << columns;
371         }
372         cout << endl << "   Row indexing parameter: " << LookupR->getName() << endl;
373       }
374
375       if (type == TABLE) {
376         cout << "   Column indexing parameter: " << LookupC->getName() << endl;
377       }
378
379       if (type == VALUE) {
380         cout << "      Value = " << StaticValue << endl;
381       } else if (type == VECTOR || type == TABLE) {
382         Table->Print();
383       }
384
385       DisplayCoeffFactors();
386     }
387   }
388   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
389     if (from == 0) cout << "Instantiated: FGCoefficient" << endl;
390     if (from == 1) cout << "Destroyed:    FGCoefficient" << endl;
391   }
392   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
393   }
394   if (debug_lvl & 8 ) { // Runtime state variables
395   }
396   if (debug_lvl & 16) { // Sanity checking
397   }
398   if (debug_lvl & 64) {
399     if (from == 0) { // Constructor
400       cout << IdSrc << endl;
401       cout << IdHdr << endl;
402     }
403   }
404 }
405