]> git.mxchange.org Git - flightgear.git/blob - src/WeatherCM/FGLocalWeatherDatabase.cpp
da85deea137eda0e9db06927520242782d5440c4
[flightgear.git] / src / WeatherCM / FGLocalWeatherDatabase.cpp
1 /*****************************************************************************
2
3  Module:       FGLocalWeatherDatabase.cpp
4  Author:       Christian Mayer
5  Date started: 28.05.99
6  Called by:    main program
7
8  -------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
9
10  This program is free software; you can redistribute it and/or modify it under
11  the terms of the GNU General Public License as published by the Free Software
12  Foundation; either version 2 of the License, or (at your option) any later
13  version.
14
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 General Public License for more
18  details.
19
20  You should have received a copy of the GNU 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.
23
24  Further information about the GNU General Public License can also be found on
25  the world wide web at http://www.gnu.org.
26
27 FUNCTIONAL DESCRIPTION
28 ------------------------------------------------------------------------------
29 Database for the local weather
30 This database is the only one that gets called from FG
31
32 HISTORY
33 ------------------------------------------------------------------------------
34 28.05.1999 Christian Mayer      Created
35 16.06.1999 Durk Talsma          Portability for Linux
36 20.06.1999 Christian Mayer      added lots of consts
37 11.10.1999 Christian Mayer      changed set<> to map<> on Bernie Bright's 
38                                 suggestion
39 19.10.1999 Christian Mayer      change to use PLIB's sg instead of Point[2/3]D
40                                 and lots of wee code cleaning
41 14.12.1999 Christian Mayer      Changed the internal structure to use Dave
42                                 Eberly's spherical interpolation code. This
43                                 stops our dependancy on the (ugly) voronoi
44                                 code and simplyfies the code structure a lot.
45 *****************************************************************************/
46
47 /****************************************************************************/
48 /* INCLUDES                                                                 */
49 /****************************************************************************/
50 #include <simgear/compiler.h>
51 #include <simgear/constants.h>
52 #include <simgear/misc/fgpath.hxx>
53
54 #include <Aircraft/aircraft.hxx>
55
56 #include "FGLocalWeatherDatabase.h"
57
58 #include "FGWeatherParse.h"
59
60 /****************************************************************************/
61 /********************************** CODE ************************************/
62 /****************************************************************************/
63
64 FGLocalWeatherDatabase* FGLocalWeatherDatabase::theFGLocalWeatherDatabase = 0;
65 FGLocalWeatherDatabase *WeatherDatabase;
66
67 void FGLocalWeatherDatabase::init( const WeatherPrecision visibility,
68                                    const DatabaseWorkingType type,
69                                    const string& root )
70 {
71     cerr << "Initializing FGLocalWeatherDatabase\n";
72     cerr << "-----------------------------------\n";
73
74     if (theFGLocalWeatherDatabase)
75     {
76         cerr << "Error: only one local weather allowed";
77         exit(-1);
78     }
79
80     setWeatherVisibility(visibility);
81
82     DatabaseStatus = type;
83     database = 0;           //just get sure...
84
85     Thunderstorm = false;
86     //I don't need to set theThunderstorm as Thunderstorm == false
87
88     switch(DatabaseStatus)
89     {
90     case use_global:
91         {
92             cerr << "Error: there's no global database anymore!\n";
93             exit(-1);
94         }
95         break;
96
97     case use_internet:
98         {
99             FGWeatherParse *parsed_data = new FGWeatherParse();
100
101             FGPath file( root );
102             file.append( "Weather" );
103             file.append( "current.txt.gz" );
104             parsed_data->input( file.c_str() );
105             unsigned int n = parsed_data->stored_stations();
106
107             sgVec2               *p = new sgVec2              [n];
108             FGPhysicalProperties *f = new FGPhysicalProperties[n];
109
110             // fill the database
111             for (unsigned int i = 0; i < n; i++) 
112             {
113                 f[i] = parsed_data->getFGPhysicalProperties(i);
114                 parsed_data->getPosition(i, p[i]);
115
116                 if ( (i%100) == 0)
117                     cerr << ".";
118             }
119
120             // free the memory of the parsed data to ease the required memory
121             // for the very memory consuming spherical interpolation
122             delete parsed_data;
123
124             //and finally init the interpolation
125             cerr << "\nInitialiating Interpolation. (2-3 minutes on a PII-350)\n";
126             database = new SphereInterpolate<FGPhysicalProperties>(n, p, f);
127
128             //and free my allocations:
129             delete[] p;
130             delete[] f;
131             cerr << "Finished weather init.\n";
132
133         }
134         break;
135
136     case distant:
137         cerr << "FGLocalWeatherDatabase error: Distant database isn't implemented yet!\n";
138         cerr << "  using random mode instead!\n";
139     case random:
140     case manual:
141     case default_mode:
142         {
143             double x[2] = {0.0,  0.0};  //make an standard weather that's the same at the whole world
144             double y[2] = {0.0,  0.0};  //make an standard weather that's the same at the whole world
145             double z[2] = {1.0, -1.0};  //make an standard weather that's the same at the whole world
146             FGPhysicalProperties f[2];  //make an standard weather that's the same at the whole world
147             database = new SphereInterpolate<FGPhysicalProperties>(2,x,y,z,f);
148         }
149         break;
150
151     default:
152         cerr << "FGLocalWeatherDatabase error: Unknown database type specified!\n";
153     };
154 }
155
156 FGLocalWeatherDatabase::~FGLocalWeatherDatabase()
157 {
158     //Tidying up:
159     delete database;
160 }
161
162 /****************************************************************************/
163 /* reset the whole database                                                 */
164 /****************************************************************************/
165 void FGLocalWeatherDatabase::reset(const DatabaseWorkingType type)
166 {
167     cerr << "FGLocalWeatherDatabase::reset isn't supported yet\n";
168 }
169
170 /****************************************************************************/
171 /* update the database. Since the last call we had dt seconds               */
172 /****************************************************************************/
173 void FGLocalWeatherDatabase::update(const WeatherPrecision dt)
174 {
175     //if (DatabaseStatus==use_global)
176     //  global->update(dt);
177 }
178
179 void FGLocalWeatherDatabase::update(const sgVec3& p) //position has changed
180 {
181     sgCopyVec3(last_known_position, p);
182
183     //uncomment this when you are using the GlobalDatabase
184     /*
185     cerr << "****\nupdate(p) inside\n";
186     cerr << "Parameter: " << p[0] << "/" << p[1] << "/" << p[2] << "\n";
187     sgVec2 p2d;
188     sgSetVec2( p2d, p[0], p[1] );
189     cerr << FGPhysicalProperties2D(get(p2d), p2d);
190     cerr << "****\n";
191     */
192     
193 }
194
195 void FGLocalWeatherDatabase::update(const sgVec3& p, const WeatherPrecision dt)   //time and/or position has changed
196 {
197     sgCopyVec3(last_known_position, p);
198 }
199
200 /****************************************************************************/
201 /* Get the physical properties on the specified point p out of the database */
202 /****************************************************************************/
203 FGPhysicalProperty FGLocalWeatherDatabase::get(const sgVec3& p) const
204 {
205     return FGPhysicalProperty(database->Evaluate(p), p[3]);
206 }
207
208 #ifdef MACOS
209     /* fix a problem with mw compilers in that they don't know the
210        difference between the next two methods. Since the first one
211        doesn't seem to be used anywhere, I commented it out. This is
212        supposed to be fixed in the forthcoming CodeWarrior Release
213        6. */
214 #else
215 FGPhysicalProperties FGLocalWeatherDatabase::get(const sgVec2& p) const
216 {
217     return database->Evaluate(p);
218 }
219 #endif
220
221 WeatherPrecision FGLocalWeatherDatabase::getAirDensity(const sgVec3& p) const
222 {
223     FGPhysicalProperty dummy(database->Evaluate(p), p[3]);
224
225     return 
226         (dummy.AirPressure*FG_WEATHER_DEFAULT_AIRDENSITY*FG_WEATHER_DEFAULT_TEMPERATURE) / 
227         (dummy.Temperature*FG_WEATHER_DEFAULT_AIRPRESSURE);
228 }
229
230
231 void FGLocalWeatherDatabase::setSnowRainIntensity(const WeatherPrecision x, const sgVec2& p)
232 {
233     /* not supported yet */
234 }
235
236 void FGLocalWeatherDatabase::setSnowRainType(const SnowRainType x, const sgVec2& p)
237 {
238     /* not supported yet */
239 }
240
241 void FGLocalWeatherDatabase::setLightningProbability(const WeatherPrecision x, const sgVec2& p)
242 {
243     /* not supported yet */
244 }
245
246 void FGLocalWeatherDatabase::setProperties(const FGPhysicalProperties2D& x)
247 {
248     /* not supported yet */
249 }
250
251 void fgUpdateWeatherDatabase(void)
252 {
253     sgVec3 position;
254         sgVec3 wind;
255     
256         
257         sgSetVec3(position, 
258         current_aircraft.fdm_state->get_Latitude(),
259         current_aircraft.fdm_state->get_Longitude(),
260         current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER);
261
262     WeatherDatabase->update( position );
263         
264         #define rho0 1.293 /*for air in normal altitudes*/
265     #define PATOPSF  0.02089    // Pascals to psf
266         #define KTOR     1.8        // Kelvin to degree Rankine
267         #define KGMTOSGF 0.0019403  // kg/m^3 to slug/ft^3
268
269
270     FGPhysicalProperty my_value = WeatherDatabase->get(position);
271     current_aircraft.fdm_state->set_Static_temperature(my_value.Temperature*KTOR);
272     current_aircraft.fdm_state->set_Static_pressure(my_value.AirPressure*PATOPSF);
273     float density=rho0 * 273.15 * my_value.AirPressure / (101300 *my_value.Temperature )*KGMTOSGF;
274     current_aircraft.fdm_state->set_Density(density*KGMTOSGF);
275         
276 #define KPHTOFPS 0.9113 //km/hr to ft/s
277 #define MSTOFPS  3.2808 //m/s to ft/s
278     current_aircraft.fdm_state->set_Velocities_Local_Airmass(my_value.Wind[1]*KPHTOFPS,
279                                                              my_value.Wind[0]*KPHTOFPS,
280                                                              my_value.Wind[2]*KPHTOFPS);
281         
282 }
283