]> git.mxchange.org Git - flightgear.git/blob - src/Environment/environment_mgr.cxx
Merge branch 'next' of git://gitorious.org/fg/flightgear into next
[flightgear.git] / src / Environment / environment_mgr.cxx
1 // environment-mgr.cxx -- manager for natural environment information.
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21 // $Id$
22
23 #ifdef HAVE_CONFIG_H
24 #  include <config.h>
25 #endif
26
27 #include <cstring>
28
29 #include <simgear/constants.h>
30 #include <simgear/debug/logstream.hxx>
31 #include <simgear/scene/sky/sky.hxx>
32 #include <simgear/environment/visual_enviro.hxx>
33 #include <simgear/scene/model/particles.hxx>
34
35 #include <Main/main.hxx>
36 #include <Main/fg_props.hxx>
37 #include <FDM/flight.hxx>
38
39 #include "environment.hxx"
40 #include "environment_mgr.hxx"
41 #include "environment_ctrl.hxx"
42 #include "fgclouds.hxx"
43 #include "precipitation_mgr.hxx"
44 #include "ridge_lift.hxx"
45
46 class SGSky;
47 extern SGSky *thesky;
48
49
50
51 FGEnvironmentMgr::FGEnvironmentMgr ()
52   : _environment(new FGEnvironment)
53 {
54
55   _controller = new FGInterpolateEnvironmentCtrl;
56   _controller->setEnvironment(_environment);
57   set_subsystem("controller", _controller, 0.1 );
58
59   fgClouds = new FGClouds();
60
61   _metarcontroller = new FGMetarCtrl(_controller );
62   set_subsystem("metarcontroller", _metarcontroller, 0.1 );
63
64   _metarfetcher = new FGMetarFetcher();
65   set_subsystem("metarfetcher", _metarfetcher, 1.0 );
66
67   _precipitationManager = new FGPrecipitationMgr;
68   set_subsystem("precipitation", _precipitationManager);
69
70   set_subsystem("ridgelift", new FGRidgeLift);
71 }
72
73 FGEnvironmentMgr::~FGEnvironmentMgr ()
74 {
75   SGSubsystem * subsys;
76
77   subsys = get_subsystem( "ridgelift" );
78   remove_subsystem( "ridgelift" );
79   delete subsys;
80
81   remove_subsystem("precipitation");
82   delete _precipitationManager;
83
84   remove_subsystem("metarcontroller");
85   delete _metarfetcher;
86
87   remove_subsystem("metarfetcher");
88   delete _metarcontroller;
89
90   delete fgClouds;
91
92   remove_subsystem("controller");
93   delete _controller;
94
95   delete _environment;
96 }
97
98 void
99 FGEnvironmentMgr::init ()
100 {
101   SG_LOG( SG_GENERAL, SG_INFO, "Initializing environment subsystem");
102   SGSubsystemGroup::init();
103   //_update_fdm();
104 }
105
106 void
107 FGEnvironmentMgr::reinit ()
108 {
109   SG_LOG( SG_GENERAL, SG_INFO, "Reinitializing environment subsystem");
110   SGSubsystemGroup::reinit();
111   //_update_fdm();
112 }
113
114 void
115 FGEnvironmentMgr::bind ()
116 {
117   SGSubsystemGroup::bind();
118   fgTie("/environment/visibility-m", _environment,
119         &FGEnvironment::get_visibility_m, &FGEnvironment::set_visibility_m);
120   fgSetArchivable("/environment/visibility-m");
121   fgTie("/environment/effective-visibility-m", thesky,
122        &SGSky::get_visibility );
123   fgTie("/environment/temperature-sea-level-degc", _environment,
124         &FGEnvironment::get_temperature_sea_level_degc,
125         &FGEnvironment::set_temperature_sea_level_degc);
126   fgSetArchivable("/environment/temperature-sea-level-degc");
127   fgTie("/environment/temperature-degc", _environment,
128         &FGEnvironment::get_temperature_degc); // FIXME: read-only for now
129   fgTie("/environment/temperature-degf", _environment,
130         &FGEnvironment::get_temperature_degf); // FIXME: read-only for now
131   fgTie("/environment/dewpoint-sea-level-degc", _environment,
132         &FGEnvironment::get_dewpoint_sea_level_degc,
133         &FGEnvironment::set_dewpoint_sea_level_degc);
134   fgSetArchivable("/environment/dewpoint-sea-level-degc");
135   fgTie("/environment/dewpoint-degc", _environment,
136         &FGEnvironment::get_dewpoint_degc); // FIXME: read-only for now
137   fgTie("/environment/pressure-sea-level-inhg", _environment,
138         &FGEnvironment::get_pressure_sea_level_inhg,
139         &FGEnvironment::set_pressure_sea_level_inhg);
140   fgSetArchivable("/environment/pressure-sea-level-inhg");
141   fgTie("/environment/pressure-inhg", _environment,
142         &FGEnvironment::get_pressure_inhg); // FIXME: read-only for now
143   fgTie("/environment/density-slugft3", _environment,
144         &FGEnvironment::get_density_slugft3); // read-only
145   fgTie("/environment/relative-humidity", _environment,
146         &FGEnvironment::get_relative_humidity); //ro
147   fgTie("/environment/atmosphere/density-tropo-avg", _environment,
148         &FGEnvironment::get_density_tropo_avg_kgm3); //ro
149   fgTie("/environment/atmosphere/altitude-half-to-sun", _environment,
150         &FGEnvironment::get_altitude_half_to_sun_m, 
151         &FGEnvironment::set_altitude_half_to_sun_m);
152   fgTie("/environment/atmosphere/altitude-troposphere-top", _environment,
153         &FGEnvironment::get_altitude_tropo_top_m,
154         &FGEnvironment::set_altitude_tropo_top_m);
155   fgTie("/environment/wind-from-heading-deg", _environment,
156         &FGEnvironment::get_wind_from_heading_deg,
157         &FGEnvironment::set_wind_from_heading_deg);
158   fgTie("/environment/wind-speed-kt", _environment,
159         &FGEnvironment::get_wind_speed_kt, &FGEnvironment::set_wind_speed_kt);
160   fgTie("/environment/wind-from-north-fps", _environment,
161         &FGEnvironment::get_wind_from_north_fps,
162         &FGEnvironment::set_wind_from_north_fps);
163   fgSetArchivable("/environment/wind-from-north-fps");
164   fgTie("/environment/wind-from-east-fps", _environment,
165         &FGEnvironment::get_wind_from_east_fps,
166         &FGEnvironment::set_wind_from_east_fps);
167   fgSetArchivable("/environment/wind-from-east-fps");
168   fgTie("/environment/wind-from-down-fps", _environment,
169         &FGEnvironment::get_wind_from_down_fps,
170         &FGEnvironment::set_wind_from_down_fps);
171   fgSetArchivable("/environment/wind-from-down-fps");
172
173   fgTie("/environment/thermal-lift-fps", _environment,
174         &FGEnvironment::get_thermal_lift_fps,
175         &FGEnvironment::set_thermal_lift_fps);
176   fgSetArchivable("/environment/thermal-lift-fps");
177   fgTie("/environment/ridge-lift-fps", _environment,
178         &FGEnvironment::get_ridge_lift_fps,
179         &FGEnvironment::set_ridge_lift_fps);    
180   fgSetArchivable("/environment/ridge-lift-fps");
181   
182     fgTie("/environment/local-weather-lift", _environment,
183         &FGEnvironment::get_local_weather_lift_fps); //read-only
184      
185   fgTie("/environment/turbulence/magnitude-norm", _environment,
186         &FGEnvironment::get_turbulence_magnitude_norm,
187         &FGEnvironment::set_turbulence_magnitude_norm);
188   fgSetArchivable("/environment/turbulence/magnitude-norm");
189   fgTie("/environment/turbulence/rate-hz", _environment,
190         &FGEnvironment::get_turbulence_rate_hz,
191         &FGEnvironment::set_turbulence_rate_hz);
192   fgSetArchivable("/environment/turbulence/rate-hz");
193
194   for (int i = 0; i < MAX_CLOUD_LAYERS; i++) {
195     char buf[128];
196     sprintf(buf, "/environment/clouds/layer[%d]/span-m", i);
197     fgTie(buf, this, i,
198           &FGEnvironmentMgr::get_cloud_layer_span_m,
199           &FGEnvironmentMgr::set_cloud_layer_span_m);
200     fgSetArchivable(buf);
201     sprintf(buf, "/environment/clouds/layer[%d]/elevation-ft", i);
202     fgTie(buf, this, i,
203           &FGEnvironmentMgr::get_cloud_layer_elevation_ft,
204           &FGEnvironmentMgr::set_cloud_layer_elevation_ft);
205     fgSetArchivable(buf);
206     sprintf(buf, "/environment/clouds/layer[%d]/thickness-ft", i);
207     fgTie(buf, this, i,
208           &FGEnvironmentMgr::get_cloud_layer_thickness_ft,
209           &FGEnvironmentMgr::set_cloud_layer_thickness_ft);
210     fgSetArchivable(buf);
211     sprintf(buf, "/environment/clouds/layer[%d]/transition-ft", i);
212     fgTie(buf, this, i,
213           &FGEnvironmentMgr::get_cloud_layer_transition_ft,
214           &FGEnvironmentMgr::set_cloud_layer_transition_ft);
215     fgSetArchivable(buf);
216     sprintf(buf, "/environment/clouds/layer[%d]/coverage", i);
217     fgTie(buf, this, i,
218           &FGEnvironmentMgr::get_cloud_layer_coverage,
219           &FGEnvironmentMgr::set_cloud_layer_coverage);
220     fgSetArchivable(buf);
221   }
222
223   fgTie("/environment/metar/data", _metarcontroller,
224           &FGMetarCtrl::get_metar, &FGMetarCtrl::set_metar );
225
226   fgTie("/sim/rendering/clouds3d-enable", fgClouds,
227           &FGClouds::get_3dClouds,
228           &FGClouds::set_3dClouds);
229   fgTie("/sim/rendering/clouds3d-density", thesky,
230           &SGSky::get_3dCloudDensity,
231           &SGSky::set_3dCloudDensity);
232   fgTie("/sim/rendering/clouds3d-vis-range", thesky,
233         &SGSky::get_3dCloudVisRange,
234         &SGSky::set_3dCloudVisRange);
235   
236   fgTie("/sim/rendering/precipitation-enable", &sgEnviro,
237           &SGEnviro::get_precipitation_enable_state, 
238           &SGEnviro::set_precipitation_enable_state);
239   fgTie("/environment/rebuild-layers", fgClouds,
240       &FGClouds::get_update_event,
241       &FGClouds::set_update_event);
242   fgTie("/sim/rendering/lightning-enable", &sgEnviro,
243       &SGEnviro::get_lightning_enable_state,
244       &SGEnviro::set_lightning_enable_state);
245   fgTie("/environment/turbulence/use-cloud-turbulence", &sgEnviro,
246       &SGEnviro::get_turbulence_enable_state,
247       &SGEnviro::set_turbulence_enable_state);
248   sgEnviro.config(fgGetNode("/sim/rendering/precipitation"));
249 }
250
251 void
252 FGEnvironmentMgr::unbind ()
253 {
254   fgUntie("/environment/visibility-m");
255   fgUntie("/environment/effective-visibility-m");
256   fgUntie("/environment/temperature-sea-level-degc");
257   fgUntie("/environment/temperature-degc");
258   fgUntie("/environment/dewpoint-sea-level-degc");
259   fgUntie("/environment/dewpoint-degc");
260   fgUntie("/environment/pressure-sea-level-inhg");
261   fgUntie("/environment/pressure-inhg");
262   fgUntie("/environment/density-inhg");
263   fgUntie("/environment/relative-humidity");
264   fgUntie("/environment/atmosphere/density-tropo-avg");
265   fgUntie("/environment/wind-from-north-fps");
266   fgUntie("/environment/wind-from-east-fps");
267   fgUntie("/environment/wind-from-down-fps");
268
269   fgUntie("/environment/thermal-lift-fps");
270   fgUntie("/environment/ridge-lift-fps");
271   fgUntie("/environment/local-weather-lift");
272
273   fgUntie("/environment/atmosphere/altitude-half-to-sun");
274   fgUntie("/environment/atmosphere/altitude-troposphere-top");
275   for (int i = 0; i < MAX_CLOUD_LAYERS; i++) {
276     char buf[128];
277     sprintf(buf, "/environment/clouds/layer[%d]/span-m", i);
278     fgUntie(buf);
279     sprintf(buf, "/environment/clouds/layer[%d]/elevation-ft", i);
280     fgUntie(buf);
281     sprintf(buf, "/environment/clouds/layer[%d]/thickness-ft", i);
282     fgUntie(buf);
283     sprintf(buf, "/environment/clouds/layer[%d]/transition-ft", i);
284     fgUntie(buf);
285     sprintf(buf, "/environment/clouds/layer[%d]/type", i);
286     fgUntie(buf);
287   }
288   fgUntie("/sim/rendering/clouds3d-enable");
289   fgUntie("/sim/rendering/clouds3d-vis-range");
290   fgUntie("/sim/rendering/clouds3d-density");
291   fgUntie("/sim/rendering/precipitation-enable");
292   fgUntie("/environment/rebuild-layers");
293   fgUntie("/environment/weather-scenario");
294   fgUntie("/sim/rendering/lightning-enable");
295   fgUntie("/environment/turbulence/use-cloud-turbulence");
296   SGSubsystemGroup::unbind();
297 }
298
299 void
300 FGEnvironmentMgr::update (double dt)
301 {
302   SGSubsystemGroup::update(dt);
303   
304   _environment->set_elevation_ft(fgGetDouble("/position/altitude-ft"));
305   _environment->set_local_weather_lift_fps(fgGetDouble("/local-weather/current/thermal-lift"));
306   osg::Vec3 windVec(_environment->get_wind_from_north_fps(),
307                     -_environment->get_wind_from_east_fps(),
308                     0);
309   simgear::Particles::setWindVector(windVec * SG_FEET_TO_METER);
310   //simgear::Particles::setWindFrom( _environment->get_wind_from_heading_deg(),
311   //                       _environment->get_wind_speed_kt() );
312 }
313
314 FGEnvironment
315 FGEnvironmentMgr::getEnvironment () const
316 {
317   return *_environment;
318 }
319
320 FGEnvironment
321 FGEnvironmentMgr::getEnvironment (double lat, double lon, double alt) const
322 {
323                                 // Always returns the same environment
324                                 // for now; we'll make it interesting
325                                 // later.
326   FGEnvironment env = *_environment;
327   env.set_elevation_ft(alt);
328   return env;
329 }
330
331 FGEnvironment
332 FGEnvironmentMgr::getEnvironment(const SGGeod& aPos) const
333 {
334   // Always returns the same environment
335   // for now; we'll make it interesting
336   // later.
337   FGEnvironment env = *_environment;
338   env.set_elevation_ft(aPos.getElevationFt());
339   return env;
340
341 }
342
343 double
344 FGEnvironmentMgr::get_cloud_layer_span_m (int index) const
345 {
346   return thesky->get_cloud_layer(index)->getSpan_m();
347 }
348
349 void
350 FGEnvironmentMgr::set_cloud_layer_span_m (int index, double span_m)
351 {
352   thesky->get_cloud_layer(index)->setSpan_m(span_m);
353 }
354
355 double
356 FGEnvironmentMgr::get_cloud_layer_elevation_ft (int index) const
357 {
358   return thesky->get_cloud_layer(index)->getElevation_m() * SG_METER_TO_FEET;
359 }
360
361 void
362 FGEnvironmentMgr::set_cloud_layer_elevation_ft (int index, double elevation_ft)
363 {
364   FGEnvironment env = *_environment;
365   env.set_elevation_ft(elevation_ft);
366
367   thesky->get_cloud_layer(index)
368     ->setElevation_m(elevation_ft * SG_FEET_TO_METER);
369
370   thesky->get_cloud_layer(index)
371     ->setSpeed(env.get_wind_speed_kt() * 0.5151);       // 1 kt = 0.5151 m/s
372
373   thesky->get_cloud_layer(index)
374     ->setDirection(env.get_wind_from_heading_deg());
375 }
376
377 double
378 FGEnvironmentMgr::get_cloud_layer_thickness_ft (int index) const
379 {
380   return thesky->get_cloud_layer(index)->getThickness_m() * SG_METER_TO_FEET;
381 }
382
383 void
384 FGEnvironmentMgr::set_cloud_layer_thickness_ft (int index, double thickness_ft)
385 {
386   thesky->get_cloud_layer(index)
387     ->setThickness_m(thickness_ft * SG_FEET_TO_METER);
388 }
389
390 double
391 FGEnvironmentMgr::get_cloud_layer_transition_ft (int index) const
392 {
393   return thesky->get_cloud_layer(index)->getTransition_m() * SG_METER_TO_FEET;
394 }
395
396 void
397 FGEnvironmentMgr::set_cloud_layer_transition_ft (int index,
398                                                  double transition_ft)
399 {
400   thesky->get_cloud_layer(index)
401     ->setTransition_m(transition_ft * SG_FEET_TO_METER);
402 }
403
404 const char *
405 FGEnvironmentMgr::get_cloud_layer_coverage (int index) const
406 {
407   switch (thesky->get_cloud_layer(index)->getCoverage()) {
408   case SGCloudLayer::SG_CLOUD_OVERCAST:
409     return "overcast";
410   case SGCloudLayer::SG_CLOUD_BROKEN:
411     return "broken";
412   case SGCloudLayer::SG_CLOUD_SCATTERED:
413     return "scattered";
414   case SGCloudLayer::SG_CLOUD_FEW:
415     return "few";
416   case SGCloudLayer::SG_CLOUD_CIRRUS:
417     return "cirrus";
418   case SGCloudLayer::SG_CLOUD_CLEAR:
419     return "clear";
420   default:
421     return "unknown";
422   }
423 }
424
425 void
426 FGEnvironmentMgr::set_cloud_layer_coverage (int index,
427                                             const char * coverage_name)
428 {
429   SGCloudLayer::Coverage coverage;
430   if (!strcmp(coverage_name, "overcast"))
431     coverage = SGCloudLayer::SG_CLOUD_OVERCAST;
432   else if (!strcmp(coverage_name, "broken"))
433     coverage = SGCloudLayer::SG_CLOUD_BROKEN;
434   else if (!strcmp(coverage_name, "scattered"))
435     coverage = SGCloudLayer::SG_CLOUD_SCATTERED;
436   else if (!strcmp(coverage_name, "few"))
437     coverage = SGCloudLayer::SG_CLOUD_FEW;
438   else if (!strcmp(coverage_name, "cirrus"))
439     coverage = SGCloudLayer::SG_CLOUD_CIRRUS;
440   else if (!strcmp(coverage_name, "clear"))
441     coverage = SGCloudLayer::SG_CLOUD_CLEAR;
442   else {
443     SG_LOG(SG_INPUT, SG_WARN, "Unknown cloud type " << coverage_name);
444     coverage = SGCloudLayer::SG_CLOUD_CLEAR;
445   }
446   thesky->get_cloud_layer(index)->setCoverage(coverage);
447 }
448
449
450
451 // end of environment-mgr.cxx