1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 Module: FGCoefficient.cpp
6 Purpose: Encapsulates the stability derivative class FGCoefficient;
9 ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
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
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
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.
25 Further information about the GNU General Public License can also be found on
26 the world wide web at http://www.gnu.org.
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.
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.
37 See the header file FGCoefficient.h for the values of the identifiers.
40 --------------------------------------------------------------------------------
43 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
45 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
47 #include "FGCoefficient.h"
49 #include "FGFDMExec.h"
50 #include "FGPropertyManager.h"
53 # if defined(sgi) && !defined(__GNUC__)
62 static const char *IdSrc = "$Id$";
63 static const char *IdHdr = ID_COEFFICIENT;
65 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
67 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
69 FGCoefficient::FGCoefficient( FGFDMExec* fdex )
73 State = FDMExec->GetState();
76 PropertyManager = FDMExec->GetPropertyManager();
81 LookupR = LookupC = 0;
85 if (debug_lvl & 2) cout << "Instantiated: FGCoefficient" << endl;
88 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
90 FGCoefficient::~FGCoefficient()
92 if (Table) delete Table;
93 if (debug_lvl & 2) cout << "Destroyed: FGCoefficient" << endl;
96 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
98 bool FGCoefficient::Load(FGConfigFile *AC_cfg)
104 name = AC_cfg->GetValue("NAME");
105 method = AC_cfg->GetValue("TYPE");
106 AC_cfg->GetNextConfigLine();
107 *AC_cfg >> description;
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;
115 if (type == VECTOR || type == TABLE) {
119 Table = new FGTable(rows, columns);
121 Table = new FGTable(rows);
124 *AC_cfg >> multparmsRow;
125 prop = State->GetPropertyName( multparmsRow );
126 LookupR = PropertyManager->GetNode( prop );
130 *AC_cfg >> multparmsCol;
131 prop = State->GetPropertyName( multparmsCol );
133 LookupC = PropertyManager->GetNode( prop );
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
140 *AC_cfg >> multparms;
142 end = multparms.length();
143 n = multparms.find("|");
146 if (multparms != string("FG_NONE")) {
147 while (n < end && n >= 0) {
149 mult = multparms.substr(start,n);
150 prop= State->GetPropertyName( mult );
151 multipliers.push_back( PropertyManager->GetNode(prop) );
153 n = multparms.find("|",start);
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
162 *AC_cfg >> StaticValue;
163 } else if (type == VECTOR || type == TABLE) {
166 cerr << "Unimplemented coefficient type: " << type << endl;
169 AC_cfg->GetNextConfigLine();
170 FGCoefficient::Debug(2);
180 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182 double FGCoefficient::Value(double rVal, double cVal)
187 SD = Value = gain*Table->GetValue(rVal, cVal) + bias;
190 for (midx=0; midx < multipliers.size(); midx++) {
191 Value *= multipliers[midx]->getDoubleValue();
196 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
198 double FGCoefficient::Value(double Val)
202 SD = Value = gain*Table->GetValue(Val) + bias;
204 for (unsigned int midx=0; midx < multipliers.size(); midx++)
205 Value *= multipliers[midx]->getDoubleValue();
210 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
212 double FGCoefficient::Value(void)
216 SD = Value = gain*StaticValue + bias;
218 for (unsigned int midx=0; midx < multipliers.size(); midx++)
219 Value *= multipliers[midx]->getDoubleValue();
224 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
226 double FGCoefficient::TotalValue(void)
236 totalValue=Value( LookupR->getDoubleValue() );
239 totalValue=Value( LookupR->getDoubleValue(),
240 LookupC->getDoubleValue() );
249 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
251 void FGCoefficient::DumpSD(void)
253 cout << " " << name << ": " << SD << endl;
256 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
258 void FGCoefficient::DisplayCoeffFactors(void)
262 cout << " Non-Dimensionalized by: ";
264 if (multipliers.size() == 0) {
265 cout << "none" << endl;
267 for (i=0; i<multipliers.size(); i++)
268 cout << multipliers[i]->getName() << " ";
273 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
275 string FGCoefficient::GetCoefficientValues(void)
280 sprintf(buffer,"%9.6f",SD);
281 value = string(buffer);
285 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
287 void FGCoefficient::bind(FGPropertyManager *parent) {
291 node=parent->GetNode(name,true);
293 node->SetString("description",description);
294 if(LookupR) node->SetString("row-parm",LookupR->getName() );
295 if(LookupC) node->SetString("column-parm",LookupC->getName() );
298 if(multipliers.size() == 0)
301 for (i=0; i<multipliers.size(); i++) {
302 mult += multipliers[i]->getName();
303 if( i < multipliers.size()-1 ) mult += " ";
305 node->SetString("multipliers",mult);
307 node->Tie("SD-norm",this,&FGCoefficient::GetSD );
308 node->Tie("value-lbs",this,&FGCoefficient::GetValue );
310 node->Tie("bias", this, &FGCoefficient::getBias,
311 &FGCoefficient::setBias );
313 node->Tie("gain", this, &FGCoefficient::getGain,
314 &FGCoefficient::setGain );
318 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
320 void FGCoefficient::unbind(void) {
321 node->Untie("SD-norm");
322 node->Untie("value-lbs");
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
334 // 1: This value explicity requests the normal JSBSim
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
345 void FGCoefficient::Debug(int from)
347 if (debug_lvl <= 0) return;
349 if (debug_lvl & 1) { // Standard console startup message output
351 if (from == 2) { // Loading
352 cout << "\n " << highint << underon << name << underoff << normint << endl;
353 cout << " " << description << endl;
354 cout << " " << method << endl;
356 if (type == VECTOR || type == TABLE) {
357 cout << " Rows: " << rows << " ";
359 cout << "Cols: " << columns;
361 cout << endl << " Row indexing parameter: " << LookupR->getName() << endl;
365 cout << " Column indexing parameter: " << LookupC->getName() << endl;
369 cout << " Value = " << StaticValue << endl;
370 } else if (type == VECTOR || type == TABLE) {
374 DisplayCoeffFactors();
377 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
378 if (from == 0) cout << "Instantiated: FGCoefficient" << endl;
379 if (from == 1) cout << "Destroyed: FGCoefficient" << endl;
381 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
383 if (debug_lvl & 8 ) { // Runtime state variables
385 if (debug_lvl & 16) { // Sanity checking
387 if (debug_lvl & 64) {
388 if (from == 0) { // Constructor
389 cout << IdSrc << endl;
390 cout << IdHdr << endl;