]> git.mxchange.org Git - flightgear.git/blobdiff - src/ATC/AIGAVFRTraffic.cxx
fix another crash on exit by finally converting the rest of unguarded
[flightgear.git] / src / ATC / AIGAVFRTraffic.cxx
index 8449f236c35f8e01e27fbac8c89855e1737e4d2a..6941a2489260d00055f7179c5a3ed09ff7e57d76 100644 (file)
 //
 // 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.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
 #endif
 
-//#include <simgear/scene/model/location.hxx>
-
 #include <Airports/runways.hxx>
 #include <Main/globals.hxx>
-//#include <Scenery/scenery.hxx>
-//#include <Scenery/tilemgr.hxx>
 #include <simgear/math/point3d.hxx>
-//#include <simgear/math/sg_geodesy.hxx>
-//#include <simgear/misc/sg_path.hxx>
 #include <string>
 #include <math.h>
 
 SG_USING_STD(string);
 
+#include "ATC.hxx"
 #include "ATCmgr.hxx"
 #include "AILocalTraffic.hxx"
 #include "AIGAVFRTraffic.hxx"
 #include "ATCutils.hxx"
+#include "tower.hxx"
 
 FGAIGAVFRTraffic::FGAIGAVFRTraffic() {
        ATC = globals->get_ATC_mgr();
@@ -72,19 +68,21 @@ FGAIGAVFRTraffic::~FGAIGAVFRTraffic() {
 
 // Init en-route to destID at point pt.
 // TODO - no idea what to do if pt is above planes ceiling due mountains!!
-bool FGAIGAVFRTraffic::Init(Point3D pt, string destID, const string& callsign) {
+bool FGAIGAVFRTraffic::Init(const Point3D& pt, const string& destID, const string& callsign) {
        FGAILocalTraffic::Init(callsign, destID, EN_ROUTE);
        // TODO FIXME - to get up and running we're going to ignore elev and get FGAIMgr to 
        // pass in known good values for the test location.  Need to fix this!!! (or at least canonically decide who has responsibility for setting elev).
        _enroute = true;
        _destID = destID;
        _pos = pt;
-       _destPos = dclGetAirportPos(destID);    // TODO - check if we are within the tower catchment area already.
+       _destPos = fgGetAirportPos(destID);     // TODO - check if we are within the tower catchment area already.
        _cruise_alt = (_destPos.elev() + 2500.0) * SG_FEET_TO_METER;    // TODO look at terrain elevation as well
        _pos.setelev(_cruise_alt);
        // initially set waypoint as airport location
        _wp = _destPos;
-       //_hdg = GetHeadingFromTo(_pos, _wp);
+       // Set the initial track
+       track = GetHeadingFromTo(_pos, _wp);
+       // And set the plane to keep following it.
        SetTrack(GetHeadingFromTo(_pos, _wp));
        _roll = 0.0;
        _pitch = 0.0;
@@ -99,7 +97,7 @@ bool FGAIGAVFRTraffic::Init(Point3D pt, string destID, const string& callsign) {
 }
 
 // Init at srcID to fly to destID
-bool FGAIGAVFRTraffic::Init(string srcID, string destID, const string& callsign, OperatingState state) {
+bool FGAIGAVFRTraffic::Init(const string& srcID, const string& destID, const string& callsign, OperatingState state) {
        _enroute = false;
        FGAILocalTraffic::Init(callsign, srcID, PARKED);
        return(true);
@@ -168,18 +166,27 @@ void FGAIGAVFRTraffic::FlyPlane(double dt) {
                                //cout << "_" << flush;
                                GetAirportDetails(airportID);
                                //cout << "L" << flush;
-                               // TODO FIXME TODO - need to check that tower is valid before this else if problem -> BOOM!
-                               freq = (double)tower->get_freq() / 100.0;
-                               tuned_station = tower;
+                               if(_controlled) {
+                                       freq = (double)tower->get_freq() / 100.0;
+                                       tuned_station = tower;
+                               } else {
+                                       freq = 122.8;   // TODO - need to get the correct CTAF/Unicom frequency if no tower
+                                       tuned_station = NULL;
+                               }
                                //cout << "freq = " << freq << endl;
                                GetRwyDetails(airportID);
-                               //"@AP Tower @CS @MI miles @CD of the airport for full stop with the ATIS"
+                               //"@AP Tower @CS @MI miles @CD of the airport for full stop with ATIS"
                                // At the bare minimum we ought to make sure it goes the right way at dual parallel rwy airports!
                                if(rwy.rwyID.size() == 3) {
                                        patternDirection = (rwy.rwyID.substr(2,1) == "R" ? 1 : -1);
                                }
-                               pending_transmission = tower->get_name();
-                               pending_transmission += " Tower ";
+                               if(_controlled) {
+                                       pending_transmission = tower->get_name();
+                                       pending_transmission += " Tower ";
+                               } else {
+                                       pending_transmission = "Traffic ";
+                                       // TODO - find some way of getting uncontrolled airport name
+                               }
                                pending_transmission += plane.callsign;
                                //char buf[10];
                                int dist_miles = (int)dclGetHorizontalSeparation(_pos, _destPos) / 1600;
@@ -189,7 +196,7 @@ void FGAIGAVFRTraffic::FlyPlane(double dt) {
                                if(dist_miles > 1) pending_transmission += " miles ";
                                else pending_transmission += " mile ";
                                pending_transmission += GetCompassDirection(GetHeadingFromTo(_destPos, _pos));
-                               pending_transmission += " of the airport for full stop with the ATIS";
+                               pending_transmission += " of the airport for full stop with ATIS";
                                //cout << pending_transmission << endl;
                                Transmit(14);   // 14 is the callback code, NOT the timeout!
                                responseCounter = 0;
@@ -207,7 +214,7 @@ void FGAIGAVFRTraffic::FlyPlane(double dt) {
                                        slope = atan((_wp.elev() - _pos.elev()) / dclGetHorizontalSeparation(_wp, _pos)) * DCL_RADIANS_TO_DEGREES;
                                        double thesh_offset = 0.0;
                                        Point3D opos = ortho.ConvertToLocal(_pos);
-                                       double angToApt = atan((_pos.elev() - dclGetAirportElev(airportID)) / (opos.y() - thesh_offset)) * DCL_RADIANS_TO_DEGREES;
+                                       double angToApt = atan((_pos.elev() - fgGetAirportElev(airportID)) / (opos.y() - thesh_offset)) * DCL_RADIANS_TO_DEGREES;
                                        //cout << "angToApt = " << angToApt << ' ';
                                        slope = (angToApt > -5.0 ? 0.0 : angToApt);
                                        //cout << "slope = " << slope << '\n';
@@ -235,7 +242,7 @@ void FGAIGAVFRTraffic::FlyPlane(double dt) {
                                        ConditionalTransmit(4);
                                }
                        }
-                       if(_pos.elev() < (dclGetAirportElev(airportID) + (1000.0 * SG_FEET_TO_METER))) slope = 0.0;     
+                       if(_pos.elev() < (fgGetAirportElev(airportID) + (1000.0 * SG_FEET_TO_METER))) slope = 0.0;      
                }
        }
        if(_incoming) {
@@ -243,7 +250,7 @@ void FGAIGAVFRTraffic::FlyPlane(double dt) {
                Point3D orthopos = ortho.ConvertToLocal(_pos);
                // TODO - Check whether to start descent
                // become _local after the 3 mile report.
-               if(_pos.elev() < (dclGetAirportElev(airportID) + (1000.0 * SG_FEET_TO_METER))) slope = 0.0;     
+               if(_pos.elev() < (fgGetAirportElev(airportID) + (1000.0 * SG_FEET_TO_METER))) slope = 0.0;      
                // TODO - work out why I needed to add the above line to stop the plane going underground!!!
                // (Although it's worth leaving it in as a robustness check anyway).
                if(_straightIn) {
@@ -254,9 +261,9 @@ void FGAIGAVFRTraffic::FlyPlane(double dt) {
                                //cout << "Established at " << orthopos << '\n';
                        }
                        double thesh_offset = 30.0;
-                       //cout << "orthopos.y = " << orthopos.y() << " alt = " << _pos.elev() - dclGetAirportElev(airportID) << '\n';
+                       //cout << "orthopos.y = " << orthopos.y() << " alt = " << _pos.elev() - fgGetAirportElev(airportID) << '\n';
                        if(_established && (orthopos.y() > -5400.0)) {
-                               slope = atan((_pos.elev() - dclGetAirportElev(airportID)) / (orthopos.y() - thesh_offset)) * DCL_RADIANS_TO_DEGREES;
+                               slope = atan((_pos.elev() - fgGetAirportElev(airportID)) / (orthopos.y() - thesh_offset)) * DCL_RADIANS_TO_DEGREES;
                                //cout << "slope0 = " << slope << '\n';
                        }
                        //cout << "slope1 = " << slope << '\n';
@@ -373,6 +380,8 @@ void FGAIGAVFRTraffic::RegisterTransmission(int code) {
                _clearedDownwindEntry = true;
                break;
        default:
+               SG_LOG(SG_ATC, SG_WARN, "FGAIGAVFRTraffic::RegisterTransmission(...) called with unknown code " << code);
+               FGAILocalTraffic::RegisterTransmission(code);
                break;
        }
 }
@@ -387,10 +396,17 @@ void FGAIGAVFRTraffic::ProcessCallback(int code) {
        // 12 - report base
        // 13 - report final
        // 14 - Contact Tower for VFR arrival
+       // 99 - Remove self
        if(code < 14) {
                FGAILocalTraffic::ProcessCallback(code);
        } else if(code == 14) {
-               tower->VFRArrivalContact(plane, this, FULL_STOP);
+               if(_controlled) {
+                       tower->VFRArrivalContact(plane, this, FULL_STOP);
+               }
+               // TODO else possibly announce arrival intentions at uncontrolled airport?
+       } else if(code == 99) {
+               // Might handle this different in future - hence separated from the other codes to pass to AILocalTraffic.
+               FGAILocalTraffic::ProcessCallback(code);
        }
 }
 
@@ -417,20 +433,20 @@ Point3D FGAIGAVFRTraffic::GetPatternApproachPos() {
                if((orthopos.x() * patternDirection) > 0.0) {   // 45 deg entry
                        tmp.setx(2000 * patternDirection);
                        tmp.sety((rwy.end2ortho.y() / 2.0) + 2000);
-                       tmp.setelev(dclGetAirportElev(airportID) + (1000 * SG_FEET_TO_METER));
+                       tmp.setelev(fgGetAirportElev(airportID) + (1000 * SG_FEET_TO_METER));
                        _e45 = true;
                        //cout << "45 deg entry... ";
                } else {
                        tmp.setx(1000 * patternDirection * -1);
                        tmp.sety(rwy.end2ortho.y());
-                       tmp.setelev(dclGetAirportElev(airportID) + (1000 * SG_FEET_TO_METER));
+                       tmp.setelev(fgGetAirportElev(airportID) + (1000 * SG_FEET_TO_METER));
                        _e45 = false;
                        //cout << "90 deg entry... ";
                }
        } else {
                tmp.setx(0);
                tmp.sety(-5400);
-               tmp.setelev((5400.0 / 6.0) + dclGetAirportElev(airportID) + 10.0);
+               tmp.setelev((5400.0 / 6.0) + fgGetAirportElev(airportID) + 10.0);
                //cout << "Straight in... ";
        }
        //cout << "Waypoint is " << tmp << '\n';