]> git.mxchange.org Git - flightgear.git/blob - src/WeatherCM/FGLocalWeatherDatabase.cpp
5913f7cbff736e2cc5ee69eb7da741c357ecde66
[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
53 #include <Aircraft/aircraft.hxx>
54
55 #include "FGLocalWeatherDatabase.h"
56
57 #include "FGWeatherParse.h"
58
59 /****************************************************************************/
60 /********************************** CODE ************************************/
61 /****************************************************************************/
62
63 FGLocalWeatherDatabase* FGLocalWeatherDatabase::theFGLocalWeatherDatabase = 0;
64 FGLocalWeatherDatabase *WeatherDatabase;
65
66 void FGLocalWeatherDatabase::init(const WeatherPrecision visibility, const DatabaseWorkingType type)
67 {
68     cerr << "Initializing FGLocalWeatherDatabase\n";
69     cerr << "-----------------------------------\n";
70
71     if (theFGLocalWeatherDatabase)
72     {
73         cerr << "Error: only one local weather allowed";
74         exit(-1);
75     }
76
77     setWeatherVisibility(visibility);
78
79     DatabaseStatus = type;
80     database = 0;           //just get sure...
81
82     Thunderstorm = false;
83     //I don't need to set theThunderstorm as Thunderstorm == false
84
85     switch(DatabaseStatus)
86     {
87     case use_global:
88         {
89             cerr << "Error: there's no global database anymore!\n";
90             exit(-1);
91         }
92         break;
93
94     case use_internet:
95         {
96             FGWeatherParse *parsed_data = new FGWeatherParse();
97
98             parsed_data->input( "weather/current.gz" );
99             unsigned int n = parsed_data->stored_stations();
100
101             sgVec2               *p = new sgVec2              [n];
102             FGPhysicalProperties *f = new FGPhysicalProperties[n];
103
104             // fill the database
105             for (unsigned int i = 0; i < n; i++) 
106             {
107                 f[i] = parsed_data->getFGPhysicalProperties(i);
108                 parsed_data->getPosition(i, p[i]);
109
110                 if ( (i%100) == 0)
111                     cerr << ".";
112             }
113
114             // free the memory of the parsed data to ease the required memory
115             // for the very memory consuming spherical interpolation
116             delete parsed_data;
117
118             //and finally init the interpolation
119             cerr << "\nInitialiating Interpolation. (2-3 minutes on a PII-350)\n";
120             database = new SphereInterpolate<FGPhysicalProperties>(n, p, f);
121
122             //and free my allocations:
123             delete[] p;
124             delete[] f;
125             cerr << "Finished weather init.\n";
126
127         }
128         break;
129
130     case distant:
131         cerr << "FGLocalWeatherDatabase error: Distant database isn't implemented yet!\n";
132         cerr << "  using random mode instead!\n";
133     case random:
134     case manual:
135     case default_mode:
136         {
137             double x[2] = {0.0,  0.0};  //make an standard weather that's the same at the whole world
138             double y[2] = {0.0,  0.0};  //make an standard weather that's the same at the whole world
139             double z[2] = {1.0, -1.0};  //make an standard weather that's the same at the whole world
140             FGPhysicalProperties f[2];  //make an standard weather that's the same at the whole world
141             database = new SphereInterpolate<FGPhysicalProperties>(2,x,y,z,f);
142         }
143         break;
144
145     default:
146         cerr << "FGLocalWeatherDatabase error: Unknown database type specified!\n";
147     };
148 }
149
150 FGLocalWeatherDatabase::~FGLocalWeatherDatabase()
151 {
152     //Tidying up:
153     delete database;
154 }
155
156 /****************************************************************************/
157 /* reset the whole database                                                 */
158 /****************************************************************************/
159 void FGLocalWeatherDatabase::reset(const DatabaseWorkingType type)
160 {
161     cerr << "FGLocalWeatherDatabase::reset isn't supported yet\n";
162 }
163
164 /****************************************************************************/
165 /* update the database. Since the last call we had dt seconds               */
166 /****************************************************************************/
167 void FGLocalWeatherDatabase::update(const WeatherPrecision dt)
168 {
169     //if (DatabaseStatus==use_global)
170     //  global->update(dt);
171 }
172
173 void FGLocalWeatherDatabase::update(const sgVec3& p) //position has changed
174 {
175     sgCopyVec3(last_known_position, p);
176
177     //uncomment this when you are using the GlobalDatabase
178     /*
179     cerr << "****\nupdate(p) inside\n";
180     cerr << "Parameter: " << p[0] << "/" << p[1] << "/" << p[2] << "\n";
181     sgVec2 p2d;
182     sgSetVec2( p2d, p[0], p[1] );
183     cerr << FGPhysicalProperties2D(get(p2d), p2d);
184     cerr << "****\n";
185     */
186     
187 }
188
189 void FGLocalWeatherDatabase::update(const sgVec3& p, const WeatherPrecision dt)   //time and/or position has changed
190 {
191     sgCopyVec3(last_known_position, p);
192 }
193
194 /****************************************************************************/
195 /* Get the physical properties on the specified point p out of the database */
196 /****************************************************************************/
197 FGPhysicalProperty FGLocalWeatherDatabase::get(const sgVec3& p) const
198 {
199     return FGPhysicalProperty(database->Evaluate(p), p[3]);
200 }
201
202 #ifdef MACOS
203     /* fix a problem with mw compilers in that they don't know the
204        difference between the next two methods. Since the first one
205        doesn't seem to be used anywhere, I commented it out. This is
206        supposed to be fixed in the forthcoming CodeWarrior Release
207        6. */
208 #else
209 FGPhysicalProperties FGLocalWeatherDatabase::get(const sgVec2& p) const
210 {
211     return database->Evaluate(p);
212 }
213 #endif
214
215 WeatherPrecision FGLocalWeatherDatabase::getAirDensity(const sgVec3& p) const
216 {
217     FGPhysicalProperty dummy(database->Evaluate(p), p[3]);
218
219     return 
220         (dummy.AirPressure*FG_WEATHER_DEFAULT_AIRDENSITY*FG_WEATHER_DEFAULT_TEMPERATURE) / 
221         (dummy.Temperature*FG_WEATHER_DEFAULT_AIRPRESSURE);
222 }
223
224
225 void FGLocalWeatherDatabase::setSnowRainIntensity(const WeatherPrecision x, const sgVec2& p)
226 {
227     /* not supported yet */
228 }
229
230 void FGLocalWeatherDatabase::setSnowRainType(const SnowRainType x, const sgVec2& p)
231 {
232     /* not supported yet */
233 }
234
235 void FGLocalWeatherDatabase::setLightningProbability(const WeatherPrecision x, const sgVec2& p)
236 {
237     /* not supported yet */
238 }
239
240 void FGLocalWeatherDatabase::setProperties(const FGPhysicalProperties2D& x)
241 {
242     /* not supported yet */
243 }
244
245 void fgUpdateWeatherDatabase(void)
246 {
247     sgVec3 position;
248         sgVec3 wind;
249     
250         
251         sgSetVec3(position, 
252         current_aircraft.fdm_state->get_Latitude(),
253         current_aircraft.fdm_state->get_Longitude(),
254         current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER);
255
256     WeatherDatabase->update( position );
257         
258         #define rho0 1.293 /*for air in normal altitudes*/
259     #define PATOPSF  0.02089    // Pascals to psf
260         #define KTOR     1.8        // Kelvin to degree Rankine
261         #define KGMTOSGF 0.0019403  // kg/m^3 to slug/ft^3
262
263
264     FGPhysicalProperty my_value = WeatherDatabase->get(position);
265     current_aircraft.fdm_state->set_Static_temperature(my_value.Temperature*KTOR);
266         current_aircraft.fdm_state->set_Static_pressure(my_value.AirPressure*PATOPSF);
267         float density=rho0 * 273.15 * my_value.AirPressure / (101300 *my_value.Temperature )*KGMTOSGF;
268         current_aircraft.fdm_state->set_Density(density*KGMTOSGF);
269         
270         #define KPHTOFPS 0.9113 //km/hr to ft/s
271         #define MSTOFPS  3.2808 //m/s to ft/s
272         current_aircraft.fdm_state->set_Velocities_Local_Airmass(my_value.Wind[1]*KPHTOFPS,
273                                                                                                             my_value.Wind[0]*KPHTOFPS,
274                                                                                                                     my_value.Wind[2]*KPHTOFPS);
275         
276 }
277