1 /*****************************************************************************
3 Module: FGLocalWeatherDatabase.cpp
4 Author: Christian Mayer
6 Called by: main program
8 -------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
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
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
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.
24 Further information about the GNU General Public License can also be found on
25 the world wide web at http://www.gnu.org.
27 FUNCTIONAL DESCRIPTION
28 ------------------------------------------------------------------------------
29 Database for the local weather
30 This database is the only one that gets called from FG
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
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 *****************************************************************************/
47 /****************************************************************************/
49 /****************************************************************************/
50 #include <simgear/compiler.h>
51 #include <simgear/constants.h>
52 #include <simgear/misc/fgpath.hxx>
54 #include <Aircraft/aircraft.hxx>
56 #include "FGLocalWeatherDatabase.h"
58 #include "FGWeatherParse.h"
60 /****************************************************************************/
61 /********************************** CODE ************************************/
62 /****************************************************************************/
64 FGLocalWeatherDatabase* FGLocalWeatherDatabase::theFGLocalWeatherDatabase = 0;
65 FGLocalWeatherDatabase *WeatherDatabase;
67 void FGLocalWeatherDatabase::init( const WeatherPrecision visibility,
68 const DatabaseWorkingType type,
71 cerr << "Initializing FGLocalWeatherDatabase\n";
72 cerr << "-----------------------------------\n";
74 if (theFGLocalWeatherDatabase)
76 cerr << "Error: only one local weather allowed";
80 setWeatherVisibility(visibility);
82 DatabaseStatus = type;
83 database = 0; //just get sure...
86 //I don't need to set theThunderstorm as Thunderstorm == false
88 switch(DatabaseStatus)
92 cerr << "Error: there's no global database anymore!\n";
99 FGWeatherParse *parsed_data = new FGWeatherParse();
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();
107 sgVec2 *p = new sgVec2 [n];
108 FGPhysicalProperties *f = new FGPhysicalProperties[n];
111 for (unsigned int i = 0; i < n; i++)
113 f[i] = parsed_data->getFGPhysicalProperties(i);
114 parsed_data->getPosition(i, p[i]);
120 // free the memory of the parsed data to ease the required memory
121 // for the very memory consuming spherical interpolation
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);
128 //and free my allocations:
131 cerr << "Finished weather init.\n";
137 cerr << "FGLocalWeatherDatabase error: Distant database isn't implemented yet!\n";
138 cerr << " using random mode instead!\n";
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);
152 cerr << "FGLocalWeatherDatabase error: Unknown database type specified!\n";
156 FGLocalWeatherDatabase::~FGLocalWeatherDatabase()
162 /****************************************************************************/
163 /* reset the whole database */
164 /****************************************************************************/
165 void FGLocalWeatherDatabase::reset(const DatabaseWorkingType type)
167 cerr << "FGLocalWeatherDatabase::reset isn't supported yet\n";
170 /****************************************************************************/
171 /* update the database. Since the last call we had dt seconds */
172 /****************************************************************************/
173 void FGLocalWeatherDatabase::update(const WeatherPrecision dt)
175 //if (DatabaseStatus==use_global)
176 // global->update(dt);
179 void FGLocalWeatherDatabase::update(const sgVec3& p) //position has changed
181 sgCopyVec3(last_known_position, p);
183 //uncomment this when you are using the GlobalDatabase
185 cerr << "****\nupdate(p) inside\n";
186 cerr << "Parameter: " << p[0] << "/" << p[1] << "/" << p[2] << "\n";
188 sgSetVec2( p2d, p[0], p[1] );
189 cerr << FGPhysicalProperties2D(get(p2d), p2d);
195 void FGLocalWeatherDatabase::update(const sgVec3& p, const WeatherPrecision dt) //time and/or position has changed
197 sgCopyVec3(last_known_position, p);
200 /****************************************************************************/
201 /* Get the physical properties on the specified point p out of the database */
202 /****************************************************************************/
203 FGPhysicalProperty FGLocalWeatherDatabase::get(const sgVec3& p) const
205 return FGPhysicalProperty(database->Evaluate(p), p[3]);
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
215 FGPhysicalProperties FGLocalWeatherDatabase::get(const sgVec2& p) const
217 return database->Evaluate(p);
221 WeatherPrecision FGLocalWeatherDatabase::getAirDensity(const sgVec3& p) const
223 FGPhysicalProperty dummy(database->Evaluate(p), p[3]);
226 (dummy.AirPressure*FG_WEATHER_DEFAULT_AIRDENSITY*FG_WEATHER_DEFAULT_TEMPERATURE) /
227 (dummy.Temperature*FG_WEATHER_DEFAULT_AIRPRESSURE);
231 void FGLocalWeatherDatabase::setSnowRainIntensity(const WeatherPrecision x, const sgVec2& p)
233 /* not supported yet */
236 void FGLocalWeatherDatabase::setSnowRainType(const SnowRainType x, const sgVec2& p)
238 /* not supported yet */
241 void FGLocalWeatherDatabase::setLightningProbability(const WeatherPrecision x, const sgVec2& p)
243 /* not supported yet */
246 void FGLocalWeatherDatabase::setProperties(const FGPhysicalProperties2D& x)
248 /* not supported yet */
251 void fgUpdateWeatherDatabase(void)
258 current_aircraft.fdm_state->get_Latitude(),
259 current_aircraft.fdm_state->get_Longitude(),
260 current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER);
262 WeatherDatabase->update( position );
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
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);
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);