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 )
72 State = FDMExec->GetState();
75 PropertyManager = FDMExec->GetPropertyManager();
78 LookupR = LookupC = 0;
99 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101 FGCoefficient::~FGCoefficient()
103 if (Table) delete Table;
107 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109 bool FGCoefficient::Load(FGConfigFile *AC_cfg)
115 name = AC_cfg->GetValue("NAME");
116 method = AC_cfg->GetValue("TYPE");
117 AC_cfg->GetNextConfigLine();
118 *AC_cfg >> description;
120 if (method == "EQUATION") type = EQUATION;
121 else if (method == "TABLE") type = TABLE;
122 else if (method == "VECTOR") type = VECTOR;
123 else if (method == "VALUE") type = VALUE;
126 if (type == VECTOR || type == TABLE) {
130 Table = new FGTable(rows, columns);
132 Table = new FGTable(rows);
135 *AC_cfg >> multparmsRow;
136 prop = State->GetPropertyName( multparmsRow );
137 LookupR = PropertyManager->GetNode( prop );
141 *AC_cfg >> multparmsCol;
142 prop = State->GetPropertyName( multparmsCol );
144 LookupC = PropertyManager->GetNode( prop );
147 // Here, read in the line of the form (e.g.) FG_MACH|FG_QBAR|FG_ALPHA
148 // where each non-dimensionalizing parameter for this coefficient is
149 // separated by a | character
151 *AC_cfg >> multparms;
153 end = multparms.length();
154 n = multparms.find("|");
157 if (multparms != string("FG_NONE")) {
158 while (n < end && n >= 0) {
160 mult = multparms.substr(start,n);
161 prop= State->GetPropertyName( mult );
162 multipliers.push_back( PropertyManager->GetNode(prop) );
164 n = multparms.find("|",start);
166 prop=State->GetPropertyName( multparms.substr(start,n) );
167 mult = multparms.substr(start,n);
168 multipliers.push_back( PropertyManager->GetNode(prop) );
169 // End of non-dimensionalizing parameter read-in
173 *AC_cfg >> StaticValue;
174 } else if (type == VECTOR || type == TABLE) {
177 cerr << "Unimplemented coefficient type: " << type << endl;
180 AC_cfg->GetNextConfigLine();
181 FGCoefficient::Debug(2);
191 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
193 double FGCoefficient::Value(double rVal, double cVal)
198 SD = Value = gain*Table->GetValue(rVal, cVal) + bias;
200 for (midx=0; midx < multipliers.size(); midx++) {
201 Value *= multipliers[midx]->getDoubleValue();
206 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
208 double FGCoefficient::Value(double Val)
212 SD = Value = gain*Table->GetValue(Val) + bias;
214 for (unsigned int midx=0; midx < multipliers.size(); midx++)
215 Value *= multipliers[midx]->getDoubleValue();
220 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222 double FGCoefficient::Value(void)
226 SD = Value = gain*StaticValue + bias;
228 for (unsigned int midx=0; midx < multipliers.size(); midx++)
229 Value *= multipliers[midx]->getDoubleValue();
234 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
236 double FGCoefficient::TotalValue(void)
245 totalValue = Value();
249 totalValue = Value( LookupR->getDoubleValue() );
253 totalValue = Value( LookupR->getDoubleValue(),
254 LookupC->getDoubleValue() );
264 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
266 void FGCoefficient::DisplayCoeffFactors(void)
270 cout << " Non-Dimensionalized by: ";
272 if (multipliers.size() == 0) {
273 cout << "none" << endl;
275 for (i=0; i<multipliers.size(); i++)
276 cout << multipliers[i]->getName() << " ";
281 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
283 string FGCoefficient::GetSDstring(void)
288 sprintf(buffer,"%9.6f",SD);
289 value = string(buffer);
293 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
295 void FGCoefficient::bind(FGPropertyManager *parent)
300 node=parent->GetNode(name,true);
302 node->SetString("description",description);
303 if (LookupR) node->SetString("row-parm",LookupR->getName() );
304 if (LookupC) node->SetString("column-parm",LookupC->getName() );
307 if (multipliers.size() == 0)
310 for (i=0; i<multipliers.size(); i++) {
311 mult += multipliers[i]->getName();
312 if ( i < multipliers.size()-1 ) mult += " ";
314 node->SetString("multipliers",mult);
316 node->Tie("SD-norm",this,&FGCoefficient::GetSD );
317 node->Tie("value-lbs",this,&FGCoefficient::GetValue );
319 node->Tie("bias", this, &FGCoefficient::getBias,
320 &FGCoefficient::setBias );
322 node->Tie("gain", this, &FGCoefficient::getGain,
323 &FGCoefficient::setGain );
327 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
329 void FGCoefficient::unbind(void)
331 node->Untie("SD-norm");
332 node->Untie("value-lbs");
337 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
338 // The bitmasked value choices are as follows:
339 // unset: In this case (the default) JSBSim would only print
340 // out the normally expected messages, essentially echoing
341 // the config files as they are read. If the environment
342 // variable is not set, debug_lvl is set to 1 internally
343 // 0: This requests JSBSim not to output any messages
345 // 1: This value explicity requests the normal JSBSim
347 // 2: This value asks for a message to be printed out when
348 // a class is instantiated
349 // 4: When this value is set, a message is displayed when a
350 // FGModel object executes its Run() method
351 // 8: When this value is set, various runtime state variables
352 // are printed out periodically
353 // 16: When set various parameters are sanity checked and
354 // a message is printed out when they go out of bounds
356 void FGCoefficient::Debug(int from)
358 if (debug_lvl <= 0) return;
360 if (debug_lvl & 1) { // Standard console startup message output
362 if (from == 2) { // Loading
363 cout << "\n " << highint << underon << name << underoff << normint << endl;
364 cout << " " << description << endl;
365 cout << " " << method << endl;
367 if (type == VECTOR || type == TABLE) {
368 cout << " Rows: " << rows << " ";
370 cout << "Cols: " << columns;
372 cout << endl << " Row indexing parameter: " << LookupR->getName() << endl;
376 cout << " Column indexing parameter: " << LookupC->getName() << endl;
380 cout << " Value = " << StaticValue << endl;
381 } else if (type == VECTOR || type == TABLE) {
385 DisplayCoeffFactors();
388 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
389 if (from == 0) cout << "Instantiated: FGCoefficient" << endl;
390 if (from == 1) cout << "Destroyed: FGCoefficient" << endl;
392 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
394 if (debug_lvl & 8 ) { // Runtime state variables
396 if (debug_lvl & 16) { // Sanity checking
398 if (debug_lvl & 64) {
399 if (from == 0) { // Constructor
400 cout << IdSrc << endl;
401 cout << IdHdr << endl;