]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/models/flight_control/FGGain.cpp
sync. with JSBSim v. 2.0
[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 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 General Public License for more
17  details.
18
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.
22
23  Further information about the GNU 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     if (gain_string.find_first_not_of("+-.0123456789") != string::npos) { // property
73       GainPropertyNode = PropertyManager->GetNode(gain_string);
74     } else {
75       Gain = element->FindElementValueAsNumber("gain");
76     }
77   }
78
79   if (Type == "AEROSURFACE_SCALE") {
80     scale_element = element->FindElement("domain");
81     if (scale_element) {
82       if (scale_element->FindElement("max") && scale_element->FindElement("min") )
83       {
84         InMax = scale_element->FindElementValueAsNumber("max");
85         InMin = scale_element->FindElementValueAsNumber("min");
86       }
87     }
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") )
91     {
92       OutMax = scale_element->FindElementValueAsNumber("max");
93       OutMin = scale_element->FindElementValueAsNumber("min");
94     } else {
95       cerr << "Maximum and minimum output values must be supplied for the "
96               "aerosurface scale component" << endl;
97       exit(-1);
98     }
99     ZeroCentered = true;
100     zero_centered = element->FindElement("zero_centered");
101     if (zero_centered) {
102       sZeroCentered = zero_centered->FindElementValue("zero_centered");
103       if (sZeroCentered == string("0") || sZeroCentered == string("false")) {
104         ZeroCentered = false;
105       }
106     }
107   }
108
109   if (Type == "SCHEDULED_GAIN") {
110     if (element->FindElement("table")) {
111       Table = new FGTable(PropertyManager, element->FindElement("table"));
112     } else {
113       cerr << "A table must be provided for the scheduled gain component" << endl;
114       exit(-1);
115     }
116   }
117
118   FGFCSComponent::bind();
119
120   Debug(0);
121 }
122
123 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
124
125 FGGain::~FGGain()
126 {
127   Debug(1);
128 }
129
130 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
131
132 bool FGGain::Run(void )
133 {
134   double SchedGain = 1.0;
135
136   Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
137
138   if (GainPropertyNode != 0) Gain = GainPropertyNode->getDoubleValue();
139
140   if (Type == "PURE_GAIN") {                       // PURE_GAIN
141
142     Output = Gain * Input;
143
144   } else if (Type == "SCHEDULED_GAIN") {           // SCHEDULED_GAIN
145
146     SchedGain = Table->GetValue();
147     Output = Gain * SchedGain * Input;
148
149   } else if (Type == "AEROSURFACE_SCALE") {        // AEROSURFACE_SCALE
150
151     if (ZeroCentered) {
152       if (Input == 0.0) {
153         Output = 0.0;
154       } else if (Input > 0) {
155         Output = (Input / InMax) * OutMax;
156       } else {
157         Output = (Input / InMin) * OutMin;
158       }
159     } else {
160       Output = OutMin + ((Input - InMin) / (InMax - InMin)) * (OutMax - OutMin);
161     }
162
163     Output *= Gain;
164   }
165
166   Clip();
167   if (IsOutput) SetOutput();
168
169   return true;
170 }
171
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
179 //       whatsoever.
180 //    1: This value explicity requests the normal JSBSim
181 //       startup messages
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
190
191 void FGGain::Debug(int from)
192 {
193   if (debug_lvl <= 0) return;
194
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;
199       else
200         cout << "      INPUT: " << InputNodes[0]->getName() << endl;
201
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;
210       }
211       if (Table != 0) {
212         cout << "      Scheduled by table: " << endl;
213         Table->Print();
214       }
215     }
216   }
217   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
218     if (from == 0) cout << "Instantiated: FGGain" << endl;
219     if (from == 1) cout << "Destroyed:    FGGain" << endl;
220   }
221   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
222   }
223   if (debug_lvl & 8 ) { // Runtime state variables
224   }
225   if (debug_lvl & 16) { // Sanity checking
226   }
227   if (debug_lvl & 64) {
228     if (from == 0) { // Constructor
229       cout << IdSrc << endl;
230       cout << IdHdr << endl;
231     }
232   }
233 }
234 }