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