fgfunction.cpp
来自「6 DOF Missle Simulation」· C++ 代码 · 共 416 行
CPP
416 行
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Module: FGFunction.cppAuthor: Jon BerndtDate started: 8/25/2004Purpose: Stores various parameter types for functions ------------- Copyright (C) 2004 Jon S. Berndt (jsb@hal-pc.org) ------------- This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Further information about the GNU Lesser General Public License can also be found on the world wide web at http://www.gnu.org.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%INCLUDES%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/#include <stdio.h>#include "FGFunction.h"#include "FGTable.h"#include "FGPropertyValue.h"#include "FGRealValue.h"namespace JSBSim {static const char *IdSrc = "$Id$";static const char *IdHdr = ID_FUNCTION;/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%CLASS IMPLEMENTATION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/FGFunction::FGFunction(FGPropertyManager* propMan, Element* el, string prefix) : PropertyManager(propMan), Prefix(prefix){ Element* element; string operation, property_name; int size = el->GetNumElements(); cached = false; cachedValue = -HUGE_VAL; property_string = "property"; value_string = "value"; table_string = "table"; p_string = "p"; v_string = "v"; t_string = "t"; function_string = "function"; description_string = "description"; sum_string = "sum"; difference_string = "difference"; product_string = "product"; quotient_string = "quotient"; pow_string = "pow"; exp_string = "exp"; abs_string = "abs"; sin_string = "sin"; cos_string = "cos"; tan_string = "tan"; asin_string = "asin"; acos_string = "acos"; atan_string = "atan"; atan2_string = "atan2"; min_string = "min"; max_string = "max"; avg_string = "avg"; fraction_string = "fraction"; mod_string = "mod"; random_string = "random"; integer_string = "integer"; Name = el->GetAttributeValue("name"); operation = el->GetName(); if (operation == function_string) { Type = eTopLevel; } else if (operation == product_string) { Type = eProduct; } else if (operation == difference_string) { Type = eDifference; } else if (operation == sum_string) { Type = eSum; } else if (operation == quotient_string) { Type = eQuotient; } else if (operation == pow_string) { Type = ePow; } else if (operation == abs_string) { Type = eAbs; } else if (operation == sin_string) { Type = eSin; } else if (operation == exp_string) { Type = eExp; } else if (operation == cos_string) { Type = eCos; } else if (operation == tan_string) { Type = eTan; } else if (operation == asin_string) { Type = eASin; } else if (operation == acos_string) { Type = eACos; } else if (operation == atan_string) { Type = eATan; } else if (operation == atan2_string) { Type = eATan2; } else if (operation == min_string) { Type = eMin; } else if (operation == max_string) { Type = eMax; } else if (operation == avg_string) { Type = eAvg; } else if (operation == fraction_string) { Type = eFrac; } else if (operation == integer_string) { Type = eInteger; } else if (operation == mod_string) { Type = eMod; } else if (operation == random_string) { Type = eRandom; } else if (operation != description_string) { cerr << "Bad operation " << operation << " detected in configuration file" << endl; } element = el->GetElement(); if (!element) { cerr << fgred << highint << endl; cerr << " No element was specified as an argument to the \"" << operation << "\" operation" << endl; cerr << " This can happen when, for instance, a cos operation is specified and a " << endl; cerr << " property name is given explicitly, but is not placed within a" << endl; cerr << " <property></property> element tag pair." << endl; cerr << reset; exit(-2); } while (element) { operation = element->GetName(); // data types if (operation == property_string || operation == p_string) { property_name = element->GetDataLine(); FGPropertyManager* newNode = PropertyManager->GetNode(property_name); if (newNode == 0) { cerr << "The property " << property_name << " is undefined." << endl; abort(); } else { Parameters.push_back(new FGPropertyValue( newNode )); } } else if (operation == value_string || operation == v_string) { Parameters.push_back(new FGRealValue(element->GetDataAsNumber())); } else if (operation == table_string || operation == t_string) { Parameters.push_back(new FGTable(PropertyManager, element)); // operations } else if (operation == product_string || operation == difference_string || operation == sum_string || operation == quotient_string || operation == pow_string || operation == exp_string || operation == abs_string || operation == sin_string || operation == cos_string || operation == tan_string || operation == asin_string || operation == acos_string || operation == atan_string || operation == atan2_string || operation == min_string || operation == max_string || operation == fraction_string || operation == integer_string || operation == mod_string || operation == random_string || operation == avg_string ) { Parameters.push_back(new FGFunction(PropertyManager, element)); } else if (operation != description_string) { cerr << "Bad operation " << operation << " detected in configuration file" << endl; } element = el->GetNextElement(); } bind(); // Allow any function to save its value Debug(0);}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%FGFunction::~FGFunction(void){ for (unsigned int i=0; i<Parameters.size(); i++) delete Parameters[i];}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%void FGFunction::cacheValue(bool cache){ cached = false; // Must set cached to false prior to calling GetValue(), else // it will _never_ calculate the value; if (cache) { cachedValue = GetValue(); cached = true; }}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%double FGFunction::GetValue(void) const{ unsigned int i; double scratch; if (cached) return cachedValue; double temp = Parameters[0]->GetValue(); switch (Type) { case eTopLevel: break; case eProduct: for (i=1;i<Parameters.size();i++) { temp *= Parameters[i]->GetValue(); } break; case eDifference: for (i=1;i<Parameters.size();i++) { temp -= Parameters[i]->GetValue(); } break; case eSum: for (i=1;i<Parameters.size();i++) { temp += Parameters[i]->GetValue(); } break; case eQuotient: temp /= Parameters[1]->GetValue(); break; case ePow: temp = pow(temp,Parameters[1]->GetValue()); break; case eExp: temp = exp(temp); break; case eAbs: temp = fabs(temp); break; case eSin: temp = sin(temp); break; case eCos: temp = cos(temp); break; case eTan: temp = tan(temp); break; case eACos: temp = acos(temp); break; case eASin: temp = asin(temp); break; case eATan: temp = atan(temp); break; case eATan2: temp = atan2(temp, Parameters[1]->GetValue()); break; case eMod: temp = ((int)temp) % ((int) Parameters[1]->GetValue()); break; case eMin: for (i=1;i<Parameters.size();i++) { if (Parameters[i]->GetValue() < temp) temp = Parameters[i]->GetValue(); } break; case eMax: for (i=1;i<Parameters.size();i++) { if (Parameters[i]->GetValue() > temp) temp = Parameters[i]->GetValue(); } break; case eAvg: for (i=1;i<Parameters.size();i++) { temp += Parameters[i]->GetValue(); } temp /= Parameters.size(); break; case eFrac: temp = modf(temp, &scratch); break; case eInteger: modf(temp, &scratch); temp = scratch; break; case eRandom: temp = GaussianRandomNumber(); break; default: cerr << "Unknown function operation type" << endl; break; } return temp;}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%string FGFunction::GetValueAsString(void) const{ char buffer[20]; string value; sprintf(buffer,"%9.6f",GetValue()); value = string(buffer); return value;}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%double FGFunction::GaussianRandomNumber(void) const{ static double V1, V2, S; static int phase = 0; double X; if (phase == 0) { do { double U1 = (double)rand() / RAND_MAX; double U2 = (double)rand() / RAND_MAX; V1 = 2 * U1 - 1; V2 = 2 * U2 - 1; S = V1 * V1 + V2 * V2; } while(S >= 1 || S == 0); X = V1 * sqrt(-2 * log(S) / S); } else X = V2 * sqrt(-2 * log(S) / S); phase = 1 - phase; return X;}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%void FGFunction::bind(void){ if ( !Name.empty() ) { string tmp = PropertyManager->mkPropertyName(Prefix + Name, false); // Allow upper case PropertyManager->Tie( tmp, this, &FGFunction::GetValue); }}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%// 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 boundsvoid FGFunction::Debug(int from){ if (debug_lvl <= 0) return; if (debug_lvl & 1) { // Standard console startup message output if (from == 0) { // Constructor if (Type == eTopLevel) cout << " Function: " << Name << endl; } } if (debug_lvl & 2 ) { // Instantiation/Destruction notification if (from == 0) cout << "Instantiated: FGFunction" << endl; if (from == 1) cout << "Destroyed: FGFunction" << 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; } }}}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?