diff --git a/src/ATCDCL/ATCmgr.cxx b/src/ATCDCL/ATCmgr.cxx index fe0375015..ec42f249d 100644 --- a/src/ATCDCL/ATCmgr.cxx +++ b/src/ATCDCL/ATCmgr.cxx @@ -31,7 +31,6 @@ #include "commlist.hxx" #include "ATCDialog.hxx" #include "ATCutils.hxx" -#include "transmissionlist.hxx" #include "ground.hxx" @@ -97,14 +96,6 @@ void FGATCMgr::init() { // -EMH- // Initialise the ATC Dialogs - //cout << "Initing Transmissions..." << endl; - SG_LOG(SG_ATC, SG_INFO, " ATC Transmissions"); - current_transmissionlist = new FGTransmissionList; - SGPath p_transmission( globals->get_fg_root() ); - p_transmission.append( "ATC/default.transmissions" ); - current_transmissionlist->init( p_transmission ); - //cout << "Done Transmissions" << endl; - SG_LOG(SG_ATC, SG_INFO, " ATC Dialog System"); current_atcdialog = new FGATCDialog; current_atcdialog->Init(); @@ -147,12 +138,6 @@ void FGATCMgr::update(double dt) { // Search the tuned frequencies every now and then - this should be done with the event scheduler static int i = 0; // Very ugly - but there should only ever be one instance of FGATCMgr. - /*** Area search is defeated. Why? - if(i == 7) { - //cout << "About to AreaSearch()" << endl; - AreaSearch(); - } - ***/ if(i == 15) { //cout << "About to search navcomm1" << endl; FreqSearch("comm", 0); @@ -459,7 +444,6 @@ void FGATCMgr::FreqSearch(const string navcomm, const int unit) { || data.type == AWOS) (*atc_list)[svc_name] = new FGATIS; else if (data.type == TOWER) (*atc_list)[svc_name] = new FGTower; else if (data.type == GROUND) (*atc_list)[svc_name] = new FGGround; - else if (data.type == APPROACH) (*atc_list)[svc_name] = new FGApproach; FGATC* svc = (*atc_list)[svc_name]; svc->SetData(&data); svc->active_on[ncunit] = 1; @@ -471,64 +455,3 @@ void FGATCMgr::FreqSearch(const string navcomm, const int unit) { ZapOtherService(ncunit, "x x x"); } } - -#ifdef AREA_SEARCH -/* I don't think AreaSearch ever gets called */ -// Search ATC stations by area in order that we appear 'on the radar' -void FGATCMgr::AreaSearch() { - const string AREA("AREA"); - // Search for Approach stations - comm_list_type approaches; - comm_list_iterator app_itr; - - lon = lon_node->getDoubleValue(); - lat = lat_node->getDoubleValue(); - elev = elev_node->getDoubleValue() * SG_FEET_TO_METER; - for (atc_list_iterator svc = atc_list->begin(); svc != atc_list->end(); svc++) { - MSI &actv = svc->second->active_on; - if (actv.count(AREA)) actv[AREA] = 0; // Mark all as maybe not in range - } - - // search stations in range - int num_app = current_commlist->FindByPos(lon, lat, elev, 100.0, &approaches, APPROACH); - if (num_app != 0) { - //cout << num_app << " approaches found in area search !!!!" << endl; - - for(app_itr = approaches.begin(); app_itr != approaches.end(); app_itr++) { - FGATC* app = FindInList(app_itr->ident, app_itr->type); - string svc_name = app_itr->ident+decimalNumeral(app_itr->type); - if(app != NULL) { - // The station is already in the ATC list - app->AddPlane("Player"); - } else { - // Generate the station and put in the ATC list - FGApproach* a = new FGApproach; - a->SetData(&(*app_itr)); - a->AddPlane("Player"); - (*atc_list)[svc_name] = a; - //cout << "New area service: " << svc_name << endl; - } - FGATC* svc = (*atc_list)[svc_name]; - svc->active_on[AREA] = 1; - } - } - - for (atc_list_iterator svc = atc_list->begin(); svc != atc_list->end(); svc++) { - MSI &actv = svc->second->active_on; - if (!actv.count(AREA)) continue; - if (!actv[AREA]) actv.erase(AREA); - if (!actv.size()) { // this service no longer active at all - cout << "Eradicating area service: " << svc->first << endl; - svc->second->SetNoDisplay(); - svc->second->Update(0); - delete (svc->second); - atc_list->erase(svc); -// Reset the persistent iterator, since any erase() makes it invalid: - atc_list_itr = atc_list->begin(); -// Hope we only move out of one approach-area; -// others will not be noticed until next update: - break; - } - } -} -#endif diff --git a/src/ATCDCL/ATCmgr.hxx b/src/ATCDCL/ATCmgr.hxx index c21d0c5f3..29601b826 100644 --- a/src/ATCDCL/ATCmgr.hxx +++ b/src/ATCDCL/ATCmgr.hxx @@ -32,7 +32,6 @@ #include #include "tower.hxx" -#include "approach.hxx" using std::string; using std::list; @@ -108,8 +107,6 @@ private: //FGATIS atis; //FGGround ground; FGTower tower; - FGApproach approach; - //FGDeparture departure; // Voice related stuff bool voice; // Flag - true if we are using voice @@ -173,12 +170,6 @@ private: // Search the specified radio for stations on the same frequency and in range. void FreqSearch(const string navcomm, const int unit); - -#ifdef AREA_SEARCH - // Search ATC stations by area in order that we appear 'on the radar' - void AreaSearch(); -#endif - }; #endif // _FG_ATCMGR_HXX diff --git a/src/ATCDCL/Makefile.am b/src/ATCDCL/Makefile.am index eecca04f2..28999cd7e 100644 --- a/src/ATCDCL/Makefile.am +++ b/src/ATCDCL/Makefile.am @@ -4,15 +4,12 @@ libATCDCL_a_SOURCES = \ ATC.hxx ATC.cxx \ atis.hxx atis.cxx \ tower.hxx tower.cxx \ - approach.hxx approach.cxx \ ground.hxx ground.cxx \ commlist.hxx commlist.cxx \ ATCDialog.hxx ATCDialog.cxx \ ATCVoice.hxx ATCVoice.cxx \ ATCmgr.hxx ATCmgr.cxx \ ATCutils.hxx ATCutils.cxx \ - ATCProjection.hxx ATCProjection.cxx \ - transmission.hxx transmission.cxx \ - transmissionlist.hxx transmissionlist.cxx + ATCProjection.hxx ATCProjection.cxx INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src diff --git a/src/ATCDCL/approach.cxx b/src/ATCDCL/approach.cxx deleted file mode 100644 index e1ff8226e..000000000 --- a/src/ATCDCL/approach.cxx +++ /dev/null @@ -1,750 +0,0 @@ -// FGApproach - a class to provide approach control at larger airports. -// -// Written by Alexander Kappes, started March 2002. -// -// Copyright (C) 2002 Alexander Kappes -// -// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include "approach.hxx" -#include "transmission.hxx" -#include "transmissionlist.hxx" -#include "ATCDialog.hxx" - -#include -#include - -#include -#include - -#include -#include - - -#include - -using std::cout; -using std::endl; - -//Constructor -FGApproach::FGApproach(){ - comm1_node = fgGetNode("/instrumentation/comm[0]/frequencies/selected-mhz", true); - comm2_node = fgGetNode("/instrumentation/comm[1]/frequencies/selected-mhz", true); - - _type = APPROACH; - - num_planes = 0; - lon_node = fgGetNode("/position/longitude-deg", true); - lat_node = fgGetNode("/position/latitude-deg", true); - elev_node = fgGetNode("/position/altitude-ft", true); - hdg_node = fgGetNode("/orientation/heading-deg", true); - speed_node = fgGetNode("/velocities/airspeed-kt", true); - etime_node = fgGetNode("/sim/time/elapsed-sec", true); - - first = true; - active_runway = ""; - int i; - for ( i=0; igetDoubleValue(); - - //bool DisplayTransmissions = true; - - for (i=0; igen_text(station, code, tpars, false); - transm = current_transmissionlist->gen_text(station, code, tpars, true); - // is the transmission already registered? - if (!current_atcdialog->trans_reg( ident, transm, APPROACH )) { - current_atcdialog->add_entry( ident, transm, mentry, APPROACH, 0 ); - } - } - } - } - } - } - } - - for ( i=0; i 100.0) tpars.VDir = 1; - else if (planes[i].alt-planes[i].aalt < -100.0) tpars.VDir = 3; - else tpars.VDir = 2; - tpars.alt = planes[i].aalt; - message = current_transmissionlist->gen_text(station, code, tpars, true ); - //cout << message << '\n'; - set_message(message); - planes[i].lmc = code; - planes[i].tlm = etime_node->getDoubleValue(); - planes[i].on_crs = true; - planes[i].contact = 1; - } - //} - - //if(1) { - if ( planes[i].contact == 1 ) { - // ========================= - // === update parameters === - // ========================= - update_param( i ); - //cout << planes[i].brg << " " << planes[i].dist << " " << planes[i].wpts[wpn+1][0] - //<< " " << planes[i].wpts[wpn+1][1] << " " << planes[i].wpts[wpn+1][4] - //cout << wpn << " distance to current course = " << planes[i].dcc << endl; - //cout << etime_node->getDoubleValue() << endl; - - // ========================= - // === reached waypoint? === - // ========================= - wpn = planes[i].wpn-2; - adif = angle_diff_deg( planes[i].hdg, planes[i].wpts[wpn][4] ) - * SGD_DEGREES_TO_RADIANS; - datp = 2*sin(fabs(adif)/2.0)*sin(fabs(adif)/2.0) * - planes[i].spd/3600. * planes[i].turn_rate + - planes[i].spd/3600. * 3.0; - //cout << adif/SGD_DEGREES_TO_RADIANS << " " - // << datp << " " << planes[i].dnc << " " << planes[i].dcc < 100.0) tpars.VDir = 1; - else if (planes[i].alt-planes[i].aalt < -100.0) tpars.VDir = 3; - else tpars.VDir = 2; - tpars.alt = planes[i].aalt; - message = current_transmissionlist->gen_text(station, code, tpars, true ); - //cout << "Approach transmitting...\n"; - //cout << message << endl; - set_message(message); - } - else { - code.c1 = 1; - code.c2 = 3; - code.c3 = 0; - tpars.runway = active_runway; - message = current_transmissionlist->gen_text(station, code, tpars, true); - //cout << "Approach transmitting 2 ...\n"; - //cout << message << endl; - set_message(message); - } - planes[i].lmc = code; - planes[i].tlm = etime_node->getDoubleValue(); - planes[i].on_crs = true; - - update_param( i ); - } - - // ========================= - // === come off course ? === - // ========================= - if ( fabs(planes[i].dcc) > 1.0 && - ( !planes[i].wp_change || etime_node->getDoubleValue() - planes[i].tlm > tbm ) ) { - //cout << "Off course!\n"; - if ( planes[i].on_crs ) { - if ( planes[i].dcc < 0) { - planes[i].ahdg += 30.0; - } - else { - planes[i].ahdg -= 30.0; - } - if (planes[i].ahdg > 360.0) planes[i].ahdg -= 360.0; - else if (planes[i].ahdg < 0.0) planes[i].ahdg += 360.0; - } - //cout << planes[i].on_crs << " " - // << angle_diff_deg( planes[i].hdg, planes[i].ahdg) << " " - // << etime_node->getDoubleValue() << " " - // << planes[i].tlm << endl; - // generate the message - if ( planes[i].on_crs || - ( fabs(angle_diff_deg( planes[i].hdg, planes[i].ahdg )) > 30.0 && - etime_node->getDoubleValue() - planes[i].tlm > tbm) ) { - // generate the message - code.c1 = 1; - code.c2 = 4; - code.c3 = 0; - adif = angle_diff_deg( planes[i].hdg, planes[i].ahdg ); - tpars.station = name; - tpars.callsign = "Player"; - tpars.miles = fabs(planes[i].dcc); - if ( adif < 0 ) tpars.tdir = 1; - else tpars.tdir = 2; - tpars.heading = planes[i].ahdg; - message = current_transmissionlist->gen_text(station, code, tpars, true); - //cout << "Approach transmitting 3 ...\n"; - //cout << message << '\n'; - set_message(message); - planes[i].lmc = code; - planes[i].tlm = etime_node->getDoubleValue(); - } - - planes[i].on_crs = false; - } - else if ( !planes[i].on_crs ) { - //cout << "Off course 2!\n"; - wpn = planes[i].wpn-1; - adif = angle_diff_deg( planes[i].hdg, planes[i].wpts[wpn][4] ) - * SGD_DEGREES_TO_RADIANS; - datp = 2*sin(fabs(adif)/2.0)*sin(fabs(adif)/2.0) * - planes[i].spd/3600. * planes[i].turn_rate + - planes[i].spd/3600. * 3.0; - if ( fabs(planes[i].dcc) < datp ) { - planes[i].ahdg = fabs(planes[i].wpts[wpn][4]); - - // generate the message - code.c1 = 1; - code.c2 = 2; - code.c3 = 0; - tpars.station = name; - tpars.callsign = "Player"; - if ( adif < 0 ) tpars.tdir = 1; - else tpars.tdir = 2; - tpars.heading = planes[i].ahdg; - message = current_transmissionlist->gen_text(station, code, tpars, true); - //cout << "Approach transmitting 4 ...\n"; - //cout << message << '\n'; - set_message(message); - planes[i].lmc = code; - planes[i].tlm = etime_node->getDoubleValue(); - - planes[i].on_crs = true; - } - } - else if ( planes[i].wp_change ) { - planes[i].wp_change = false; - } - - // =================================================================== - // === Less than two minutes away from touchdown? -> Contact Tower === - // =================================================================== - if ( planes[i].wpn == 2 && planes[i].dnwp < planes[i].spd/60.*2.0 ) { - - double freq = 121.95; // Hardwired - FIXME - // generate message - code.c1 = 1; - code.c2 = 5; - code.c3 = 0; - tpars.station = name; - tpars.callsign = "Player"; - tpars.freq = freq; - message = current_transmissionlist->gen_text(station, code, tpars, true); - //cout << "Approach transmitting 5 ...\n"; - //cout << message << '\n'; - set_message(message); - planes[i].lmc = code; - planes[i].tlm = etime_node->getDoubleValue(); - - planes[i].contact = 2; - } - } - } -} - - -// ============================================================================ -// update course parameters -// ============================================================================ -void FGApproach::update_param( const int &i ) { - - double course, d; - - int wpn = planes[i].wpn-1; // this is the current waypoint - - planes[i].dcc = calc_psl_dist(planes[i].brg, planes[i].dist, - planes[i].wpts[wpn][0], planes[i].wpts[wpn][1], - planes[i].wpts[wpn][4]); - planes[i].dnc = calc_psl_dist(planes[i].brg, planes[i].dist, - planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1], - planes[i].wpts[wpn-1][4]); - calc_hd_course_dist(planes[i].brg, planes[i].dist, - planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1], - &course, &d); - planes[i].dnwp = d; - -} - -// ============================================================================ -// smallest difference between two angles in degree -// difference is negative if a1 > a2 and positive if a2 > a1 -// =========================================================================== -double FGApproach::angle_diff_deg( const double &a1, const double &a2) { - - double a3 = a2 - a1; - if (a3 < 180.0) a3 += 360.0; - if (a3 > 180.0) a3 -= 360.0; - - return a3; -} - -// ============================================================================ -// calculate waypoints -// ============================================================================ -void FGApproach::calc_wp( const int &i ) { - - int j; - double course, d, cd, a1, az2; - - int wpn = planes[i].wpn; - // waypoint 0: Threshold of active runway - SGGeod activeRunway(SGGeod::fromDeg(active_rw_lon, active_rw_lat)); - SGGeodesy::inverse(_geod, activeRunway, course, az2, d); - - double d1 = active_rw_hdg+180.0; - if ( d1 > 360.0 ) d1 -=360.0; - calc_cd_head_dist(360.0-course, d/SG_NM_TO_METER, - d1, active_rw_len/SG_NM_TO_METER/2.0, - &planes[i].wpts[wpn][0], &planes[i].wpts[wpn][1]); - planes[i].wpts[wpn][2] = _geod.getElevationM(); - planes[i].wpts[wpn][4] = 0.0; - planes[i].wpts[wpn][5] = 0.0; - wpn += 1; - - // ====================== - // horizontal navigation - // ====================== - // waypoint 1: point for turning onto final - calc_cd_head_dist(planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1], d1, lfl, - &planes[i].wpts[wpn][0], &planes[i].wpts[wpn][1]); - calc_hd_course_dist(planes[i].wpts[wpn][0], planes[i].wpts[wpn][1], - planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1], - &course, &d); - planes[i].wpts[wpn][4] = course; - planes[i].wpts[wpn][5] = d; - wpn += 1; - - // calculate course and distance from plane position to waypoint 1 - calc_hd_course_dist(planes[i].brg, planes[i].dist, planes[i].wpts[1][0], - planes[i].wpts[1][1], &course, &d); - // check if airport is not between plane and waypoint 1 and - // DCA to airport on course to waypoint 1 is larger than 10 miles - double zero = 0.0; - if ( fabs(angle_diff_deg( planes[i].wpts[1][0], planes[i].brg )) < 90.0 || - calc_psl_dist( zero, zero, planes[i].brg, planes[i].dist, course ) > 10.0 ) { - // check if turning angle at waypoint 1 would be > max_ta - if ( fabs(angle_diff_deg( planes[i].wpts[1][4], course )) > max_ta ) { - cd = calc_psl_dist(planes[i].brg, planes[i].dist, - planes[i].wpts[1][0], planes[i].wpts[1][1], - planes[i].wpts[1][4]); - a1 = atan2(cd,planes[i].wpts[1][1]); - planes[i].wpts[wpn][0] = planes[i].wpts[1][0] - a1/SGD_DEGREES_TO_RADIANS; - if ( planes[i].wpts[wpn][0] < 0.0) planes[i].wpts[wpn][0] += 360.0; - if ( planes[i].wpts[wpn][0] > 360.0) planes[i].wpts[wpn][0] -= 360.0; - planes[i].wpts[wpn][1] = fabs(cd) / sin(fabs(a1)); - calc_hd_course_dist(planes[i].wpts[wpn][0], planes[i].wpts[wpn][1], - planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1], - &course, &d); - planes[i].wpts[wpn][4] = course; - planes[i].wpts[wpn][5] = d; - wpn += 1; - - calc_hd_course_dist(planes[i].brg, planes[i].dist, planes[i].wpts[wpn-1][0], - planes[i].wpts[wpn-1][1], &course, &d); - } - } else { - double leg = 10.0; - a1 = atan2(planes[i].wpts[1][1], leg ); - - if ( angle_diff_deg(planes[i].brg,planes[i].wpts[1][0]) < 0 ) - planes[i].wpts[wpn][0] = planes[i].wpts[1][0] + a1/SGD_DEGREES_TO_RADIANS; - else planes[i].wpts[wpn][0] = planes[i].wpts[1][0] - a1/SGD_DEGREES_TO_RADIANS; - - planes[i].wpts[wpn][1] = sqrt( planes[i].wpts[1][1]*planes[i].wpts[1][1] + leg*leg ); - calc_hd_course_dist(planes[i].wpts[wpn][0], planes[i].wpts[wpn][1], - planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1], - &course, &d); - planes[i].wpts[wpn][4] = course; - planes[i].wpts[wpn][5] = d; - wpn += 1; - - calc_hd_course_dist(planes[i].brg, planes[i].dist, - planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1], - &course, &d); - } - - planes[i].wpts[wpn][0] = planes[i].brg; - planes[i].wpts[wpn][1] = planes[i].dist; - planes[i].wpts[wpn][2] = planes[i].alt; - planes[i].wpts[wpn][4] = course; - planes[i].wpts[wpn][5] = d; - wpn += 1; - - planes[i].wpn = wpn; - - // Now check if legs are too short or if legs can be shortend - // legs must be at least 2 flight minutes long - double mdist = planes[i].spd / 60.0 * 2.0; - for ( j=2; j 0 ) { - alt = planes[i].wpts[j-1][2] + - (planes[i].wpts[j][5] / planes[i].spd) * 60.0 * planes[i].desc_rate; - planes[i].wpts[j][2] = round_alt( false, alt ); - if ( planes[i].wpts[j][2] > planes[i].alt ) - planes[i].wpts[j][2] = round_alt( false, planes[i].alt ); - } - else { - planes[i].wpts[j][2] = planes[i].wpts[1][2]; - } - } - - cout << "Plane position: " << planes[i].brg << " " << planes[i].dist << endl; - for ( j=0; j (int)(alt)+0.5 ) alt = ((int)(alt)+1)*1000.0; - else alt = ((int)(alt)+0.5)*1000.0; - } - else { - if ( alt > (int)(alt)+0.5 ) alt = ((int)(alt)+0.5)*1000.0; - else alt = ((int)(alt))*1000.0; - } - - return alt; -} - - -// ============================================================================ -// get active runway -// ============================================================================ -void FGApproach::get_active_runway() { - //cout << "Entering FGApproach::get_active_runway()\n"; - - const FGAirport* apt = fgFindAirportID(ident); - assert(apt); - FGRunway* runway = apt->getActiveRunwayForUsage(); - - active_runway = runway->ident(); - active_rw_hdg = runway->headingDeg(); - active_rw_lon = runway->longitude(); - active_rw_lat = runway->latitude(); - active_rw_len = runway->lengthFt(); -} - -// ======================================================================== -// update infos about plane -// ======================================================================== -void FGApproach::update_plane_dat() { - - //cout << "Update Approach " << ident << " " << num_planes << " registered" << endl; - // update plane positions - int i; - for (i=0; igetDoubleValue(); - planes[i].lat = lat_node->getDoubleValue(); - planes[i].alt = elev_node->getDoubleValue(); - planes[i].hdg = hdg_node->getDoubleValue(); - planes[i].spd = speed_node->getDoubleValue(); - - double course, distance, az2; - SGGeod plane(SGGeod::fromDeg(planes[1].lon, active_rw_lat)); - SGGeodesy::inverse(_geod, plane, course, az2, distance); - planes[i].dist = distance * SG_METER_TO_NM; - planes[i].brg = 360.0-course; - - //cout << "Plane Id: " << planes[i].ident << " Distance to " << ident - // << " is " << planes[i].dist << " miles " << "Bearing " << planes[i].brg << endl; - - } -} - -// ======================================================================= -// Add plane to Approach list -// ======================================================================= -void FGApproach::AddPlane(const string& pid) { - - int i; - for ( i=0; i SGD_PI ) da -= SGD_2PI; - if ( fabs(da) > SGD_PI_2) { - //if ( x3*(x1-x2) < 0.0 && y3*(y1-y2) < 0.0) { - x3 *= -1.0; - y3 *= -1.0; - } - //cout << x3 << " " << y3 << endl; - double dis1 = x1-x2-x3; - double dis2 = y1-y2-y3; - dis = sqrt(dis); - da = atan2(dis2,dis1); - if ( da < 0.0 ) da += SGD_2PI; - if ( da < a3 ) dis *= -1.0; - //cout << dis1 << " " << dis2 << " " << da*SGD_RADIANS_TO_DEGREES << " " << h3 - // << " " << sqrt(dis1*dis1 + dis2*dis2) << " " << dis << endl; - //cout << atan2(dis2,dis1)*SGD_RADIANS_TO_DEGREES << " " << dis << endl; - - return dis; -} - - -// ======================================================================== -// Calculate new bear/dist given starting bear/dis, and offset radial, -// and distance. -// ======================================================================== -void FGApproach::calc_cd_head_dist(const double &h1, const double &d1, - const double &course, const double &dist, - double *h2, double *d2) -{ - double a1 = h1 * SGD_DEGREES_TO_RADIANS; - double a2 = course * SGD_DEGREES_TO_RADIANS; - double x1 = cos(a1) * d1; - double y1 = sin(a1) * d1; - double x2 = cos(a2) * dist; - double y2 = sin(a2) * dist; - - *d2 = sqrt((x1+x2)*(x1+x2) + (y1+y2)*(y1+y2)); - *h2 = atan2( (y1+y2), (x1+x2) ) * SGD_RADIANS_TO_DEGREES; - if ( *h2 < 0 ) *h2 = *h2+360; -} - - - -// ======================================================================== -// get heading and distance between two points; point1 ---> point2 -// ======================================================================== -void FGApproach::calc_hd_course_dist(const double &h1, const double &d1, - const double &h2, const double &d2, - double *course, double *dist) -{ - double a1 = h1 * SGD_DEGREES_TO_RADIANS; - double a2 = h2 * SGD_DEGREES_TO_RADIANS; - double x1 = cos(a1) * d1; - double y1 = sin(a1) * d1; - double x2 = cos(a2) * d2; - double y2 = sin(a2) * d2; - - *dist = sqrt( (y2-y1)*(y2-y1) + (x2-x1)*(x2-x1) ); - *course = atan2( (y2-y1), (x2-x1) ) * SGD_RADIANS_TO_DEGREES; - if ( *course < 0 ) *course = *course+360; - //cout << x1 << " " << y1 << " " << x2 << " " << y2 << " " << *dist << " " << *course << endl; -} - - - -int FGApproach::RemovePlane() { - - // first check if anything has to be done - bool rmplane = false; - int i; - - for (i=0; i range*SG_NM_TO_METER) { - rmplane = true; - break; - } - } - if (!rmplane) return num_planes; - - // now make a copy of the plane list - PlaneApp tmp[max_planes]; - for (i=0; i - -#include -#include -#include -#include -#include -#include - -#include
- -# include - -#include "ATC.hxx" -#include "transmission.hxx" - -//DCL - a complete guess for now. -#define FG_APPROACH_DEFAULT_RANGE 100 - -// Contains all the information about a plane that the approach control needs -const int max_planes = 20; // max number of planes on the stack -const int max_wp = 10; // max number of waypoints for approach phase -const double max_ta = 130; // max turning angle for plane during approach -const double tbm = 2.0; // min time (in sec) between two messages -const double lfl = 10.0; // length of final leg - -struct PlaneApp { - - // variables for plane if it's on the radar - std::string ident; // indentification of plane - double lon; // longitude in degrees - double lat; // latitude in degrees - double alt; // Altitute above sea level in feet - double hdg; // heading of plane in degrees - double dist; // distance to airport in miles - double brg; // bearing relative to airport in degrees - double spd; // speed above ground - int contact; // contact with approach established? - // 0 = no contact yet - // 1 = in contact - // 2 = handed off to tower - double turn_rate; // standard turning rate of the plane in seconds per degree - double desc_rate; // standard descent rate of the plane in feets per minute - double clmb_rate; // standard climb rate of the plane in feets per minute - - // additional variables if contact has been established - int wpn; // number of waypoints - double wpts[max_wp][6]; // assigned waypoints for approach phase - // first wp in list is airport - // last waypoint point at which contact was established - // second index: 0 = bearing to airport - // second index: 1 = distance to airport - // second index: 2 = alt - // second index: 3 = ETA - // second index: 4 = heading to next waypoint - // second index: 5 = distance to next waypoint - - double dnwp; // distance to next waypoint - double dcc; // closest distance to current assigned course - double dnc; // closest distance to course from next to next to next wp - double aalt; // assigned altitude - double ahdg; // assigned heading - bool on_crs; // is the plane on course? - bool wp_change; // way point has changed - double tlm; // time when last message was sent - TransCode lmc; // code of last message -}; - - -class FGApproach : public FGATC { - - int bucket; - - std::string active_runway; - double active_rw_hdg; - double active_rw_lon; - double active_rw_lat; - double active_rw_len; - - int num_planes; // number of planes on the stack - PlaneApp planes[max_planes]; // Array of planes - std::string transmission; - bool first; - - SGPropertyNode_ptr comm1_node; - SGPropertyNode_ptr comm2_node; - - SGPropertyNode_ptr atcmenu_node; - SGPropertyNode_ptr atcopt0_node; - SGPropertyNode_ptr atcopt1_node; - SGPropertyNode_ptr atcopt2_node; - SGPropertyNode_ptr atcopt3_node; - SGPropertyNode_ptr atcopt4_node; - SGPropertyNode_ptr atcopt5_node; - SGPropertyNode_ptr atcopt6_node; - SGPropertyNode_ptr atcopt7_node; - SGPropertyNode_ptr atcopt8_node; - SGPropertyNode_ptr atcopt9_node; - - // for failure modeling - std::string trans_ident; // transmitted ident - bool approach_failed; // approach failed? - -public: - - FGApproach(void); - ~FGApproach(void); - - void Init(); - - void Update(double dt); - - // Add new plane to stack if not already registered - // Input: pid - id of plane (name) - // Output: "true" if added; "false" if already existend - void AddPlane(const std::string& pid); - - // Remove plane from stack if out of range - int RemovePlane(); - - inline double get_bucket() const { return bucket; } - inline int get_pnum() const { return num_planes; } - inline const std::string& get_trans_ident() { return trans_ident; } - -private: - - void calc_wp( const int &i); - - void update_plane_dat(); - - void get_active_runway(); - - void update_param(const int &i); - - double round_alt( bool hl, double alt ); - - double angle_diff_deg( const double &a1, const double &a2); - - void set_message(const std::string &s); - -// ======================================================================== -// get point2 given starting point1 and course and distance -// input: point1 = heading in degrees, distance -// input: course in degrees, distance -// output: point2 = heading in degrees, distance -// ======================================================================== - void calc_cd_head_dist(const double &h1, const double &d1, - const double &course, const double &dist, - double *h2, double *d2); - - -// ======================================================================== -// get heading and distance between two points; point2 ---> point1 -// input: point1 = heading in degrees, distance -// input: point2 = heading in degrees, distance -// output: course in degrees, distance -// ======================================================================== - void calc_hd_course_dist(const double &h1, const double &d1, - const double &h2, const double &d2, - double *course, double *dist); - - - -// ======================================================================== -// closest distance between a point and a straigt line in 2 dim. -// the input variables are given in (heading, distance) -// relative to a common point -// input: point = heading in degrees, distance -// input: straigt line = anker vector (heading in degrees, distance), -// heading of direction vector -// output: distance -// ======================================================================== - double calc_psl_dist(const double &h1, const double &d1, - const double &h2, const double &d2, - const double &h3); - - // Pointers to current users position - SGPropertyNode_ptr lon_node; - SGPropertyNode_ptr lat_node; - SGPropertyNode_ptr elev_node; - SGPropertyNode_ptr hdg_node; - SGPropertyNode_ptr speed_node; - SGPropertyNode_ptr etime_node; - - //Update the transmission string - void UpdateTransmission(void); - - friend std::istream& operator>> ( std::istream&, FGApproach& ); -}; - -#endif // _FG_APPROACH_HXX diff --git a/src/ATCDCL/transmission.cxx b/src/ATCDCL/transmission.cxx deleted file mode 100644 index 5c1d01572..000000000 --- a/src/ATCDCL/transmission.cxx +++ /dev/null @@ -1,103 +0,0 @@ -// FGTransmission - a class to provide transmission control at larger airports. -// -// Written by Alexander Kappes, started March 2002. -// Based on ground.cxx by David Luff, started March 2002. -// -// Copyright (C) 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "transmission.hxx" - -#include - -#include -#include - - -//Constructor -FGTransmission::FGTransmission(){ -} - -//Destructor -FGTransmission::~FGTransmission(){ -} - -void FGTransmission::Init() { -} - -// ============================================================================ -// extract parameters from transmission -// ============================================================================ -TransPar FGTransmission::Parse() { - TransPar tpar; - string tokens[20]; - int msglen,toklen; - //char dum; - int i,j,k; - const char *capl = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - msglen = strlen( TransText.c_str() ); - - int tkn = 0; - for ( i=0; i < msglen; ++i ) { - if ( TransText.c_str()[i] != ' ' ) { - if ( TransText.c_str()[i] != ',' ) tokens[tkn] += TransText.c_str()[i]; - } else if ( !tokens[tkn].empty() ) { - if ( tkn <= 20 ) { - tkn += 1; - } else { - SG_LOG(SG_ATC, SG_WARN,"Too many tokens"); - } - } - } - - for ( i=0; i<20; ++i) { - - if ( tokens[i] == "request" ) { - tpar.request = true; - } else if ( tokens[i] == "approach" ) { - tpar.station = "approach"; - tpar.airport = tokens[i-1]; - } else if ( tokens[i] == "landing" ) { - tpar.intention = "landing"; - for ( j=i+1; j<=i+2; ++j ) { - if ( !tokens[j].empty() ) { - toklen = strlen( tokens[j].c_str() ); - bool aid = true; - for ( k=0; k - -#include -#include -#include -#include -#include -#include - -#include
- -# include - -#include "ATC.hxx" - -struct TransCode { - int c1; - int c2; - int c3; -}; - -// TransPar - a representation of the logic of a parsed speech transmission -struct TransPar { - std::string station; - std::string callsign; - std::string airport; - std::string intention; // landing, crossing - std::string intid; // (airport) ID for intention - bool request; // is the transmission a request or an answer? - int tdir; // turning direction: 1=left, 2=right - double heading; - int VDir; // vertical direction: 1=descent, 2=maintain, 3=climb - double alt; - double miles; - std::string runway; - double freq; - double time; -}; - -// FGTransmission - a class to encapsulate a speech transmission -class FGTransmission { - - //int StationType; // Type of ATC station: 1 Approach - atc_type StationType; - TransCode Code; // DCL - no idea what this is. - std::string TransText; // The text of the spoken transmission - std::string MenuText; // An abbreviated version of the text for the menu entry - -public: - - FGTransmission(void); - ~FGTransmission(void); - - void Init(); - - inline atc_type get_station() const { return StationType; } - inline const TransCode& get_code() { return Code; } - inline const std::string& get_transtext() { return TransText; } - inline const std::string& get_menutext() { return MenuText; } - - // Return the parsed logic of the transmission - TransPar Parse(); - -private: - - friend std::istream& operator>> ( std::istream&, FGTransmission& ); - -}; - - -inline std::istream& -operator >> ( std::istream& in, FGTransmission& a ) { - char ch; - int tmp; - - static bool first_time = true; - static double julian_date = 0; - static const double MJD0 = 2415020.0; - if ( first_time ) { - julian_date = sgTimeCurrentMJD(0, 0) + MJD0; - first_time = false; - } - // Ugly hack alert - eventually we'll use xml format for the transmissions file - in >> tmp; - if(tmp == 1) { - a.StationType = APPROACH; - } else { - a.StationType = INVALID; - } - in >> a.Code.c1; - in >> a.Code.c2; - in >> a.Code.c3; - a.TransText = ""; - in >> ch; - if ( ch != '"' ) a.TransText += ch; - while(1) { - //in >> noskipws - in.unsetf(ios::skipws); - in >> ch; - if ( ch != '"' ) a.TransText += 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); - - a.MenuText = ""; - in >> ch; - if ( ch != '"' ) a.MenuText += ch; - while(1) { - //in >> noskipws - in.unsetf(ios::skipws); - in >> ch; - if ( ch != '"' ) a.MenuText += 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 << "Code = " << a.Code << " Transmission text = " << a.TransText - // << " Menu text = " << a.MenuText << endl; - - return in >> skipeol; -} - - -#endif // _FG_TRANSMISSION_HXX diff --git a/src/ATCDCL/transmissionlist.cxx b/src/ATCDCL/transmissionlist.cxx deleted file mode 100644 index f9e4fe373..000000000 --- a/src/ATCDCL/transmissionlist.cxx +++ /dev/null @@ -1,247 +0,0 @@ -// transmissionlist.cxx -- transmission management class -// -// Written by Alexander Kappes, started March 2002. -// Based on navlist.cxx by Curtis Olson, started April 2000. -// -// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt -// -// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// $Id$ - - -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef HAVE_STRINGS_H -# include // bcopy() -#else -# include // MSVC doesn't have strings.h -#endif - - -#include -#include -#include - -#include "transmissionlist.hxx" - -#include - - -FGTransmissionList *current_transmissionlist; - - -FGTransmissionList::FGTransmissionList( void ) { -} - - -FGTransmissionList::~FGTransmissionList( void ) { -} - - -// load default.transmissions -bool FGTransmissionList::init( const SGPath& path ) { - FGTransmission a; - - transmissionlist_station.erase( transmissionlist_station.begin(), transmissionlist_station.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; - - double min = 100000; - double max = 0; - - while ( ! in.eof() ) { - in >> a; - transmissionlist_station[a.get_station()].push_back(a); - - in >> skipcomment; - - if ( a.get_station() < min ) { - min = a.get_station(); - } - if ( a.get_station() > max ) { - max = a.get_station(); - } - - /* - cout << a.get_station() << " " << a.get_code().c1 << " " << a.get_code().c2 << " " - << a.get_code().c3 << " " << a.get_transtext() - << " " << a.get_menutext() << endl; - */ - } - - // init ATC menu - fgSetBool("/sim/atc/menu",false); - - return true; -} - -// query the database for the specified station type; -// for station see FlightGear/ATC/default.transmissions -bool FGTransmissionList::query_station( const atc_type &station, FGTransmission *t, - int max_trans, int &num_trans ) -{ - transmission_list_type tmissions = transmissionlist_station[station]; - transmission_list_iterator current = tmissions.begin(); - transmission_list_iterator last = tmissions.end(); - - for ( ; current != last ; ++current ) { - if (num_trans < max_trans) { - t[num_trans] = *current; - num_trans += 1; - } - else { - SG_LOG(SG_GENERAL, SG_WARN, "Transmissionlist error: Too many transmissions"); - } - } - - if ( num_trans != 0 ) return true; - else { - SG_LOG(SG_GENERAL, SG_WARN, "No transmission with station " << station << "found."); - string empty; - return false; - } -} - -string FGTransmissionList::gen_text(const atc_type &station, const TransCode code, - const TransPar &tpars, const bool ttext ) -{ - const int cmax = 300; - string message; - char tag[4]; - char crej = '@'; - char mes[cmax]; - char dum[cmax]; - //char buf[10]; - char *pos; - int len; - FGTransmission t; - - // if (current_transmissionlist->query_station( station, &t ) ) { - transmission_list_type tmissions = transmissionlist_station[station]; - transmission_list_iterator current = tmissions.begin(); - transmission_list_iterator last = tmissions.end(); - - for ( ; current != last ; ++current ) { - if ( current->get_code().c1 == code.c1 && - current->get_code().c2 == code.c2 && - current->get_code().c3 == code.c3 ) { - - if ( ttext ) message = current->get_transtext(); - else message = current->get_menutext(); - strcpy( &mes[0], message.c_str() ); - - // Replace all the '@' parameters with the actual text. - int check = 0; // If mes gets overflowed the while loop can go infinite - while ( strchr(&mes[0], crej) != NULL ) { // ie. loop until no more occurances of crej ('@') found - pos = strchr( &mes[0], crej ); - memmove(&tag[0], pos, 3); - tag[3] = '\0'; - int i; - len = 0; - for ( i=0; i 10) { - SG_LOG(SG_GENERAL, SG_WARN, "WARNING: Possibly endless loop terminated in FGTransmissionlist::gen_text(...)"); - break; - } - } - - //cout << mes << endl; - break; - } - } - return mes[0] ? mes : "No transmission found"; -} - - diff --git a/src/ATCDCL/transmissionlist.hxx b/src/ATCDCL/transmissionlist.hxx deleted file mode 100644 index ac1c76025..000000000 --- a/src/ATCDCL/transmissionlist.hxx +++ /dev/null @@ -1,82 +0,0 @@ -// transmissionlist.hxx -- transmission management class -// -// Written by Alexander Kappes, started March 2002. -// Based on navlist.hxx by Curtis Olson, started April 2000. -// -// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt -// -// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// - - -#ifndef _FG_TRANSMISSIONLIST_HXX -#define _FG_TRANSMISSIONLIST_HXX - - -#include -#include - -#include -#include - -#include "ATC.hxx" -#include "transmission.hxx" - -using std::map; -using std::vector; - -class FGTransmissionList { - - // convenience types - typedef vector < FGTransmission > transmission_list_type; - typedef transmission_list_type::iterator transmission_list_iterator; - typedef transmission_list_type::const_iterator transmission_list_const_iterator; - - // Map of transmission lists by station type - // typedef map < int, transmission_list_type, less > transmission_map_type; - typedef map < atc_type, transmission_list_type > transmission_map_type; - typedef transmission_map_type::iterator transmission_map_iterator; - typedef transmission_map_type::const_iterator transmission_map_const_iterator; - - transmission_map_type transmissionlist_station; - -public: - - FGTransmissionList(); - ~FGTransmissionList(); - - // load the transmission data and build the map - bool init( const SGPath& path ); - - // query the database for the specified code, - bool query_station( const atc_type &station, FGTransmission *a, int max_trans, int &num_trans ); - - // generate the transmission text given the code of the message - // and the parameters - // Set ttext = true to generate the spoken transmission text, - // or false to generate the abridged menu entry text. - string gen_text(const atc_type &station, const TransCode code, - const TransPar &tpars, const bool ttext); - -}; - - -void mkATCMenuInit (void); -void mkATCMenu (void); - -extern FGTransmissionList *current_transmissionlist; - - -#endif // _FG_TRANSMISSIONLIST_HXX