#define _ENVIRONMENT_CTRL_HXX
#include <simgear/compiler.h>
+#include <simgear/structure/subsystem_mgr.hxx>
+#include <simgear/environment/metar.hxx>
+
+#if defined(ENABLE_THREADS) && ENABLE_THREADS
+# include <simgear/threads/SGThread.hxx>
+# include <simgear/threads/SGQueue.hxx>
+#endif
#ifdef SG_HAVE_STD_INCLUDES
# include <cmath>
# include <math.h>
#endif
+#include <queue>
+#include <vector>
+
+SG_USING_STD(queue);
+SG_USING_STD(vector);
+
class SGPropertyNode;
#include "environment.hxx"
/**
* Interface to control environment information for a specific location.
*/
-class FGEnvironmentCtrl
+class FGEnvironmentCtrl : public SGSubsystem
{
public:
virtual double getLatitudeDeg () const { return _lat_deg; }
virtual double getElevationFt () const { return _elev_ft; }
- virtual void init () = 0;
- virtual void update (int dt) = 0;
-
protected:
FGEnvironment * _environment;
virtual ~FGUserDefEnvironmentCtrl ();
virtual void init ();
- virtual void update (int dt);
+ virtual void update (double dt);
private:
};
+
+\f
+/**
+ * Interplation controller using user-supplied parameters.
+ */
+class FGInterpolateEnvironmentCtrl : public FGEnvironmentCtrl
+{
+public:
+ FGInterpolateEnvironmentCtrl ();
+ virtual ~FGInterpolateEnvironmentCtrl ();
+
+ virtual void init ();
+ virtual void reinit ();
+ virtual void update (double delta_time_sec);
+
+private:
+
+ struct bucket {
+ double altitude_ft;
+ FGEnvironment environment;
+ bool operator< (const bucket &b) const;
+ };
+
+ void read_table (const SGPropertyNode * node, vector<bucket *> &table);
+ void do_interpolate (vector<bucket *> &table, double altitude_ft,
+ FGEnvironment * environment);
+
+ FGEnvironment env1, env2; // temporaries
+
+ vector<bucket *> _boundary_table;
+ vector<bucket *> _aloft_table;
+};
+
+
+// A convenience wrapper around SGMetar
+struct FGMetarResult {
+ string icao;
+ SGMetar *m;
+};
+
+
+\f
+/**
+ * Interplation controller using the SGMetar class
+ */
+class FGMetarEnvironmentCtrl : public FGEnvironmentCtrl
+{
+public:
+ FGMetarEnvironmentCtrl ();
+ virtual ~FGMetarEnvironmentCtrl ();
+
+ virtual void init ();
+ virtual void reinit ();
+ virtual void update (double delta_time_sec);
+ virtual void setEnvironment (FGEnvironment * environment);
+
+private:
+ FGInterpolateEnvironmentCtrl *env;
+
+ string _icao;
+ float station_elevation_ft;
+ float search_interval_sec;
+ float same_station_interval_sec;
+ float search_elapsed;
+ float fetch_elapsed;
+ FGAirport last_apt;
+ SGPropertyNode *proxy_host;
+ SGPropertyNode *proxy_port;
+ SGPropertyNode *proxy_auth;
+
+ FGMetarResult fetch_data( const string &icao );
+ virtual void update_metar_properties( SGMetar *m );
+ void update_env_config();
+
+private:
+
+#if defined(ENABLE_THREADS) && ENABLE_THREADS
+ /**
+ * FIFO queue which holds a pointer to the fetched metar data.
+ */
+ SGBlockingQueue < string > request_queue;
+
+ /**
+ * FIFO queue which holds a pointer to the fetched metar data.
+ */
+ SGBlockingQueue < FGMetarResult > result_queue;
+#else
+ /**
+ * FIFO queue which holds a pointer to the fetched metar data.
+ */
+ queue < string > request_queue;
+
+ /**
+ * FIFO queue which holds a pointer to the fetched metar data.
+ */
+ queue < FGMetarResult > result_queue;
+#endif
+
+#if defined(ENABLE_THREADS) && ENABLE_THREADS
+ /**
+ * This class represents the thread of execution responsible for
+ * fetching the metar data.
+ */
+ class MetarThread : public SGThread
+ {
+ public:
+ MetarThread( FGMetarEnvironmentCtrl* f ) : fetcher(f) {}
+ ~MetarThread() {}
+
+ /**
+ * Fetche the metar data from the NOAA.
+ */
+ void run();
+
+ private:
+ FGMetarEnvironmentCtrl *fetcher;
+
+ private:
+ // not implemented.
+ MetarThread();
+ MetarThread( const MetarThread& );
+ MetarThread& operator=( const MetarThread& );
+ };
+
+ friend class MetarThread;
+
+ /**
+ * Metar data fetching thread.
+ */
+ MetarThread* thread;
+
+ /**
+ * Lock and synchronize access to metar queue.
+ */
+ SGMutex mutex;
+ SGPthreadCond metar_cond;
+
+ /**
+ * Thread cleanup handler.
+ */
+ friend void metar_cleanup_handler( void* );
+
+#endif // ENABLE_THREADS
+
+ int _error_count;
+ double _dt;
+ double _error_dt;
+};
+
#endif // _ENVIRONMENT_CTRL_HXX