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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
49 #include "FGCoefficient.h"
51 #include "FGFDMExec.h"
52 #include "FGPropertyManager.h"
55 # if defined(sgi) && !defined(__GNUC__) && (_COMPILER_VERSION < 740)
66 static const char *IdSrc = "$Id$";
67 static const char *IdHdr = ID_COEFFICIENT;
69 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
71 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
73 FGCoefficient::FGCoefficient( FGFDMExec* fdex )
76 State = FDMExec->GetState();
79 PropertyManager = FDMExec->GetPropertyManager();
82 LookupR = LookupC = 0;
84 rows = columns = tables = 0;
103 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
105 FGCoefficient::~FGCoefficient()
107 if (Table) delete Table;
111 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113 bool FGCoefficient::Load(FGConfigFile *AC_cfg)
119 name = AC_cfg->GetValue("NAME");
120 method = AC_cfg->GetValue("TYPE");
121 AC_cfg->GetNextConfigLine();
122 *AC_cfg >> description;
123 if (method == "EQUATION") type = EQUATION;
124 else if (method == "TABLE") type = TABLE;
125 else if (method == "TABLE3D") type = TABLE3D;
126 else if (method == "VECTOR") type = VECTOR;
127 else if (method == "VALUE") type = VALUE;
130 if (type == VECTOR || type == TABLE || type == TABLE3D) {
132 if (type == TABLE3D) {
133 *AC_cfg >> rows >> columns >> tables;
134 Table = new FGTable(rows, columns, tables);
135 *AC_cfg >> multparmsRow >> multparmsCol >> multparmsTable;
136 LookupR = PropertyManager->GetNode( multparmsRow );
137 LookupC = PropertyManager->GetNode( multparmsCol );
138 LookupT = PropertyManager->GetNode( multparmsTable );
139 } else if (type == TABLE) {
140 *AC_cfg >> rows >> columns;
141 Table = new FGTable(rows, columns);
142 *AC_cfg >> multparmsRow >> multparmsCol;
143 LookupR = PropertyManager->GetNode( multparmsRow );
144 LookupC = PropertyManager->GetNode( multparmsCol );
147 Table = new FGTable(rows);
148 *AC_cfg >> multparmsRow;
149 LookupR = PropertyManager->GetNode( multparmsRow );
153 // Here, read in the line of the form:
154 // {property1} | {property2} | {property3}
155 // where each non-dimensionalizing property for this coefficient is
156 // separated by a | character
158 string line=AC_cfg->GetCurrentLine();
161 for(unsigned i=0;i<line.length(); i++ ) {
162 if( !isspace(line[i]) ) {
167 tmp[j]='\0'; multparms=tmp;
168 end = multparms.length();
170 n = multparms.find("|");
172 if (multparms != string("none")) {
173 while (n < end && n >= 0) {
175 mult = multparms.substr(start,n);
176 multipliers.push_back( resolveSymbol( mult ) );
178 n = multparms.find("|",start);
180 mult = multparms.substr(start,n);
181 multipliers.push_back( resolveSymbol( mult ) );
182 // End of non-dimensionalizing parameter read-in
184 AC_cfg->GetNextConfigLine();
187 *AC_cfg >> StaticValue;
188 } else if (type == VECTOR || type == TABLE || type == TABLE3D) {
191 cerr << "Unimplemented coefficient type: " << type << endl;
194 AC_cfg->GetNextConfigLine();
195 FGCoefficient::Debug(2);
205 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
207 double FGCoefficient::Value(double rVal, double cVal, double tVal)
212 SD = Value = gain*Table->GetValue(rVal, cVal, tVal) + bias;
214 for (midx=0; midx < multipliers.size(); midx++) {
215 Value *= multipliers[midx]->getDoubleValue();
220 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222 double FGCoefficient::Value(double rVal, double cVal)
227 SD = Value = gain*Table->GetValue(rVal, cVal) + bias;
229 for (midx=0; midx < multipliers.size(); midx++) {
230 Value *= multipliers[midx]->getDoubleValue();
235 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
237 double FGCoefficient::Value(double Val)
241 SD = Value = gain*Table->GetValue(Val) + bias;
243 for (unsigned int midx=0; midx < multipliers.size(); midx++)
244 Value *= multipliers[midx]->getDoubleValue();
249 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
251 double FGCoefficient::Value(void)
255 SD = Value = gain*StaticValue + bias;
257 for (unsigned int midx=0; midx < multipliers.size(); midx++)
258 Value *= multipliers[midx]->getDoubleValue();
263 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
265 double FGCoefficient::TotalValue(void)
274 totalValue = Value();
278 totalValue = Value( LookupR->getDoubleValue() );
282 totalValue = Value( LookupR->getDoubleValue(),
283 LookupC->getDoubleValue() );
287 totalValue = Value( LookupR->getDoubleValue(),
288 LookupC->getDoubleValue(),
289 LookupT->getDoubleValue() );
299 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
301 void FGCoefficient::DisplayCoeffFactors(void)
305 cout << " Non-Dimensionalized by: ";
307 if (multipliers.size() == 0) {
308 cout << "none" << endl;
310 for (i=0; i<multipliers.size(); i++)
311 cout << multipliers[i]->getName() << " ";
316 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
318 string FGCoefficient::GetSDstring(void)
323 sprintf(buffer,"%9.6f",SD);
324 value = string(buffer);
328 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
330 void FGCoefficient::bind(FGPropertyManager *parent)
335 node = parent->GetNode(name,true);
337 node->SetString("description",description);
338 if (LookupR) node->SetString("row-parm",LookupR->getName() );
339 if (LookupC) node->SetString("column-parm",LookupC->getName() );
342 if (multipliers.size() == 0)
345 for (i=0; i<multipliers.size(); i++) {
346 mult += multipliers[i]->getName();
347 if ( i < multipliers.size()-1 ) mult += " ";
349 node->SetString("multipliers",mult);
351 node->Tie("SD-norm",this,&FGCoefficient::GetSD );
352 node->Tie("value-lbs",this,&FGCoefficient::GetValue );
354 node->Tie("bias", this, &FGCoefficient::getBias,
355 &FGCoefficient::setBias );
357 node->Tie("gain", this, &FGCoefficient::getGain,
358 &FGCoefficient::setGain );
362 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
364 void FGCoefficient::unbind(void)
366 node->Untie("SD-norm");
367 node->Untie("value-lbs");
372 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
374 FGPropertyManager* FGCoefficient::resolveSymbol(string name)
376 FGPropertyManager* tmpn;
378 tmpn = PropertyManager->GetNode(name,false);
380 cerr << "Coefficient multipliers cannot create properties, check spelling?" << endl;
386 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
387 // The bitmasked value choices are as follows:
388 // unset: In this case (the default) JSBSim would only print
389 // out the normally expected messages, essentially echoing
390 // the config files as they are read. If the environment
391 // variable is not set, debug_lvl is set to 1 internally
392 // 0: This requests JSBSim not to output any messages
394 // 1: This value explicity requests the normal JSBSim
396 // 2: This value asks for a message to be printed out when
397 // a class is instantiated
398 // 4: When this value is set, a message is displayed when a
399 // FGModel object executes its Run() method
400 // 8: When this value is set, various runtime state variables
401 // are printed out periodically
402 // 16: When set various parameters are sanity checked and
403 // a message is printed out when they go out of bounds
405 void FGCoefficient::Debug(int from)
407 if (debug_lvl <= 0) return;
409 if (debug_lvl & 1) { // Standard console startup message output
411 if (from == 2) { // Loading
412 cout << "\n " << highint << underon << name << underoff << normint << endl;
413 cout << " " << description << endl;
414 cout << " " << method << endl;
416 if (type == VECTOR || type == TABLE || type == TABLE3D) {
417 cout << " Rows: " << rows << " indexed by: " << LookupR->getName() << endl;
418 if (type == TABLE || type == TABLE3D) {
419 cout << " Cols: " << columns << " indexed by: " << LookupC->getName() << endl;
420 if (type == TABLE3D) {
421 cout << " Tables: " << tables << " indexed by: " << LookupT->getName() << endl;
425 } else if (type == VALUE) {
426 cout << " Value = " << StaticValue << endl;
429 DisplayCoeffFactors();
432 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
433 if (from == 0) cout << "Instantiated: FGCoefficient" << endl;
434 if (from == 1) cout << "Destroyed: FGCoefficient" << endl;
436 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
438 if (debug_lvl & 8 ) { // Runtime state variables
440 if (debug_lvl & 16) { // Sanity checking
442 if (debug_lvl & 64) {
443 if (from == 0) { // Constructor
444 cout << IdSrc << endl;
445 cout << IdHdr << endl;
450 } // namespace JSBSim