-dnl aclocal.m4 generated automatically by aclocal 1.4-p4
+dnl aclocal.m4 generated automatically by aclocal 1.4
dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
# include <config.h>
#endif
-// #include <sys/types.h> // for gdbm open flags
-// #include <sys/stat.h> // for gdbm open flags
+#include <stdio.h> // sprintf()
#include <simgear/compiler.h>
}
+// Return the runway closest to a given heading
+bool FGRunways::search( const string& aptid, const int tgt_hdg,
+ FGRunway* runway )
+{
+ FGRunway r;
+ double found_dir = 0.0;
+
+ if ( !search( aptid, &r ) ) {
+ SG_LOG( SG_GENERAL, SG_ALERT,
+ "Failed to find " << aptid << " in database." );
+ return false;
+ }
+
+ double diff;
+ double min_diff = 360.0;
+
+ while ( r.id == aptid ) {
+ // forward direction
+ diff = tgt_hdg - r.heading;
+ while ( diff < -180.0 ) { diff += 360.0; }
+ while ( diff > 180.0 ) { diff -= 360.0; }
+ diff = fabs(diff);
+ // SG_LOG( SG_GENERAL, SG_INFO,
+ // "Runway " << r.rwy_no << " heading = " << r.heading <<
+ // " diff = " << diff );
+ if ( diff < min_diff ) {
+ min_diff = diff;
+ runway = &r;
+ found_dir = 0;
+ }
+
+ // reverse direction
+ diff = tgt_hdg - r.heading - 180.0;
+ while ( diff < -180.0 ) { diff += 360.0; }
+ while ( diff > 180.0 ) { diff -= 360.0; }
+ diff = fabs(diff);
+ // SG_LOG( SG_GENERAL, SG_INFO,
+ // "Runway -" << r.rwy_no << " heading = " <<
+ // r.heading + 180.0 <<
+ // " diff = " << diff );
+ if ( diff < min_diff ) {
+ min_diff = diff;
+ runway = &r;
+ found_dir = 180.0;
+ }
+
+ next( &r );
+ }
+
+ // SG_LOG( SG_GENERAL, SG_INFO, "closest runway = " << runway->rwy_no
+ // << " + " << found_dir );
+
+ double heading = runway->heading + found_dir;
+ while ( heading >= 360.0 ) { heading -= 360.0; }
+ runway->heading = heading;
+
+ return true;
+}
+
+
+// Return the runway number of the runway closest to a given heading
+string FGRunways::search( const string& aptid, const int tgt_hdg ) {
+ FGRunway r;
+ string rn;
+ double found_dir = 0.0;
+
+ if ( !search( aptid, &r ) ) {
+ SG_LOG( SG_GENERAL, SG_ALERT,
+ "Failed to find " << aptid << " in database." );
+ return "NN";
+ }
+
+ double diff;
+ double min_diff = 360.0;
+
+ while ( r.id == aptid ) {
+ // forward direction
+ diff = tgt_hdg - r.heading;
+ while ( diff < -180.0 ) { diff += 360.0; }
+ while ( diff > 180.0 ) { diff -= 360.0; }
+ diff = fabs(diff);
+ // SG_LOG( SG_GENERAL, SG_INFO,
+ // "Runway " << r.rwy_no << " heading = " << r.heading <<
+ // " diff = " << diff );
+ if ( diff < min_diff ) {
+ min_diff = diff;
+ rn = r.rwy_no;
+ found_dir = 0;
+ }
+
+ // reverse direction
+ diff = tgt_hdg - r.heading - 180.0;
+ while ( diff < -180.0 ) { diff += 360.0; }
+ while ( diff > 180.0 ) { diff -= 360.0; }
+ diff = fabs(diff);
+ // SG_LOG( SG_GENERAL, SG_INFO,
+ // "Runway -" << r.rwy_no << " heading = " <<
+ // r.heading + 180.0 <<
+ // " diff = " << diff );
+ if ( diff < min_diff ) {
+ min_diff = diff;
+ rn = r.rwy_no;
+ found_dir = 180.0;
+ }
+
+ next( &r );
+ }
+
+ // SG_LOG( SG_GENERAL, SG_INFO, "closest runway = " << r.rwy_no
+ // << " + " << found_dir );
+ // rn = r.rwy_no;
+ // cout << "In search, rn = " << rn << endl;
+ if ( found_dir == 180 ) {
+ int irn = atoi(rn.c_str());
+ irn += 18;
+ if ( irn > 36 ) {
+ irn -= 36;
+ }
+ char buf[4]; // 2 chars + string terminator + 1 for safety
+ sprintf(buf, "%i", irn);
+ rn = buf;
+ }
+
+ return rn;
+}
+
+
// Destructor
FGRunways::~FGRunways( void ) {
delete storage;
// "runway" is not changed if "apt" is not found.
bool search( const string& aptid, FGRunway* runway );
bool search( const string& aptid, const string& rwyno, FGRunway* runway );
+
+ // DCL - search for runway closest to desired heading in degrees
+ bool search( const string& aptid, const int hdg, FGRunway* runway );
+
+ // Return the runway number of the runway closest to a given heading
+ string FGRunways::search( const string& aptid, const int tgt_hdg );
+
FGRunway search( const string& aptid );
bool next( FGRunway* runway );
FGRunway next();
#include <simgear/math/sg_random.h>
#include <Aircraft/aircraft.hxx>
+#include <ATC/ATCdisplay.hxx>
+//#include <Navaids/atis.hxx>
#include <Navaids/ilslist.hxx>
#include <Navaids/mkrbeacons.hxx>
#include <Navaids/navlist.hxx>
#include "radiostack.hxx"
+#include <string>
+SG_USING_STD(string);
+
static int nav1_play_count = 0;
static int nav2_play_count = 0;
static int adf_play_count = 0;
lat_node(fgGetNode("/position/latitude-deg", true)),
alt_node(fgGetNode("/position/altitude-ft", true)),
need_update(true),
+ comm1_freq(0.0),
+ comm1_alt_freq(0.0),
+ comm2_freq(0.0),
+ comm2_alt_freq(0.0),
nav1_freq(0.0),
nav1_alt_freq(0.0),
nav1_radial(0.0),
FGRadioStack::bind ()
{
// User inputs
+ fgTie("/radios/comm[0]/frequencies/selected-mhz", this,
+ &FGRadioStack::get_comm1_freq, &FGRadioStack::set_comm1_freq);
+ fgSetArchivable("/radios/comm[0]/frequencies/selected-mhz");
+ fgTie("/radios/comm[0]/frequencies/standby-mhz", this,
+ &FGRadioStack::get_comm1_alt_freq, &FGRadioStack::set_comm1_alt_freq);
+ fgSetArchivable("/radios/comm[0]/frequencies/standby-mhz");
+ fgTie("/radios/comm[0]/volume", this,
+ &FGRadioStack::get_comm1_vol_btn,
+ &FGRadioStack::set_comm1_vol_btn);
+ fgSetArchivable("/radios/comm[0]/volume");
+ fgTie("/radios/comm[0]/ident", this,
+ &FGRadioStack::get_comm1_ident_btn,
+ &FGRadioStack::set_comm1_ident_btn);
+ fgSetArchivable("/radios/comm[0]/ident");
+
+ fgTie("/radios/comm[1]/frequencies/selected-mhz", this,
+ &FGRadioStack::get_comm2_freq, &FGRadioStack::set_comm2_freq);
+ fgSetArchivable("/radios/comm[0]/frequencies/selected-mhz");
+ fgTie("/radios/comm[1]/frequencies/standby-mhz", this,
+ &FGRadioStack::get_comm2_alt_freq, &FGRadioStack::set_comm2_alt_freq);
+ fgSetArchivable("/radios/comm[0]/frequencies/standby-mhz");
+ fgTie("/radios/comm[1]/volume", this,
+ &FGRadioStack::get_comm2_vol_btn,
+ &FGRadioStack::set_comm2_vol_btn);
+ fgSetArchivable("/radios/comm[0]/volume");
+ fgTie("/radios/comm[1]/ident", this,
+ &FGRadioStack::get_comm2_ident_btn,
+ &FGRadioStack::set_comm2_ident_btn);
+ fgSetArchivable("/radios/comm[1]/ident");
+
fgTie("/radios/nav[0]/frequencies/selected-mhz", this,
&FGRadioStack::get_nav1_freq, &FGRadioStack::set_nav1_freq);
fgSetArchivable("/radios/nav[0]/frequencies/selected-mhz");
void
FGRadioStack::unbind ()
{
+ fgUntie("/radios/comm[0]/frequencies/selected-mhz");
+ fgUntie("/radios/comm[0]/frequencies/standby-mhz");
+ fgUntie("/radios/comm[0]/on");
+ fgUntie("/radios/comm[0]/ident");
+
+ fgUntie("/radios/comm[1]/frequencies/selected-mhz");
+ fgUntie("/radios/comm[1]/frequencies/standby-mhz");
+ fgUntie("/radios/comm[1]/on");
+ fgUntie("/radios/comm[1]/ident");
+
fgUntie("/radios/nav[0]/frequencies/selected-mhz");
fgUntie("/radios/nav[0]/frequencies/standby-mhz");
fgUntie("/radios/nav[0]/radials/actual-deg");
void
FGRadioStack::update()
{
+ //DCL
+ string transmission;
+
double lon = lon_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
double lat = lat_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
double elev = alt_node->getDoubleValue() * SG_FEET_TO_METER;
Point3D station;
double az1, az2, s;
+ ////////////////////////////////////////////////////////////////////////
+ // Comm1.
+ ////////////////////////////////////////////////////////////////////////
+
+ static bool repeating_message_registered = false;
+ static int dcl_i = 0; //Hack to only call the transmission now and then - should use the event scheduler
+ if ( comm1_valid ) {
+ station = Point3D( comm1_x, comm1_y, comm1_z );
+ comm1_dist = aircraft.distance3D( station );
+ if ( comm1_dist < comm1_effective_range * SG_NM_TO_METER ) {
+ comm1_inrange = true;
+ // TODO - only get the transmission and register every now and then
+ if(dcl_i == 0) {
+ transmission = atis.get_transmission();
+ //ChangeRepeatingMessage(transmission);
+ }
+ if(!repeating_message_registered) {
+ current_atcdisplay->RegisterRepeatingMessage( transmission );
+ repeating_message_registered = true;
+ }
+ dcl_i++;
+ if(dcl_i == 3000) {
+ dcl_i = 0;
+ }
+ } else {
+ comm1_inrange = false;
+ if(repeating_message_registered) {
+ current_atcdisplay->CancelRepeatingMessage();
+ repeating_message_registered = false;
+ }
+ dcl_i = 0;
+ }
+ } else {
+ comm1_inrange = false;
+ if(repeating_message_registered) {
+ current_atcdisplay->CancelRepeatingMessage();
+ repeating_message_registered = false;
+ }
+ dcl_i = 0;
+ // cout << "not picking up comm1. :-(" << endl;
+ }
+
////////////////////////////////////////////////////////////////////////
// Nav1.
////////////////////////////////////////////////////////////////////////
FGILS ils;
FGNav nav;
+ static string last_comm1_ident = "";
+ static string last_comm2_ident = "";
static string last_nav1_ident = "";
static string last_nav2_ident = "";
static string last_adf_ident = "";
static bool last_nav2_vor = false;
+ ////////////////////////////////////////////////////////////////////////
+ // Comm1.
+ ////////////////////////////////////////////////////////////////////////
+
+ if ( current_atislist->query( lon, lat, elev, comm1_freq, &atis ) ) {
+ //cout << "atis found in radiostack search !!!!" << endl;
+ comm1_ident = atis.get_ident();
+ comm1_valid = true;
+ if ( last_comm1_ident != comm1_ident ) {
+ //nav1_trans_ident = ils.get_trans_ident();
+ last_comm1_ident = comm1_ident;
+ comm1_elev = atis.get_elev();
+ comm1_range = FG_ATIS_DEFAULT_RANGE;
+ comm1_effective_range = comm1_range;
+ comm1_x = atis.get_x();
+ comm1_y = atis.get_y();
+ comm1_z = atis.get_z();
+ //cout << "Found a new atis station in range" << endl;
+ //cout << " id = " << atis.get_ident() << endl;
+ }
+ } else {
+ comm1_valid = false;
+ comm1_ident = "";
+ //comm1_trans_ident = "";
+ last_comm1_ident = "";
+ // cout << "not picking up atis" << endl;
+ }
+
////////////////////////////////////////////////////////////////////////
// Nav1.
////////////////////////////////////////////////////////////////////////
#include <Navaids/ilslist.hxx>
#include <Navaids/navlist.hxx>
+#include <ATC/atislist.hxx>
#include <Sound/beacon.hxx>
#include <Sound/morse.hxx>
bool need_update;
+ FGATIS atis;
+
+ string comm1_ident;
+ bool comm1_valid;
+ bool comm1_inrange;
+ double comm1_freq;
+ double comm1_alt_freq;
+ double comm1_vol_btn;
+ bool comm1_ident_btn;
+ double comm1_x;
+ double comm1_y;
+ double comm1_z;
+ double comm1_dist;
+ double comm1_elev;
+ double comm1_range;
+ double comm1_effective_range;
+
+ string comm2_ident;
+ bool comm2_valid;
+ bool comm2_inrange;
+ double comm2_freq;
+ double comm2_alt_freq;
+ double comm2_vol_btn;
+ bool comm2_ident_btn;
+ double comm2_x;
+ double comm2_y;
+ double comm2_z;
+ double comm2_dist;
+ double comm2_elev;
+ double comm2_range;
+ double comm2_effective_range;
+
string nav1_ident;
string nav1_trans_ident;
bool nav1_valid;
// Update nav/adf radios based on current postition
void search ();
+ // COMM1 Setters
+ inline void set_comm1_freq( double freq ) {
+ comm1_freq = freq; need_update = true;
+ }
+ inline void set_comm1_alt_freq( double freq ) { comm1_alt_freq = freq; }
+ inline void set_comm1_vol_btn( double val ) {
+ if ( val < 0.0 ) val = 0.0;
+ if ( val > 1.0 ) val = 1.0;
+ comm1_vol_btn = val;
+ }
+ inline void set_comm1_ident_btn( bool val ) { comm1_ident_btn = val; }
+
+ // COMM2 Setters
+ inline void set_comm2_freq( double freq ) {
+ comm2_freq = freq; need_update = true;
+ }
+ inline void set_comm2_alt_freq( double freq ) { comm2_alt_freq = freq; }
+ inline void set_comm2_vol_btn( double val ) {
+ if ( val < 0.0 ) val = 0.0;
+ if ( val > 1.0 ) val = 1.0;
+ comm2_vol_btn = val;
+ }
+ inline void set_comm2_ident_btn( bool val ) { comm2_ident_btn = val; }
+
// NAV1 Setters
inline void set_nav1_freq( double freq ) {
nav1_freq = freq; need_update = true;
}
inline void set_adf_ident_btn( bool val ) { adf_ident_btn = val; }
+ // COMM1 Accessors
+ inline double get_comm1_freq () const { return comm1_freq; }
+ inline double get_comm1_alt_freq () const { return comm1_alt_freq; }
+
+ // COMM2 Accessors
+ inline double get_comm2_freq () const { return comm2_freq; }
+ inline double get_comm2_alt_freq () const { return comm2_alt_freq; }
// NAV1 Accessors
inline double get_nav1_freq () const { return nav1_freq; }
inline bool get_outer_blink () const { return outer_blink; }
// Calculated values.
+ inline bool get_comm1_inrange() const { return comm1_inrange; }
+ inline double get_comm1_vol_btn() const { return comm1_vol_btn; }
+ inline bool get_comm1_ident_btn() const { return comm1_ident_btn; }
+
+ inline bool get_comm2_inrange() const { return comm2_inrange; }
+ inline double get_comm2_vol_btn() const { return comm2_vol_btn; }
+ inline bool get_comm2_ident_btn() const { return comm2_ident_btn; }
+
inline bool get_nav1_inrange() const { return nav1_inrange; }
bool get_nav1_to_flag () const;
bool get_nav1_from_flag () const;
-/* src/Include/config.h.in. Generated automatically from configure.in by autoheader 2.13. */
+/* src/Include/config.h.in. Generated automatically from configure.in by autoheader. */
/* Define to empty if the keyword does not work. */
#undef const
fgfs_LDADD = \
$(top_builddir)/src/Aircraft/libAircraft.a \
+ $(top_builddir)/src/ATC/libATC.a \
$(top_builddir)/src/Autopilot/libAutopilot.a \
$(top_builddir)/src/Cockpit/libCockpit.a \
$(top_builddir)/src/Controls/libControls.a \
#include <FDM/UIUCModel/uiuc_aircraftdir.h>
#include <Airports/runways.hxx>
#include <Airports/simple.hxx>
+#include <ATC/ATCdisplay.hxx>
#include <Autopilot/auto_gui.hxx>
#include <Autopilot/newauto.hxx>
#include <Cockpit/cockpit.hxx>
p_fix.append( "Navaids/default.fix" );
current_fixlist->init( p_fix );
+ ////////////////////////////////////////////////////////////////////
+ // Initialize ATC list management and query systems
+ ////////////////////////////////////////////////////////////////////
+
+ //DCL
+ SG_LOG(SG_GENERAL, SG_INFO, " ATIS");
+ current_atislist = new FGATISList;
+ SGPath p_atis( globals->get_fg_root() );
+ p_atis.append( "ATC/default.atis" );
+ current_atislist->init( p_atis );
+
+ ////////////////////////////////////////////////////////////////////
+ // Initialise ATC display system
+ ////////////////////////////////////////////////////////////////////
+
+ //DCL
+ SG_LOG(SG_GENERAL, SG_INFO, " ATC Display");
+ current_atcdisplay = new FGATCDisplay;
+ current_atcdisplay->init();
////////////////////////////////////////////////////////////////////
// Initialize the built-in commands.
#include <Aircraft/aircraft.hxx>
+#include <ATC/ATCdisplay.hxx>
#include <Autopilot/newauto.hxx>
+
#include <Cockpit/cockpit.hxx>
#include <Cockpit/radiostack.hxx>
#include <Cockpit/steam.hxx>
hud_and_panel->apply();
fgCockpitUpdate();
+ // Use the hud_and_panel ssgSimpleState for rendering the ATC output
+ // This only works properly if called before the panel call
+ current_atcdisplay->update();
+
// update the panel subsystem
if ( current_panel != NULL ) {
current_panel->update();
double speed = atof(val.substr(pos+1).c_str());
SG_LOG(SG_GENERAL, SG_INFO, "WIND: " << dir << '@' <<
speed << " knots" << endl);
- // convert to fps
+ fgSetDouble("/environment/wind-from-heading-deg", dir);
+ fgSetDouble("/environment/wind-speed-knots", speed);
+
+ // convert to fps
speed *= SG_NM_TO_METER * SG_METER_TO_FEET * (1.0/3600);
dir += 180;
if (dir >= 360)
Include \
Aircraft \
Airports \
+ ATC \
Autopilot \
Cockpit \
Controls \
SGPath p_nav( "/home/curt/FlightGear/Navaids/default.nav" );
current_navlist->init( p_nav );
FGNav n;
- if ( current_navlist->query( -93.2, 45.14, 3000, 117.30, &n) ) {
+ if ( current_navlist->query( -93.2 * SG_DEGREES_TO_RADIANS,
+ 45.14 * SG_DEGREES_TO_RADIANS,
+ 3000, 117.30, &n) )
+ {
cout << "Found a vor station in range" << endl;
cout << " id = " << n.get_ident() << endl;
} else {
SGPath p_ils( "/home/curt/FlightGear/Navaids/default.ils" );
current_ilslist->init( p_ils );
FGILS i;
- if ( current_ilslist->query( -93.1, 45.24, 3000, 110.30, &i) ) {
+ if ( current_ilslist->query( -93.1 * SG_DEGREES_TO_RADIANS,
+ 45.24 * SG_DEGREES_TO_RADIANS,
+ 3000, 110.30, &i) )
+ {
cout << "Found an ils station in range" << endl;
cout << " apt = " << i.get_aptcode() << endl;
cout << " rwy = " << i.get_rwyno() << endl;
SGPath p_fix( "/home/curt/FlightGear/Navaids/default.fix" );
current_fixlist->init( p_fix );
FGFix fix;
- if ( current_fixlist->query( "SHELL", -82, 41, 3000,
- &fix, &heading, &dist) ) {
+ if ( current_fixlist->query( "SHELL", -82 * SG_DEGREES_TO_RADIANS,
+ 41 * SG_DEGREES_TO_RADIANS, 3000,
+ &fix, &heading, &dist) )
+ {
cout << "Found a matching fix" << endl;
cout << " id = " << fix.get_ident() << endl;
cout << " heading = " << heading << " dist = " << dist << endl;