]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/models/flight_control/FGGain.cpp
Sync. w. JSB CVS as of 15/01/2007
[flightgear.git] / src / FDM / JSBSim / models / flight_control / FGGain.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Module:       FGGain.cpp
4  Author:       Jon S. Berndt
5  Date started: 4/2000
6
7  ------------- Copyright (C) 2000 -------------
8
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
12  version.
13
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
17  details.
18
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.
22
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.
25
26 FUNCTIONAL DESCRIPTION
27 --------------------------------------------------------------------------------
28
29 HISTORY
30 --------------------------------------------------------------------------------
31
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33 COMMENTS, REFERENCES,  and NOTES
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37 INCLUDES
38 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
39
40 #include "FGGain.h"
41
42 namespace JSBSim {
43
44 static const char *IdSrc = "$Id$";
45 static const char *IdHdr = ID_GAIN;
46
47 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
48 CLASS IMPLEMENTATION
49 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
50
51 FGGain::FGGain(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
52 {
53   Element *scale_element, *zero_centered;
54   string strScheduledBy, gain_string, sZeroCentered;
55
56   GainPropertyNode = 0;
57   Gain = 1.000;
58   Rows = 0;
59   Table = 0;
60   InMin = -1.0;
61   InMax =  1.0;
62   OutMin = OutMax = 0.0;
63
64   if (Type == "PURE_GAIN") {
65     if ( !element->FindElement("gain") ) {
66       cout << highint << "      No GAIN specified (default: 1.0)" << normint << endl;
67     }
68   }
69
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);
75     } else {
76       Gain = element->FindElementValueAsNumber("gain");
77     }
78   }
79
80   if (Type == "AEROSURFACE_SCALE") {
81     scale_element = element->FindElement("domain");
82     if (scale_element) {
83       if (scale_element->FindElement("max") && scale_element->FindElement("min") )
84       {
85         InMax = scale_element->FindElementValueAsNumber("max");
86         InMin = scale_element->FindElementValueAsNumber("min");
87       }
88     }
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") )
92     {
93       OutMax = scale_element->FindElementValueAsNumber("max");
94       OutMin = scale_element->FindElementValueAsNumber("min");
95     } else {
96       cerr << "Maximum and minimum output values must be supplied for the "
97               "aerosurface scale component" << endl;
98       exit(-1);
99     }
100     ZeroCentered = true;
101     zero_centered = element->FindElement("zero_centered");
102     //ToDo if zero centered, then mins must be <0 and max's must be >0
103     if (zero_centered) {
104       sZeroCentered = zero_centered->FindElementValue("zero_centered");
105       if (sZeroCentered == string("0") || sZeroCentered == string("false")) {
106         ZeroCentered = false;
107       }
108     }
109   }
110
111   if (Type == "SCHEDULED_GAIN") {
112     if (element->FindElement("table")) {
113       Table = new FGTable(PropertyManager, element->FindElement("table"));
114     } else {
115       cerr << "A table must be provided for the scheduled gain component" << endl;
116       exit(-1);
117     }
118   }
119
120   FGFCSComponent::bind();
121
122   Debug(0);
123 }
124
125 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126
127 FGGain::~FGGain()
128 {
129   Debug(1);
130 }
131
132 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
133
134 bool FGGain::Run(void )
135 {
136   double SchedGain = 1.0;
137
138   Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
139
140   if (GainPropertyNode != 0) Gain = GainPropertyNode->getDoubleValue();
141
142   if (Type == "PURE_GAIN") {                       // PURE_GAIN
143
144     Output = Gain * Input;
145
146   } else if (Type == "SCHEDULED_GAIN") {           // SCHEDULED_GAIN
147
148     SchedGain = Table->GetValue();
149     Output = Gain * SchedGain * Input;
150
151   } else if (Type == "AEROSURFACE_SCALE") {        // AEROSURFACE_SCALE
152
153     if (ZeroCentered) {
154       if (Input == 0.0) {
155         Output = 0.0;
156       } else if (Input > 0) {
157         Output = (Input / InMax) * OutMax;
158       } else {
159         Output = (Input / InMin) * OutMin;
160       }
161     } else {
162       Output = OutMin + ((Input - InMin) / (InMax - InMin)) * (OutMax - OutMin);
163     }
164
165     Output *= Gain;
166   }
167
168   Clip();
169   if (IsOutput) SetOutput();
170
171   return true;
172 }
173
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
181 //       whatsoever.
182 //    1: This value explicity requests the normal JSBSim
183 //       startup messages
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
192
193 void FGGain::Debug(int from)
194 {
195   if (debug_lvl <= 0) return;
196
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;
201       else
202         cout << "      INPUT: " << InputNodes[0]->getName() << endl;
203
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;
212       }
213       if (Table != 0) {
214         cout << "      Scheduled by table: " << endl;
215         Table->Print();
216       }
217     }
218   }
219   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
220     if (from == 0) cout << "Instantiated: FGGain" << endl;
221     if (from == 1) cout << "Destroyed:    FGGain" << endl;
222   }
223   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
224   }
225   if (debug_lvl & 8 ) { // Runtime state variables
226   }
227   if (debug_lvl & 16) { // Sanity checking
228   }
229   if (debug_lvl & 64) {
230     if (from == 0) { // Constructor
231       cout << IdSrc << endl;
232       cout << IdHdr << endl;
233     }
234   }
235 }
236 }