![]() |
JSBSim Flight Dynamics Model 1.0 (23 February 2013)
An Open Source Flight Dynamics and Control Software Library in C++
|
00001 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00002 00003 Module: FGGain.cpp 00004 Author: Jon S. Berndt 00005 Date started: 4/2000 00006 00007 ------------- Copyright (C) 2000 ------------- 00008 00009 This program is free software; you can redistribute it and/or modify it under 00010 the terms of the GNU Lesser General Public License as published by the Free Software 00011 Foundation; either version 2 of the License, or (at your option) any later 00012 version. 00013 00014 This program is distributed in the hope that it will be useful, but WITHOUT 00015 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00016 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00017 details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA. 00022 00023 Further information about the GNU Lesser General Public License can also be found on 00024 the world wide web at http://www.gnu.org. 00025 00026 FUNCTIONAL DESCRIPTION 00027 -------------------------------------------------------------------------------- 00028 00029 HISTORY 00030 -------------------------------------------------------------------------------- 00031 00032 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00033 COMMENTS, REFERENCES, and NOTES 00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00035 00036 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00037 INCLUDES 00038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 00039 00040 #include "FGGain.h" 00041 #include "input_output/FGXMLElement.h" 00042 #include <iostream> 00043 #include <string> 00044 #include <cstdlib> 00045 00046 using namespace std; 00047 00048 namespace JSBSim { 00049 00050 static const char *IdSrc = "$Id: FGGain.cpp,v 1.23 2011/04/18 08:51:12 andgi Exp $"; 00051 static const char *IdHdr = ID_GAIN; 00052 00053 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00054 CLASS IMPLEMENTATION 00055 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 00056 00057 FGGain::FGGain(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element) 00058 { 00059 Element *scale_element, *zero_centered; 00060 string strScheduledBy, gain_string, sZeroCentered; 00061 00062 GainPropertyNode = 0; 00063 GainPropertySign = 1.0; 00064 Gain = 1.000; 00065 Rows = 0; 00066 Table = 0; 00067 InMin = -1.0; 00068 InMax = 1.0; 00069 OutMin = OutMax = 0.0; 00070 00071 if (Type == "PURE_GAIN") { 00072 if ( !element->FindElement("gain") ) { 00073 cerr << highint << " No GAIN specified (default: 1.0)" << normint << endl; 00074 } 00075 } 00076 00077 if ( element->FindElement("gain") ) { 00078 gain_string = element->FindElementValue("gain"); 00079 if (!is_number(gain_string)) { // property 00080 if (gain_string[0] == '-') { 00081 GainPropertySign = -1.0; 00082 gain_string.erase(0,1); 00083 } 00084 GainPropertyNode = PropertyManager->GetNode(gain_string); 00085 } else { 00086 Gain = element->FindElementValueAsNumber("gain"); 00087 } 00088 } 00089 00090 if (Type == "AEROSURFACE_SCALE") { 00091 scale_element = element->FindElement("domain"); 00092 if (scale_element) { 00093 if (scale_element->FindElement("max") && scale_element->FindElement("min") ) 00094 { 00095 InMax = scale_element->FindElementValueAsNumber("max"); 00096 InMin = scale_element->FindElementValueAsNumber("min"); 00097 } 00098 } 00099 scale_element = element->FindElement("range"); 00100 if (!scale_element) throw(string("No range supplied for aerosurface scale component")); 00101 if (scale_element->FindElement("max") && scale_element->FindElement("min") ) 00102 { 00103 OutMax = scale_element->FindElementValueAsNumber("max"); 00104 OutMin = scale_element->FindElementValueAsNumber("min"); 00105 } else { 00106 cerr << "Maximum and minimum output values must be supplied for the " 00107 "aerosurface scale component" << endl; 00108 exit(-1); 00109 } 00110 ZeroCentered = true; 00111 zero_centered = element->FindElement("zero_centered"); 00112 //ToDo if zero centered, then mins must be <0 and max's must be >0 00113 if (zero_centered) { 00114 sZeroCentered = element->FindElementValue("zero_centered"); 00115 if (sZeroCentered == string("0") || sZeroCentered == string("false")) { 00116 ZeroCentered = false; 00117 } 00118 } 00119 } 00120 00121 if (Type == "SCHEDULED_GAIN") { 00122 if (element->FindElement("table")) { 00123 Table = new FGTable(PropertyManager, element->FindElement("table")); 00124 } else { 00125 cerr << "A table must be provided for the scheduled gain component" << endl; 00126 exit(-1); 00127 } 00128 } 00129 00130 FGFCSComponent::bind(); 00131 00132 Debug(0); 00133 } 00134 00135 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00136 00137 FGGain::~FGGain() 00138 { 00139 delete Table; 00140 00141 Debug(1); 00142 } 00143 00144 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00145 00146 bool FGGain::Run(void ) 00147 { 00148 double SchedGain = 1.0; 00149 00150 Input = InputNodes[0]->getDoubleValue() * InputSigns[0]; 00151 00152 if (GainPropertyNode != 0) Gain = GainPropertyNode->getDoubleValue() * GainPropertySign; 00153 00154 if (Type == "PURE_GAIN") { // PURE_GAIN 00155 00156 Output = Gain * Input; 00157 00158 } else if (Type == "SCHEDULED_GAIN") { // SCHEDULED_GAIN 00159 00160 SchedGain = Table->GetValue(); 00161 Output = Gain * SchedGain * Input; 00162 00163 } else if (Type == "AEROSURFACE_SCALE") { // AEROSURFACE_SCALE 00164 00165 if (ZeroCentered) { 00166 if (Input == 0.0) { 00167 Output = 0.0; 00168 } else if (Input > 0) { 00169 Output = (Input / InMax) * OutMax; 00170 } else { 00171 Output = (Input / InMin) * OutMin; 00172 } 00173 } else { 00174 Output = OutMin + ((Input - InMin) / (InMax - InMin)) * (OutMax - OutMin); 00175 } 00176 00177 Output *= Gain; 00178 } 00179 00180 Clip(); 00181 if (IsOutput) SetOutput(); 00182 00183 return true; 00184 } 00185 00186 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00187 // The bitmasked value choices are as follows: 00188 // unset: In this case (the default) JSBSim would only print 00189 // out the normally expected messages, essentially echoing 00190 // the config files as they are read. If the environment 00191 // variable is not set, debug_lvl is set to 1 internally 00192 // 0: This requests JSBSim not to output any messages 00193 // whatsoever. 00194 // 1: This value explicity requests the normal JSBSim 00195 // startup messages 00196 // 2: This value asks for a message to be printed out when 00197 // a class is instantiated 00198 // 4: When this value is set, a message is displayed when a 00199 // FGModel object executes its Run() method 00200 // 8: When this value is set, various runtime state variables 00201 // are printed out periodically 00202 // 16: When set various parameters are sanity checked and 00203 // a message is printed out when they go out of bounds 00204 00205 void FGGain::Debug(int from) 00206 { 00207 if (debug_lvl <= 0) return; 00208 00209 if (debug_lvl & 1) { // Standard console startup message output 00210 if (from == 0) { // Constructor 00211 if (InputSigns[0] < 0) 00212 cout << " INPUT: -" << InputNodes[0]->GetName() << endl; 00213 else 00214 cout << " INPUT: " << InputNodes[0]->GetName() << endl; 00215 00216 if (GainPropertyNode != 0) { 00217 cout << " GAIN: " << GainPropertyNode->GetName() << endl; 00218 } else { 00219 cout << " GAIN: " << Gain << endl; 00220 } 00221 if (IsOutput) { 00222 for (unsigned int i=0; i<OutputNodes.size(); i++) 00223 cout << " OUTPUT: " << OutputNodes[i]->getName() << endl; 00224 } 00225 if (Type == "AEROSURFACE_SCALE") { 00226 cout << " In/Out Mapping:" << endl; 00227 cout << " Input MIN: " << InMin << endl; 00228 cout << " Input MAX: " << InMax << endl; 00229 cout << " Output MIN: " << OutMin << endl; 00230 cout << " Output MAX: " << OutMax << endl; 00231 } 00232 if (Table != 0) { 00233 cout << " Scheduled by table: " << endl; 00234 Table->Print(); 00235 } 00236 } 00237 } 00238 if (debug_lvl & 2 ) { // Instantiation/Destruction notification 00239 if (from == 0) cout << "Instantiated: FGGain" << endl; 00240 if (from == 1) cout << "Destroyed: FGGain" << endl; 00241 } 00242 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects 00243 } 00244 if (debug_lvl & 8 ) { // Runtime state variables 00245 } 00246 if (debug_lvl & 16) { // Sanity checking 00247 } 00248 if (debug_lvl & 64) { 00249 if (from == 0) { // Constructor 00250 cout << IdSrc << endl; 00251 cout << IdHdr << endl; 00252 } 00253 } 00254 } 00255 }