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