]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/FGJSBBase.cpp
GUI ‘restore defaults’ support.
[flightgear.git] / src / FDM / JSBSim / FGJSBBase.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Module:       FGJSBBase.cpp
4  Author:       Jon S. Berndt
5  Date started: 07/01/01
6  Purpose:      Encapsulates the JSBBase object
7
8  ------------- Copyright (C) 2001  Jon S. Berndt (jon@jsbsim.org) -------------
9
10  This program is free software; you can redistribute it and/or modify it under
11  the terms of the GNU Lesser General Public License as published by the Free Software
12  Foundation; either version 2 of the License, or (at your option) any later
13  version.
14
15  This program is distributed in the hope that it will be useful, but WITHOUT
16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
18  details.
19
20  You should have received a copy of the GNU Lesser General Public License along with
21  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22  Place - Suite 330, Boston, MA  02111-1307, USA.
23
24  Further information about the GNU Lesser General Public License can also be found on
25  the world wide web at http://www.gnu.org.
26
27 FUNCTIONAL DESCRIPTION
28 --------------------------------------------------------------------------------
29
30 HISTORY
31 --------------------------------------------------------------------------------
32 07/01/01  JSB  Created
33
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 INCLUDES
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
37
38 #define BASE
39
40 #include "FGJSBBase.h"
41 #include <iostream>
42 #include <sstream>
43 #include <cstdlib>
44
45 namespace JSBSim {
46
47 IDENT(IdSrc,"$Id: FGJSBBase.cpp,v 1.39 2014/09/03 17:35:04 bcoconni Exp $");
48 IDENT(IdHdr,ID_JSBBASE);
49
50 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
51 CLASS IMPLEMENTATION
52 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
53
54 #ifndef _MSC_VER
55     char FGJSBBase::highint[5]  = {27, '[', '1', 'm', '\0'      };
56     char FGJSBBase::halfint[5]  = {27, '[', '2', 'm', '\0'      };
57     char FGJSBBase::normint[6]  = {27, '[', '2', '2', 'm', '\0' };
58     char FGJSBBase::reset[5]    = {27, '[', '0', 'm', '\0'      };
59     char FGJSBBase::underon[5]  = {27, '[', '4', 'm', '\0'      };
60     char FGJSBBase::underoff[6] = {27, '[', '2', '4', 'm', '\0' };
61     char FGJSBBase::fgblue[6]   = {27, '[', '3', '4', 'm', '\0' };
62     char FGJSBBase::fgcyan[6]   = {27, '[', '3', '6', 'm', '\0' };
63     char FGJSBBase::fgred[6]    = {27, '[', '3', '1', 'm', '\0' };
64     char FGJSBBase::fggreen[6]  = {27, '[', '3', '2', 'm', '\0' };
65     char FGJSBBase::fgdef[6]    = {27, '[', '3', '9', 'm', '\0' };
66 #else
67     char FGJSBBase::highint[5]  = {'\0' };
68     char FGJSBBase::halfint[5]  = {'\0' };
69     char FGJSBBase::normint[6]  = {'\0' };
70     char FGJSBBase::reset[5]    = {'\0' };
71     char FGJSBBase::underon[5]  = {'\0' };
72     char FGJSBBase::underoff[6] = {'\0' };
73     char FGJSBBase::fgblue[6]   = {'\0' };
74     char FGJSBBase::fgcyan[6]   = {'\0' };
75     char FGJSBBase::fgred[6]    = {'\0' };
76     char FGJSBBase::fggreen[6]  = {'\0' };
77     char FGJSBBase::fgdef[6]    = {'\0' };
78 #endif
79
80 const double FGJSBBase::radtodeg = 57.295779513082320876798154814105;
81 const double FGJSBBase::degtorad = 0.017453292519943295769236907684886;
82 const double FGJSBBase::hptoftlbssec = 550.0;
83 const double FGJSBBase::psftoinhg = 0.014138;
84 const double FGJSBBase::psftopa = 47.88;
85 const double FGJSBBase::fpstokts = 0.592484;
86 const double FGJSBBase::ktstofps = 1.68781;
87 const double FGJSBBase::inchtoft = 0.08333333;
88 const double FGJSBBase::in3tom3 = 1.638706E-5;
89 const double FGJSBBase::m3toft3 = 1.0/(fttom*fttom*fttom);
90 const double FGJSBBase::inhgtopa = 3386.38;
91 const double FGJSBBase::fttom = 0.3048;
92 double FGJSBBase::Reng = 1716.56;   // Gas constant for Air (ft-lb/slug-R)
93 double FGJSBBase::Rstar = 1545.348; // Universal gas constant
94 double FGJSBBase::Mair = 28.9645;   //
95 const double FGJSBBase::SHRatio = 1.40;
96
97 // Note that definition of lbtoslug by the inverse of slugtolb and not
98 // to a different constant you can also get from some tables will make
99 // lbtoslug*slugtolb == 1 up to the magnitude of roundoff. So converting from
100 // slug to lb and back will yield to the original value you started with up
101 // to the magnitude of roundoff.
102 // Taken from units gnu commandline tool
103 const double FGJSBBase::slugtolb = 32.174049;
104 const double FGJSBBase::lbtoslug = 1.0/slugtolb;
105 const double FGJSBBase::kgtolb = 2.20462;
106 const double FGJSBBase::kgtoslug = 0.06852168;
107
108 const string FGJSBBase::needed_cfg_version = "2.0";
109 const string FGJSBBase::JSBSim_version = "1.0 " __DATE__ " " __TIME__ ;
110
111 std::queue <FGJSBBase::Message> FGJSBBase::Messages;
112 FGJSBBase::Message FGJSBBase::localMsg;
113 unsigned int FGJSBBase::messageId = 0;
114
115 int FGJSBBase::gaussian_random_number_phase = 0;
116
117 short FGJSBBase::debug_lvl  = 1;
118
119 using std::cerr;
120 using std::cout;
121 using std::endl;
122
123 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
124
125 void FGJSBBase::PutMessage(const Message& msg)
126 {
127   Messages.push(msg);
128 }
129
130 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
131
132 void FGJSBBase::PutMessage(const string& text)
133 {
134   Message msg;
135   msg.text = text;
136   msg.messageId = messageId++;
137   msg.subsystem = "FDM";
138   msg.type = Message::eText;
139   Messages.push(msg);
140 }
141
142 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143
144 void FGJSBBase::PutMessage(const string& text, bool bVal)
145 {
146   Message msg;
147   msg.text = text;
148   msg.messageId = messageId++;
149   msg.subsystem = "FDM";
150   msg.type = Message::eBool;
151   msg.bVal = bVal;
152   Messages.push(msg);
153 }
154
155 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
156
157 void FGJSBBase::PutMessage(const string& text, int iVal)
158 {
159   Message msg;
160   msg.text = text;
161   msg.messageId = messageId++;
162   msg.subsystem = "FDM";
163   msg.type = Message::eInteger;
164   msg.iVal = iVal;
165   Messages.push(msg);
166 }
167
168 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
169
170 void FGJSBBase::PutMessage(const string& text, double dVal)
171 {
172   Message msg;
173   msg.text = text;
174   msg.messageId = messageId++;
175   msg.subsystem = "FDM";
176   msg.type = Message::eDouble;
177   msg.dVal = dVal;
178   Messages.push(msg);
179 }
180
181 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182
183 int FGJSBBase::SomeMessages(void)
184 {
185   return !Messages.empty();
186 }
187
188 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
189
190 void FGJSBBase::ProcessMessage(void)
191 {
192   if (Messages.empty()) return;
193   localMsg = Messages.front();
194
195   while (Messages.size() > 0) {
196       switch (localMsg.type) {
197       case JSBSim::FGJSBBase::Message::eText:
198         cout << localMsg.messageId << ": " << localMsg.text << endl;
199         break;
200       case JSBSim::FGJSBBase::Message::eBool:
201         cout << localMsg.messageId << ": " << localMsg.text << " " << localMsg.bVal << endl;
202         break;
203       case JSBSim::FGJSBBase::Message::eInteger:
204         cout << localMsg.messageId << ": " << localMsg.text << " " << localMsg.iVal << endl;
205         break;
206       case JSBSim::FGJSBBase::Message::eDouble:
207         cout << localMsg.messageId << ": " << localMsg.text << " " << localMsg.dVal << endl;
208         break;
209       default:
210         cerr << "Unrecognized message type." << endl;
211         break;
212       }
213       Messages.pop();
214       if (Messages.size() > 0) localMsg = Messages.front();
215       else break;
216   }
217
218 }
219
220 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221
222 FGJSBBase::Message* FGJSBBase::ProcessNextMessage(void)
223 {
224   if (Messages.empty()) return NULL;
225   localMsg = Messages.front();
226
227   Messages.pop();
228   return &localMsg;
229 }
230
231 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
232
233 void FGJSBBase::disableHighLighting(void)
234 {
235   highint[0]='\0';
236   halfint[0]='\0';
237   normint[0]='\0';
238   reset[0]='\0';
239   underon[0]='\0';
240   underoff[0]='\0';
241   fgblue[0]='\0';
242   fgcyan[0]='\0';
243   fgred[0]='\0';
244   fggreen[0]='\0';
245   fgdef[0]='\0';
246 }
247
248 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249
250 string FGJSBBase::CreateIndexedPropertyName(const string& Property, int index)
251 {
252   std::ostringstream buf;
253   buf << Property << '[' << index << ']';
254   return buf.str();
255 }
256
257 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
258
259 double FGJSBBase::GaussianRandomNumber(void)
260 {
261   static double V1, V2, S;
262   double X;
263
264   if (gaussian_random_number_phase == 0) {
265     V1 = V2 = S = X = 0.0;
266
267     do {
268       double U1 = (double)rand() / RAND_MAX;
269       double U2 = (double)rand() / RAND_MAX;
270
271       V1 = 2 * U1 - 1;
272       V2 = 2 * U2 - 1;
273       S = V1 * V1 + V2 * V2;
274     } while(S >= 1 || S == 0);
275
276     X = V1 * sqrt(-2 * log(S) / S);
277   } else
278     X = V2 * sqrt(-2 * log(S) / S);
279
280   gaussian_random_number_phase = 1 - gaussian_random_number_phase;
281
282   return X;
283 }
284
285 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286
287 double FGJSBBase::VcalibratedFromMach(double mach, double p, double psl, double rhosl)
288 {
289   double pt,A;
290
291   if (mach < 0) mach=0;
292   if (mach < 1)    //calculate total pressure assuming isentropic flow
293     pt=p*pow((1 + 0.2*mach*mach),3.5);
294   else {
295     // shock in front of pitot tube, we'll assume its normal and use
296     // the Rayleigh Pitot Tube Formula, i.e. the ratio of total
297     // pressure behind the shock to the static pressure in front of
298     // the normal shock assumption should not be a bad one -- most supersonic
299     // aircraft place the pitot probe out front so that it is the forward
300     // most point on the aircraft.  The real shock would, of course, take
301     // on something like the shape of a rounded-off cone but, here again,
302     // the assumption should be good since the opening of the pitot probe
303     // is very small and, therefore, the effects of the shock curvature
304     // should be small as well. AFAIK, this approach is fairly well accepted
305     // within the aerospace community
306
307     // The denominator below is zero for Mach ~ 0.38, for which
308     // we'll never be here, so we're safe
309
310     pt = p*166.92158*pow(mach,7.0)/pow(7*mach*mach-1,2.5);
311   }
312
313   A = pow(((pt-p)/psl+1),0.28571);
314   return sqrt(7*psl/rhosl*(A-1));
315 }
316
317 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
318
319 double FGJSBBase::MachFromVcalibrated(double vcas, double p, double psl, double rhosl)
320 {
321   double pt = p + psl*(pow(1+vcas*vcas*rhosl/(7.0*psl),3.5)-1);
322
323   if (pt/p < 1.89293)
324     return sqrt(5.0*(pow(pt/p, 0.2857143) -1)); // Mach < 1
325   else {
326     // Mach >= 1
327     double mach = sqrt(0.77666*pt/p); // Initial guess is based on a quadratic approximation of the Rayleigh formula
328     double delta = 1.;
329     double target = pt/(166.92158*p);
330     int iter = 0;
331
332     // Find the root with Newton-Raphson. Since the differential is never zero,
333     // the function is monotonic and has only one root with a multiplicity of one.
334     // Convergence is certain.
335     while (delta > 1E-5 && iter < 10) {
336       double m2 = mach*mach; // Mach^2
337       double m6 = m2*m2*m2;  // Mach^6
338       delta = mach*m6/pow(7.0*m2-1.0,2.5) - target;
339       double diff = 7.0*m6*(2.0*m2-1)/pow(7.0*m2-1.0,3.5); // Never zero when Mach >= 1
340       mach -= delta/diff;
341       iter++;
342     }
343
344     return mach;
345   }
346 }
347 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
348
349 } // namespace JSBSim
350