JSBSim Flight Dynamics Model 1.3.0 (09 Apr 2026)
An Open Source Flight Dynamics and Control Software Library in C++
Loading...
Searching...
No Matches
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
11 Software Foundation; either version 2 of the License, or (at your option) any
12 later 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
20 with this program; if not, write to the Free Software Foundation, Inc., 59
21 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23 Further information about the GNU Lesser General Public License can also be
24 found on the world wide web at http://www.gnu.org.
25
26FUNCTIONAL DESCRIPTION
27--------------------------------------------------------------------------------
28
29HISTORY
30--------------------------------------------------------------------------------
31
32%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33COMMENTS, REFERENCES, and NOTES
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35
36%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37INCLUDES
38%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
39
40#include "FGGain.h"
41#include "models/FGFCS.h"
42#include "math/FGParameterValue.h"
43#include "math/FGTable.h"
44#include "input_output/FGLog.h"
45
46using namespace std;
47
48namespace JSBSim {
49
50/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
51CLASS IMPLEMENTATION
52%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
53
54FGGain::FGGain(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
55{
56 Gain = nullptr;
57 Table = nullptr;
58 InMin = -1.0;
59 InMax = 1.0;
60 OutMin = OutMax = 0.0;
61
62 CheckInputNodes(1, 1, element);
63
64 if (Type == "PURE_GAIN") {
65 if ( !element->FindElement("gain") ) {
66 FGXMLLogging log(element, LogLevel::ERROR);
67 log << LogFormat::BOLD << " No GAIN specified (default: 1.0)\n";
68 }
69 }
70
71 auto PropertyManager = fcs->GetPropertyManager();
72 Element* gain_element = element->FindElement("gain");
73 if (gain_element)
74 Gain = new FGParameterValue(gain_element, PropertyManager);
75 else
76 Gain = new FGRealValue(1.0);
77
78 if (Type == "AEROSURFACE_SCALE") {
79 Element* scale_element = element->FindElement("domain");
80 if (scale_element) {
81 if (scale_element->FindElement("max") && scale_element->FindElement("min") )
82 {
83 InMax = scale_element->FindElementValueAsNumber("max");
84 InMin = scale_element->FindElementValueAsNumber("min");
85 }
86 }
87 scale_element = element->FindElement("range");
88 if (!scale_element) {
89 XMLLogException err(scale_element);
90 err << "No range supplied for aerosurface scale component\n";
91 throw err;
92 }
93 if (scale_element->FindElement("max") && scale_element->FindElement("min") )
94 {
95 OutMax = scale_element->FindElementValueAsNumber("max");
96 OutMin = scale_element->FindElementValueAsNumber("min");
97 } else {
98 XMLLogException err(scale_element);
99 err << "Maximum and minimum output values must be supplied for the "
100 "aerosurface scale component\n";
101 throw err;
102 }
103 ZeroCentered = true;
104 Element* zero_centered = element->FindElement("zero_centered");
105 //ToDo if zero centered, then mins must be <0 and max's must be >0
106 if (zero_centered) {
107 string sZeroCentered = element->FindElementValue("zero_centered");
108 if (sZeroCentered == string("0") || sZeroCentered == string("false")) {
109 ZeroCentered = false;
110 }
111 }
112 }
113
114 if (Type == "SCHEDULED_GAIN") {
115 if (element->FindElement("table")) {
116 Table = new FGTable(PropertyManager, element->FindElement("table"));
117 } else {
118 XMLLogException err(element);
119 err << "A table must be provided for the scheduled gain component\n";
120 throw err;
121 }
122 }
123
124 bind(element, PropertyManager.get());
125
126 Debug(0);
127}
128
129//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130
131FGGain::~FGGain()
132{
133 delete Table;
134
135 Debug(1);
136}
137
138//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139
140bool FGGain::Run(void )
141{
142 Input = InputNodes[0]->getDoubleValue();
143
144 if (Type == "PURE_GAIN") { // PURE_GAIN
145
146 Output = Gain * Input;
147
148 } else if (Type == "SCHEDULED_GAIN") { // SCHEDULED_GAIN
149
150 double SchedGain = Table->GetValue();
151 Output = Gain * SchedGain * Input;
152
153 } else if (Type == "AEROSURFACE_SCALE") { // AEROSURFACE_SCALE
154
155 if (ZeroCentered) {
156 if (Input == 0.0) {
157 Output = 0.0;
158 } else if (Input > 0) {
159 Output = (Input / InMax) * OutMax;
160 } else {
161 Output = (Input / InMin) * OutMin;
162 }
163 } else {
164 Output = OutMin + ((Input - InMin) / (InMax - InMin)) * (OutMax - OutMin);
165 }
166
167 Output *= Gain->GetValue();
168 }
169
170 Clip();
171 SetOutput();
172
173 return true;
174}
175
176//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177// The bitmasked value choices are as follows:
178// unset: In this case (the default) JSBSim would only print
179// out the normally expected messages, essentially echoing
180// the config files as they are read. If the environment
181// variable is not set, debug_lvl is set to 1 internally
182// 0: This requests JSBSim not to output any messages
183// whatsoever.
184// 1: This value explicitly requests the normal JSBSim
185// startup messages
186// 2: This value asks for a message to be printed out when
187// a class is instantiated
188// 4: When this value is set, a message is displayed when a
189// FGModel object executes its Run() method
190// 8: When this value is set, various runtime state variables
191// are printed out periodically
192// 16: When set various parameters are sanity checked and
193// a message is printed out when they go out of bounds
194
195void FGGain::Debug(int from)
196{
197 if (debug_lvl <= 0) return;
198
199 if (debug_lvl & 1) { // Standard console startup message output
200 if (from == 0) { // Constructor
201 FGLogging log(LogLevel::DEBUG);
202 log << " INPUT: " << InputNodes[0]->GetNameWithSign() << "\n";
203 log << " GAIN: " << Gain->GetName() << fixed << "\n";
204
205 for (auto node: OutputNodes)
206 log << " OUTPUT: " << node->getNameString() << "\n";
207
208 if (Type == "AEROSURFACE_SCALE") {
209 log << " In/Out Mapping:\n" << setprecision(4);
210 log << " Input MIN: " << InMin << "\n";
211 log << " Input MAX: " << InMax << "\n";
212 log << " Output MIN: " << OutMin << "\n";
213 log << " Output MAX: " << OutMax << "\n";
214 }
215 if (Table) {
216 log << " Scheduled by table:\n";
217 Table->Print();
218 }
219 }
220 }
221 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
222 FGLogging log(LogLevel::DEBUG);
223 if (from == 0) log << "Instantiated: FGGain\n";
224 if (from == 1) log << "Destroyed: FGGain\n";
225 }
226 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
227 }
228 if (debug_lvl & 8 ) { // Runtime state variables
229 }
230 if (debug_lvl & 16) { // Sanity checking
231 }
232 if (debug_lvl & 64) {
233 if (from == 0) { // Constructor
234 }
235 }
236}
237}
Main namespace for the JSBSim Flight Dynamics Model.
Definition FGFDMExec.cpp:71