Initial revision of ATIS module contributed by Dave Luff.
This commit is contained in:
parent
e19d456716
commit
20f0d3f83e
7 changed files with 760 additions and 0 deletions
136
src/ATC/ATCdisplay.cxx
Normal file
136
src/ATC/ATCdisplay.cxx
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
// ATCdisplay.cxx - routines to display ATC output - graphically for now
|
||||||
|
//
|
||||||
|
// Written by David Luff, started October 2001.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2001 David C Luff - david.luff@nottingham.ac.uk
|
||||||
|
//
|
||||||
|
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <simgear/misc/props.hxx>
|
||||||
|
|
||||||
|
#include <Include/general.hxx>
|
||||||
|
#include <Main/fg_props.hxx>
|
||||||
|
#include <GUI/gui.h>
|
||||||
|
|
||||||
|
#include "ATCdisplay.hxx"
|
||||||
|
|
||||||
|
|
||||||
|
FGATCDisplay *current_atcdisplay;
|
||||||
|
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
FGATCDisplay::FGATCDisplay( void ) {
|
||||||
|
rep_msg = false;
|
||||||
|
dsp_offset1 = 0;
|
||||||
|
dsp_offset2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
FGATCDisplay::~FGATCDisplay( void ) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGATCDisplay::init( void ) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// update - this actually draws the visuals and should be called from the main Flightgear rendering loop.
|
||||||
|
void FGATCDisplay::update() {
|
||||||
|
|
||||||
|
if(rep_msg) {
|
||||||
|
float fps = general.get_frame_rate();
|
||||||
|
|
||||||
|
//cout << "In FGATC::update()" << endl;
|
||||||
|
SGPropertyNode *xsize_node = fgGetNode("/sim/startup/xsize");
|
||||||
|
SGPropertyNode *ysize_node = fgGetNode("/sim/startup/ysize");
|
||||||
|
int iwidth = xsize_node->getIntValue();
|
||||||
|
int iheight = ysize_node->getIntValue();
|
||||||
|
|
||||||
|
//TODO - if the string is bigger than the buffer the program exits - we really ought to have a robust check here
|
||||||
|
char buf[256];
|
||||||
|
//float fps = visibility/1600;
|
||||||
|
// sprintf(buf,"%-4.1f %7.0f %7.0f", fps, tris, culled);
|
||||||
|
// sprintf(buf,"%s %-5.1f", "visibility ", visibility);
|
||||||
|
sprintf(buf,"%s", rep_msg_str.c_str());
|
||||||
|
|
||||||
|
glMatrixMode( GL_PROJECTION );
|
||||||
|
glPushMatrix();
|
||||||
|
glLoadIdentity();
|
||||||
|
gluOrtho2D( 0, iwidth, 0, iheight );
|
||||||
|
glMatrixMode( GL_MODELVIEW );
|
||||||
|
glPushMatrix();
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
glDisable( GL_DEPTH_TEST );
|
||||||
|
glDisable( GL_LIGHTING );
|
||||||
|
|
||||||
|
glColor3f( 0.9, 0.4, 0.2 );
|
||||||
|
|
||||||
|
// guiFnt.drawString( buf,
|
||||||
|
// int(iwidth - guiFnt.getStringWidth(buf) - 10 - (int)dsp_offset),
|
||||||
|
// (iheight - 20) );
|
||||||
|
guiFnt.drawString( buf,
|
||||||
|
int(iwidth - 10 - dsp_offset1),
|
||||||
|
(iheight - 20) );
|
||||||
|
guiFnt.drawString( buf,
|
||||||
|
int(iwidth - 10 - dsp_offset2),
|
||||||
|
(iheight - 20) );
|
||||||
|
glEnable( GL_DEPTH_TEST );
|
||||||
|
glEnable( GL_LIGHTING );
|
||||||
|
glMatrixMode( GL_PROJECTION );
|
||||||
|
glPopMatrix();
|
||||||
|
glMatrixMode( GL_MODELVIEW );
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
// Try to scroll at a frame rate independent speed
|
||||||
|
// 40 pixels/second looks about right for now
|
||||||
|
if(dsp_offset1 >= dsp_offset2) {
|
||||||
|
dsp_offset1+=(40.0/fps);
|
||||||
|
dsp_offset2 = dsp_offset1 - (rep_msg_str.size() * 10) - 100;
|
||||||
|
if(dsp_offset1 > (iwidth + (rep_msg_str.size() * 10)))
|
||||||
|
dsp_offset1 = 0;
|
||||||
|
} else {
|
||||||
|
dsp_offset2+=(40.0/fps);
|
||||||
|
dsp_offset1 = dsp_offset2 - (rep_msg_str.size() * 10) - 100;
|
||||||
|
if(dsp_offset2 > (iwidth + (rep_msg_str.size() * 10)))
|
||||||
|
dsp_offset2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FGATCDisplay::RegisterRepeatingMessage(string msg) {
|
||||||
|
rep_msg = true;
|
||||||
|
rep_msg_str = msg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGATCDisplay::ChangeRepeatingMessage(string newmsg) {
|
||||||
|
//Not implemented yet
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGATCDisplay::CancelRepeatingMessage() {
|
||||||
|
rep_msg = false;
|
||||||
|
rep_msg_str = "";
|
||||||
|
dsp_offset1 = 0;
|
||||||
|
dsp_offset2 = 0;
|
||||||
|
return;
|
||||||
|
}
|
83
src/ATC/ATCdisplay.hxx
Normal file
83
src/ATC/ATCdisplay.hxx
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
// ATCdisplay.hxx - class to manage the graphical display of ATC messages.
|
||||||
|
// - The idea is to separate the display of ATC messages from their
|
||||||
|
// - generation so that the generation may come from any source.
|
||||||
|
//
|
||||||
|
// Written by David Luff, started October 2001.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2001 David C Luff - david.luff@nottingham.ac.uk
|
||||||
|
//
|
||||||
|
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
#ifndef _FG_ATC_DISPLAY_HXX
|
||||||
|
#define _FG_ATC_DISPLAY_HXX
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
SG_USING_STD(vector);
|
||||||
|
SG_USING_STD(string);
|
||||||
|
|
||||||
|
struct atcMessage {
|
||||||
|
string msg;
|
||||||
|
bool repeating;
|
||||||
|
int id;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ASSUMPTION - with two radios the list won't be long so we don't need to map the id's
|
||||||
|
typedef vector<atcMessage> atcMessageList;
|
||||||
|
typedef vector<atcMessage>::iterator atcMessageListIterator;
|
||||||
|
|
||||||
|
class FGATCDisplay {
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool rep_msg; // Flag to indicate there is a repeating transmission to display
|
||||||
|
float dsp_offset1; // Used to set the correct position of scrolling display
|
||||||
|
float dsp_offset2;
|
||||||
|
string rep_msg_str; // The repeating transmission to play
|
||||||
|
atcMessageList msgList;
|
||||||
|
atcMessageListIterator msgList_itr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FGATCDisplay();
|
||||||
|
~FGATCDisplay();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
// Display any registered messages
|
||||||
|
void update();
|
||||||
|
|
||||||
|
// Register a single message for display when possible
|
||||||
|
void RegisterSingleMessage(string msg); // OK - I know passing a string in and out is probably not good but it will have to do for now.
|
||||||
|
|
||||||
|
/* For now we will assume only one repeating message at once */
|
||||||
|
// This is not really robust
|
||||||
|
|
||||||
|
// Register a continuously repeating message
|
||||||
|
void RegisterRepeatingMessage(string msg);
|
||||||
|
|
||||||
|
// Change a repeating message - assume that the message changes after the string has finished for now
|
||||||
|
void ChangeRepeatingMessage(string newmsg);
|
||||||
|
|
||||||
|
// Cancel the current repeating message
|
||||||
|
void CancelRepeatingMessage();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern FGATCDisplay *current_atcdisplay;
|
||||||
|
|
||||||
|
#endif // _FG_ATC_DISPLAY_HXX
|
7
src/ATC/Makefile.am
Normal file
7
src/ATC/Makefile.am
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
noinst_LIBRARIES = libATC.a
|
||||||
|
|
||||||
|
libATC_a_SOURCES = \
|
||||||
|
atis.cxx atis.hxx atislist.hxx atislist.cxx \
|
||||||
|
ATCdisplay.hxx ATCdisplay.cxx
|
||||||
|
|
||||||
|
INCLUDES += -I$(top_srcdir) -I$(top_srcdir)/src
|
156
src/ATC/atis.cxx
Normal file
156
src/ATC/atis.cxx
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
// atis.cxx - routines to generate the ATIS info string
|
||||||
|
//
|
||||||
|
// Written by David Luff, started October 2001.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2001 David C Luff - david.luff@nottingham.ac.uk
|
||||||
|
//
|
||||||
|
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <simgear/compiler.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
SG_USING_STD(string);
|
||||||
|
|
||||||
|
//#include STL_IOSTREAM
|
||||||
|
//#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
|
||||||
|
//SG_USING_STD(cout);
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
//#include <simgear/debug/logstream.hxx>
|
||||||
|
//#include <simgear/misc/sgstream.hxx>
|
||||||
|
//#include <simgear/math/sg_geodesy.hxx>
|
||||||
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
|
||||||
|
//#ifndef FG_OLD_WEATHER
|
||||||
|
//#include <WeatherCM/FGLocalWeatherDatabase.h>
|
||||||
|
//#else
|
||||||
|
//# include <Weather/weather.hxx>
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
#include <Main/fg_props.hxx>
|
||||||
|
#include <Airports/runways.hxx>
|
||||||
|
|
||||||
|
#include "atis.hxx"
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
FGATIS::FGATIS() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
FGATIS::~FGATIS() {
|
||||||
|
}
|
||||||
|
|
||||||
|
string FGATIS::get_transmission() {
|
||||||
|
//void FGATIS::get_transmission() {
|
||||||
|
|
||||||
|
string transmission = "";
|
||||||
|
double visibility;
|
||||||
|
double temperature;
|
||||||
|
char buf[10];
|
||||||
|
|
||||||
|
// Only update every so-many loops - FIXME - possibly register this with the event scheduler
|
||||||
|
// Ack this doesn't work since the static counter is shared between all instances of FGATIS
|
||||||
|
// OK, for now the radiostack is handling only calling this every-so-often but that is not really
|
||||||
|
// a proper solution since the atis knows when the transmission is going to change not the radio.
|
||||||
|
//static int i=0;
|
||||||
|
//if(i == 0) {
|
||||||
|
transmission = "";
|
||||||
|
|
||||||
|
// Start with the transmitted station name.
|
||||||
|
transmission += name;
|
||||||
|
|
||||||
|
// Add the recording identifier
|
||||||
|
// TODO - this is hardwired for now - ultimately we need to start with a random one and then increment it with each recording
|
||||||
|
transmission += " Charlie";
|
||||||
|
|
||||||
|
// Output the recording time. - we'll just output the last whole hour for now.
|
||||||
|
string time_str = fgGetString("sim/time/gmt-string");
|
||||||
|
// FIXME - this only gets GMT time but that appears to be all the clock outputs for now
|
||||||
|
//cout << "in atis.cxx, time = " << time_str << endl;
|
||||||
|
transmission = transmission + " Weather " + time_str.substr(0,3) + "00 hours Zulu";
|
||||||
|
|
||||||
|
// Get the temperature
|
||||||
|
// Hardwire the temperature for now - is the local weather database running yet?
|
||||||
|
transmission += " Temperature 25 degrees Celcius";
|
||||||
|
|
||||||
|
// Get the pressure / altimeter
|
||||||
|
|
||||||
|
// Get the visibility
|
||||||
|
visibility = fgGetDouble("/environment/visibility-m");
|
||||||
|
sprintf(buf, "%d", int(visibility/1600));
|
||||||
|
transmission += " Visibility ";
|
||||||
|
transmission += buf;
|
||||||
|
transmission += " miles";
|
||||||
|
|
||||||
|
// Get the cloudbase
|
||||||
|
if(fgGetBool("/environment/clouds/status")) {
|
||||||
|
double cloudbase = fgGetDouble("/environment/clouds/altitude-ft");
|
||||||
|
// For some reason the altitude returned doesn't seem to correspond to the actual cloud altitude.
|
||||||
|
char buf3[10];
|
||||||
|
cout << "cloudbase = " << cloudbase << endl;
|
||||||
|
sprintf(buf3, "%i", int(cloudbase));
|
||||||
|
transmission = transmission + " Cloudbase " + buf3 + " feet";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Based on the airport-id and wind get the active runway
|
||||||
|
//FGRunway *r;
|
||||||
|
SGPath path( globals->get_fg_root() );
|
||||||
|
path.append( "Airports" );
|
||||||
|
path.append( "runways.mk4" );
|
||||||
|
FGRunways runways( path.c_str() );
|
||||||
|
|
||||||
|
//Set the heading to into the wind
|
||||||
|
double hdg = fgGetDouble("/environment/wind-from-heading-deg");
|
||||||
|
double speed = fgGetDouble("/environment/wind-speed-knots");
|
||||||
|
|
||||||
|
//cout << "in atis.cxx, hdg = " << hdg << " speed = " << speed << endl;
|
||||||
|
|
||||||
|
//If no wind use 270degrees
|
||||||
|
if(speed == 0) {
|
||||||
|
hdg = 270;
|
||||||
|
transmission += " Winds light and variable";
|
||||||
|
} else {
|
||||||
|
//add a description of the wind to the transmission
|
||||||
|
char buf2[48];
|
||||||
|
sprintf(buf2, "%s %i %s %i %s", " Winds ", int(speed), " knots from ", int(hdg), " degrees");
|
||||||
|
transmission += buf2;
|
||||||
|
}
|
||||||
|
|
||||||
|
string rwy_no = runways.search(ident, hdg);
|
||||||
|
if(rwy_no != "NN") {
|
||||||
|
transmission += " Landing and departing runway ";
|
||||||
|
transmission += rwy_no;
|
||||||
|
//cout << "in atis.cxx, r.rwy_no = " << rwy_no << " r.id = " << r->id << " r.heading = " << r->heading << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Anything else?
|
||||||
|
|
||||||
|
// TODO - unhardwire the identifier
|
||||||
|
transmission += " Advise controller on initial contact you have Charlie";
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
// i++;
|
||||||
|
// if(i == 600) {
|
||||||
|
// i=0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
return(transmission);
|
||||||
|
}
|
160
src/ATC/atis.hxx
Normal file
160
src/ATC/atis.hxx
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
// atis.hxx -- ATIS class
|
||||||
|
//
|
||||||
|
// Written by Curtis Olson, started April 2000.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
|
||||||
|
//
|
||||||
|
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _FG_ATIS_HXX
|
||||||
|
#define _FG_ATIS_HXX
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <simgear/compiler.h>
|
||||||
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
|
#include <simgear/misc/sgstream.hxx>
|
||||||
|
#include <simgear/magvar/magvar.hxx>
|
||||||
|
#include <simgear/timing/sg_time.hxx>
|
||||||
|
|
||||||
|
#ifdef SG_HAVE_STD_INCLUDES
|
||||||
|
# include <istream>
|
||||||
|
#include <iomanip>
|
||||||
|
#elif defined( SG_HAVE_NATIVE_SGI_COMPILERS )
|
||||||
|
# include <iostream.h>
|
||||||
|
#elif defined( __BORLANDC__ )
|
||||||
|
# include <iostream>
|
||||||
|
#else
|
||||||
|
# include <istream.h>
|
||||||
|
#include <iomanip.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ! defined( SG_HAVE_NATIVE_SGI_COMPILERS )
|
||||||
|
SG_USING_STD(istream);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
SG_USING_STD(string);
|
||||||
|
|
||||||
|
//DCL - a complete guess for now.
|
||||||
|
#define FG_ATIS_DEFAULT_RANGE 30
|
||||||
|
|
||||||
|
class FGATIS {
|
||||||
|
|
||||||
|
char type;
|
||||||
|
double lon, lat;
|
||||||
|
double elev;
|
||||||
|
double x, y, z;
|
||||||
|
int freq;
|
||||||
|
int range;
|
||||||
|
string ident; // Code of the airport its at.
|
||||||
|
string name; // Name transmitted in the broadcast.
|
||||||
|
string info; // The actual ATIS transmission
|
||||||
|
// This is not stored in default.atis but is generated
|
||||||
|
// from the prevailing conditions when required.
|
||||||
|
|
||||||
|
// for failure modeling
|
||||||
|
string trans_ident; // transmitted ident
|
||||||
|
bool atis_failed; // atis failed?
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FGATIS(void);
|
||||||
|
~FGATIS(void);
|
||||||
|
|
||||||
|
inline char get_type() const { return type; }
|
||||||
|
inline double get_lon() const { return lon; }
|
||||||
|
inline double get_lat() const { return lat; }
|
||||||
|
inline double get_elev() const { return elev; }
|
||||||
|
inline double get_x() const { return x; }
|
||||||
|
inline double get_y() const { return y; }
|
||||||
|
inline double get_z() const { return z; }
|
||||||
|
inline int get_freq() const { return freq; }
|
||||||
|
inline int get_range() const { return range; }
|
||||||
|
inline const char *get_ident() { return ident.c_str(); }
|
||||||
|
inline string get_trans_ident() { return trans_ident; }
|
||||||
|
string get_transmission(void);
|
||||||
|
// void get_transmission();
|
||||||
|
|
||||||
|
/* inline void set_type( char t ) { type = t; }
|
||||||
|
inline void set_lon( double l ) { lon = l; }
|
||||||
|
inline void set_lat( double l ) { lat = l; }
|
||||||
|
inline void set_elev( double e ) { elev = e; }
|
||||||
|
inline void set_freq( int f ) { freq = f; }
|
||||||
|
inline void set_range( int r ) { range = r; }
|
||||||
|
inline void set_dme( bool b ) { dme = b; }
|
||||||
|
inline void set_ident( char *i ) { strncpy( ident, i, 5 ); } */
|
||||||
|
|
||||||
|
friend istream& operator>> ( istream&, FGATIS& );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline istream&
|
||||||
|
operator >> ( istream& in, FGATIS& a )
|
||||||
|
{
|
||||||
|
double f;
|
||||||
|
char ch;
|
||||||
|
|
||||||
|
static bool first_time = true;
|
||||||
|
static double julian_date = 0;
|
||||||
|
static const double MJD0 = 2415020.0;
|
||||||
|
if ( first_time ) {
|
||||||
|
julian_date = sgTimeCurrentMJD( 0 ) + MJD0;
|
||||||
|
first_time = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
in >> a.type;
|
||||||
|
|
||||||
|
if ( a.type == '[' )
|
||||||
|
return in >> skipeol;
|
||||||
|
|
||||||
|
in >> a.lat >> a.lon >> a.elev >> f >> a.range
|
||||||
|
>> a.ident;
|
||||||
|
|
||||||
|
a.name = "";
|
||||||
|
in >> ch;
|
||||||
|
a.name += ch;
|
||||||
|
while(1) {
|
||||||
|
//in >> noskipws
|
||||||
|
in.unsetf(ios::skipws);
|
||||||
|
in >> ch;
|
||||||
|
a.name += ch;
|
||||||
|
if((ch == '"') || (ch == 0x0A)) {
|
||||||
|
break;
|
||||||
|
} // we shouldn't need the 0x0A but it makes a nice safely in case someone leaves off the "
|
||||||
|
}
|
||||||
|
in.setf(ios::skipws);
|
||||||
|
//cout << "atis.name = " << a.name << '\n';
|
||||||
|
|
||||||
|
a.freq = (int)(f*100.0 + 0.5);
|
||||||
|
|
||||||
|
// cout << a.ident << endl;
|
||||||
|
|
||||||
|
// generate cartesian coordinates
|
||||||
|
Point3D geod( a.lon * SGD_DEGREES_TO_RADIANS, a.lat * SGD_DEGREES_TO_RADIANS, a.elev );
|
||||||
|
Point3D cart = sgGeodToCart( geod );
|
||||||
|
a.x = cart.x();
|
||||||
|
a.y = cart.y();
|
||||||
|
a.z = cart.z();
|
||||||
|
|
||||||
|
a.trans_ident = a.ident;
|
||||||
|
a.atis_failed = false;
|
||||||
|
|
||||||
|
return in >> skipeol;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _FG_ATIS_HXX
|
149
src/ATC/atislist.cxx
Normal file
149
src/ATC/atislist.cxx
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
// atislist.cxx -- navaids management class
|
||||||
|
//
|
||||||
|
// Written by Curtis Olson, started April 2000.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
|
||||||
|
//
|
||||||
|
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
#include <simgear/misc/sgstream.hxx>
|
||||||
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
|
|
||||||
|
#include "atislist.hxx"
|
||||||
|
|
||||||
|
|
||||||
|
FGATISList *current_atislist;
|
||||||
|
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
FGATISList::FGATISList( void ) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
FGATISList::~FGATISList( void ) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// load the navaids and build the map
|
||||||
|
bool FGATISList::init( SGPath path ) {
|
||||||
|
FGATIS a;
|
||||||
|
|
||||||
|
atislist.erase( atislist.begin(), atislist.end() );
|
||||||
|
|
||||||
|
sg_gzifstream in( path.str() );
|
||||||
|
if ( !in.is_open() ) {
|
||||||
|
SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << path.str() );
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read in each line of the file
|
||||||
|
|
||||||
|
in >> skipeol;
|
||||||
|
in >> skipcomment;
|
||||||
|
|
||||||
|
#ifdef __MWERKS__
|
||||||
|
|
||||||
|
char c = 0;
|
||||||
|
while ( in.get(c) && c != '\0' && a.get_type() != '[' ) {
|
||||||
|
in.putback(c);
|
||||||
|
in >> a;
|
||||||
|
if ( a.get_type() != '[' ) {
|
||||||
|
atislist[a.get_freq()].push_back(a);
|
||||||
|
}
|
||||||
|
in >> skipcomment;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
double min = 100000;
|
||||||
|
double max = 0;
|
||||||
|
|
||||||
|
while ( ! in.eof() && a.get_type() != '[' ) {
|
||||||
|
in >> a;
|
||||||
|
//cout << "id = " << a.get_ident() << endl;
|
||||||
|
//cout << " type = " << a.get_type() << endl;
|
||||||
|
//cout << " lon = " << a.get_lon() << endl;
|
||||||
|
//cout << " lat = " << a.get_lat() << endl;
|
||||||
|
//cout << " elev = " << a.get_elev() << endl;
|
||||||
|
//cout << " freq = " << a.get_freq() << endl;
|
||||||
|
//cout << " range = " << a.get_range() << endl;
|
||||||
|
if ( a.get_type() != '[' ) {
|
||||||
|
atislist[a.get_freq()].push_back(a);
|
||||||
|
}
|
||||||
|
in >> skipcomment;
|
||||||
|
|
||||||
|
if ( a.get_type() != 'N' ) {
|
||||||
|
if ( a.get_freq() < min ) {
|
||||||
|
min = a.get_freq();
|
||||||
|
}
|
||||||
|
if ( a.get_freq() > max ) {
|
||||||
|
max = a.get_freq();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cout << "min freq = " << min << endl;
|
||||||
|
// cout << "max freq = " << max << endl;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// query the database for the specified frequency, lon and lat are in
|
||||||
|
// degrees, elev is in meters
|
||||||
|
bool FGATISList::query( double lon, double lat, double elev, double freq,
|
||||||
|
FGATIS *a )
|
||||||
|
{
|
||||||
|
atis_list_type stations = atislist[(int)(freq*100.0 + 0.5)];
|
||||||
|
|
||||||
|
atis_list_iterator current = stations.begin();
|
||||||
|
atis_list_iterator last = stations.end();
|
||||||
|
|
||||||
|
// double az1, az2, s;
|
||||||
|
Point3D aircraft = sgGeodToCart( Point3D(lon, lat, elev) );
|
||||||
|
Point3D station;
|
||||||
|
double d;
|
||||||
|
for ( ; current != last ; ++current ) {
|
||||||
|
//cout << "testing " << current->get_ident() << endl;
|
||||||
|
station = Point3D(current->get_x(), current->get_y(), current->get_z());
|
||||||
|
//cout << "aircraft = " << aircraft << endl;
|
||||||
|
//cout << "station = " << station << endl;
|
||||||
|
|
||||||
|
d = aircraft.distance3Dsquared( station );
|
||||||
|
|
||||||
|
//cout << " dist = " << sqrt(d)
|
||||||
|
// << " range = " << current->get_range() * SG_NM_TO_METER << endl;
|
||||||
|
|
||||||
|
// match up to twice the published range so we can model
|
||||||
|
// reduced signal strength
|
||||||
|
if ( d < (2 * current->get_range() * SG_NM_TO_METER
|
||||||
|
* 2 * current->get_range() * SG_NM_TO_METER ) ) {
|
||||||
|
//cout << "matched = " << current->get_ident() << endl;
|
||||||
|
*a = *current;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
69
src/ATC/atislist.hxx
Normal file
69
src/ATC/atislist.hxx
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
// atislist.hxx -- atis management class
|
||||||
|
//
|
||||||
|
// Written by Curtis Olson, started April 2000.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
|
||||||
|
//
|
||||||
|
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _FG_ATISLIST_HXX
|
||||||
|
#define _FG_ATISLIST_HXX
|
||||||
|
|
||||||
|
|
||||||
|
#include <simgear/compiler.h>
|
||||||
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "atis.hxx"
|
||||||
|
|
||||||
|
SG_USING_STD(map);
|
||||||
|
SG_USING_STD(vector);
|
||||||
|
|
||||||
|
|
||||||
|
class FGATISList {
|
||||||
|
|
||||||
|
// convenience types
|
||||||
|
typedef vector < FGATIS > atis_list_type;
|
||||||
|
typedef atis_list_type::iterator atis_list_iterator;
|
||||||
|
typedef atis_list_type::const_iterator atis_list_const_iterator;
|
||||||
|
|
||||||
|
// typedef map < int, atis_list_type, less<int> > atis_map_type;
|
||||||
|
typedef map < int, atis_list_type > atis_map_type;
|
||||||
|
typedef atis_map_type::iterator atis_map_iterator;
|
||||||
|
typedef atis_map_type::const_iterator atis_map_const_iterator;
|
||||||
|
|
||||||
|
atis_map_type atislist;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FGATISList();
|
||||||
|
~FGATISList();
|
||||||
|
|
||||||
|
// load all atis and build the map
|
||||||
|
bool init( SGPath path );
|
||||||
|
|
||||||
|
// query the database for the specified frequency, lon and lat are
|
||||||
|
// in degrees, elev is in meters
|
||||||
|
bool query( double lon, double lat, double elev, double freq, FGATIS *a );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern FGATISList *current_atislist;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _FG_ATISLIST_HXX
|
Loading…
Reference in a new issue