]> git.mxchange.org Git - flightgear.git/blobdiff - src/ATC/AILocalTraffic.cxx
Catch sound exceptions at the earliest, report problem has an alert, and continue...
[flightgear.git] / src / ATC / AILocalTraffic.cxx
index cfbe1ca6b528afb7102bbbf6cb3f1f0d795b36dd..29dda83d328078b59c772c0fce58f9c9d54635ea 100644 (file)
@@ -61,7 +61,6 @@ FGAILocalTraffic::FGAILocalTraffic() {
                                          globals->get_sim_time_sec() );
        *//*
        _model = model;
-       _model->ref();
        _aip.init(_model);
        */
        //SetModel(model);
@@ -107,6 +106,7 @@ FGAILocalTraffic::FGAILocalTraffic() {
        contactTower = false;
        contactGround = false;
        _taxiToGA = false;
+       _removeSelf = false;
        
        descending = false;
        targetDescentRate = 0.0;
@@ -119,13 +119,14 @@ FGAILocalTraffic::FGAILocalTraffic() {
        _savedSlope = 0.0;
        
        _controlled = false;
+       
+       _invisible = false;
 }
 
 FGAILocalTraffic::~FGAILocalTraffic() {
-       //_model->deRef();
 }
 
-void FGAILocalTraffic::GetAirportDetails(string id) {
+void FGAILocalTraffic::GetAirportDetails(const string& id) {
        AirportATC a;
        if(ATC->GetAirportATCDetails(airportID, &a)) {
                if(a.tower_freq) {      // Has a tower - TODO - check the opening hours!!!
@@ -153,7 +154,7 @@ void FGAILocalTraffic::GetAirportDetails(string id) {
                _controlled = false;
        }
        // Get the airport elevation
-       aptElev = dclGetAirportElev(airportID.c_str());
+       aptElev = fgGetAirportElev(airportID.c_str());
        //cout << "Airport elev in AILocalTraffic = " << aptElev << '\n';
        // WARNING - we use this elev for the whole airport - some assumptions in the code 
        // might fall down with very slopey airports.
@@ -161,7 +162,7 @@ void FGAILocalTraffic::GetAirportDetails(string id) {
 
 // Get details of the active runway
 // It is assumed that by the time this is called the tower control and airport code will have been set up.
-void FGAILocalTraffic::GetRwyDetails(string id) {
+void FGAILocalTraffic::GetRwyDetails(const string& id) {
        //cout << "GetRwyDetails called" << endl;
        
        if(_controlled) {
@@ -176,20 +177,20 @@ void FGAILocalTraffic::GetRwyDetails(string id) {
        FGRunway runway;
        bool rwyGood = globals->get_runways()->search(id, rwy.rwyID, &runway);
        if(rwyGood) {
-       double hdg = runway.heading;
+       double hdg = runway._heading;
                double other_way = hdg - 180.0;
                while(other_way <= 0.0) {
                        other_way += 360.0;
                }
 
        // move to the +l end/center of the runway
-               //cout << "Runway center is at " << runway.lon << ", " << runway.lat << '\n';
-       Point3D origin = Point3D(runway.lon, runway.lat, aptElev);
+               //cout << "Runway center is at " << runway._lon << ", " << runway._lat << '\n';
+       Point3D origin = Point3D(runway._lon, runway._lat, aptElev);
                Point3D ref = origin;
        double tshlon, tshlat, tshr;
                double tolon, tolat, tor;
-               rwy.length = runway.length * SG_FEET_TO_METER;
-               rwy.width = runway.width * SG_FEET_TO_METER;
+               rwy.length = runway._length * SG_FEET_TO_METER;
+               rwy.width = runway._width * SG_FEET_TO_METER;
        geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), other_way, 
                                rwy.length / 2.0 - 25.0, &tshlat, &tshlon, &tshr );
        geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), hdg, 
@@ -223,7 +224,7 @@ To a certain extent it's FGAIMgr that has to worry about this, but we need to pr
 sufficient initialisation functionality within the plane classes to allow the manager
 to initially position them where and how required.
 */
-bool FGAILocalTraffic::Init(const string& callsign, string ICAO, OperatingState initialState, PatternLeg initialLeg) {
+bool FGAILocalTraffic::Init(const string& callsign, const string& ICAO, OperatingState initialState, PatternLeg initialLeg) {
        //cout << "FGAILocalTraffic.Init(...) called" << endl;
        airportID = ICAO;
        
@@ -468,6 +469,16 @@ void FGAILocalTraffic::FlyCircuits(int numCircuits, bool tag) {
 // Run the internal calculations
 void FGAILocalTraffic::Update(double dt) {
        //cout << "U" << flush;
+       
+       // we shouldn't really need this since there's a LOD of 10K on the whole plane anyway I think.
+       // At the moment though I need to to avoid DList overflows - the whole plane LOD obviously isn't getting picked up.
+       if(!_invisible) {
+               if(dclGetHorizontalSeparation(_pos, Point3D(fgGetDouble("/position/longitude-deg"), fgGetDouble("/position/latitude-deg"), 0.0)) > 8000) _aip.setVisible(false);
+               else _aip.setVisible(true);
+       } else {
+               _aip.setVisible(false);
+       }
+       
        //double responseTime = 10.0;           // seconds - this should get more sophisticated at some point
        responseCounter += dt;
        if((contactTower) && (responseCounter >= 8.0)) {
@@ -509,14 +520,20 @@ void FGAILocalTraffic::Update(double dt) {
                string trns = "GA Parking, Thank you and Good Day";
                //double f = globals->get_ATC_mgr()->GetFrequency(airportID, GROUND) / 100.0;   
                pending_transmission = trns;
-               ConditionalTransmit(5.0);
+               ConditionalTransmit(5.0, 99);
+               _taxiToGA = false;
                if(_controlled) {
                        tower->DeregisterAIPlane(plane.callsign);
                }
-               _taxiToGA = false;
-               // HACK - check if we are at a simple airport or not first
-               globals->get_AI_mgr()->ScheduleRemoval(plane.callsign);
-       }               
+               // NOTE - we can't delete this instance yet since then the frequency won't get release when the message display finishes.
+       }
+
+       if((_removeSelf) && (responseCounter >= 8.0)) {
+               _removeSelf = false;
+               // MEGA HACK - check if we are at a simple airport or not first instead of simply hardwiring KEMT as the only non-simple airport.
+               // TODO FIXME TODO FIXME !!!!!!!
+               if(airportID != "KEMT") globals->get_AI_mgr()->ScheduleRemoval(plane.callsign);
+       }
        
        if((changeFreq) && (responseCounter > 8.0)) {
                switch(changeFreqType) {
@@ -553,9 +570,6 @@ void FGAILocalTraffic::Update(double dt) {
                        tower->DeregisterAIPlane(plane.callsign);
                        tuned_station = ground;
                        freq = (double)ground->get_freq() / 100.0;
-                       // HACK - check if we are at a simple airport or not first
-                       // TODO FIXME TODO FIXME !!!!!!!
-                       if(airportID != "KEMT") globals->get_AI_mgr()->ScheduleRemoval(plane.callsign);
                        break;
                // And to avoid compiler warnings...
                case APPROACH:  break;
@@ -1053,8 +1067,8 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) {
                if(descending) {
                        if(orthopos.y() < -50.0) {
                                double thesh_offset = 30.0;
-                               slope = atan((_pos.elev() - dclGetAirportElev(airportID)) / (orthopos.y() - thesh_offset)) * DCL_RADIANS_TO_DEGREES;
-                               //cout << "slope = " << slope << ", elev = " << _pos.elev() << ", apt_elev = " << dclGetAirportElev(airportID) << ", op.y = " << orthopos.y() << '\n';
+                               slope = atan((_pos.elev() - fgGetAirportElev(airportID)) / (orthopos.y() - thesh_offset)) * DCL_RADIANS_TO_DEGREES;
+                               //cout << "slope = " << slope << ", elev = " << _pos.elev() << ", apt_elev = " << fgGetAirportElev(airportID) << ", op.y = " << orthopos.y() << '\n';
                                if(slope < -10.0) slope = -10.0;
                                _savedSlope = slope;
                                _pitch = -4.0;
@@ -1291,10 +1305,14 @@ void FGAILocalTraffic::ProcessCallback(int code) {
                tower->ReportDownwind(plane.callsign);
        } else if(code == 13) {
                tower->ReportFinal(plane.callsign);
+       } else if(code == 99) { // Flag this instance for deletion
+               responseCounter = 0;
+               _removeSelf = true;
+               SG_LOG(SG_ATC, SG_INFO, "AI local traffic " << plane.callsign << " delete instance callback called.");
        }
 }
 
-void FGAILocalTraffic::ExitRunway(Point3D orthopos) {
+void FGAILocalTraffic::ExitRunway(const Point3D& orthopos) {
        //cout << "In ExitRunway" << endl;
        //cout << "Runway ID is " << rwy.ID << endl;
        
@@ -1360,9 +1378,10 @@ void FGAILocalTraffic::ExitRunway(Point3D orthopos) {
        } else {
                // Something must have gone wrong with the ground network file - or there is only a rwy here and no exits defined
                SG_LOG(SG_ATC, SG_INFO, "No exits found by FGAILocalTraffic from runway " << rwy.rwyID << " at " << airportID << '\n');
-               //cout << "No exits found by " << plane.callsign << " from runway " << rwy.rwyID << " at " << airportID << '\n';
+               //if(airportID == "KRHV") cout << "No exits found by " << plane.callsign << " from runway " << rwy.rwyID << " at " << airportID << '\n';
                // What shall we do - just remove the plane from sight?
                _aip.setVisible(false);
+               _invisible = true;
                //cout << "Setting visible false\n";
                //tower->ReportRunwayVacated(plane.callsign);
                string trns = "Clear of the runway ";
@@ -1559,24 +1578,19 @@ void FGAILocalTraffic::DoGroundElev() {
                _aip.getSGLocation()->set_cur_elev_m(aptElev);
                return;
        }
-       
-       
-       //globals->get_tile_mgr()->prep_ssg_nodes( acmodel_location,
-       globals->get_tile_mgr()->prep_ssg_nodes( _aip.getSGLocation(),  visibility_meters );
-       Point3D scenery_center = globals->get_scenery()->get_center();
-       globals->get_tile_mgr()->update( _aip.getSGLocation(), visibility_meters, (_aip.getSGLocation())->get_absolute_view_pos( scenery_center ) );
-       // save results of update in SGLocation for fdm...
-       
-       //if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
-       //      acmodel_location->
-       //      set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
-       //}
-       
-       // The need for this here means that at least 2 consecutive passes are needed :-(
-       _aip.getSGLocation()->set_tile_center( globals->get_scenery()->get_next_center() );
-       
-       //cout << "Transform Elev is " << globals->get_scenery()->get_cur_elev() << '\n';
-       _aip.getSGLocation()->set_cur_elev_m(globals->get_scenery()->get_cur_elev());
-       //return(globals->get_scenery()->get_cur_elev());
+
+        // FIXME: make shure the pos.lat/pos.lon values are in degrees ...
+        double range = 500.0;
+        double lat = _aip.getSGLocation()->getLatitude_deg();
+        double lon = _aip.getSGLocation()->getLongitude_deg();
+        if (!globals->get_tile_mgr()->scenery_available(lat, lon, range)) {
+          // Try to shedule tiles for that position.
+          globals->get_tile_mgr()->update( _aip.getSGLocation(), range );
+        }
+
+        // FIXME: make shure the pos.lat/pos.lon values are in degrees ...
+        double alt;
+        if (globals->get_scenery()->get_elevation_m(lat, lon, 20000.0, alt))
+          _aip.getSGLocation()->set_cur_elev_m(alt);
 }