]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/filtersjb/FGGain.cpp
Fix stall widths for the "auxilliary" (reverse flow) stalls so they
[flightgear.git] / src / FDM / JSBSim / filtersjb / 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
52 FGGain::FGGain(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
53                                                    AC_cfg(AC_cfg)
54 {
55   string token;
56   string strScheduledBy;
57   string sOutputIdx;
58
59   State = fcs->GetState();
60
61   Gain = 1.000;
62   Rows = 0;
63   Min = Max = 0.0;
64   OutputPct = 0;
65   invert = false;
66   ScheduledBy = 0;
67   clip = false;
68   clipmin = clipmax = 0.0;
69
70   Type = AC_cfg->GetValue("TYPE");
71   Name = AC_cfg->GetValue("NAME");
72   AC_cfg->GetNextConfigLine();
73
74   while ((token = AC_cfg->GetValue()) != string("/COMPONENT")) {
75     *AC_cfg >> token;
76     if (token == "INPUT") {
77       *AC_cfg >> token;
78
79       if (token[0] == '-') {
80         invert = true;
81         token.erase(0,1);
82       }
83
84       if (InputNodes.size() > 0) {
85         cerr << "Gains can only accept one input" << endl;
86       } else  {
87         InputNodes.push_back( resolveSymbol(token) );
88       }
89
90     } else if (token == "GAIN") {
91       *AC_cfg >> Gain;
92     } else if (token == "MIN") {
93       *AC_cfg >> Min;
94     } else if (token == "MAX") {
95       *AC_cfg >> Max;
96     } else if (token == "CLIPTO") {
97       *AC_cfg >> clipmin >> clipmax;
98       if (clipmax > clipmin) {
99         clip = true;
100       }
101     } else if (token == "INVERT") {
102       invert = true;
103       cerr << endl << "The INVERT keyword is being deprecated and will not be "
104                       "supported in the future. Please use a minus sign in front "
105                       "of an input property in the future." << endl << endl;
106     } else if (token == "ROWS") {
107       *AC_cfg >> Rows;
108       Table = new FGTable(Rows);
109     } else if (token == "SCHEDULED_BY") {
110       token = AC_cfg->GetValue("SCHEDULED_BY");
111       *AC_cfg >> strScheduledBy;
112       ScheduledBy = PropertyManager->GetNode( strScheduledBy );
113     } else if (token == "OUTPUT") {
114       IsOutput = true;
115       *AC_cfg >> sOutputIdx;
116       OutputNode = PropertyManager->GetNode( sOutputIdx, true );
117     } else {
118       AC_cfg->ResetLineIndexToZero();
119       *Table << *AC_cfg;
120     }
121   }
122
123   FGFCSComponent::bind();
124   if (Type == "AEROSURFACE_SCALE")
125     treenode->Tie( "output-norm", this, &FGGain::GetOutputPct );
126
127   Debug(0);
128 }
129
130 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
131
132 FGGain::~FGGain()
133 {
134   Debug(1);
135 }
136
137 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
138
139 bool FGGain::Run(void )
140 {
141   double SchedGain = 1.0;
142   double LookupVal = 0;
143
144   FGFCSComponent::Run(); // call the base class for initialization of Input
145   Input = InputNodes[0]->getDoubleValue();
146
147   if (invert) Input = -Input;
148
149   if (Type == "PURE_GAIN") {                       // PURE_GAIN
150
151     Output = Gain * Input;
152
153   } else if (Type == "SCHEDULED_GAIN") {           // SCHEDULED_GAIN
154
155     LookupVal = ScheduledBy->getDoubleValue();
156     SchedGain = Table->GetValue(LookupVal);
157     Output = Gain * SchedGain * Input;
158
159   } else if (Type == "AEROSURFACE_SCALE") {        // AEROSURFACE_SCALE
160
161     OutputPct = Input;
162     if (Input >= 0.0) Output = Input * Max;
163     else Output = Input * -Min;
164     Output *= Gain;
165
166   }
167
168   if (clip) {
169     if (Output > clipmax)      Output = clipmax;
170     else if (Output < clipmin) Output = clipmin;
171   }
172
173   if (IsOutput) SetOutput();
174
175   return true;
176 }
177
178 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
179
180 void FGGain::convert(void)
181 {
182   cout << endl;
183   cout << "        <component name=\"" << Name << "\" type=\"" << Type << "\">" << endl;
184
185   if (invert)
186     cout << "            <input>-" << (InputNodes[0]->GetFullyQualifiedName()).substr(12) << "</input>" << endl;
187   else
188     cout << "            <input>" << (InputNodes[0]->GetFullyQualifiedName()).substr(12) << "</input>" << endl;
189
190   if (Gain != 1.0)
191     cout << "            <gain>" << Gain << "</gain>" << endl;
192
193   if (Type == "PURE_GAIN") {                       // PURE_GAIN
194   } else if (Type == "SCHEDULED_GAIN") {           // SCHEDULED_GAIN
195     cout << "            <table>" << endl;
196     cout << "                <independentVar>" << ScheduledBy->GetFullyQualifiedName().substr(12) << "</independentVar>" << endl;
197     cout << "                <tableData>" << endl;
198     Table->Print(20);
199     cout << "                </tableData>" << endl;
200     cout << "            </table>" << endl;
201   } else if (Type == "AEROSURFACE_SCALE") {        // AEROSURFACE_SCALE
202     cout << "            <limit>" << endl;
203     cout << "                <min>" << Min << "</min>" << endl;
204     cout << "                <max>" << Max << "</max>" << endl;
205     cout << "            </limit>" << endl;
206   }
207
208   if (clip) {
209     cout << "            <clip>" << endl;
210     cout << "                <min>" << clipmin << "</min>" << endl;
211     cout << "                <max>" << clipmax << "</max>" << endl;
212     cout << "            </clip>" << endl;
213   }
214
215   if (IsOutput)
216     cout << "            <output>" << (OutputNode->GetFullyQualifiedName()).substr(12) << "</output>" << endl;
217
218   cout << "        </component>" << endl;
219 }
220
221 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222 //    The bitmasked value choices are as follows:
223 //    unset: In this case (the default) JSBSim would only print
224 //       out the normally expected messages, essentially echoing
225 //       the config files as they are read. If the environment
226 //       variable is not set, debug_lvl is set to 1 internally
227 //    0: This requests JSBSim not to output any messages
228 //       whatsoever.
229 //    1: This value explicity requests the normal JSBSim
230 //       startup messages
231 //    2: This value asks for a message to be printed out when
232 //       a class is instantiated
233 //    4: When this value is set, a message is displayed when a
234 //       FGModel object executes its Run() method
235 //    8: When this value is set, various runtime state variables
236 //       are printed out periodically
237 //    16: When set various parameters are sanity checked and
238 //       a message is printed out when they go out of bounds
239
240 void FGGain::Debug(int from)
241 {
242   if (debug_lvl <= 0) return;
243
244   if (debug_lvl & 1) { // Standard console startup message output
245     if (from == 0) { // Constructor
246       if (invert)
247         cout << "      INPUT: -" << InputNodes[0]->getName() << endl;
248       else
249         cout << "      INPUT: " << InputNodes[0]->getName() << endl;
250
251       cout << "      GAIN: " << Gain << endl;
252       if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
253       cout << "      MIN: " << Min << endl;
254       cout << "      MAX: " << Max << endl;
255       if (ScheduledBy != 0) {
256         cout << "      Scheduled by parameter: " << ScheduledBy->getName() << endl;
257         Table->Print();
258       }
259     }
260   }
261   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
262     if (from == 0) cout << "Instantiated: FGGain" << endl;
263     if (from == 1) cout << "Destroyed:    FGGain" << endl;
264   }
265   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
266   }
267   if (debug_lvl & 8 ) { // Runtime state variables
268   }
269   if (debug_lvl & 16) { // Sanity checking
270   }
271   if (debug_lvl & 64) {
272     if (from == 0) { // Constructor
273       cout << IdSrc << endl;
274       cout << IdHdr << endl;
275     }
276   }
277 }
278 }