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