]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/FGCoefficient.cpp
Added flap_deflection so that remote fdm can pass back actual flap deflection
[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
200   for (midx=0; midx < multipliers.size(); midx++) {
201       Value *= multipliers[midx]->getDoubleValue();
202   }
203   return Value;
204 }
205
206 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
207
208 double FGCoefficient::Value(double Val)
209 {
210   double Value;
211
212   SD = Value = gain*Table->GetValue(Val) + bias;
213   
214   for (unsigned int midx=0; midx < multipliers.size(); midx++) 
215       Value *= multipliers[midx]->getDoubleValue();
216   
217   return Value;
218 }
219
220 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221
222 double FGCoefficient::Value(void)
223 {
224         double Value;
225
226   SD = Value = gain*StaticValue + bias;
227
228   for (unsigned int midx=0; midx < multipliers.size(); midx++)
229     Value *= multipliers[midx]->getDoubleValue();
230
231   return Value;
232 }
233
234 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235
236 double FGCoefficient::TotalValue(void)
237 {
238   switch(type) {
239   case 0:
240     totalValue=-1;
241     return totalValue;
242   case 1:
243     totalValue=Value();
244     return totalValue;
245   case 2:
246     totalValue=Value( LookupR->getDoubleValue() );
247     return totalValue;
248   case 3:
249     totalValue=Value( LookupR->getDoubleValue(),
250                         LookupC->getDoubleValue() );
251     return totalValue;
252   case 4:
253     totalValue=0.0;
254     return totalValue;
255   }
256   return totalValue;
257 }
258
259 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
260
261 void FGCoefficient::DumpSD(void)
262 {
263   cout << "   " << name << ": " << SD << endl;
264 }
265
266 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
267
268 void FGCoefficient::DisplayCoeffFactors(void)
269 {
270   unsigned int i;
271
272   cout << "   Non-Dimensionalized by: ";
273
274   if (multipliers.size() == 0) {
275     cout << "none" << endl;
276   } else {
277     for (i=0; i<multipliers.size(); i++) 
278       cout << multipliers[i]->getName() << "  ";
279   }
280   cout << endl;
281 }
282
283 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284
285 string FGCoefficient::GetCoefficientValues(void)
286 {
287   char buffer[10];
288   string value;
289
290   sprintf(buffer,"%9.6f",SD);
291   value = string(buffer);
292   return value;
293 }
294
295 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
296
297 void FGCoefficient::bind(FGPropertyManager *parent)
298 {
299   string mult;
300   unsigned i;
301   
302   node=parent->GetNode(name,true);
303   
304   node->SetString("description",description);
305   if (LookupR) node->SetString("row-parm",LookupR->getName() );
306   if (LookupC) node->SetString("column-parm",LookupC->getName() );
307   
308   mult="";
309   if (multipliers.size() == 0) 
310     mult="none";
311     
312   for (i=0; i<multipliers.size(); i++) {
313       mult += multipliers[i]->getName();
314       if ( i < multipliers.size()-1 ) mult += " "; 
315   }
316   node->SetString("multipliers",mult);
317   
318   node->Tie("SD-norm",this,&FGCoefficient::GetSD );
319   node->Tie("value-lbs",this,&FGCoefficient::GetValue );
320   
321   node->Tie("bias", this, &FGCoefficient::getBias,
322                           &FGCoefficient::setBias );
323                           
324   node->Tie("gain", this, &FGCoefficient::getGain,
325                           &FGCoefficient::setGain );
326
327 }
328
329 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
330
331 void FGCoefficient::unbind(void)
332 {
333   node->Untie("SD-norm");
334   node->Untie("value-lbs"); 
335   node->Untie("bias");  
336   node->Untie("gain");
337 }
338   
339 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
340 //    The bitmasked value choices are as follows:
341 //    unset: In this case (the default) JSBSim would only print
342 //       out the normally expected messages, essentially echoing
343 //       the config files as they are read. If the environment
344 //       variable is not set, debug_lvl is set to 1 internally
345 //    0: This requests JSBSim not to output any messages
346 //       whatsoever.
347 //    1: This value explicity requests the normal JSBSim
348 //       startup messages
349 //    2: This value asks for a message to be printed out when
350 //       a class is instantiated
351 //    4: When this value is set, a message is displayed when a
352 //       FGModel object executes its Run() method
353 //    8: When this value is set, various runtime state variables
354 //       are printed out periodically
355 //    16: When set various parameters are sanity checked and
356 //       a message is printed out when they go out of bounds
357
358 void FGCoefficient::Debug(int from)
359 {
360   if (debug_lvl <= 0) return;
361
362   if (debug_lvl & 1) { // Standard console startup message output
363     
364     if (from == 2) { // Loading
365       cout << "\n   " << highint << underon << name << underoff << normint << endl;
366       cout << "   " << description << endl;
367       cout << "   " << method << endl;
368
369       if (type == VECTOR || type == TABLE) {
370         cout << "   Rows: " << rows << " ";
371         if (type == TABLE) {
372           cout << "Cols: " << columns;
373         }
374         cout << endl << "   Row indexing parameter: " << LookupR->getName() << endl;
375       }
376
377       if (type == TABLE) {
378         cout << "   Column indexing parameter: " << LookupC->getName() << endl;
379       }
380
381       if (type == VALUE) {
382         cout << "      Value = " << StaticValue << endl;
383       } else if (type == VECTOR || type == TABLE) {
384         Table->Print();
385       }
386
387       DisplayCoeffFactors();
388     }
389   }
390   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
391     if (from == 0) cout << "Instantiated: FGCoefficient" << endl;
392     if (from == 1) cout << "Destroyed:    FGCoefficient" << endl;
393   }
394   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
395   }
396   if (debug_lvl & 8 ) { // Runtime state variables
397   }
398   if (debug_lvl & 16) { // Sanity checking
399   }
400   if (debug_lvl & 64) {
401     if (from == 0) { // Constructor
402       cout << IdSrc << endl;
403       cout << IdHdr << endl;
404     }
405   }
406 }
407