JSBSim Flight Dynamics Model  1.0 (02 March 2017)
An Open Source Flight Dynamics and Control Software Library in C++
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 IDENT(IdSrc,"$Id: FGGain.cpp,v 1.25 2014/01/13 10:46:09 ehofman Exp $");
51 IDENT(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 }
STL namespace.
static char normint[6]
normal intensity text
Definition: FGJSBBase.h:129
static char highint[5]
highlights text
Definition: FGJSBBase.h:125