Branch data Line data Source code
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.22 2010/08/24 10:37:17 jberndt Exp $";
51 : : static const char *IdHdr = ID_GAIN;
52 : :
53 : : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
54 : : CLASS IMPLEMENTATION
55 : : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
56 : :
57 : 7 : FGGain::FGGain(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
58 : : {
59 : : Element *scale_element, *zero_centered;
60 : 7 : string strScheduledBy, gain_string, sZeroCentered;
61 : :
62 : 7 : GainPropertyNode = 0;
63 : 7 : GainPropertySign = 1.0;
64 : 7 : Gain = 1.000;
65 : 7 : Rows = 0;
66 : 7 : Table = 0;
67 : 7 : InMin = -1.0;
68 : 7 : InMax = 1.0;
69 : 7 : OutMin = OutMax = 0.0;
70 : :
71 [ + - # # ]: 7 : if (Type == "PURE_GAIN") {
72 [ - + ][ # # ]: 7 : if ( !element->FindElement("gain") ) {
73 : 0 : cerr << highint << " No GAIN specified (default: 1.0)" << normint << endl;
74 : : }
75 : : }
76 : :
77 [ + - ][ # # ]: 7 : if ( element->FindElement("gain") ) {
78 : 14 : gain_string = element->FindElementValue("gain");
79 [ - + # # ]: 7 : if (!is_number(gain_string)) { // property
80 [ # # # # ]: 0 : if (gain_string[0] == '-') {
81 : 0 : GainPropertySign = -1.0;
82 : 0 : gain_string.erase(0,1);
83 : : }
84 : 0 : GainPropertyNode = PropertyManager->GetNode(gain_string);
85 : : } else {
86 : 7 : Gain = element->FindElementValueAsNumber("gain");
87 : : }
88 : : }
89 : :
90 [ - + # # ]: 7 : if (Type == "AEROSURFACE_SCALE") {
91 : 0 : scale_element = element->FindElement("domain");
92 [ # # # # ]: 0 : if (scale_element) {
93 [ # # ][ # # ]: 0 : if (scale_element->FindElement("max") && scale_element->FindElement("min") )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
94 : : {
95 : 0 : InMax = scale_element->FindElementValueAsNumber("max");
96 : 0 : InMin = scale_element->FindElementValueAsNumber("min");
97 : : }
98 : : }
99 : 0 : scale_element = element->FindElement("range");
100 [ # # ][ # # ]: 0 : if (!scale_element) throw(string("No range supplied for aerosurface scale component"));
101 [ # # ][ # # ]: 0 : if (scale_element->FindElement("max") && scale_element->FindElement("min") )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
102 : : {
103 : 0 : OutMax = scale_element->FindElementValueAsNumber("max");
104 : 0 : OutMin = scale_element->FindElementValueAsNumber("min");
105 : : } else {
106 : : cerr << "Maximum and minimum output values must be supplied for the "
107 : 0 : "aerosurface scale component" << endl;
108 : 0 : exit(-1);
109 : : }
110 : 0 : ZeroCentered = true;
111 : 0 : zero_centered = element->FindElement("zero_centered");
112 : : //ToDo if zero centered, then mins must be <0 and max's must be >0
113 [ # # # # ]: 0 : if (zero_centered) {
114 : 0 : sZeroCentered = element->FindElementValue("zero_centered");
115 [ # # ][ # # ]: 0 : if (sZeroCentered == string("0") || sZeroCentered == string("false")) {
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
116 : 0 : ZeroCentered = false;
117 : : }
118 : : }
119 : : }
120 : :
121 [ - + # # ]: 7 : if (Type == "SCHEDULED_GAIN") {
122 [ # # ][ # # ]: 0 : if (element->FindElement("table")) {
123 : 0 : Table = new FGTable(PropertyManager, element->FindElement("table"));
124 : : } else {
125 : 0 : cerr << "A table must be provided for the scheduled gain component" << endl;
126 : 0 : exit(-1);
127 : : }
128 : : }
129 : :
130 : 7 : FGFCSComponent::bind();
131 : :
132 : 7 : Debug(0);
133 : 7 : }
134 : :
135 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136 : :
137 : 7 : FGGain::~FGGain()
138 : : {
139 [ - + ][ # # ]: 7 : delete Table;
[ # # ]
140 : :
141 : 7 : Debug(1);
142 [ + - ][ # # ]: 7 : }
[ # # ]
143 : :
144 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
145 : :
146 : 378035 : bool FGGain::Run(void )
147 : : {
148 : 378035 : double SchedGain = 1.0;
149 : :
150 : 378035 : Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
151 : :
152 [ - + ]: 378035 : if (GainPropertyNode != 0) Gain = GainPropertyNode->getDoubleValue() * GainPropertySign;
153 : :
154 [ + - ]: 378035 : if (Type == "PURE_GAIN") { // PURE_GAIN
155 : :
156 : 378035 : Output = Gain * Input;
157 : :
158 [ # # ]: 0 : } else if (Type == "SCHEDULED_GAIN") { // SCHEDULED_GAIN
159 : :
160 : 0 : SchedGain = Table->GetValue();
161 : 0 : Output = Gain * SchedGain * Input;
162 : :
163 [ # # ]: 0 : } else if (Type == "AEROSURFACE_SCALE") { // AEROSURFACE_SCALE
164 : :
165 [ # # ]: 0 : if (ZeroCentered) {
166 [ # # ]: 0 : if (Input == 0.0) {
167 : 0 : Output = 0.0;
168 [ # # ]: 0 : } else if (Input > 0) {
169 : 0 : Output = (Input / InMax) * OutMax;
170 : : } else {
171 : 0 : Output = (Input / InMin) * OutMin;
172 : : }
173 : : } else {
174 : 0 : Output = OutMin + ((Input - InMin) / (InMax - InMin)) * (OutMax - OutMin);
175 : : }
176 : :
177 : 0 : Output *= Gain;
178 : : }
179 : :
180 : 378035 : Clip();
181 [ - + ]: 378035 : if (IsOutput) SetOutput();
182 : :
183 : 378035 : 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 : 14 : void FGGain::Debug(int from)
206 : : {
207 [ + - ]: 14 : if (debug_lvl <= 0) return;
208 : :
209 [ + - ]: 14 : if (debug_lvl & 1) { // Standard console startup message output
210 [ + + ]: 14 : if (from == 0) { // Constructor
211 [ - + ]: 7 : if (InputSigns[0] < 0)
212 : 0 : cout << " INPUT: -" << InputNames[0] << endl;
213 : : else
214 : 7 : cout << " INPUT: " << InputNames[0] << endl;
215 : :
216 [ - + ]: 7 : if (GainPropertyNode != 0) {
217 : 0 : cout << " GAIN: " << GainPropertyNode->GetName() << endl;
218 : : } else {
219 : 7 : cout << " GAIN: " << Gain << endl;
220 : : }
221 [ - + ]: 7 : if (IsOutput) {
222 [ # # ]: 0 : for (unsigned int i=0; i<OutputNodes.size(); i++)
223 : 0 : cout << " OUTPUT: " << OutputNodes[i]->getName() << endl;
224 : : }
225 [ - + ]: 7 : if (Type == "AEROSURFACE_SCALE") {
226 : 0 : cout << " In/Out Mapping:" << endl;
227 : 0 : cout << " Input MIN: " << InMin << endl;
228 : 0 : cout << " Input MAX: " << InMax << endl;
229 : 0 : cout << " Output MIN: " << OutMin << endl;
230 : 0 : cout << " Output MAX: " << OutMax << endl;
231 : : }
232 [ - + ]: 7 : if (Table != 0) {
233 : 0 : cout << " Scheduled by table: " << endl;
234 : 0 : Table->Print();
235 : : }
236 : : }
237 : : }
238 [ - + ]: 14 : if (debug_lvl & 2 ) { // Instantiation/Destruction notification
239 [ # # ]: 0 : if (from == 0) cout << "Instantiated: FGGain" << endl;
240 [ # # ]: 0 : if (from == 1) cout << "Destroyed: FGGain" << endl;
241 : : }
242 : 14 : if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
243 : : }
244 : 14 : if (debug_lvl & 8 ) { // Runtime state variables
245 : : }
246 : 14 : if (debug_lvl & 16) { // Sanity checking
247 : : }
248 [ - + ]: 14 : if (debug_lvl & 64) {
249 [ # # ]: 0 : if (from == 0) { // Constructor
250 : 0 : cout << IdSrc << endl;
251 : 0 : cout << IdHdr << endl;
252 : : }
253 : : }
254 : : }
255 [ + + ][ + - ]: 12 : }
|