1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 Implementation of 1959 Standard Atmosphere added by Tony Peden
8 ------------- Copyright (C) 1999 Jon S. Berndt (jon@jsbsim.org) -------------
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
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
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.
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.
28 --------------------------------------------------------------------------------
30 07/23/99 TP Added implementation of 1959 Standard Atmosphere
31 Moved calculation of Mach number to FGPropagate
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
38 #ifndef FGATMOSPHERE_H
39 #define FGATMOSPHERE_H
41 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
46 #include "math/FGColumnVector3.h"
47 #include "math/FGTable.h"
49 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
51 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
53 #define ID_ATMOSPHERE "$Id: FGAtmosphere.h,v 1.26 2011/05/20 03:18:36 jberndt Exp $"
55 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
61 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
65 /** Models the 1976 Standard Atmosphere.
66 @author Tony Peden, Jon Berndt
67 @version $Id: FGAtmosphere.h,v 1.26 2011/05/20 03:18:36 jberndt Exp $
68 @see Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill,
69 1989, ISBN 0-07-001641-0
71 Additionally, various turbulence models are available. They are specified
72 via the property <tt>atmosphere/turb-type</tt>. The following models are
74 - 0: ttNone (turbulence disabled)
78 - 4: ttMilspec (Dryden spectrum)
79 - 5: ttTustin (Dryden spectrum)
81 The Milspec and Tustin models are described in the Yeager report cited below.
82 They both use a Dryden spectrum model whose parameters (scale lengths and intensities)
83 are modelled according to MIL-F-8785C. Parameters are modelled differently
84 for altitudes below 1000ft and above 2000ft, for altitudes in between they
85 are interpolated linearly.
87 The two models differ in the implementation of the transfer functions
88 described in the milspec.
90 To use one of these two models, set <tt>atmosphere/turb-type</tt> to 4 resp. 5,
91 and specify values for <tt>atmosphere/turbulence/milspec/windspeed_at_20ft_AGL-fps<tt>
92 and <tt>atmosphere/turbulence/milspec/severity<tt> (the latter corresponds to
93 the probability of exceedence curves from Fig. 7 of the milspec, allowable
94 range is 0 (disabled) to 7). <tt>atmosphere/psiw-rad</tt> is respected as well;
95 note that you have to specify a positive wind magnitude to prevent psiw from
98 Reference values (cf. figures 7 and 9 from the milspec):
100 <tr><td><b>Intensity</b></td>
101 <td><b><tt>windspeed_at_20ft_AGL-fps</tt></b></td>
102 <td><b><tt>severity</tt></b></td></tr>
104 <td>25 (15 knots)</td>
106 <tr><td>moderate</td>
107 <td>50 (30 knots)</td>
110 <td>75 (45 knots)</td>
114 @see Yeager, Jessie C.: "Implementation and Testing of Turbulence Models for
116 href="http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19980028448_1998081596.pdf">
117 pdf</a>), NASA CR-1998-206937, 1998
119 @see MIL-F-8785C: Military Specification: Flying Qualities of Piloted Aircraft
123 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
127 class FGAtmosphere : public FGModel {
131 FGAtmosphere(FGFDMExec*);
134 /** Runs the Atmosphere model; called by the Executive
135 Can pass in a value indicating if the executive is directing the simulation to Hold.
136 @param Holding if true, the executive has been directed to hold the sim from
137 advancing time. Some models may ignore this flag, such as the Input
138 model, which may need to be active to listen on a socket for the
139 "Resume" command to be given.
140 @return false if no error */
141 bool Run(bool Holding);
142 bool InitModel(void);
143 enum tType {ttNone, ttStandard, ttCulp, ttMilspec, ttTustin} turbType;
145 /// Returns the temperature in degrees Rankine.
146 virtual double GetTemperature(void) const {return *temperature;}
147 /** Returns the density in slugs/ft^3.
148 <i>This function may <b>only</b> be used if Run() is called first.</i> */
149 virtual double GetDensity(void) const {return *density;}
150 /// Returns the pressure in psf.
151 virtual double GetPressure(void) const {return *pressure;}
152 /// Returns the standard pressure at a specified altitude
153 virtual double GetPressure(double altitude);
154 /// Returns the standard temperature at a specified altitude
155 virtual double GetTemperature(double altitude);
156 /// Returns the standard density at a specified altitude
157 virtual double GetDensity(double altitude);
158 /// Returns the speed of sound in ft/sec.
159 virtual double GetSoundSpeed(void) const {return soundspeed;}
160 /// Returns the absolute viscosity.
161 virtual double GetAbsoluteViscosity(void) const {return intViscosity;}
162 /// Returns the kinematic viscosity.
163 virtual double GetKinematicViscosity(void) const {return intKinematicViscosity;}
165 /// Returns the sea level temperature in degrees Rankine.
166 virtual double GetTemperatureSL(void) const { return SLtemperature; }
167 /// Returns the sea level density in slugs/ft^3
168 virtual double GetDensitySL(void) const { return SLdensity; }
169 /// Returns the sea level pressure in psf.
170 virtual double GetPressureSL(void) const { return SLpressure; }
171 /// Returns the sea level speed of sound in ft/sec.
172 virtual double GetSoundSpeedSL(void) const { return SLsoundspeed; }
174 /// Returns the ratio of at-altitude temperature over the sea level value.
175 virtual double GetTemperatureRatio(void) const { return (*temperature)*rSLtemperature; }
176 /// Returns the ratio of at-altitude density over the sea level value.
177 virtual double GetDensityRatio(void) const { return (*density)*rSLdensity; }
178 /// Returns the ratio of at-altitude pressure over the sea level value.
179 virtual double GetPressureRatio(void) const { return (*pressure)*rSLpressure; }
180 /// Returns the ratio of at-altitude sound speed over the sea level value.
181 virtual double GetSoundSpeedRatio(void) const { return soundspeed*rSLsoundspeed; }
183 /// Tells the simulator to use an externally calculated atmosphere model.
184 virtual void UseExternal(void);
185 /// Tells the simulator to use the internal atmosphere model.
186 virtual void UseInternal(void); //this is the default
187 /// Gets the boolean that tells if the external atmosphere model is being used.
188 virtual bool External(void) { return useExternal; }
190 /// Provides the external atmosphere model with an interface to set the temperature.
191 virtual void SetExTemperature(double t) { exTemperature=t; }
192 /// Provides the external atmosphere model with an interface to set the density.
193 virtual void SetExDensity(double d) { exDensity=d; }
194 /// Provides the external atmosphere model with an interface to set the pressure.
195 virtual void SetExPressure(double p) { exPressure=p; }
197 /// Sets the temperature deviation at sea-level in degrees Fahrenheit
198 virtual void SetSLTempDev(double d) { T_dev_sl = d; }
199 /// Gets the temperature deviation at sea-level in degrees Fahrenheit
200 virtual double GetSLTempDev(void) const { return T_dev_sl; }
201 /// Sets the current delta-T in degrees Fahrenheit
202 virtual void SetDeltaT(double d) { delta_T = d; }
203 /// Gets the current delta-T in degrees Fahrenheit
204 virtual double GetDeltaT(void) const { return delta_T; }
205 /// Gets the at-altitude temperature deviation in degrees Fahrenheit
206 virtual double GetTempDev(void) const { return T_dev; }
207 /// Gets the density altitude in feet
208 virtual double GetDensityAltitude(void) const { return density_altitude; }
210 // TOTAL WIND access functions (wind + gust + turbulence)
212 /// Retrieves the total wind components in NED frame.
213 virtual const FGColumnVector3& GetTotalWindNED(void) const { return vTotalWindNED; }
215 /// Retrieves a total wind component in NED frame.
216 virtual double GetTotalWindNED(int idx) const {return vTotalWindNED(idx);}
218 // WIND access functions
220 /// Sets the wind components in NED frame.
221 virtual void SetWindNED(double wN, double wE, double wD) { vWindNED(1)=wN; vWindNED(2)=wE; vWindNED(3)=wD;}
223 /// Sets a wind component in NED frame.
224 virtual void SetWindNED(int idx, double wind) { vWindNED(idx)=wind;}
226 /// Retrieves the wind components in NED frame.
227 virtual FGColumnVector3& GetWindNED(void) { return vWindNED; }
229 /// Retrieves a wind component in NED frame.
230 virtual double GetWindNED(int idx) const {return vWindNED(idx);}
232 /** Retrieves the direction that the wind is coming from.
233 The direction is defined as north=0 and increases counterclockwise.
234 The wind heading is returned in radians.*/
235 virtual double GetWindPsi(void) const { return psiw; }
237 /** Sets the direction that the wind is coming from.
238 The direction is defined as north=0 and increases counterclockwise to 2*pi (radians). The
239 vertical component of wind is assumed to be zero - and is forcibly set to zero. This function
240 sets the vWindNED vector components based on the supplied direction. The magnitude of
241 the wind set in the vector is preserved (assuming the vertical component is non-zero).
242 @param dir wind direction in the horizontal plane, in radians.*/
243 virtual void SetWindPsi(double dir);
245 virtual void SetWindspeed(double speed);
247 virtual double GetWindspeed(void) const;
249 // GUST access functions
251 /// Sets a gust component in NED frame.
252 virtual void SetGustNED(int idx, double gust) { vGustNED(idx)=gust;}
254 /// Sets a turbulence component in NED frame.
255 virtual void SetTurbNED(int idx, double turb) { vTurbulenceNED(idx)=turb;}
257 /// Sets the gust components in NED frame.
258 virtual void SetGustNED(double gN, double gE, double gD) { vGustNED(eNorth)=gN; vGustNED(eEast)=gE; vGustNED(eDown)=gD;}
260 /// Retrieves a gust component in NED frame.
261 virtual double GetGustNED(int idx) const {return vGustNED(idx);}
263 /// Retrieves a turbulence component in NED frame.
264 virtual double GetTurbNED(int idx) const {return vTurbulenceNED(idx);}
266 /// Retrieves the gust components in NED frame.
267 virtual FGColumnVector3& GetGustNED(void) {return vGustNED;}
269 /** Turbulence models available: ttNone, ttStandard, ttBerndt, ttCulp, ttMilspec, ttTustin */
270 virtual void SetTurbType(tType tt) {turbType = tt;}
271 virtual tType GetTurbType() const {return turbType;}
273 virtual void SetTurbGain(double tg) {TurbGain = tg;}
274 virtual double GetTurbGain() const {return TurbGain;}
276 virtual void SetTurbRate(double tr) {TurbRate = tr;}
277 virtual double GetTurbRate() const {return TurbRate;}
279 virtual void SetRhythmicity(double r) {Rhythmicity=r;}
280 virtual double GetRhythmicity() const {return Rhythmicity;}
282 virtual double GetTurbPQR(int idx) const {return vTurbPQR(idx);}
283 virtual double GetTurbMagnitude(void) const {return Magnitude;}
284 virtual const FGColumnVector3& GetTurbDirection(void) const {return vDirection;}
285 virtual const FGColumnVector3& GetTurbPQR(void) const {return vTurbPQR;}
287 virtual void SetWindspeed20ft(double ws) { windspeed_at_20ft = ws;}
288 virtual double GetWindspeed20ft() const { return windspeed_at_20ft;}
290 /// allowable range: 0-7, 3=light, 4=moderate, 6=severe turbulence
291 virtual void SetProbabilityOfExceedence( int idx) {probability_of_exceedence_index = idx;}
292 virtual int GetProbabilityOfExceedence() const { return probability_of_exceedence_index;}
297 struct atmType {double Temperature; double Pressure; double Density;};
301 double StdSLtemperature,StdSLdensity,StdSLpressure,StdSLsoundspeed;
302 double rSLtemperature,rSLdensity,rSLpressure,rSLsoundspeed; //reciprocals
303 double SLtemperature,SLdensity,SLpressure,SLsoundspeed;
304 double *temperature, *density, *pressure;
307 double exTemperature,exDensity,exPressure;
308 double intTemperature, intDensity, intPressure;
309 double SutherlandConstant, Beta, intViscosity, intKinematicViscosity;
310 double T_dev_sl, T_dev, delta_T, density_altitude;
312 bool StandardTempOnly;
315 double MagnitudedAccelDt, MagnitudeAccel, Magnitude;
319 double wind_from_clockwise;
320 double spike, target_time, strength;
321 FGColumnVector3 vDirectiondAccelDt;
322 FGColumnVector3 vDirectionAccel;
323 FGColumnVector3 vDirection;
324 FGColumnVector3 vTurbulenceGrad;
325 FGColumnVector3 vBodyTurbGrad;
326 FGColumnVector3 vTurbPQR;
328 // Dryden turbulence model
329 double windspeed_at_20ft; ///< in ft/s
330 int probability_of_exceedence_index; ///< this is bound as the severity property
331 FGTable *POE_Table; ///< probability of exceedence table
334 FGColumnVector3 vTotalWindNED;
335 FGColumnVector3 vWindNED;
336 FGColumnVector3 vGustNED;
337 FGColumnVector3 vTurbulenceNED;
339 /// Calculate the atmosphere for the given altitude, including effects of temperature deviation.
340 void Calculate(double altitude);
341 /// Calculate atmospheric properties other than the basic T, P and rho.
342 void CalculateDerived(void);
343 /// Get T, P and rho for a standard atmosphere at the given altitude.
344 void GetStdAtmosphere(double altitude);
345 void Turbulence(void);
346 virtual void bind(void);
347 void Debug(int from);
350 } // namespace JSBSim
352 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%