INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#include <stdio.h>
+
#include "FGCoefficient.h"
#include "FGState.h"
#include "FGFDMExec.h"
+#include "FGPropertyManager.h"
#ifndef FGFS
-# include <iomanip>
+# if defined(sgi) && !defined(__GNUC__) && (_COMPILER_VERSION < 740)
+# include <iomanip.h>
+# else
+# include <iomanip>
+# endif
#else
# include STL_IOMANIP
#endif
+namespace JSBSim {
+
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_COEFFICIENT;
-extern char highint[5];
-extern char halfint[5];
-extern char normint[6];
-extern char reset[5];
-extern char underon[5];
-extern char underoff[6];
-extern char fgblue[6];
-extern char fgcyan[6];
-extern char fgred[6];
-extern char fggreen[6];
-extern char fgdef[6];
-
-extern short debug_lvl;
-
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGCoefficient::FGCoefficient( FGFDMExec* fdex )
{
-
FDMExec = fdex;
State = FDMExec->GetState();
Table = 0;
-
- if (debug_lvl & 2) cout << "Instantiated: FGCoefficient" << endl;
+
+ PropertyManager = FDMExec->GetPropertyManager();
+
+ Table = (FGTable*)0L;
+ LookupR = LookupC = 0;
+ numInstances = 0;
+ rows = columns = 0;
+
+ StaticValue = 0.0;
+ totalValue = 0.0;
+ bias = 0.0;
+ gain = 1.0;
+ SD = 0.0;
+
+ filename.erase();
+ description.erase();
+ name.erase();
+ method.erase();
+ multparms.erase();
+ multparmsRow.erase();
+ multparmsCol.erase();
+
+ Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGCoefficient::~FGCoefficient()
{
if (Table) delete Table;
- if (debug_lvl & 2) cout << "Destroyed: FGCoefficient" << endl;
+ Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-bool FGCoefficient::Load(FGConfigFile *AC_cfg) {
+bool FGCoefficient::Load(FGConfigFile *AC_cfg)
+{
int start, end, n;
- string multparms, mult;
+ string mult;
if (AC_cfg) {
name = AC_cfg->GetValue("NAME");
method = AC_cfg->GetValue("TYPE");
AC_cfg->GetNextConfigLine();
*AC_cfg >> description;
- if (debug_lvl > 0) {
- cout << "\n " << highint << underon << name << underoff << normint << endl;
- cout << " " << description << endl;
- cout << " " << method << endl;
- }
-
if (method == "EQUATION") type = EQUATION;
else if (method == "TABLE") type = TABLE;
else if (method == "VECTOR") type = VECTOR;
if (type == VECTOR || type == TABLE) {
*AC_cfg >> rows;
- if (debug_lvl > 0) cout << " Rows: " << rows << " ";
if (type == TABLE) {
*AC_cfg >> columns;
- if (debug_lvl > 0) cout << "Cols: " << columns;
Table = new FGTable(rows, columns);
} else {
Table = new FGTable(rows);
}
- if (debug_lvl > 0) cout << endl;
-
- *AC_cfg >> multparms;
- LookupR = State->GetParameterIndex(multparms);
- if (debug_lvl > 0) cout << " Row indexing parameter: " << multparms << endl;
+ *AC_cfg >> multparmsRow;
+ LookupR = PropertyManager->GetNode( multparmsRow );
}
if (type == TABLE) {
- *AC_cfg >> multparms;
- LookupC = State->GetParameterIndex(multparms);
- if (debug_lvl > 0) cout << " Column indexing parameter: " << multparms << endl;
+ *AC_cfg >> multparmsCol;
+
+ LookupC = PropertyManager->GetNode( multparmsCol );
}
// Here, read in the line of the form (e.g.) FG_MACH|FG_QBAR|FG_ALPHA
// where each non-dimensionalizing parameter for this coefficient is
// separated by a | character
- *AC_cfg >> multparms;
+ string line=AC_cfg->GetCurrentLine();
+ unsigned j=0;
+ char tmp[255];
+ for(unsigned i=0;i<line.length(); i++ ) {
+ if( !isspace(line[i]) ) {
+ tmp[j]=line[i];
+ j++;
+ }
+ }
+ tmp[j]='\0'; multparms=tmp;
+ end = multparms.length();
- end = multparms.length();
n = multparms.find("|");
start = 0;
-
- if(multparms != "FG_NONE") {
+ if (multparms != string("none")) {
while (n < end && n >= 0) {
n -= start;
mult = multparms.substr(start,n);
- multipliers.push_back( State->GetParameterIndex(mult) );
+ multipliers.push_back( resolveSymbol( mult ) );
start += n+1;
n = multparms.find("|",start);
}
- multipliers.push_back(State->GetParameterIndex(multparms.substr(start,n)));
+ mult = multparms.substr(start,n);
+ multipliers.push_back( resolveSymbol( mult ) );
// End of non-dimensionalizing parameter read-in
}
-
- switch(type) {
- case VALUE:
+ AC_cfg->GetNextConfigLine();
+ if (type == VALUE) {
*AC_cfg >> StaticValue;
- if (debug_lvl > 0) cout << " Value = " << StaticValue << endl;
- break;
- case VECTOR:
- case TABLE:
+ } else if (type == VECTOR || type == TABLE) {
*Table << *AC_cfg;
- if (debug_lvl > 0) Table->Print();
- break;
- case EQUATION:
- case UNKNOWN:
+ } else {
cerr << "Unimplemented coefficient type: " << type << endl;
- break;
}
+
AC_cfg->GetNextConfigLine();
- if (debug_lvl > 0) DisplayCoeffFactors();
+ FGCoefficient::Debug(2);
+
return true;
} else {
return false;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-float FGCoefficient::Value(float rVal, float cVal)
+double FGCoefficient::Value(double rVal, double cVal)
{
- float Value;
+ double Value;
unsigned int midx;
- SD = Value = Table->GetValue(rVal, cVal);
+ SD = Value = gain*Table->GetValue(rVal, cVal) + bias;
for (midx=0; midx < multipliers.size(); midx++) {
- Value *= State->GetParameter(multipliers[midx]);
+ Value *= multipliers[midx]->getDoubleValue();
}
return Value;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-float FGCoefficient::Value(float Val)
+double FGCoefficient::Value(double Val)
{
- float Value;
-
- SD = Value = Table->GetValue(Val);
+ double Value;
+
+ SD = Value = gain*Table->GetValue(Val) + bias;
for (unsigned int midx=0; midx < multipliers.size(); midx++)
- Value *= State->GetParameter(multipliers[midx]);
+ Value *= multipliers[midx]->getDoubleValue();
return Value;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-float FGCoefficient::Value(void)
+double FGCoefficient::Value(void)
{
- float Value;
+ double Value;
- SD = Value = StaticValue;
+ SD = Value = gain*StaticValue + bias;
for (unsigned int midx=0; midx < multipliers.size(); midx++)
- Value *= State->GetParameter(multipliers[midx]);
+ Value *= multipliers[midx]->getDoubleValue();
return Value;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-float FGCoefficient::TotalValue()
+double FGCoefficient::TotalValue(void)
{
-
switch(type) {
- case 0:
- return -1;
- case 1:
- return (Value());
- case 2:
- return (Value(State->GetParameter(LookupR)));
- case 3:
- return (Value(State->GetParameter(LookupR),State->GetParameter(LookupC)));
- case 4:
- return 0.0;
- }
- return 0;
-}
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ case UNKNOWN:
+ totalValue = -1;
+ break;
-void FGCoefficient::DumpSD(void)
-{
- cout << " " << name << ": " << SD << endl;
-}
+ case VALUE:
+ totalValue = Value();
+ break;
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ case VECTOR:
+ totalValue = Value( LookupR->getDoubleValue() );
+ break;
-void FGCoefficient::Debug(void)
-{
- //TODO: Add your source code here
+ case TABLE:
+ totalValue = Value( LookupR->getDoubleValue(),
+ LookupC->getDoubleValue() );
+ break;
+
+ case EQUATION:
+ totalValue = 0.0;
+ break;
+ }
+ return totalValue;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
cout << " Non-Dimensionalized by: ";
- if( multipliers.size() == 0) {
+ if (multipliers.size() == 0) {
cout << "none" << endl;
} else {
- for (i=0; i<multipliers.size();i++)
- cout << FDMExec->GetState()->paramdef[multipliers[i]];
+ for (i=0; i<multipliers.size(); i++)
+ cout << multipliers[i]->getName() << " ";
}
cout << endl;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-string FGCoefficient::GetCoefficientValues(void) {
- char buffer[10];
+string FGCoefficient::GetSDstring(void)
+{
+ char buffer[16];
string value;
- //value = ", ";
- snprintf(buffer,10,"%9.6f",SD);
- value += string(buffer);
+
+ sprintf(buffer,"%9.6f",SD);
+ value = string(buffer);
return value;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGCoefficient::bind(FGPropertyManager *parent)
+{
+ string mult;
+ unsigned i;
+
+ node = parent->GetNode(name,true);
+
+ node->SetString("description",description);
+ if (LookupR) node->SetString("row-parm",LookupR->getName() );
+ if (LookupC) node->SetString("column-parm",LookupC->getName() );
+
+ mult="";
+ if (multipliers.size() == 0)
+ mult="none";
+
+ for (i=0; i<multipliers.size(); i++) {
+ mult += multipliers[i]->getName();
+ if ( i < multipliers.size()-1 ) mult += " ";
+ }
+ node->SetString("multipliers",mult);
+
+ node->Tie("SD-norm",this,&FGCoefficient::GetSD );
+ node->Tie("value-lbs",this,&FGCoefficient::GetValue );
+
+ node->Tie("bias", this, &FGCoefficient::getBias,
+ &FGCoefficient::setBias );
+
+ node->Tie("gain", this, &FGCoefficient::getGain,
+ &FGCoefficient::setGain );
+
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGCoefficient::unbind(void)
+{
+ node->Untie("SD-norm");
+ node->Untie("value-lbs");
+ node->Untie("bias");
+ node->Untie("gain");
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+FGPropertyManager* FGCoefficient::resolveSymbol(string name)
+{
+ FGPropertyManager* tmpn;
+
+ tmpn = PropertyManager->GetNode(name,false);
+ if ( !tmpn ) {
+ cerr << "Coefficient multipliers cannot create properties, check spelling?" << endl;
+ exit(1);
+ }
+ return tmpn;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+// The bitmasked value choices are as follows:
+// unset: In this case (the default) JSBSim would only print
+// out the normally expected messages, essentially echoing
+// the config files as they are read. If the environment
+// variable is not set, debug_lvl is set to 1 internally
+// 0: This requests JSBSim not to output any messages
+// whatsoever.
+// 1: This value explicity requests the normal JSBSim
+// startup messages
+// 2: This value asks for a message to be printed out when
+// a class is instantiated
+// 4: When this value is set, a message is displayed when a
+// FGModel object executes its Run() method
+// 8: When this value is set, various runtime state variables
+// are printed out periodically
+// 16: When set various parameters are sanity checked and
+// a message is printed out when they go out of bounds
+
+void FGCoefficient::Debug(int from)
+{
+ if (debug_lvl <= 0) return;
+
+ if (debug_lvl & 1) { // Standard console startup message output
+
+ if (from == 2) { // Loading
+ cout << "\n " << highint << underon << name << underoff << normint << endl;
+ cout << " " << description << endl;
+ cout << " " << method << endl;
+
+ if (type == VECTOR || type == TABLE) {
+ cout << " Rows: " << rows << " ";
+ if (type == TABLE) {
+ cout << "Cols: " << columns;
+ }
+ cout << endl << " Row indexing parameter: " << LookupR->getName() << endl;
+ }
+
+ if (type == TABLE) {
+ cout << " Column indexing parameter: " << LookupC->getName() << endl;
+ }
+
+ if (type == VALUE) {
+ cout << " Value = " << StaticValue << endl;
+ } else if (type == VECTOR || type == TABLE) {
+ Table->Print();
+ }
+
+ DisplayCoeffFactors();
+ }
+ }
+ if (debug_lvl & 2 ) { // Instantiation/Destruction notification
+ if (from == 0) cout << "Instantiated: FGCoefficient" << endl;
+ if (from == 1) cout << "Destroyed: FGCoefficient" << endl;
+ }
+ if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
+ }
+ if (debug_lvl & 8 ) { // Runtime state variables
+ }
+ if (debug_lvl & 16) { // Sanity checking
+ }
+ if (debug_lvl & 64) {
+ if (from == 0) { // Constructor
+ cout << IdSrc << endl;
+ cout << IdHdr << endl;
+ }
+ }
+}
+
+} // namespace JSBSim