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