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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
44 static const char *IdSrc = "$Id$";
45 static const char *IdHdr = ID_GAIN;
47 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
49 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
51 FGGain::FGGain(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
53 Element *scale_element, *zero_centered;
54 string strScheduledBy, gain_string, sZeroCentered;
62 OutMin = OutMax = 0.0;
64 if (Type == "PURE_GAIN") {
65 if ( !element->FindElement("gain") ) {
66 cout << highint << " No GAIN specified (default: 1.0)" << normint << endl;
70 if ( element->FindElement("gain") ) {
71 gain_string = element->FindElementValue("gain");
72 //ToDo allow for negative sign here for property
73 if (gain_string.find_first_not_of("+-.0123456789") != string::npos) { // property
74 GainPropertyNode = PropertyManager->GetNode(gain_string);
76 Gain = element->FindElementValueAsNumber("gain");
80 if (Type == "AEROSURFACE_SCALE") {
81 scale_element = element->FindElement("domain");
83 if (scale_element->FindElement("max") && scale_element->FindElement("min") )
85 InMax = scale_element->FindElementValueAsNumber("max");
86 InMin = scale_element->FindElementValueAsNumber("min");
89 scale_element = element->FindElement("range");
90 if (!scale_element) throw(string("No range supplied for aerosurface scale component"));
91 if (scale_element->FindElement("max") && scale_element->FindElement("min") )
93 OutMax = scale_element->FindElementValueAsNumber("max");
94 OutMin = scale_element->FindElementValueAsNumber("min");
96 cerr << "Maximum and minimum output values must be supplied for the "
97 "aerosurface scale component" << endl;
101 zero_centered = element->FindElement("zero_centered");
102 //ToDo if zero centered, then mins must be <0 and max's must be >0
104 sZeroCentered = zero_centered->FindElementValue("zero_centered");
105 if (sZeroCentered == string("0") || sZeroCentered == string("false")) {
106 ZeroCentered = false;
111 if (Type == "SCHEDULED_GAIN") {
112 if (element->FindElement("table")) {
113 Table = new FGTable(PropertyManager, element->FindElement("table"));
115 cerr << "A table must be provided for the scheduled gain component" << endl;
120 FGFCSComponent::bind();
125 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
132 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134 bool FGGain::Run(void )
136 double SchedGain = 1.0;
138 Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
140 if (GainPropertyNode != 0) Gain = GainPropertyNode->getDoubleValue();
142 if (Type == "PURE_GAIN") { // PURE_GAIN
144 Output = Gain * Input;
146 } else if (Type == "SCHEDULED_GAIN") { // SCHEDULED_GAIN
148 SchedGain = Table->GetValue();
149 Output = Gain * SchedGain * Input;
151 } else if (Type == "AEROSURFACE_SCALE") { // AEROSURFACE_SCALE
156 } else if (Input > 0) {
157 Output = (Input / InMax) * OutMax;
159 Output = (Input / InMin) * OutMin;
162 Output = OutMin + ((Input - InMin) / (InMax - InMin)) * (OutMax - OutMin);
169 if (IsOutput) SetOutput();
174 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
175 // The bitmasked value choices are as follows:
176 // unset: In this case (the default) JSBSim would only print
177 // out the normally expected messages, essentially echoing
178 // the config files as they are read. If the environment
179 // variable is not set, debug_lvl is set to 1 internally
180 // 0: This requests JSBSim not to output any messages
182 // 1: This value explicity requests the normal JSBSim
184 // 2: This value asks for a message to be printed out when
185 // a class is instantiated
186 // 4: When this value is set, a message is displayed when a
187 // FGModel object executes its Run() method
188 // 8: When this value is set, various runtime state variables
189 // are printed out periodically
190 // 16: When set various parameters are sanity checked and
191 // a message is printed out when they go out of bounds
193 void FGGain::Debug(int from)
195 if (debug_lvl <= 0) return;
197 if (debug_lvl & 1) { // Standard console startup message output
198 if (from == 0) { // Constructor
199 if (InputSigns[0] < 0)
200 cout << " INPUT: -" << InputNodes[0]->getName() << endl;
202 cout << " INPUT: " << InputNodes[0]->getName() << endl;
204 cout << " GAIN: " << Gain << endl;
205 if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
206 if (Type == "AEROSURFACE_SCALE") {
207 cout << " In/Out Mapping:" << endl;
208 cout << " Input MIN: " << InMin << endl;
209 cout << " Input MAX: " << InMax << endl;
210 cout << " Output MIN: " << OutMin << endl;
211 cout << " Output MAX: " << OutMax << endl;
214 cout << " Scheduled by table: " << endl;
219 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
220 if (from == 0) cout << "Instantiated: FGGain" << endl;
221 if (from == 1) cout << "Destroyed: FGGain" << endl;
223 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
225 if (debug_lvl & 8 ) { // Runtime state variables
227 if (debug_lvl & 16) { // Sanity checking
229 if (debug_lvl & 64) {
230 if (from == 0) { // Constructor
231 cout << IdSrc << endl;
232 cout << IdHdr << endl;