JSBSim Flight Dynamics Model  1.0 (02 March 2017)
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 Software
13  Foundation; either version 2 of the License, or (at your option) any later
14  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 with
22  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
23  Place - Suite 330, Boston, MA 02111-1307, USA.
24 
25  Further information about the GNU Lesser General Public License can also be found on
26  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 derived
31 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 <iostream>
46 #include <iomanip>
47 #include <cstdlib>
48 #include "FGFDMExec.h"
49 #include "FGAtmosphere.h"
50 
51 namespace JSBSim {
52 
53 IDENT(IdSrc,"$Id: FGAtmosphere.cpp,v 1.62 2016/01/16 12:05:47 bcoconni Exp $");
54 IDENT(IdHdr,ID_ATMOSPHERE);
55 
56 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57 CLASS IMPLEMENTATION
58 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
59 
61  PressureAltitude(0.0), // ft
62  DensityAltitude(0.0), // ft
63  SutherlandConstant(198.72), // deg Rankine
64  Beta(2.269690E-08) // slug/(sec ft R^0.5)
65 {
66  Name = "FGAtmosphere";
67 
68  bind();
69  Debug(0);
70 }
71 
72 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73 
75 {
76  Debug(1);
77 }
78 
79 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80 
81 bool FGAtmosphere::InitModel(void)
82 {
83  if (!FGModel::InitModel()) return false;
84 
85  Calculate(0.0);
86  SLtemperature = Temperature = 518.67;
87  SLpressure = Pressure = 2116.22;
88  SLdensity = Density = Pressure/(Reng*Temperature);
89  SLsoundspeed = Soundspeed = sqrt(SHRatio*Reng*(Temperature));
90 
91  rSLtemperature = 1/SLtemperature ;
92  rSLpressure = 1/SLpressure ;
93  rSLdensity = 1/SLdensity ;
94  rSLsoundspeed = 1/SLsoundspeed ;
95 
96  return true;
97 }
98 
99 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
100 
101 bool FGAtmosphere::Run(bool Holding)
102 {
103  if (FGModel::Run(Holding)) return true;
104  if (Holding) return false;
105 
106  Calculate(in.altitudeASL);
107 
108  Debug(2);
109  return false;
110 }
111 
112 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113 
114 void FGAtmosphere::Calculate(double altitude)
115 {
116  FGPropertyNode* node = PropertyManager->GetNode();
117  if (!PropertyManager->HasNode("atmosphere/override/temperature"))
118  Temperature = GetTemperature(altitude);
119  else
120  Temperature = node->GetDouble("atmosphere/override/temperature");
121 
122  if (!PropertyManager->HasNode("atmosphere/override/pressure"))
123  Pressure = GetPressure(altitude);
124  else
125  Pressure = node->GetDouble("atmosphere/override/pressure");
126 
127  if (!PropertyManager->HasNode("atmosphere/override/density"))
128  Density = Pressure/(Reng*Temperature);
129  else
130  Density = node->GetDouble("atmosphere/override/density");
131 
132  Soundspeed = sqrt(SHRatio*Reng*(Temperature));
133  PressureAltitude = altitude;
134  DensityAltitude = altitude;
135 
136  Viscosity = Beta * pow(Temperature, 1.5) / (SutherlandConstant + Temperature);
137  KinematicViscosity = Viscosity / Density;
138 }
139 
140 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
141 
142 void FGAtmosphere::SetPressureSL(ePressure unit, double pressure)
143 {
144  double press = ConvertToPSF(pressure, unit);
145 
146  SLpressure = press;
147 }
148 
149 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
150 // Get the modeled density at a specified altitude
151 
152 double FGAtmosphere::GetDensity(double altitude) const
153 {
154  return GetPressure(altitude)/(Reng * GetTemperature(altitude));
155 }
156 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
157 // Get the sound speed at a specified altitude
158 
159 double FGAtmosphere::GetSoundSpeed(double altitude) const
160 {
161  return sqrt(SHRatio * Reng * GetTemperature(altitude));
162 }
163 
164 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
165 // This function sets the sea level temperature.
166 // Internally, the Rankine scale is used for calculations, so any temperature
167 // supplied must be converted to that unit.
168 
170 {
171  SLtemperature = ConvertToRankine(t, unit);
172 }
173 
174 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
175 
176 double FGAtmosphere::ConvertToRankine(double t, eTemperature unit) const
177 {
178  double targetTemp=0; // in degrees Rankine
179 
180  switch(unit) {
181  case eFahrenheit:
182  targetTemp = t + 459.67;
183  break;
184  case eCelsius:
185  targetTemp = t*9.0/5.0 + 32.0 + 459.67;
186  break;
187  case eRankine:
188  targetTemp = t;
189  break;
190  case eKelvin:
191  targetTemp = t*9.0/5.0;
192  break;
193  default:
194  break;
195  }
196 
197  return targetTemp;
198 }
199 
200 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
201 
202 double FGAtmosphere::ConvertToPSF(double p, ePressure unit) const
203 {
204  double targetPressure=0; // Pressure in PSF
205 
206  switch(unit) {
207  case ePSF:
208  targetPressure = p;
209  break;
210  case eMillibars:
211  targetPressure = p*2.08854342;
212  break;
213  case ePascals:
214  targetPressure = p*0.0208854342;
215  break;
216  case eInchesHg:
217  targetPressure = p*70.7180803;
218  break;
219  default:
220  throw("Undefined pressure unit given");
221  }
222 
223  return targetPressure;
224 }
225 
226 double FGAtmosphere::ConvertFromPSF(double p, ePressure unit) const
227 {
228  double targetPressure=0; // Pressure in PSF
229 
230  switch(unit) {
231  case ePSF:
232  targetPressure = p;
233  break;
234  case eMillibars:
235  targetPressure = p/2.08854342;
236  break;
237  case ePascals:
238  targetPressure = p/0.0208854342;
239  break;
240  case eInchesHg:
241  targetPressure = p/70.7180803;
242  break;
243  default:
244  throw("Undefined pressure unit given");
245  }
246 
247  return targetPressure;
248 }
249 
250 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
251 
252 void FGAtmosphere::bind(void)
253 {
254  PropertyManager->Tie("atmosphere/T-R", this, &FGAtmosphere::GetTemperature);
255  PropertyManager->Tie("atmosphere/rho-slugs_ft3", this, &FGAtmosphere::GetDensity);
256  PropertyManager->Tie("atmosphere/P-psf", this, &FGAtmosphere::GetPressure);
257  PropertyManager->Tie("atmosphere/a-fps", this, &FGAtmosphere::GetSoundSpeed);
258  PropertyManager->Tie("atmosphere/T-sl-R", this, &FGAtmosphere::GetTemperatureSL);
259  PropertyManager->Tie("atmosphere/rho-sl-slugs_ft3", this, &FGAtmosphere::GetDensitySL);
260  PropertyManager->Tie("atmosphere/a-sl-fps", this, &FGAtmosphere::GetSoundSpeedSL);
261  PropertyManager->Tie("atmosphere/theta", this, &FGAtmosphere::GetTemperatureRatio);
262  PropertyManager->Tie("atmosphere/sigma", this, &FGAtmosphere::GetDensityRatio);
263  PropertyManager->Tie("atmosphere/delta", this, &FGAtmosphere::GetPressureRatio);
264  PropertyManager->Tie("atmosphere/a-ratio", this, &FGAtmosphere::GetSoundSpeedRatio);
265  PropertyManager->Tie("atmosphere/density-altitude", this, &FGAtmosphere::GetDensityAltitude);
266  PropertyManager->Tie("atmosphere/pressure-altitude", this, &FGAtmosphere::GetPressureAltitude);
267 }
268 
269 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
270 // The bitmasked value choices are as follows:
271 // unset: In this case (the default) JSBSim would only print
272 // out the normally expected messages, essentially echoing
273 // the config files as they are read. If the environment
274 // variable is not set, debug_lvl is set to 1 internally
275 // 0: This requests JSBSim not to output any messages
276 // whatsoever.
277 // 1: This value explicity requests the normal JSBSim
278 // startup messages
279 // 2: This value asks for a message to be printed out when
280 // a class is instantiated
281 // 4: When this value is set, a message is displayed when a
282 // FGModel object executes its Run() method
283 // 8: When this value is set, various runtime state variables
284 // are printed out periodically
285 // 16: When set various parameters are sanity checked and
286 // a message is printed out when they go out of bounds
287 
288 void FGAtmosphere::Debug(int from)
289 {
290  if (debug_lvl <= 0) return;
291 
292  if (debug_lvl & 1) { // Standard console startup message output
293  if (from == 0) { // Constructor
294  }
295  }
296  if (debug_lvl & 2 ) { // Instantiation/Destruction notification
297  if (from == 0) std::cout << "Instantiated: FGAtmosphere" << std::endl;
298  if (from == 1) std::cout << "Destroyed: FGAtmosphere" << std::endl;
299  }
300  if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
301  }
302  if (debug_lvl & 8 ) { // Runtime state variables
303  }
304  if (debug_lvl & 16) { // Sanity checking
305  }
306  if (debug_lvl & 128) { //
307  }
308  if (debug_lvl & 64) {
309  if (from == 0) { // Constructor
310  std::cout << IdSrc << std::endl;
311  std::cout << IdHdr << std::endl;
312  }
313  }
314 }
315 
316 } // namespace JSBSim
virtual void SetPressureSL(ePressure unit, double pressure)
Sets the sea level pressure for modeling.
virtual void SetTemperatureSL(double t, eTemperature unit=eFahrenheit)
Sets the Sea Level temperature.
void Calculate(double altitude)
Calculate the atmosphere for the given altitude.
virtual double GetSoundSpeedSL(void) const
Returns the sea level speed of sound in ft/sec.
Definition: FGAtmosphere.h:197
Class wrapper for property handling.
ePressure
Enums for specifying pressure units.
Definition: FGAtmosphere.h:91
virtual double GetPressure(void) const
Returns the pressure in psf.
Definition: FGAtmosphere.h:152
virtual ~FGAtmosphere()
Destructor.
virtual double GetPressureRatio(void) const
Returns the ratio of at-altitude pressure over the sea level value.
Definition: FGAtmosphere.h:161
virtual bool Run(bool Holding)
Runs the model; called by the Executive.
Definition: FGModel.cpp:92
void Tie(const std::string &name, bool *pointer, bool useDefault=true)
Tie a property to an external bool variable.
virtual double GetDensitySL(void) const
Returns the sea level density in slugs/ft^3.
Definition: FGAtmosphere.h:181
virtual double GetSoundSpeed(void) const
Returns the speed of sound in ft/sec.
Definition: FGAtmosphere.h:191
Base class for all scheduled JSBSim models.
Definition: FGModel.h:74
virtual double GetTemperatureSL() const
Returns the actual, modeled sea level temperature in degrees Rankine.
Definition: FGAtmosphere.h:126
double GetDouble(const std::string &name, double defaultValue=0.0) const
Get a double value for a property.
bool Run(bool Holding)
Runs the atmosphere forces model; called by the Executive.
virtual double GetDensity(void) const
Returns the density in slugs/ft^3.
Definition: FGAtmosphere.h:175
FGAtmosphere(FGFDMExec *)
Constructor.
eTemperature
Enums for specifying temperature units.
Definition: FGAtmosphere.h:88
virtual double GetSoundSpeedRatio(void) const
Returns the ratio of at-altitude sound speed over the sea level value.
Definition: FGAtmosphere.h:200
Encapsulates the JSBSim simulation executive.
Definition: FGFDMExec.h:189
virtual double GetDensityRatio(void) const
Returns the ratio of at-altitude density over the sea level value.
Definition: FGAtmosphere.h:184
virtual double GetTemperatureRatio() const
Returns the ratio of the at-current-altitude temperature as modeled over the sea level value...
Definition: FGAtmosphere.h:130
virtual double GetTemperature() const
Returns the actual, modeled temperature at the current altitude in degrees Rankine.
Definition: FGAtmosphere.h:117