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 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 General Public License for more
19 You should have received a copy of the GNU 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 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 if (gain_string.find_first_not_of("+-.0123456789") != string::npos) { // property
73 GainPropertyNode = PropertyManager->GetNode(gain_string);
75 Gain = element->FindElementValueAsNumber("gain");
79 if (Type == "AEROSURFACE_SCALE") {
80 scale_element = element->FindElement("domain");
82 if (scale_element->FindElement("max") && scale_element->FindElement("min") )
84 InMax = scale_element->FindElementValueAsNumber("max");
85 InMin = scale_element->FindElementValueAsNumber("min");
88 scale_element = element->FindElement("range");
89 if (!scale_element) throw(string("No range supplied for aerosurface scale component"));
90 if (scale_element->FindElement("max") && scale_element->FindElement("min") )
92 OutMax = scale_element->FindElementValueAsNumber("max");
93 OutMin = scale_element->FindElementValueAsNumber("min");
95 cerr << "Maximum and minimum output values must be supplied for the "
96 "aerosurface scale component" << endl;
100 zero_centered = element->FindElement("zero_centered");
102 sZeroCentered = zero_centered->FindElementValue("zero_centered");
103 if (sZeroCentered == string("0") || sZeroCentered == string("false")) {
104 ZeroCentered = false;
109 if (Type == "SCHEDULED_GAIN") {
110 if (element->FindElement("table")) {
111 Table = new FGTable(PropertyManager, element->FindElement("table"));
113 cerr << "A table must be provided for the scheduled gain component" << endl;
118 FGFCSComponent::bind();
123 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
132 bool FGGain::Run(void )
134 double SchedGain = 1.0;
136 Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
138 if (GainPropertyNode != 0) Gain = GainPropertyNode->getDoubleValue();
140 if (Type == "PURE_GAIN") { // PURE_GAIN
142 Output = Gain * Input;
144 } else if (Type == "SCHEDULED_GAIN") { // SCHEDULED_GAIN
146 SchedGain = Table->GetValue();
147 Output = Gain * SchedGain * Input;
149 } else if (Type == "AEROSURFACE_SCALE") { // AEROSURFACE_SCALE
154 } else if (Input > 0) {
155 Output = (Input / InMax) * OutMax;
157 Output = (Input / InMin) * OutMin;
160 Output = OutMin + ((Input - InMin) / (InMax - InMin)) * (OutMax - OutMin);
167 if (IsOutput) SetOutput();
172 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
173 // The bitmasked value choices are as follows:
174 // unset: In this case (the default) JSBSim would only print
175 // out the normally expected messages, essentially echoing
176 // the config files as they are read. If the environment
177 // variable is not set, debug_lvl is set to 1 internally
178 // 0: This requests JSBSim not to output any messages
180 // 1: This value explicity requests the normal JSBSim
182 // 2: This value asks for a message to be printed out when
183 // a class is instantiated
184 // 4: When this value is set, a message is displayed when a
185 // FGModel object executes its Run() method
186 // 8: When this value is set, various runtime state variables
187 // are printed out periodically
188 // 16: When set various parameters are sanity checked and
189 // a message is printed out when they go out of bounds
191 void FGGain::Debug(int from)
193 if (debug_lvl <= 0) return;
195 if (debug_lvl & 1) { // Standard console startup message output
196 if (from == 0) { // Constructor
197 if (InputSigns[0] < 0)
198 cout << " INPUT: -" << InputNodes[0]->getName() << endl;
200 cout << " INPUT: " << InputNodes[0]->getName() << endl;
202 cout << " GAIN: " << Gain << endl;
203 if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
204 if (Type == "AEROSURFACE_SCALE") {
205 cout << " In/Out Mapping:" << endl;
206 cout << " Input MIN: " << InMin << endl;
207 cout << " Input MAX: " << InMax << endl;
208 cout << " Output MIN: " << OutMin << endl;
209 cout << " Output MAX: " << OutMax << endl;
212 cout << " Scheduled by table: " << endl;
217 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
218 if (from == 0) cout << "Instantiated: FGGain" << endl;
219 if (from == 1) cout << "Destroyed: FGGain" << endl;
221 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
223 if (debug_lvl & 8 ) { // Runtime state variables
225 if (debug_lvl & 16) { // Sanity checking
227 if (debug_lvl & 64) {
228 if (from == 0) { // Constructor
229 cout << IdSrc << endl;
230 cout << IdHdr << endl;