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