1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7 ------------- Copyright (C) 2000 -------------
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU Lesser General Public License as published by the Free Software
11 Foundation; either version 2 of the License, or (at your option) any later
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
19 You should have received a copy of the GNU Lesser General Public License along with
20 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21 Place - Suite 330, Boston, MA 02111-1307, USA.
23 Further information about the GNU Lesser General Public License can also be found on
24 the world wide web at http://www.gnu.org.
26 FUNCTIONAL DESCRIPTION
27 --------------------------------------------------------------------------------
30 --------------------------------------------------------------------------------
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33 COMMENTS, REFERENCES, and NOTES
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
41 #include "input_output/FGXMLElement.h"
50 static const char *IdSrc = "$Id$";
51 static const char *IdHdr = ID_GAIN;
53 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
55 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
57 FGGain::FGGain(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
59 Element *scale_element, *zero_centered;
60 string strScheduledBy, gain_string, sZeroCentered;
63 GainPropertySign = 1.0;
69 OutMin = OutMax = 0.0;
71 if (Type == "PURE_GAIN") {
72 if ( !element->FindElement("gain") ) {
73 cout << highint << " No GAIN specified (default: 1.0)" << normint << endl;
77 if ( element->FindElement("gain") ) {
78 gain_string = element->FindElementValue("gain");
79 if (!is_number(gain_string)) { // property
80 if (gain_string[0] == '-') {
81 GainPropertySign = -1.0;
82 gain_string.erase(0,1);
84 GainPropertyNode = PropertyManager->GetNode(gain_string);
86 Gain = element->FindElementValueAsNumber("gain");
90 if (Type == "AEROSURFACE_SCALE") {
91 scale_element = element->FindElement("domain");
93 if (scale_element->FindElement("max") && scale_element->FindElement("min") )
95 InMax = scale_element->FindElementValueAsNumber("max");
96 InMin = scale_element->FindElementValueAsNumber("min");
99 scale_element = element->FindElement("range");
100 if (!scale_element) throw(string("No range supplied for aerosurface scale component"));
101 if (scale_element->FindElement("max") && scale_element->FindElement("min") )
103 OutMax = scale_element->FindElementValueAsNumber("max");
104 OutMin = scale_element->FindElementValueAsNumber("min");
106 cerr << "Maximum and minimum output values must be supplied for the "
107 "aerosurface scale component" << endl;
111 zero_centered = element->FindElement("zero_centered");
112 //ToDo if zero centered, then mins must be <0 and max's must be >0
114 sZeroCentered = element->FindElementValue("zero_centered");
115 if (sZeroCentered == string("0") || sZeroCentered == string("false")) {
116 ZeroCentered = false;
121 if (Type == "SCHEDULED_GAIN") {
122 if (element->FindElement("table")) {
123 Table = new FGTable(PropertyManager, element->FindElement("table"));
125 cerr << "A table must be provided for the scheduled gain component" << endl;
130 FGFCSComponent::bind();
135 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
144 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146 bool FGGain::Run(void )
148 double SchedGain = 1.0;
150 Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
152 if (GainPropertyNode != 0) Gain = GainPropertyNode->getDoubleValue() * GainPropertySign;
154 if (Type == "PURE_GAIN") { // PURE_GAIN
156 Output = Gain * Input;
158 } else if (Type == "SCHEDULED_GAIN") { // SCHEDULED_GAIN
160 SchedGain = Table->GetValue();
161 Output = Gain * SchedGain * Input;
163 } else if (Type == "AEROSURFACE_SCALE") { // AEROSURFACE_SCALE
168 } else if (Input > 0) {
169 Output = (Input / InMax) * OutMax;
171 Output = (Input / InMin) * OutMin;
174 Output = OutMin + ((Input - InMin) / (InMax - InMin)) * (OutMax - OutMin);
181 if (IsOutput) SetOutput();
186 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
187 // The bitmasked value choices are as follows:
188 // unset: In this case (the default) JSBSim would only print
189 // out the normally expected messages, essentially echoing
190 // the config files as they are read. If the environment
191 // variable is not set, debug_lvl is set to 1 internally
192 // 0: This requests JSBSim not to output any messages
194 // 1: This value explicity requests the normal JSBSim
196 // 2: This value asks for a message to be printed out when
197 // a class is instantiated
198 // 4: When this value is set, a message is displayed when a
199 // FGModel object executes its Run() method
200 // 8: When this value is set, various runtime state variables
201 // are printed out periodically
202 // 16: When set various parameters are sanity checked and
203 // a message is printed out when they go out of bounds
205 void FGGain::Debug(int from)
207 if (debug_lvl <= 0) return;
209 if (debug_lvl & 1) { // Standard console startup message output
210 if (from == 0) { // Constructor
211 if (InputSigns[0] < 0)
212 cout << " INPUT: -" << InputNodes[0]->getName() << endl;
214 cout << " INPUT: " << InputNodes[0]->getName() << endl;
216 if (GainPropertyNode != 0) {
217 cout << " GAIN: " << GainPropertyNode->GetName() << endl;
219 cout << " GAIN: " << Gain << endl;
222 for (unsigned int i=0; i<OutputNodes.size(); i++)
223 cout << " OUTPUT: " << OutputNodes[i]->getName() << endl;
225 if (Type == "AEROSURFACE_SCALE") {
226 cout << " In/Out Mapping:" << endl;
227 cout << " Input MIN: " << InMin << endl;
228 cout << " Input MAX: " << InMax << endl;
229 cout << " Output MIN: " << OutMin << endl;
230 cout << " Output MAX: " << OutMax << endl;
233 cout << " Scheduled by table: " << endl;
238 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
239 if (from == 0) cout << "Instantiated: FGGain" << endl;
240 if (from == 1) cout << "Destroyed: FGGain" << endl;
242 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
244 if (debug_lvl & 8 ) { // Runtime state variables
246 if (debug_lvl & 16) { // Sanity checking
248 if (debug_lvl & 64) {
249 if (from == 0) { // Constructor
250 cout << IdSrc << endl;
251 cout << IdHdr << endl;