]> git.mxchange.org Git - flightgear.git/blob - src/Environment/environment.cxx
e9e2b884a264147b873d8a823908b77c6a961231
[flightgear.git] / src / Environment / environment.cxx
1 // environment.cxx -- routines to model the natural environment
2 //
3 // Written by David Megginson, started February 2002.
4 //
5 // Copyright (C) 2002  David Megginson - david@megginson.com
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // $Id$
22
23
24 #ifdef HAVE_CONFIG_H
25 #  include <config.h>
26 #endif
27
28 #ifdef HAVE_WINDOWS_H
29 #  include <windows.h>                     
30 #endif
31
32 #include <math.h>
33
34 #include <plib/sg.h>
35
36 #include <simgear/constants.h>
37 #include <simgear/debug/logstream.hxx>
38
39 #include <Main/fg_props.hxx>
40 #include "environment.hxx"
41
42
43 FGEnvironment::FGEnvironment()
44   : visibility_m(32000),
45     temperature_sea_level_degc(20),
46     pressure_sea_level_inhg(28),
47     wind_from_heading_deg(0),
48     wind_speed_kt(0),
49     wind_from_north_fps(0),
50     wind_from_east_fps(0),
51     wind_from_down_fps(0)
52 {
53 }
54
55 FGEnvironment::FGEnvironment (const FGEnvironment &env)
56   : elevation_ft(env.elevation_ft),
57     visibility_m(env.visibility_m),
58     temperature_sea_level_degc(env.temperature_sea_level_degc),
59     pressure_sea_level_inhg(env.pressure_sea_level_inhg),
60     wind_from_heading_deg(env.wind_from_heading_deg),
61     wind_speed_kt(env.wind_speed_kt),
62     wind_from_north_fps(env.wind_from_north_fps),
63     wind_from_east_fps(env.wind_from_east_fps),
64     wind_from_down_fps(env.wind_from_down_fps)
65 {
66 }
67
68 FGEnvironment::~FGEnvironment()
69 {
70 }
71
72
73 double
74 FGEnvironment::get_visibility_m () const
75 {
76   return visibility_m;
77 }
78
79 double
80 FGEnvironment::get_temperature_sea_level_degc () const
81 {
82   return temperature_sea_level_degc;
83 }
84
85 double
86 FGEnvironment::get_temperature_degc () const
87 {
88   return temperature_degc;
89 }
90
91 double
92 FGEnvironment::get_pressure_sea_level_inhg () const
93 {
94   return pressure_sea_level_inhg;
95 }
96
97 double
98 FGEnvironment::get_pressure_inhg () const
99 {
100   return pressure_inhg;
101 }
102
103 double
104 FGEnvironment::get_wind_from_heading_deg () const
105 {
106   return wind_from_heading_deg;
107 }
108
109 double
110 FGEnvironment::get_wind_speed_kt () const
111 {
112   return wind_speed_kt;
113 }
114
115 double
116 FGEnvironment::get_wind_from_north_fps () const
117 {
118   return wind_from_north_fps;
119 }
120
121 double
122 FGEnvironment::get_wind_from_east_fps () const
123 {
124   return wind_from_east_fps;
125 }
126
127 double
128 FGEnvironment::get_wind_from_down_fps () const
129 {
130   return wind_from_down_fps;
131 }
132
133 double
134 FGEnvironment::get_elevation_ft () const
135 {
136   return elevation_ft;
137 }
138
139
140
141 void
142 FGEnvironment::set_visibility_m (double v)
143 {
144   visibility_m = v;
145 }
146
147 void
148 FGEnvironment::set_temperature_sea_level_degc (double t)
149 {
150   temperature_sea_level_degc = t;
151   _recalc_alt_temp();
152 }
153
154 void
155 FGEnvironment::set_temperature_degc (double t)
156 {
157   temperature_degc = t;
158   _recalc_sl_temp();
159 }
160
161 void
162 FGEnvironment::set_pressure_sea_level_inhg (double p)
163 {
164   pressure_sea_level_inhg = p;
165   _recalc_alt_press();
166 }
167
168 void
169 FGEnvironment::set_pressure_inhg (double p)
170 {
171   pressure_inhg = p;
172   _recalc_sl_press();
173 }
174
175 void
176 FGEnvironment::set_wind_from_heading_deg (double h)
177 {
178   wind_from_heading_deg = h;
179   _recalc_ne();
180 }
181
182 void
183 FGEnvironment::set_wind_speed_kt (double s)
184 {
185   wind_speed_kt = s;
186   _recalc_ne();
187 }
188
189 void
190 FGEnvironment::set_wind_from_north_fps (double n)
191 {
192   wind_from_north_fps = n;
193   _recalc_hdgspd();
194 }
195
196 void
197 FGEnvironment::set_wind_from_east_fps (double e)
198 {
199   wind_from_east_fps = e;
200   _recalc_hdgspd();
201 }
202
203 void
204 FGEnvironment::set_wind_from_down_fps (double d)
205 {
206   wind_from_down_fps = d;
207   _recalc_hdgspd();
208 }
209
210 void
211 FGEnvironment::set_elevation_ft (double e)
212 {
213   elevation_ft = e;
214   _recalc_alt_temp();
215   _recalc_alt_press();
216 }
217
218 void
219 FGEnvironment::_recalc_hdgspd ()
220 {
221   double angle_rad;
222
223   if (wind_from_east_fps == 0) {
224     angle_rad = (wind_from_north_fps >= 0 ? SGD_PI/2 : -SGD_PI/2);
225   } else {
226     angle_rad = atan(wind_from_north_fps/wind_from_east_fps);
227   }
228   wind_from_heading_deg = angle_rad * SGD_RADIANS_TO_DEGREES;
229   if (wind_from_east_fps >= 0)
230     wind_from_heading_deg = 90 - wind_from_heading_deg;
231   else
232     wind_from_heading_deg = 270 - wind_from_heading_deg;
233   if (angle_rad == 0)
234     wind_speed_kt = fabs(wind_from_east_fps
235                          * SG_METER_TO_NM * SG_FEET_TO_METER * 3600);
236   else
237     wind_speed_kt = (wind_from_north_fps / sin(angle_rad))
238       * SG_METER_TO_NM * SG_FEET_TO_METER * 3600;
239 }
240
241 void
242 FGEnvironment::_recalc_ne ()
243 {
244   double speed_fps =
245     wind_speed_kt * SG_NM_TO_METER * SG_METER_TO_FEET * (1.0/3600);
246
247   wind_from_north_fps = speed_fps *
248     cos(wind_from_heading_deg * SGD_DEGREES_TO_RADIANS);
249   wind_from_east_fps = speed_fps *
250     sin(wind_from_heading_deg * SGD_DEGREES_TO_RADIANS);
251 }
252
253 void
254 FGEnvironment::_recalc_sl_temp ()
255 {
256   // Earth atmosphere model from
257   // http://www.grc.nasa.gov/WWW/K-12/airplane/atmos.html
258
259   // Stratospheric temperatures are not really reversible, so use 15degC.
260
261   if (elevation_ft < 36152)     // Troposphere
262     temperature_sea_level_degc =
263       temperature_degc + (.00649 * SG_FEET_TO_METER * elevation_ft);
264   // If we're in the stratosphere, leave sea-level temp alone
265 }
266
267 void
268 FGEnvironment::_recalc_alt_temp ()
269 {
270   // Earth atmosphere model from
271   // http://www.grc.nasa.gov/WWW/K-12/airplane/atmos.html
272
273   if (elevation_ft < 36152)     // Troposphere
274     temperature_degc =
275       temperature_sea_level_degc - (.00649 * SG_FEET_TO_METER * elevation_ft);
276   else if (elevation_ft < 82345) // Lower Stratosphere
277     temperature_degc = -56.46;
278   else
279     temperature_degc = -131.21 + (.00299 * SG_FEET_TO_METER * elevation_ft);
280 }
281
282 void
283 FGEnvironment::_recalc_sl_press ()
284 {
285   // FIXME: calculate properly
286   pressure_sea_level_inhg = pressure_inhg;
287 }
288
289 void
290 FGEnvironment::_recalc_alt_press ()
291 {
292   // FIXME: calculate properly
293   pressure_inhg = pressure_sea_level_inhg;
294 }
295
296 // end of environment.cxx
297