1999-08-10 03:40:34 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
|
|
|
|
Module: FGLocalWeatherDatabase.cpp
|
|
|
|
Author: Christian Mayer
|
|
|
|
Date started: 28.05.99
|
|
|
|
Called by: main program
|
|
|
|
|
1999-10-20 22:19:07 +00:00
|
|
|
-------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
|
1999-08-10 03:40:34 +00:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it under
|
|
|
|
the terms of the GNU General Public License as published by the Free Software
|
|
|
|
Foundation; either version 2 of the License, or (at your option) any later
|
|
|
|
version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
|
|
details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
|
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|
|
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
|
|
|
Further information about the GNU General Public License can also be found on
|
|
|
|
the world wide web at http://www.gnu.org.
|
|
|
|
|
|
|
|
FUNCTIONAL DESCRIPTION
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
Database for the local weather
|
|
|
|
This database is the only one that gets called from FG
|
|
|
|
|
|
|
|
HISTORY
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
28.05.1999 Christian Mayer Created
|
|
|
|
16.06.1999 Durk Talsma Portability for Linux
|
|
|
|
20.06.1999 Christian Mayer added lots of consts
|
1999-10-14 20:30:54 +00:00
|
|
|
11.10.1999 Christian Mayer changed set<> to map<> on Bernie Bright's
|
|
|
|
suggestion
|
1999-10-20 22:19:07 +00:00
|
|
|
19.10.1999 Christian Mayer change to use PLIB's sg instead of Point[2/3]D
|
|
|
|
and lots of wee code cleaning
|
1999-12-23 16:54:54 +00:00
|
|
|
14.12.1999 Christian Mayer Changed the internal structure to use Dave
|
|
|
|
Eberly's spherical interpolation code. This
|
|
|
|
stops our dependancy on the (ugly) voronoi
|
|
|
|
code and simplyfies the code structure a lot.
|
1999-08-10 03:40:34 +00:00
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
/* INCLUDES */
|
|
|
|
/****************************************************************************/
|
2000-02-15 03:30:01 +00:00
|
|
|
#include <simgear/compiler.h>
|
|
|
|
#include <simgear/constants.h>
|
2000-07-06 22:13:24 +00:00
|
|
|
#include <simgear/misc/fgpath.hxx>
|
1999-10-20 22:19:07 +00:00
|
|
|
|
|
|
|
#include <Aircraft/aircraft.hxx>
|
|
|
|
|
1999-08-10 03:40:34 +00:00
|
|
|
#include "FGLocalWeatherDatabase.h"
|
|
|
|
|
1999-11-03 18:06:52 +00:00
|
|
|
#include "FGWeatherParse.h"
|
1999-08-10 03:40:34 +00:00
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
/********************************** CODE ************************************/
|
|
|
|
/****************************************************************************/
|
|
|
|
|
|
|
|
FGLocalWeatherDatabase* FGLocalWeatherDatabase::theFGLocalWeatherDatabase = 0;
|
|
|
|
FGLocalWeatherDatabase *WeatherDatabase;
|
|
|
|
|
2000-07-06 22:13:24 +00:00
|
|
|
void FGLocalWeatherDatabase::init( const WeatherPrecision visibility,
|
|
|
|
const DatabaseWorkingType type,
|
|
|
|
const string& root )
|
1999-08-10 03:40:34 +00:00
|
|
|
{
|
|
|
|
cerr << "Initializing FGLocalWeatherDatabase\n";
|
|
|
|
cerr << "-----------------------------------\n";
|
|
|
|
|
|
|
|
if (theFGLocalWeatherDatabase)
|
|
|
|
{
|
|
|
|
cerr << "Error: only one local weather allowed";
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
setWeatherVisibility(visibility);
|
1999-10-20 22:19:07 +00:00
|
|
|
|
1999-08-10 03:40:34 +00:00
|
|
|
DatabaseStatus = type;
|
1999-12-23 16:54:54 +00:00
|
|
|
database = 0; //just get sure...
|
1999-08-10 03:40:34 +00:00
|
|
|
|
1999-11-03 18:06:52 +00:00
|
|
|
Thunderstorm = false;
|
|
|
|
//I don't need to set theThunderstorm as Thunderstorm == false
|
1999-08-10 03:40:34 +00:00
|
|
|
|
|
|
|
switch(DatabaseStatus)
|
|
|
|
{
|
|
|
|
case use_global:
|
|
|
|
{
|
1999-12-23 16:54:54 +00:00
|
|
|
cerr << "Error: there's no global database anymore!\n";
|
|
|
|
exit(-1);
|
1999-11-03 18:06:52 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case use_internet:
|
|
|
|
{
|
1999-12-23 16:54:54 +00:00
|
|
|
FGWeatherParse *parsed_data = new FGWeatherParse();
|
|
|
|
|
2000-07-06 22:13:24 +00:00
|
|
|
FGPath file( root );
|
|
|
|
file.append( "Weather" );
|
|
|
|
file.append( "current.txt.gz" );
|
|
|
|
parsed_data->input( file.c_str() );
|
1999-12-23 16:54:54 +00:00
|
|
|
unsigned int n = parsed_data->stored_stations();
|
1999-11-03 18:06:52 +00:00
|
|
|
|
1999-12-23 16:54:54 +00:00
|
|
|
sgVec2 *p = new sgVec2 [n];
|
|
|
|
FGPhysicalProperties *f = new FGPhysicalProperties[n];
|
1999-11-03 18:06:52 +00:00
|
|
|
|
|
|
|
// fill the database
|
1999-12-23 16:54:54 +00:00
|
|
|
for (unsigned int i = 0; i < n; i++)
|
1999-11-03 18:06:52 +00:00
|
|
|
{
|
1999-12-23 16:54:54 +00:00
|
|
|
f[i] = parsed_data->getFGPhysicalProperties(i);
|
|
|
|
parsed_data->getPosition(i, p[i]);
|
1999-11-03 18:06:52 +00:00
|
|
|
|
|
|
|
if ( (i%100) == 0)
|
|
|
|
cerr << ".";
|
|
|
|
}
|
|
|
|
|
1999-12-23 16:54:54 +00:00
|
|
|
// free the memory of the parsed data to ease the required memory
|
|
|
|
// for the very memory consuming spherical interpolation
|
|
|
|
delete parsed_data;
|
|
|
|
|
|
|
|
//and finally init the interpolation
|
|
|
|
cerr << "\nInitialiating Interpolation. (2-3 minutes on a PII-350)\n";
|
|
|
|
database = new SphereInterpolate<FGPhysicalProperties>(n, p, f);
|
|
|
|
|
|
|
|
//and free my allocations:
|
|
|
|
delete[] p;
|
|
|
|
delete[] f;
|
1999-11-03 18:06:52 +00:00
|
|
|
cerr << "Finished weather init.\n";
|
|
|
|
|
1999-08-10 03:40:34 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case distant:
|
|
|
|
cerr << "FGLocalWeatherDatabase error: Distant database isn't implemented yet!\n";
|
|
|
|
cerr << " using random mode instead!\n";
|
|
|
|
case random:
|
|
|
|
case manual:
|
|
|
|
case default_mode:
|
|
|
|
{
|
1999-12-23 16:54:54 +00:00
|
|
|
double x[2] = {0.0, 0.0}; //make an standard weather that's the same at the whole world
|
|
|
|
double y[2] = {0.0, 0.0}; //make an standard weather that's the same at the whole world
|
|
|
|
double z[2] = {1.0, -1.0}; //make an standard weather that's the same at the whole world
|
|
|
|
FGPhysicalProperties f[2]; //make an standard weather that's the same at the whole world
|
|
|
|
database = new SphereInterpolate<FGPhysicalProperties>(2,x,y,z,f);
|
1999-08-10 03:40:34 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
cerr << "FGLocalWeatherDatabase error: Unknown database type specified!\n";
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
FGLocalWeatherDatabase::~FGLocalWeatherDatabase()
|
|
|
|
{
|
|
|
|
//Tidying up:
|
1999-12-23 16:54:54 +00:00
|
|
|
delete database;
|
1999-08-10 03:40:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
/* reset the whole database */
|
|
|
|
/****************************************************************************/
|
1999-10-20 22:19:07 +00:00
|
|
|
void FGLocalWeatherDatabase::reset(const DatabaseWorkingType type)
|
1999-08-10 03:40:34 +00:00
|
|
|
{
|
1999-12-23 16:54:54 +00:00
|
|
|
cerr << "FGLocalWeatherDatabase::reset isn't supported yet\n";
|
1999-08-10 03:40:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
/* update the database. Since the last call we had dt seconds */
|
|
|
|
/****************************************************************************/
|
1999-10-20 22:19:07 +00:00
|
|
|
void FGLocalWeatherDatabase::update(const WeatherPrecision dt)
|
1999-08-10 03:40:34 +00:00
|
|
|
{
|
1999-12-23 16:54:54 +00:00
|
|
|
//if (DatabaseStatus==use_global)
|
|
|
|
// global->update(dt);
|
1999-08-10 03:40:34 +00:00
|
|
|
}
|
|
|
|
|
1999-10-20 22:19:07 +00:00
|
|
|
void FGLocalWeatherDatabase::update(const sgVec3& p) //position has changed
|
1999-08-10 03:40:34 +00:00
|
|
|
{
|
1999-10-20 22:19:07 +00:00
|
|
|
sgCopyVec3(last_known_position, p);
|
1999-11-03 18:06:52 +00:00
|
|
|
|
|
|
|
//uncomment this when you are using the GlobalDatabase
|
|
|
|
/*
|
|
|
|
cerr << "****\nupdate(p) inside\n";
|
|
|
|
cerr << "Parameter: " << p[0] << "/" << p[1] << "/" << p[2] << "\n";
|
|
|
|
sgVec2 p2d;
|
|
|
|
sgSetVec2( p2d, p[0], p[1] );
|
1999-12-23 16:54:54 +00:00
|
|
|
cerr << FGPhysicalProperties2D(get(p2d), p2d);
|
1999-11-03 18:06:52 +00:00
|
|
|
cerr << "****\n";
|
|
|
|
*/
|
1999-12-23 16:54:54 +00:00
|
|
|
|
1999-08-10 03:40:34 +00:00
|
|
|
}
|
|
|
|
|
1999-10-20 22:19:07 +00:00
|
|
|
void FGLocalWeatherDatabase::update(const sgVec3& p, const WeatherPrecision dt) //time and/or position has changed
|
1999-08-10 03:40:34 +00:00
|
|
|
{
|
1999-10-20 22:19:07 +00:00
|
|
|
sgCopyVec3(last_known_position, p);
|
1999-08-10 03:40:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
/* Get the physical properties on the specified point p out of the database */
|
|
|
|
/****************************************************************************/
|
1999-10-20 22:19:07 +00:00
|
|
|
FGPhysicalProperty FGLocalWeatherDatabase::get(const sgVec3& p) const
|
1999-08-10 03:40:34 +00:00
|
|
|
{
|
1999-12-23 16:54:54 +00:00
|
|
|
return FGPhysicalProperty(database->Evaluate(p), p[3]);
|
1999-08-10 03:40:34 +00:00
|
|
|
}
|
|
|
|
|
2000-02-10 23:37:56 +00:00
|
|
|
#ifdef MACOS
|
|
|
|
/* fix a problem with mw compilers in that they don't know the
|
|
|
|
difference between the next two methods. Since the first one
|
|
|
|
doesn't seem to be used anywhere, I commented it out. This is
|
|
|
|
supposed to be fixed in the forthcoming CodeWarrior Release
|
|
|
|
6. */
|
|
|
|
#else
|
1999-10-14 20:30:54 +00:00
|
|
|
FGPhysicalProperties FGLocalWeatherDatabase::get(const sgVec2& p) const
|
|
|
|
{
|
1999-12-23 16:54:54 +00:00
|
|
|
return database->Evaluate(p);
|
1999-10-14 20:30:54 +00:00
|
|
|
}
|
2000-02-10 23:37:56 +00:00
|
|
|
#endif
|
1999-10-14 20:30:54 +00:00
|
|
|
|
1999-10-20 22:19:07 +00:00
|
|
|
WeatherPrecision FGLocalWeatherDatabase::getAirDensity(const sgVec3& p) const
|
1999-08-10 03:40:34 +00:00
|
|
|
{
|
1999-12-23 16:54:54 +00:00
|
|
|
FGPhysicalProperty dummy(database->Evaluate(p), p[3]);
|
1999-08-10 03:40:34 +00:00
|
|
|
|
|
|
|
return
|
|
|
|
(dummy.AirPressure*FG_WEATHER_DEFAULT_AIRDENSITY*FG_WEATHER_DEFAULT_TEMPERATURE) /
|
|
|
|
(dummy.Temperature*FG_WEATHER_DEFAULT_AIRPRESSURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-10-20 22:19:07 +00:00
|
|
|
void FGLocalWeatherDatabase::setSnowRainIntensity(const WeatherPrecision x, const sgVec2& p)
|
1999-08-10 03:40:34 +00:00
|
|
|
{
|
1999-12-23 16:54:54 +00:00
|
|
|
/* not supported yet */
|
1999-08-10 03:40:34 +00:00
|
|
|
}
|
|
|
|
|
1999-10-20 22:19:07 +00:00
|
|
|
void FGLocalWeatherDatabase::setSnowRainType(const SnowRainType x, const sgVec2& p)
|
1999-08-10 03:40:34 +00:00
|
|
|
{
|
1999-12-23 16:54:54 +00:00
|
|
|
/* not supported yet */
|
1999-08-10 03:40:34 +00:00
|
|
|
}
|
|
|
|
|
1999-10-20 22:19:07 +00:00
|
|
|
void FGLocalWeatherDatabase::setLightningProbability(const WeatherPrecision x, const sgVec2& p)
|
1999-08-10 03:40:34 +00:00
|
|
|
{
|
1999-12-23 16:54:54 +00:00
|
|
|
/* not supported yet */
|
1999-08-10 03:40:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FGLocalWeatherDatabase::setProperties(const FGPhysicalProperties2D& x)
|
|
|
|
{
|
1999-12-23 16:54:54 +00:00
|
|
|
/* not supported yet */
|
1999-08-10 03:40:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void fgUpdateWeatherDatabase(void)
|
|
|
|
{
|
1999-10-20 22:19:07 +00:00
|
|
|
sgVec3 position;
|
2000-05-11 19:17:33 +00:00
|
|
|
sgVec3 wind;
|
|
|
|
|
|
|
|
|
|
|
|
sgSetVec3(position,
|
1999-08-10 03:40:34 +00:00
|
|
|
current_aircraft.fdm_state->get_Latitude(),
|
|
|
|
current_aircraft.fdm_state->get_Longitude(),
|
1999-10-20 22:19:07 +00:00
|
|
|
current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER);
|
|
|
|
|
|
|
|
WeatherDatabase->update( position );
|
2000-05-11 19:17:33 +00:00
|
|
|
|
|
|
|
#define rho0 1.293 /*for air in normal altitudes*/
|
|
|
|
#define PATOPSF 0.02089 // Pascals to psf
|
|
|
|
#define KTOR 1.8 // Kelvin to degree Rankine
|
|
|
|
#define KGMTOSGF 0.0019403 // kg/m^3 to slug/ft^3
|
|
|
|
|
|
|
|
|
|
|
|
FGPhysicalProperty my_value = WeatherDatabase->get(position);
|
|
|
|
current_aircraft.fdm_state->set_Static_temperature(my_value.Temperature*KTOR);
|
2000-07-06 22:13:24 +00:00
|
|
|
current_aircraft.fdm_state->set_Static_pressure(my_value.AirPressure*PATOPSF);
|
|
|
|
float density=rho0 * 273.15 * my_value.AirPressure / (101300 *my_value.Temperature )*KGMTOSGF;
|
|
|
|
current_aircraft.fdm_state->set_Density(density*KGMTOSGF);
|
2000-05-11 19:17:33 +00:00
|
|
|
|
2000-07-06 22:13:24 +00:00
|
|
|
#define KPHTOFPS 0.9113 //km/hr to ft/s
|
|
|
|
#define MSTOFPS 3.2808 //m/s to ft/s
|
|
|
|
current_aircraft.fdm_state->set_Velocities_Local_Airmass(my_value.Wind[1]*KPHTOFPS,
|
|
|
|
my_value.Wind[0]*KPHTOFPS,
|
|
|
|
my_value.Wind[2]*KPHTOFPS);
|
2000-05-11 19:17:33 +00:00
|
|
|
|
1999-08-10 03:40:34 +00:00
|
|
|
}
|
|
|
|
|