JSBSim Flight Dynamics Model  1.1.11 (13 Feb 2022)
An Open Source Flight Dynamics and Control Software Library in C++
FGAtmosphere.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 
3  Module: FGAtmosphere.cpp
4  Author: Jon Berndt, Tony Peden
5  Date started: 6/2011
6  Purpose: Models an atmosphere interface class
7  Called by: FGFDMExec
8 
9  ------------- Copyright (C) 2011 Jon S. Berndt (jon@jsbsim.org) -------------
10 
11  This program is free software; you can redistribute it and/or modify it under
12  the terms of the GNU Lesser General Public License as published by the Free
13  Software Foundation; either version 2 of the License, or (at your option) any
14  later version.
15 
16  This program is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
19  details.
20 
21  You should have received a copy of the GNU Lesser General Public License along
22  with this program; if not, write to the Free Software Foundation, Inc., 59
23  Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 
25  Further information about the GNU Lesser General Public License can also be
26  found on the world wide web at http://www.gnu.org.
27 
28 FUNCTIONAL DESCRIPTION
29 --------------------------------------------------------------------------------
30 This models a base atmosphere class to serve as a common interface to any
31 derived atmosphere models.
32 
33 HISTORY
34 --------------------------------------------------------------------------------
35 6/18/2011 Started Jon S. Berndt
36 
37 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 COMMENTS, REFERENCES, and NOTES
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40 
41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 INCLUDES
43 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
44 
45 #include "FGFDMExec.h"
46 #include "FGAtmosphere.h"
47 
48 namespace JSBSim {
49 
50 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
51 CLASS IMPLEMENTATION
52 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
53 
54 // Atmosphere constants in British units converted from the SI values specified in the
55 // ISA document - https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770009539.pdf
56 double FGAtmosphere::Reng = Rstar / Mair;
57 
58 const double FGAtmosphere::StdDaySLsoundspeed = sqrt(SHRatio*Reng*StdDaySLtemperature);
59 
61  PressureAltitude(0.0), // ft
62  DensityAltitude(0.0) // ft
63 {
64  Name = "FGAtmosphere";
65 
66  bind();
67  Debug(0);
68 }
69 
70 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
71 
73 {
74  Debug(1);
75 }
76 
77 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78 
79 bool FGAtmosphere::InitModel(void)
80 {
81  if (!FGModel::InitModel()) return false;
82 
83  Calculate(0.0);
84  SLtemperature = Temperature = StdDaySLtemperature;
85  SLpressure = Pressure = StdDaySLpressure;
86  SLdensity = Density = Pressure/(Reng*Temperature);
87  SLsoundspeed = Soundspeed = StdDaySLsoundspeed;
88 
89  return true;
90 }
91 
92 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
93 
94 bool FGAtmosphere::Run(bool Holding)
95 {
96  if (FGModel::Run(Holding)) return true;
97  if (Holding) return false;
98 
99  Calculate(in.altitudeASL);
100 
101  Debug(2);
102  return false;
103 }
104 
105 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106 
107 void FGAtmosphere::Calculate(double altitude)
108 {
109  FGPropertyNode* node = PropertyManager->GetNode();
110  if (!PropertyManager->HasNode("atmosphere/override/temperature"))
111  Temperature = GetTemperature(altitude);
112  else
113  Temperature = node->GetDouble("atmosphere/override/temperature");
114 
115  if (!PropertyManager->HasNode("atmosphere/override/pressure"))
116  Pressure = GetPressure(altitude);
117  else
118  Pressure = node->GetDouble("atmosphere/override/pressure");
119 
120  if (!PropertyManager->HasNode("atmosphere/override/density"))
121  Density = GetDensity(altitude);
122  else
123  Density = node->GetDouble("atmosphere/override/density");
124 
125  Soundspeed = sqrt(SHRatio*Reng*Temperature);
126  PressureAltitude = CalculatePressureAltitude(Pressure, altitude);
127  DensityAltitude = CalculateDensityAltitude(Density, altitude);
128 
129  Viscosity = Beta * pow(Temperature, 1.5) / (SutherlandConstant + Temperature);
130  KinematicViscosity = Viscosity / Density;
131 }
132 
133 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134 
135 void FGAtmosphere::SetPressureSL(ePressure unit, double pressure)
136 {
137  double press = ConvertToPSF(pressure, unit);
138 
139  SLpressure = press;
140 }
141 
142 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143 // Get the modeled density at a specified altitude
144 
145 double FGAtmosphere::GetDensity(double altitude) const
146 {
147  return GetPressure(altitude)/(Reng * GetTemperature(altitude));
148 }
149 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
150 // Get the sound speed at a specified altitude
151 
152 double FGAtmosphere::GetSoundSpeed(double altitude) const
153 {
154  return sqrt(SHRatio * Reng * GetTemperature(altitude));
155 }
156 
157 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
158 // This function sets the sea level temperature.
159 // Internally, the Rankine scale is used for calculations, so any temperature
160 // supplied must be converted to that unit.
161 
163 {
164  SLtemperature = ConvertToRankine(t, unit);
165 }
166 
167 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
168 
169 double FGAtmosphere::ConvertToRankine(double t, eTemperature unit) const
170 {
171  double targetTemp=0; // in degrees Rankine
172 
173  switch(unit) {
174  case eFahrenheit:
175  targetTemp = t + 459.67;
176  break;
177  case eCelsius:
178  targetTemp = (t + 273.15) * 1.8;
179  break;
180  case eRankine:
181  targetTemp = t;
182  break;
183  case eKelvin:
184  targetTemp = t*1.8;
185  break;
186  default:
187  break;
188  }
189 
190  return targetTemp;
191 }
192 
193 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
194 
195 double FGAtmosphere::ConvertFromRankine(double t, eTemperature unit) const
196 {
197  double targetTemp=0;
198 
199  switch(unit) {
200  case eFahrenheit:
201  targetTemp = t - 459.67;
202  break;
203  case eCelsius:
204  targetTemp = t/1.8 - 273.15;
205  break;
206  case eRankine:
207  targetTemp = t;
208  break;
209  case eKelvin:
210  targetTemp = t/1.8;
211  break;
212  default:
213  break;
214  }
215 
216  return targetTemp;
217 }
218 
219 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
220 
221 double FGAtmosphere::ConvertToPSF(double p, ePressure unit) const
222 {
223  double targetPressure=0; // Pressure in PSF
224 
225  switch(unit) {
226  case ePSF:
227  targetPressure = p;
228  break;
229  case eMillibars:
230  targetPressure = p*2.08854342;
231  break;
232  case ePascals:
233  targetPressure = p*0.0208854342;
234  break;
235  case eInchesHg:
236  targetPressure = p*70.7180803;
237  break;
238  default:
239  throw("Undefined pressure unit given");
240  }
241 
242  return targetPressure;
243 }
244 
245 double FGAtmosphere::ConvertFromPSF(double p, ePressure unit) const
246 {
247  double targetPressure=0; // Pressure
248 
249  switch(unit) {
250  case ePSF:
251  targetPressure = p;
252  break;
253  case eMillibars:
254  targetPressure = p/2.08854342;
255  break;
256  case ePascals:
257  targetPressure = p/0.0208854342;
258  break;
259  case eInchesHg:
260  targetPressure = p/70.7180803;
261  break;
262  default:
263  throw("Undefined pressure unit given");
264  }
265 
266  return targetPressure;
267 }
268 
269 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
270 
271 void FGAtmosphere::bind(void)
272 {
273  PropertyManager->Tie("atmosphere/T-R", this, &FGAtmosphere::GetTemperature);
274  PropertyManager->Tie("atmosphere/rho-slugs_ft3", this, &FGAtmosphere::GetDensity);
275  PropertyManager->Tie("atmosphere/P-psf", this, &FGAtmosphere::GetPressure);
276  PropertyManager->Tie("atmosphere/a-fps", this, &FGAtmosphere::GetSoundSpeed);
277  PropertyManager->Tie("atmosphere/T-sl-R", this, &FGAtmosphere::GetTemperatureSL);
278  PropertyManager->Tie("atmosphere/rho-sl-slugs_ft3", this, &FGAtmosphere::GetDensitySL);
279  PropertyManager->Tie("atmosphere/a-sl-fps", this, &FGAtmosphere::GetSoundSpeedSL);
280  PropertyManager->Tie("atmosphere/theta", this, &FGAtmosphere::GetTemperatureRatio);
281  PropertyManager->Tie("atmosphere/sigma", this, &FGAtmosphere::GetDensityRatio);
282  PropertyManager->Tie("atmosphere/delta", this, &FGAtmosphere::GetPressureRatio);
283  PropertyManager->Tie("atmosphere/a-ratio", this, &FGAtmosphere::GetSoundSpeedRatio);
284  PropertyManager->Tie("atmosphere/density-altitude", this, &FGAtmosphere::GetDensityAltitude);
285  PropertyManager->Tie("atmosphere/pressure-altitude", this, &FGAtmosphere::GetPressureAltitude);
286 }
287 
288 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
289 // The bitmasked value choices are as follows:
290 // unset: In this case (the default) JSBSim would only print
291 // out the normally expected messages, essentially echoing
292 // the config files as they are read. If the environment
293 // variable is not set, debug_lvl is set to 1 internally
294 // 0: This requests JSBSim not to output any messages
295 // whatsoever.
296 // 1: This value explicity requests the normal JSBSim
297 // startup messages
298 // 2: This value asks for a message to be printed out when
299 // a class is instantiated
300 // 4: When this value is set, a message is displayed when a
301 // FGModel object executes its Run() method
302 // 8: When this value is set, various runtime state variables
303 // are printed out periodically
304 // 16: When set various parameters are sanity checked and
305 // a message is printed out when they go out of bounds
306 
307 void FGAtmosphere::Debug(int from)
308 {
309  if (debug_lvl <= 0) return;
310 
311  if (debug_lvl & 1) { // Standard console startup message output
312  if (from == 0) { // Constructor
313  }
314  }
315  if (debug_lvl & 2 ) { // Instantiation/Destruction notification
316  if (from == 0) std::cout << "Instantiated: FGAtmosphere" << std::endl;
317  if (from == 1) std::cout << "Destroyed: FGAtmosphere" << std::endl;
318  }
319  if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
320  }
321  if (debug_lvl & 8 ) { // Runtime state variables
322  }
323  if (debug_lvl & 16) { // Sanity checking
324  }
325  if (debug_lvl & 128) { //
326  }
327  if (debug_lvl & 64) {
328  if (from == 0) { // Constructor
329  }
330  }
331 }
332 
333 } // namespace JSBSim
JSBSim::FGFDMExec
Encapsulates the JSBSim simulation executive.
Definition: FGFDMExec.h:185
JSBSim::FGAtmosphere::eTemperature
eTemperature
Enums for specifying temperature units.
Definition: FGAtmosphere.h:80
JSBSim::FGAtmosphere::ConvertToRankine
double ConvertToRankine(double t, eTemperature unit) const
Converts to Rankine from one of several unit systems.
Definition: FGAtmosphere.cpp:169
JSBSim::FGAtmosphere::GetDensityRatio
virtual double GetDensityRatio(void) const
Returns the ratio of at-altitude density over the sea level value.
Definition: FGAtmosphere.h:176
JSBSim::FGAtmosphere::GetPressure
virtual double GetPressure(void) const
Returns the pressure in psf.
Definition: FGAtmosphere.h:144
JSBSim::FGModel
Base class for all scheduled JSBSim models.
Definition: FGModel.h:68
JSBSim::FGAtmosphere::GetSoundSpeedSL
virtual double GetSoundSpeedSL(void) const
Returns the sea level speed of sound in ft/sec.
Definition: FGAtmosphere.h:189
JSBSim::FGAtmosphere::ePressure
ePressure
Enums for specifying pressure units.
Definition: FGAtmosphere.h:83
JSBSim::FGAtmosphere::SetPressureSL
virtual void SetPressureSL(ePressure unit, double pressure)
Sets the sea level pressure for modeling.
Definition: FGAtmosphere.cpp:135
JSBSim::FGAtmosphere::ConvertToPSF
double ConvertToPSF(double t, ePressure unit=ePSF) const
Converts to PSF (pounds per square foot) from one of several unit systems.
Definition: FGAtmosphere.cpp:221
JSBSim::FGAtmosphere::ConvertFromPSF
double ConvertFromPSF(double t, ePressure unit=ePSF) const
Converts from PSF (pounds per square foot) to one of several unit systems.
Definition: FGAtmosphere.cpp:245
JSBSim::FGPropertyNode
Class wrapper for property handling.
Definition: FGPropertyManager.h:70
JSBSim::FGAtmosphere::Reng
static double Reng
Specific gas constant for air - ft*lbf/slug/R.
Definition: FGAtmosphere.h:270
JSBSim::FGAtmosphere::GetDensitySL
virtual double GetDensitySL(void) const
Returns the sea level density in slugs/ft^3.
Definition: FGAtmosphere.h:173
JSBSim::FGPropertyNode::GetDouble
double GetDouble(const std::string &name, double defaultValue=0.0) const
Get a double value for a property.
Definition: FGPropertyManager.cpp:203
JSBSim::FGAtmosphere::GetTemperatureSL
virtual double GetTemperatureSL() const
Returns the actual, modeled sea level temperature in degrees Rankine.
Definition: FGAtmosphere.h:118
JSBSim::FGAtmosphere::GetSoundSpeed
virtual double GetSoundSpeed(void) const
Returns the speed of sound in ft/sec.
Definition: FGAtmosphere.h:183
JSBSim::FGAtmosphere::Calculate
virtual void Calculate(double altitude)
Calculate the atmosphere for the given altitude.
Definition: FGAtmosphere.cpp:107
JSBSim::FGAtmosphere::SetTemperatureSL
virtual void SetTemperatureSL(double t, eTemperature unit=eFahrenheit)
Sets the Sea Level temperature.
Definition: FGAtmosphere.cpp:162
JSBSim::FGModel::Run
virtual bool Run(bool Holding)
Runs the model; called by the Executive.
Definition: FGModel.cpp:89
JSBSim::FGAtmosphere::GetSoundSpeedRatio
virtual double GetSoundSpeedRatio(void) const
Returns the ratio of at-altitude sound speed over the sea level value.
Definition: FGAtmosphere.h:192
JSBSim::FGAtmosphere::GetPressureRatio
virtual double GetPressureRatio(void) const
Returns the ratio of at-altitude pressure over the sea level value.
Definition: FGAtmosphere.h:153
JSBSim::FGAtmosphere::ConvertFromRankine
double ConvertFromRankine(double t, eTemperature unit) const
Converts from Rankine to one of several unit systems.
Definition: FGAtmosphere.cpp:195
JSBSim::FGAtmosphere::GetTemperature
virtual double GetTemperature() const
Returns the actual, modeled temperature at the current altitude in degrees Rankine.
Definition: FGAtmosphere.h:109
JSBSim::FGAtmosphere::CalculatePressureAltitude
virtual double CalculatePressureAltitude(double pressure, double geometricAlt)
Calculates the pressure altitude given any temperature or pressure bias.
Definition: FGAtmosphere.h:243
JSBSim::FGAtmosphere::GetTemperatureRatio
virtual double GetTemperatureRatio() const
Returns the ratio of the at-current-altitude temperature as modeled over the sea level value.
Definition: FGAtmosphere.h:122
JSBSim::FGAtmosphere::FGAtmosphere
FGAtmosphere(FGFDMExec *)
Constructor.
Definition: FGAtmosphere.cpp:60
JSBSim::FGAtmosphere::~FGAtmosphere
virtual ~FGAtmosphere()
Destructor.
Definition: FGAtmosphere.cpp:72
JSBSim::FGAtmosphere::Run
bool Run(bool Holding) override
Runs the atmosphere forces model; called by the Executive.
Definition: FGAtmosphere.cpp:94
JSBSim::FGAtmosphere::GetDensity
virtual double GetDensity(void) const
Returns the density in slugs/ft^3.
Definition: FGAtmosphere.h:167
JSBSim::FGAtmosphere::CalculateDensityAltitude
virtual double CalculateDensityAltitude(double density, double geometricAlt)
Calculates the density altitude given any temperature or pressure bias.
Definition: FGAtmosphere.h:236
JSBSim::FGPropertyManager::Tie
void Tie(const std::string &name, T *pointer)
Tie a property to an external variable.
Definition: FGPropertyManager.h:449