FlightGear next
FGJSBBase.cpp
Go to the documentation of this file.
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
12 Software Foundation; either version 2 of the License, or (at your option) any
13 later 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
21 with this program; if not, write to the Free Software Foundation, Inc., 59
22 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 Further information about the GNU Lesser General Public License can also be
25 found on the world wide web at http://www.gnu.org.
26
27FUNCTIONAL DESCRIPTION
28--------------------------------------------------------------------------------
29
30HISTORY
31--------------------------------------------------------------------------------
3207/01/01 JSB Created
33
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35INCLUDES
36%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
37
38#define BASE
39
40#include "FGJSBBase.h"
41#include "models/FGAtmosphere.h"
42
43using namespace std;
44
45namespace JSBSim {
46
47/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
48CLASS IMPLEMENTATION
49%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
50
51#ifndef _MSC_VER
52 char FGJSBBase::highint[5] = {27, '[', '1', 'm', '\0' };
53 char FGJSBBase::halfint[5] = {27, '[', '2', 'm', '\0' };
54 char FGJSBBase::normint[6] = {27, '[', '2', '2', 'm', '\0' };
55 char FGJSBBase::reset[5] = {27, '[', '0', 'm', '\0' };
56 char FGJSBBase::underon[5] = {27, '[', '4', 'm', '\0' };
57 char FGJSBBase::underoff[6] = {27, '[', '2', '4', 'm', '\0' };
58 char FGJSBBase::fgblue[6] = {27, '[', '3', '4', 'm', '\0' };
59 char FGJSBBase::fgcyan[6] = {27, '[', '3', '6', 'm', '\0' };
60 char FGJSBBase::fgred[6] = {27, '[', '3', '1', 'm', '\0' };
61 char FGJSBBase::fggreen[6] = {27, '[', '3', '2', 'm', '\0' };
62 char FGJSBBase::fgdef[6] = {27, '[', '3', '9', 'm', '\0' };
63#else
64 char FGJSBBase::highint[5] = {'\0' };
65 char FGJSBBase::halfint[5] = {'\0' };
66 char FGJSBBase::normint[6] = {'\0' };
67 char FGJSBBase::reset[5] = {'\0' };
68 char FGJSBBase::underon[5] = {'\0' };
69 char FGJSBBase::underoff[6] = {'\0' };
70 char FGJSBBase::fgblue[6] = {'\0' };
71 char FGJSBBase::fgcyan[6] = {'\0' };
72 char FGJSBBase::fgred[6] = {'\0' };
73 char FGJSBBase::fggreen[6] = {'\0' };
74 char FGJSBBase::fgdef[6] = {'\0' };
75#endif
76
77const string FGJSBBase::needed_cfg_version = "2.0";
78const string FGJSBBase::JSBSim_version = JSBSIM_VERSION " " __DATE__ " " __TIME__ ;
79
80queue <FGJSBBase::Message> FGJSBBase::Messages;
81FGJSBBase::Message FGJSBBase::localMsg;
82unsigned int FGJSBBase::messageId = 0;
83
85
86short FGJSBBase::debug_lvl = 1;
87
88//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
89
91{
92 Messages.push(msg);
93}
94
95//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
96
97void FGJSBBase::PutMessage(const string& text)
98{
99 Message msg;
100 msg.text = text;
101 msg.messageId = messageId++;
102 msg.subsystem = "FDM";
103 msg.type = Message::eText;
104 Messages.push(msg);
105}
106
107//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108
109void FGJSBBase::PutMessage(const string& text, bool bVal)
110{
111 Message msg;
112 msg.text = text;
113 msg.messageId = messageId++;
114 msg.subsystem = "FDM";
115 msg.type = Message::eBool;
116 msg.bVal = bVal;
117 Messages.push(msg);
118}
119
120//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121
122void FGJSBBase::PutMessage(const string& text, int iVal)
123{
124 Message msg;
125 msg.text = text;
126 msg.messageId = messageId++;
127 msg.subsystem = "FDM";
128 msg.type = Message::eInteger;
129 msg.iVal = iVal;
130 Messages.push(msg);
131}
132
133//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134
135void FGJSBBase::PutMessage(const string& text, double dVal)
136{
137 Message msg;
138 msg.text = text;
139 msg.messageId = messageId++;
140 msg.subsystem = "FDM";
141 msg.type = Message::eDouble;
142 msg.dVal = dVal;
143 Messages.push(msg);
144}
145
146//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
147
149{
150 if (Messages.empty()) return;
151 localMsg = Messages.front();
152
153 while (SomeMessages()) {
154 switch (localMsg.type) {
156 cout << localMsg.messageId << ": " << localMsg.text << endl;
157 break;
159 cout << localMsg.messageId << ": " << localMsg.text << " " << localMsg.bVal << endl;
160 break;
162 cout << localMsg.messageId << ": " << localMsg.text << " " << localMsg.iVal << endl;
163 break;
165 cout << localMsg.messageId << ": " << localMsg.text << " " << localMsg.dVal << endl;
166 break;
167 default:
168 cerr << "Unrecognized message type." << endl;
169 break;
170 }
171 Messages.pop();
172 if (SomeMessages()) localMsg = Messages.front();
173 else break;
174 }
175
176}
177
178//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
179
181{
182 if (Messages.empty()) return NULL;
183 localMsg = Messages.front();
184
185 Messages.pop();
186 return &localMsg;
187}
188
189//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
190
192{
193 highint[0]='\0';
194 halfint[0]='\0';
195 normint[0]='\0';
196 reset[0]='\0';
197 underon[0]='\0';
198 underoff[0]='\0';
199 fgblue[0]='\0';
200 fgcyan[0]='\0';
201 fgred[0]='\0';
202 fggreen[0]='\0';
203 fgdef[0]='\0';
204}
205
206//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
207
208string FGJSBBase::CreateIndexedPropertyName(const string& Property, int index)
209{
210 ostringstream buf;
211 buf << Property << '[' << index << ']';
212 return buf.str();
213}
214
215//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
216
218{
219 static double V1, V2, S;
220 double X;
221
223 V1 = V2 = S = X = 0.0;
224
225 do {
226 double U1 = (double)rand() / RAND_MAX;
227 double U2 = (double)rand() / RAND_MAX;
228
229 V1 = 2 * U1 - 1;
230 V2 = 2 * U2 - 1;
231 S = V1 * V1 + V2 * V2;
232 } while(S >= 1 || S == 0);
233
234 X = V1 * sqrt(-2 * log(S) / S);
235 } else
236 X = V2 * sqrt(-2 * log(S) / S);
237
239
240 return X;
241}
242
243//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244
245double FGJSBBase::PitotTotalPressure(double mach, double p)
246{
247 if (mach < 0) return p;
248 if (mach < 1) //calculate total pressure assuming isentropic flow
249 return p*pow((1 + 0.2*mach*mach),3.5);
250 else {
251 // shock in front of pitot tube, we'll assume its normal and use
252 // the Rayleigh Pitot Tube Formula, i.e. the ratio of total
253 // pressure behind the shock to the static pressure in front of
254 // the normal shock assumption should not be a bad one -- most supersonic
255 // aircraft place the pitot probe out front so that it is the forward
256 // most point on the aircraft. The real shock would, of course, take
257 // on something like the shape of a rounded-off cone but, here again,
258 // the assumption should be good since the opening of the pitot probe
259 // is very small and, therefore, the effects of the shock curvature
260 // should be small as well. AFAIK, this approach is fairly well accepted
261 // within the aerospace community
262
263 // The denominator below is zero for Mach ~ 0.38, for which
264 // we'll never be here, so we're safe
265
266 return p*166.92158009316827*pow(mach,7.0)/pow(7*mach*mach-1,2.5);
267 }
268}
269
270//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271
272// Based on the formulas in the US Air Force Aircraft Performance Flight Testing
273// Manual (AFFTC-TIH-99-01). In particular sections 4.6 to 4.8.
274
275double FGJSBBase::MachFromImpactPressure(double qc, double p)
276{
277 double A = qc / p + 1;
278 double M = sqrt(5.0*(pow(A, 1. / 3.5) - 1)); // Equation (4.12)
279
280 if (M > 1.0)
281 for (unsigned int i = 0; i<10; i++)
282 M = 0.8812848543473311*sqrt(A*pow(1 - 1.0 / (7.0*M*M), 2.5)); // Equation (4.17)
283
284 return M;
285}
286
287//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
288
289double FGJSBBase::VcalibratedFromMach(double mach, double p)
290{
293 double qc = PitotTotalPressure(mach, p) - p;
294
295 return asl * MachFromImpactPressure(qc, psl);
296}
297
298//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
299
300double FGJSBBase::MachFromVcalibrated(double vcas, double p)
301{
304 double qc = PitotTotalPressure(vcas / asl, psl) - psl;
305
306 return MachFromImpactPressure(qc, p);
307}
308//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
309
310} // namespace JSBSim
311
#define p(x)
#define i(x)
static const double StdDaySLsoundspeed
static constexpr double StdDaySLpressure
void PutMessage(const Message &msg)
Places a Message structure on the Message queue.
Definition FGJSBBase.cpp:90
static unsigned int messageId
Definition FGJSBBase.h:346
static double PitotTotalPressure(double mach, double p)
Compute the total pressure in front of the Pitot tube.
static char fgdef[6]
default text
Definition FGJSBBase.h:143
static double MachFromImpactPressure(double qc, double p)
Compute the Mach number from the differential pressure (qc) and the static pressure.
static char halfint[5]
low intensity text
Definition FGJSBBase.h:125
static std::queue< Message > Messages
Definition FGJSBBase.h:344
static double GaussianRandomNumber(void)
static char highint[5]
highlights text
Definition FGJSBBase.h:123
int SomeMessages(void) const
Reads the message on the queue (but does not delete it).
Definition FGJSBBase.h:173
static char reset[5]
resets text properties
Definition FGJSBBase.h:129
static char fgblue[6]
blue text
Definition FGJSBBase.h:135
static char normint[6]
normal intensity text
Definition FGJSBBase.h:127
static int gaussian_random_number_phase
Definition FGJSBBase.h:375
static char fgred[6]
red text
Definition FGJSBBase.h:139
static char fggreen[6]
green text
Definition FGJSBBase.h:141
Message * ProcessNextMessage(void)
Reads the next message on the queue and removes it from the queue.
void disableHighLighting(void)
Disables highlighting in the console output.
static double VcalibratedFromMach(double mach, double p)
Calculate the calibrated airspeed from the Mach number.
void ProcessMessage(void)
Reads the message on the queue and removes it from the queue.
static const std::string JSBSim_version
Definition FGJSBBase.h:371
static char underoff[6]
underline off
Definition FGJSBBase.h:133
static short debug_lvl
Definition FGJSBBase.h:190
static Message localMsg
Definition FGJSBBase.h:342
static double MachFromVcalibrated(double vcas, double p)
Calculate the Mach number from the calibrated airspeed.Based on the formulas in the US Air Force Airc...
static char underon[5]
underlines text
Definition FGJSBBase.h:131
static const std::string needed_cfg_version
Definition FGJSBBase.h:370
static char fgcyan[6]
cyan text
Definition FGJSBBase.h:137
static std::string CreateIndexedPropertyName(const std::string &Property, int index)
#define M
JSBSim Message structure.
Definition FGJSBBase.h:87