From 98048d10007da0d8ee3024ad16b8c1f38100c3a0 Mon Sep 17 00:00:00 2001 From: Durk Talsma Date: Wed, 3 Aug 2011 23:09:52 +0200 Subject: [PATCH] Some preparory work for enabling the handover from ground to tower controller. --- src/AIModel/AIAircraft.cxx | 30 +++++++++++++++++++++++++++--- src/AIModel/AIAircraft.hxx | 9 ++++++++- src/AIModel/AIFlightPlanCreate.cxx | 4 ++++ src/ATC/trafficcontrol.cxx | 3 ++- src/Airports/dynamics.cxx | 2 +- src/Airports/groundnetwork.cxx | 7 ++++++- 6 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/AIModel/AIAircraft.cxx b/src/AIModel/AIAircraft.cxx index 30b7cf9d3..eac6cd4fa 100644 --- a/src/AIModel/AIAircraft.cxx +++ b/src/AIModel/AIAircraft.cxx @@ -65,9 +65,10 @@ FGAIAircraft::FGAIAircraft(FGAISchedule *ref) : else groundOffset = 0; - fp = 0; - controller = 0; - prevController = 0; + fp = 0; + controller = 0; + prevController = 0; + towerController = 0; dt_count = 0; dt_elev_count = 0; use_perf_vs = true; @@ -92,6 +93,7 @@ FGAIAircraft::FGAIAircraft(FGAISchedule *ref) : _performance = 0; //TODO initialize to JET_TRANSPORT from PerformanceDB dt = 0; + scheduledForTakeoff = false; } @@ -555,6 +557,25 @@ void FGAIAircraft::announcePositionToController() { } } +void FGAIAircraft::scheduleForATCTowerDepartureControl() { + if (!scheduledForTakeoff) { + int leg = fp->getLeg(); + if (trafficRef) { + if (trafficRef->getDepartureAirport()->getDynamics()) { + towerController = trafficRef->getDepartureAirport()->getDynamics()->getTowerController(); + } else { + cerr << "Error: Could not find Dynamics at airport : " << trafficRef->getDepartureAirport()->getId() << endl; + } + if (towerController) { + towerController->announcePosition(getID(), fp, fp->getCurrentWaypoint()->getRouteIndex(), + _getLatitude(), _getLongitude(), hdg, speed, altitude_ft, + trafficRef->getRadius(), leg, this); + } + } + } + scheduledForTakeoff = true; +} + // Process ATC instructions and report back void FGAIAircraft::processATC(FGATCInstruction instruction) { @@ -791,6 +812,9 @@ bool FGAIAircraft::handleAirportEndPoints(FGAIWaypoint* prev, time_t now) { if (prev->contains("legend")) { fp->incrementLeg(); } + if (prev->contains(string("DepartureHold"))) { + scheduleForATCTowerDepartureControl(); + } // This is the last taxi waypoint, and marks the the end of the flight plan // so, the schedule should update and wait for the next departure time. diff --git a/src/AIModel/AIAircraft.hxx b/src/AIModel/AIAircraft.hxx index 3921bacc6..d8cbe9d60 100644 --- a/src/AIModel/AIAircraft.hxx +++ b/src/AIModel/AIAircraft.hxx @@ -77,6 +77,9 @@ public: bool getTaxiClearanceRequest() { return needsTaxiClearance; }; FGAISchedule * getTrafficRef() { return trafficRef; }; void setTrafficRef(FGAISchedule *ref) { trafficRef = ref; }; + void scheduleForATCTowerDepartureControl(); + + inline bool isScheduledForTakeoff() { return scheduledForTakeoff; }; virtual const char* getTypeString(void) const { return "aircraft"; } @@ -104,7 +107,9 @@ protected: private: FGAISchedule *trafficRef; - FGATCController *controller, *prevController; + FGATCController *controller, + *prevController, + *towerController; // Only needed to make a pre-announcement bool hdg_lock; bool alt_lock; @@ -147,6 +152,7 @@ private: void checkVisibility(); inline bool isStationary() { return ((fabs(speed)<=0.0001)&&(fabs(tgt_speed)<=0.0001));} inline bool needGroundElevation() { if (!isStationary()) _needsGroundElevation=true;return _needsGroundElevation;} + double sign(double x); @@ -167,6 +173,7 @@ private: bool reachedWaypoint; bool needsTaxiClearance; bool _needsGroundElevation; + bool scheduledForTakeoff; time_t timeElapsed; PerformanceData* _performance; // the performance data for this aircraft diff --git a/src/AIModel/AIFlightPlanCreate.cxx b/src/AIModel/AIFlightPlanCreate.cxx index 884bf25b6..ddd18078c 100644 --- a/src/AIModel/AIFlightPlanCreate.cxx +++ b/src/AIModel/AIFlightPlanCreate.cxx @@ -303,6 +303,10 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight, createOnGround(ac, buffer, tn->getGeod(), apt->getElevation(), ac->getPerformance()->vTaxi()); wpt->setRouteIndex(route); + if (taxiRoute->size() == 1) { + // Note that we actually have hold points in the ground network, but this is just an initial test. + wpt->setName( wpt->getName() + string("DepartureHold")); + } waypoints.push_back(wpt); } return true; diff --git a/src/ATC/trafficcontrol.cxx b/src/ATC/trafficcontrol.cxx index 0e660b87e..2690d5a3f 100644 --- a/src/ATC/trafficcontrol.cxx +++ b/src/ATC/trafficcontrol.cxx @@ -86,7 +86,7 @@ time_t ActiveRunway::requestTimeSlot(time_t eta) } } else { if ((((*j) - (*i)) > (separation * 2))) { // found a potential slot - // now check whether this slow is usable: + // now check whether this slot is usable: // 1) eta should fall between the two points // i.e. eta > i AND eta < j // @@ -755,6 +755,7 @@ void FGTowerController::announcePosition(int id, //rec.setCallSign(callsign); rec.setAircraft(ref); activeTraffic.push_back(rec); + cerr << ref->getTrafficRef()->getCallSign() << " You are number " << activeTraffic.size() << " for takeoff " << endl; } else { i->setPositionAndHeading(lat, lon, heading, speed, alt); } diff --git a/src/Airports/dynamics.cxx b/src/Airports/dynamics.cxx index 854b3b481..c42635f4a 100644 --- a/src/Airports/dynamics.cxx +++ b/src/Airports/dynamics.cxx @@ -496,7 +496,7 @@ const string & FGAirportDynamics::getId() const int FGAirportDynamics::getGroundFrequency(unsigned leg) { //return freqGround.size() ? freqGround[0] : 0; }; - cerr << "Getting frequency for : " << leg << endl; + //cerr << "Getting frequency for : " << leg << endl; int groundFreq = 0; if (leg < 1) { SG_LOG(SG_ATC, SG_ALERT, diff --git a/src/Airports/groundnetwork.cxx b/src/Airports/groundnetwork.cxx index 36fdeeb17..a97f8075a 100644 --- a/src/Airports/groundnetwork.cxx +++ b/src/Airports/groundnetwork.cxx @@ -710,6 +710,8 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat, } } //Check traffic at the tower controller + // Note, as of 2011-08-01, this should no longer be necessecary. + /* if (towerController->hasActiveTraffic()) { for (TrafficVectorIterator i = towerController->getActiveTraffic().begin(); @@ -731,6 +733,7 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat, } } // Finally, check UserPosition + // Note, as of 2011-08-01, this should no longer be necessecary. double userLatitude = fgGetDouble("/position/latitude-deg"); double userLongitude = fgGetDouble("/position/longitude-deg"); SGGeod user(SGGeod::fromDeg(userLongitude, userLatitude)); @@ -745,7 +748,7 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat, minbearing = bearing; otherReasonToSlowDown = true; } - + */ current->clearSpeedAdjustment(); if (current->checkPositionAndIntentions(*closest) @@ -761,6 +764,8 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat, if (closest->getId() != current->getId()) current->setSpeedAdjustment(closest->getSpeed() * (mindist / 100)); + if (closest->getAircraft()->isScheduledForTakeoff()) + current->getAircraft()->scheduleForATCTowerDepartureControl(); else current->setSpeedAdjustment(0); // This can only happen when the user aircraft is the one closest if (mindist < maxAllowableDistance) {