]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/models/flight_control/FGGain.cpp
Sync. with JSBSim cvs
[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   GainPropertySign = 1.0;
58   Gain = 1.000;
59   Rows = 0;
60   Table = 0;
61   InMin = -1.0;
62   InMax =  1.0;
63   OutMin = OutMax = 0.0;
64
65   if (Type == "PURE_GAIN") {
66     if ( !element->FindElement("gain") ) {
67       cout << highint << "      No GAIN specified (default: 1.0)" << normint << endl;
68     }
69   }
70
71   if ( element->FindElement("gain") ) {
72     gain_string = element->FindElementValue("gain");
73     if (gain_string.find_first_not_of("+-.0123456789Ee") != string::npos) { // property
74       if (gain_string[0] == '-') {
75        GainPropertySign = -1.0;
76        gain_string.erase(0,1);
77       }
78       GainPropertyNode = PropertyManager->GetNode(gain_string);
79     } else {
80       Gain = element->FindElementValueAsNumber("gain");
81     }
82   }
83
84   if (Type == "AEROSURFACE_SCALE") {
85     scale_element = element->FindElement("domain");
86     if (scale_element) {
87       if (scale_element->FindElement("max") && scale_element->FindElement("min") )
88       {
89         InMax = scale_element->FindElementValueAsNumber("max");
90         InMin = scale_element->FindElementValueAsNumber("min");
91       }
92     }
93     scale_element = element->FindElement("range");
94     if (!scale_element) throw(string("No range supplied for aerosurface scale component"));
95     if (scale_element->FindElement("max") && scale_element->FindElement("min") )
96     {
97       OutMax = scale_element->FindElementValueAsNumber("max");
98       OutMin = scale_element->FindElementValueAsNumber("min");
99     } else {
100       cerr << "Maximum and minimum output values must be supplied for the "
101               "aerosurface scale component" << endl;
102       exit(-1);
103     }
104     ZeroCentered = true;
105     zero_centered = element->FindElement("zero_centered");
106     //ToDo if zero centered, then mins must be <0 and max's must be >0
107     if (zero_centered) {
108       sZeroCentered = element->FindElementValue("zero_centered");
109       if (sZeroCentered == string("0") || sZeroCentered == string("false")) {
110         ZeroCentered = false;
111       }
112     }
113   }
114
115   if (Type == "SCHEDULED_GAIN") {
116     if (element->FindElement("table")) {
117       Table = new FGTable(PropertyManager, element->FindElement("table"));
118     } else {
119       cerr << "A table must be provided for the scheduled gain component" << endl;
120       exit(-1);
121     }
122   }
123
124   FGFCSComponent::bind();
125
126   Debug(0);
127 }
128
129 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130
131 FGGain::~FGGain()
132 {
133   delete Table;
134
135   Debug(1);
136 }
137
138 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139
140 bool FGGain::Run(void )
141 {
142   double SchedGain = 1.0;
143
144   Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
145
146   if (GainPropertyNode != 0) Gain = GainPropertyNode->getDoubleValue() * GainPropertySign;
147
148   if (Type == "PURE_GAIN") {                       // PURE_GAIN
149
150     Output = Gain * Input;
151
152   } else if (Type == "SCHEDULED_GAIN") {           // SCHEDULED_GAIN
153
154     SchedGain = Table->GetValue();
155     Output = Gain * SchedGain * Input;
156
157   } else if (Type == "AEROSURFACE_SCALE") {        // AEROSURFACE_SCALE
158
159     if (ZeroCentered) {
160       if (Input == 0.0) {
161         Output = 0.0;
162       } else if (Input > 0) {
163         Output = (Input / InMax) * OutMax;
164       } else {
165         Output = (Input / InMin) * OutMin;
166       }
167     } else {
168       Output = OutMin + ((Input - InMin) / (InMax - InMin)) * (OutMax - OutMin);
169     }
170
171     Output *= Gain;
172   }
173
174   Clip();
175   if (IsOutput) SetOutput();
176
177   return true;
178 }
179
180 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
181 //    The bitmasked value choices are as follows:
182 //    unset: In this case (the default) JSBSim would only print
183 //       out the normally expected messages, essentially echoing
184 //       the config files as they are read. If the environment
185 //       variable is not set, debug_lvl is set to 1 internally
186 //    0: This requests JSBSim not to output any messages
187 //       whatsoever.
188 //    1: This value explicity requests the normal JSBSim
189 //       startup messages
190 //    2: This value asks for a message to be printed out when
191 //       a class is instantiated
192 //    4: When this value is set, a message is displayed when a
193 //       FGModel object executes its Run() method
194 //    8: When this value is set, various runtime state variables
195 //       are printed out periodically
196 //    16: When set various parameters are sanity checked and
197 //       a message is printed out when they go out of bounds
198
199 void FGGain::Debug(int from)
200 {
201   if (debug_lvl <= 0) return;
202
203   if (debug_lvl & 1) { // Standard console startup message output
204     if (from == 0) { // Constructor
205       if (InputSigns[0] < 0)
206         cout << "      INPUT: -" << InputNodes[0]->getName() << endl;
207       else
208         cout << "      INPUT: " << InputNodes[0]->getName() << endl;
209
210       cout << "      GAIN: " << Gain << endl;
211       if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
212       if (Type == "AEROSURFACE_SCALE") {
213         cout << "      In/Out Mapping:" << endl;
214         cout << "        Input MIN: " << InMin << endl;
215         cout << "        Input MAX: " << InMax << endl;
216         cout << "        Output MIN: " << OutMin << endl;
217         cout << "        Output MAX: " << OutMax << endl;
218       }
219       if (Table != 0) {
220         cout << "      Scheduled by table: " << endl;
221         Table->Print();
222       }
223     }
224   }
225   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
226     if (from == 0) cout << "Instantiated: FGGain" << endl;
227     if (from == 1) cout << "Destroyed:    FGGain" << endl;
228   }
229   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
230   }
231   if (debug_lvl & 8 ) { // Runtime state variables
232   }
233   if (debug_lvl & 16) { // Sanity checking
234   }
235   if (debug_lvl & 64) {
236     if (from == 0) { // Constructor
237       cout << IdSrc << endl;
238       cout << IdHdr << endl;
239     }
240   }
241 }
242 }