]> 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     if (n == string::npos) n = end;
172     start = 0;
173     if (multparms != string("none")) {
174       while (n < end && n != string::npos) {
175         n -= start;
176         mult = multparms.substr(start,n);
177         multipliers.push_back( resolveSymbol( mult ) );
178         start += n+1;
179         n = multparms.find("|",start);
180       }
181       mult = multparms.substr(start,n);
182       multipliers.push_back( resolveSymbol( mult ) );
183       // End of non-dimensionalizing parameter read-in
184     }
185     AC_cfg->GetNextConfigLine();
186
187     if (type == VALUE) {
188       *AC_cfg >> StaticValue;
189     } else if (type == VECTOR || type == TABLE || type == TABLE3D) {
190       *Table << *AC_cfg;
191     } else {
192       cerr << "Unimplemented coefficient type: " << type << endl;
193     }
194
195     AC_cfg->GetNextConfigLine();
196     FGCoefficient::Debug(2);
197
198     return true;
199   } else {
200     return false;
201   }
202 }
203
204
205
206 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
207
208 double FGCoefficient::Value(double rVal, double cVal, double tVal)
209 {
210   double Value;
211   unsigned int midx;
212
213   SD = Value = gain*Table->GetValue(rVal, cVal, tVal) + bias;
214
215   for (midx=0; midx < multipliers.size(); midx++) {
216       Value *= multipliers[midx]->getDoubleValue();
217   }
218   return Value;
219 }
220
221 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222
223 double FGCoefficient::Value(double rVal, double cVal)
224 {
225   double Value;
226   unsigned int midx;
227
228   SD = Value = gain*Table->GetValue(rVal, cVal) + bias;
229
230   for (midx=0; midx < multipliers.size(); midx++) {
231       Value *= multipliers[midx]->getDoubleValue();
232   }
233   return Value;
234 }
235
236 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
237
238 double FGCoefficient::Value(double Val)
239 {
240   double Value;
241
242   SD = Value = gain*Table->GetValue(Val) + bias;
243
244   for (unsigned int midx=0; midx < multipliers.size(); midx++)
245       Value *= multipliers[midx]->getDoubleValue();
246
247   return Value;
248 }
249
250 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
251
252 double FGCoefficient::Value(void)
253 {
254   double Value;
255
256   SD = Value = gain*StaticValue + bias;
257
258   for (unsigned int midx=0; midx < multipliers.size(); midx++)
259     Value *= multipliers[midx]->getDoubleValue();
260
261   return Value;
262 }
263
264 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
265
266 double FGCoefficient::TotalValue(void)
267 {
268   switch(type) {
269
270   case UNKNOWN:
271     totalValue = -1;
272     break;
273
274   case VALUE:
275     totalValue = Value();
276     break;
277
278   case VECTOR:
279     totalValue = Value( LookupR->getDoubleValue() );
280     break;
281
282   case TABLE:
283     totalValue = Value( LookupR->getDoubleValue(),
284                         LookupC->getDoubleValue() );
285     break;
286
287   case TABLE3D:
288     totalValue = Value( LookupR->getDoubleValue(),
289                         LookupC->getDoubleValue(),
290                         LookupT->getDoubleValue() );
291     break;
292
293   case EQUATION:
294     totalValue = 0.0;
295     break;
296   }
297   return totalValue;
298 }
299
300 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
301
302 void FGCoefficient::DisplayCoeffFactors(void)
303 {
304   unsigned int i;
305
306   cout << "   Non-Dimensionalized by: ";
307
308   if (multipliers.size() == 0) {
309     cout << "none" << endl;
310   } else {
311     for (i=0; i<multipliers.size(); i++)
312       cout << multipliers[i]->getName() << "  ";
313   }
314   cout << endl;
315 }
316
317 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
318
319 string FGCoefficient::GetSDstring(void)
320 {
321   char buffer[20];
322   string value;
323
324   sprintf(buffer,"%9.6f",SD);
325   value = string(buffer);
326   return value;
327 }
328
329 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
330
331 void FGCoefficient::bind(FGPropertyManager *parent)
332 {
333   string mult;
334   unsigned i;
335
336   node = parent->GetNode(name,true);
337
338   node->SetString("description",description);
339   if (LookupR) node->SetString("row-parm",LookupR->getName() );
340   if (LookupC) node->SetString("column-parm",LookupC->getName() );
341
342   mult="";
343   if (multipliers.size() == 0)
344     mult="none";
345
346   for (i=0; i<multipliers.size(); i++) {
347       mult += multipliers[i]->getName();
348       if ( i < multipliers.size()-1 ) mult += " ";
349   }
350   node->SetString("multipliers",mult);
351
352   node->Tie("SD-norm",this,&FGCoefficient::GetSD );
353   node->Tie("value-lbs",this,&FGCoefficient::GetValue );
354
355   node->Tie("bias", this, &FGCoefficient::getBias,
356                           &FGCoefficient::setBias );
357
358   node->Tie("gain", this, &FGCoefficient::getGain,
359                           &FGCoefficient::setGain );
360
361 }
362
363 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
364
365 void FGCoefficient::unbind(void)
366 {
367   node->Untie("SD-norm");
368   node->Untie("value-lbs");
369   node->Untie("bias");
370   node->Untie("gain");
371 }
372
373 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
374
375 FGPropertyManager* FGCoefficient::resolveSymbol(string name)
376 {
377   FGPropertyManager* tmpn;
378
379   tmpn = PropertyManager->GetNode(name,false);
380   if ( !tmpn ) {
381     cerr << "Coefficient multipliers cannot create properties, check spelling?" << endl;
382     exit(1);
383   }
384   return tmpn;
385 }
386
387 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
388 //    The bitmasked value choices are as follows:
389 //    unset: In this case (the default) JSBSim would only print
390 //       out the normally expected messages, essentially echoing
391 //       the config files as they are read. If the environment
392 //       variable is not set, debug_lvl is set to 1 internally
393 //    0: This requests JSBSim not to output any messages
394 //       whatsoever.
395 //    1: This value explicity requests the normal JSBSim
396 //       startup messages
397 //    2: This value asks for a message to be printed out when
398 //       a class is instantiated
399 //    4: When this value is set, a message is displayed when a
400 //       FGModel object executes its Run() method
401 //    8: When this value is set, various runtime state variables
402 //       are printed out periodically
403 //    16: When set various parameters are sanity checked and
404 //       a message is printed out when they go out of bounds
405
406 void FGCoefficient::Debug(int from)
407 {
408   if (debug_lvl <= 0) return;
409
410   if (debug_lvl & 1) { // Standard console startup message output
411
412     if (from == 2) { // Loading
413       cout << "\n   " << highint << underon << name << underoff << normint << endl;
414       cout << "   " << description << endl;
415       cout << "   " << method << endl;
416
417       if (type == VECTOR || type == TABLE || type == TABLE3D) {
418         cout << "   Rows: " << rows << " indexed by: " << LookupR->getName() << endl;
419         if (type == TABLE || type == TABLE3D) {
420           cout << "   Cols: " << columns << " indexed by: " << LookupC->getName() << endl;
421           if (type == TABLE3D) {
422             cout << "   Tables: " << tables << " indexed by: " << LookupT->getName() << endl;
423           }
424         }
425         Table->Print();
426       } else if (type == VALUE) {
427         cout << "      Value = " << StaticValue << endl;
428       }
429
430       DisplayCoeffFactors();
431     }
432   }
433   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
434     if (from == 0) cout << "Instantiated: FGCoefficient" << endl;
435     if (from == 1) cout << "Destroyed:    FGCoefficient" << endl;
436   }
437   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
438   }
439   if (debug_lvl & 8 ) { // Runtime state variables
440   }
441   if (debug_lvl & 16) { // Sanity checking
442   }
443   if (debug_lvl & 64) {
444     if (from == 0) { // Constructor
445       cout << IdSrc << endl;
446       cout << IdHdr << endl;
447     }
448   }
449 }
450
451 } // namespace JSBSim