]> git.mxchange.org Git - flightgear.git/blobdiff - src/ATC/trafficcontrol.cxx
Different fix for traffic shutdown crash.
[flightgear.git] / src / ATC / trafficcontrol.cxx
index 15520295a5ec24296b6b9fd84acfa95c08c80406..6b77890a0acc5d461ea85eb97c2c7fce92e53010 100644 (file)
@@ -25,9 +25,7 @@
 #endif
 
 #include <algorithm>
-#include <math.h>
-#include <stdlib.h>
-#include <deque>
+#include <cstdio>
 
 #include <osg/Geode>
 #include <osg/Geometry>
@@ -37,6 +35,9 @@
 #include <simgear/scene/material/EffectGeode.hxx>
 #include <simgear/scene/material/matlib.hxx>
 #include <simgear/scene/material/mat.hxx>
+#include <simgear/scene/util/OsgMath.hxx>
+#include <simgear/timing/sg_time.hxx>
+
 #include <Scenery/scenery.hxx>
 
 #include "trafficcontrol.hxx"
 #include <AIModel/AIAircraft.hxx>
 #include <AIModel/AIFlightPlan.hxx>
 #include <AIModel/performancedata.hxx>
-#include <AIModel/performancedb.hxx>
 #include <ATC/atc_mgr.hxx>
 #include <Traffic/TrafficMgr.hxx>
 #include <Airports/groundnetwork.hxx>
 #include <Airports/dynamics.hxx>
-#include <Airports/simple.hxx>
-#define WITH_POINT_TO_POINT
-#include "itm.cpp"
+#include <Airports/airport.hxx>
+#include <Radio/radio.hxx>
+#include <signal.h>
 
 using std::sort;
+using std::string;
+using std::cout;
+using std::endl;
+
+namespace {
+
+TrafficVectorIterator findTraffic(TrafficVector& vec, int id)
+{
+    TrafficVectorIterator it = vec.begin();
+    for (; it != vec.end(); ++it) {
+        if (it->getId() == id) {
+            return it;
+        }
+    }
+
+    return it; // vec.end, effectively
+}
+
+void clearTrafficControllers(TrafficVector& vec)
+{
+    TrafficVectorIterator it = vec.begin();
+    for (; it != vec.end(); ++it) {
+        it->getAircraft()->clearATCController();
+    }
+}
+
+} // of anonymous namespace
 
 /***************************************************************************
  * ActiveRunway
@@ -63,14 +90,14 @@ time_t ActiveRunway::requestTimeSlot(time_t eta)
     time_t newEta;
     time_t separation = 90;
     bool found = false;
-    if (estimatedArrivalTimes.size() == 0) {
+    if (estimatedArrivalTimes.empty()) {
         estimatedArrivalTimes.push_back(eta);
         return eta;
     } else {
         TimeVectorIterator i = estimatedArrivalTimes.begin();
         //cerr << "Checking eta slots " << eta << ": " << endl;
         for (i = estimatedArrivalTimes.begin();
-             i != estimatedArrivalTimes.end(); i++) {
+                i != estimatedArrivalTimes.end(); i++) {
             //cerr << "Stored time : " << (*i) << endl;
         }
         i = estimatedArrivalTimes.begin();
@@ -131,7 +158,9 @@ time_t ActiveRunway::requestTimeSlot(time_t eta)
     estimatedArrivalTimes.push_back(newEta);
     sort(estimatedArrivalTimes.begin(), estimatedArrivalTimes.end());
     // do some housekeeping : remove any timestamps that are past
-    time_t now = time(NULL) + fgGetLong("/sim/time/warp");
+
+    time_t now = globals->get_time_params()->get_cur_time();
+
     TimeVectorIterator i = estimatedArrivalTimes.begin();
     while (i != estimatedArrivalTimes.end()) {
         if ((*i) < now) {
@@ -145,36 +174,58 @@ time_t ActiveRunway::requestTimeSlot(time_t eta)
     return newEta;
 }
 
+void ActiveRunway::printDepartureCue()
+{
+    cout << "Departure cue for " << rwy << ": " << endl;
+    for (AircraftVecIterator atc = departureCue.begin(); atc != departureCue.end(); atc++) {
+        cout << "     " << (*atc)->getCallSign() << " "  << (*atc)->getTakeOffStatus();
+        cout << " " << (*atc)->_getLatitude() << " " << (*atc)->_getLongitude() << (*atc)-> getSpeed() << " " << (*atc)->getAltitude() << endl;
+    }
+    
+}
+
+FGAIAircraft* ActiveRunway::getFirstOfStatus(int stat)
+{
+    for (AircraftVecIterator atc =departureCue.begin(); atc != departureCue.end(); atc++) {
+        if ((*atc)->getTakeOffStatus() == stat)
+            return (*atc);
+    }
+    return 0;
+}
+
+
+
 /***************************************************************************
  * FGTrafficRecord
  **************************************************************************/
 FGTrafficRecord::FGTrafficRecord():
-id(0), waitsForId(0),
-currentPos(0),
-leg(0),
-frequencyId(0),
-state(0),
-allowTransmission(true),
-latitude(0), longitude(0), heading(0), speed(0), altitude(0), radius(0)
+        id(0), waitsForId(0),
+        currentPos(0),
+        leg(0),
+        frequencyId(0),
+        state(0),
+        allowTransmission(true),
+        allowPushback(true),
+        priority(0),
+        timer(0),
+        latitude(0), longitude(0), heading(0), speed(0), altitude(0), radius(0)
+{
+}
+
+FGTrafficRecord::~FGTrafficRecord()
 {
 }
 
 void FGTrafficRecord::setPositionAndIntentions(int pos,
-                                               FGAIFlightPlan * route)
+        FGAIFlightPlan * route)
 {
 
     currentPos = pos;
-    if (intentions.size()) {
+    if (! intentions.empty()) {
         intVecIterator i = intentions.begin();
         if ((*i) != pos) {
-            SG_LOG(SG_GENERAL, SG_ALERT,
-                   "Error in FGTrafficRecord::setPositionAndIntentions");
-            //cerr << "Pos : " << pos << " Curr " << *(intentions.begin())  << endl;
-            for (intVecIterator i = intentions.begin();
-                 i != intentions.end(); i++) {
-                //cerr << (*i) << " ";
-            }
-            //cerr << endl;
+            SG_LOG(SG_ATC, SG_ALERT,
+                   "Error in FGTrafficRecord::setPositionAndIntentions at " << SG_ORIGIN);
         }
         intentions.erase(i);
     } else {
@@ -182,24 +233,25 @@ void FGTrafficRecord::setPositionAndIntentions(int pos,
         int size = route->getNrOfWayPoints();
         //cerr << "Setting pos" << pos << " ";
         //cerr << "setting intentions ";
-        for (int i = 0; i < size; i++) {
+        for (int i = 2; i < size; i++) {
             int val = route->getRouteIndex(i);
-            //cerr << val<< " ";
-            if ((val) && (val != pos)) {
-                intentions.push_back(val);
-                //cerr << "[set] ";
-            }
+            intentions.push_back(val);
         }
-        //cerr << endl;
-        //while (route->next(&legNr, &routeNr)) {
-        //intentions.push_back(routeNr);
-        //}
-        //route->rewind(currentPos);
     }
-    //exit(1);
 }
+
+void FGTrafficRecord::setAircraft(FGAIAircraft *ref)
+{
+    aircraft = ref;
+}
+
+FGAIAircraft* FGTrafficRecord::getAircraft() const
+{
+    return aircraft.ptr();
+}
+
 /**
- * Check if another aircraft is ahead of the current one, and on the same 
+ * Check if another aircraft is ahead of the current one, and on the same
  * return true / false is the is/isn't the case.
  *
  ****************************************************************************/
@@ -212,17 +264,17 @@ bool FGTrafficRecord::checkPositionAndIntentions(FGTrafficRecord & other)
         //cerr << callsign << ": Check Position and intentions: we are on the same taxiway" << other.callsign << "Index = " << currentPos << endl;
         result = true;
     }
-    //  else if (other.intentions.size()) 
+    //  else if (! other.intentions.empty())
     //     {
     //       cerr << "Start check 2" << endl;
-    //       intVecIterator i = other.intentions.begin(); 
+    //       intVecIterator i = other.intentions.begin();
     //       while (!((i == other.intentions.end()) || ((*i) == currentPos)))
     //     i++;
     //       if (i != other.intentions.end()) {
     //     cerr << "Check Position and intentions: current matches other.intentions" << endl;
     //     result = true;
     //       }
-    else if (intentions.size()) {
+    else if (! intentions.empty()) {
         //cerr << "Start check 3" << endl;
         intVecIterator i = intentions.begin();
         //while (!((i == intentions.end()) || ((*i) == other.currentPos)))
@@ -242,8 +294,8 @@ bool FGTrafficRecord::checkPositionAndIntentions(FGTrafficRecord & other)
 }
 
 void FGTrafficRecord::setPositionAndHeading(double lat, double lon,
-                                            double hdg, double spd,
-                                            double alt)
+        double hdg, double spd,
+        double alt)
 {
     latitude = lat;
     longitude = lon;
@@ -256,43 +308,43 @@ int FGTrafficRecord::crosses(FGGroundNetwork * net,
                              FGTrafficRecord & other)
 {
     if (checkPositionAndIntentions(other)
-        || (other.checkPositionAndIntentions(*this)))
+            || (other.checkPositionAndIntentions(*this)))
         return -1;
     intVecIterator i, j;
     int currentTargetNode = 0, otherTargetNode = 0;
     if (currentPos > 0)
-        currentTargetNode = net->findSegment(currentPos)->getEnd()->getIndex(); // OKAY,... 
+        currentTargetNode = net->findSegment(currentPos)->getEnd()->getIndex(); // OKAY,...
     if (other.currentPos > 0)
         otherTargetNode = net->findSegment(other.currentPos)->getEnd()->getIndex();     // OKAY,...
     if ((currentTargetNode == otherTargetNode) && currentTargetNode > 0)
         return currentTargetNode;
-    if (intentions.size()) {
+    if (! intentions.empty()) {
         for (i = intentions.begin(); i != intentions.end(); i++) {
             if ((*i) > 0) {
-                if ((currentTargetNode ==
-                     net->findSegment(*i)->getEnd()->getIndex())) {
+                if (currentTargetNode ==
+                        net->findSegment(*i)->getEnd()->getIndex()) {
                     //cerr << "Current crosses at " << currentTargetNode <<endl;
                     return currentTargetNode;
                 }
             }
         }
     }
-    if (other.intentions.size()) {
+    if (! other.intentions.empty()) {
         for (i = other.intentions.begin(); i != other.intentions.end();
-             i++) {
+                i++) {
             if ((*i) > 0) {
                 if (otherTargetNode ==
-                    net->findSegment(*i)->getEnd()->getIndex()) {
+                        net->findSegment(*i)->getEnd()->getIndex()) {
                     //cerr << "Other crosses at " << currentTargetNode <<endl;
                     return otherTargetNode;
                 }
             }
         }
     }
-    if (intentions.size() && other.intentions.size()) {
+    if (! intentions.empty() && ! other.intentions.empty()) {
         for (i = intentions.begin(); i != intentions.end(); i++) {
             for (j = other.intentions.begin(); j != other.intentions.end();
-                 j++) {
+                    j++) {
                 //cerr << "finding segment " << *i << " and " << *j << endl;
                 if (((*i) > 0) && ((*j) > 0)) {
                     currentTargetNode =
@@ -321,9 +373,9 @@ bool FGTrafficRecord::onRoute(FGGroundNetwork * net,
             net->findSegment(other.currentPos)->getEnd()->getIndex();
     if ((node == othernode) && (node != -1))
         return true;
-    if (other.intentions.size()) {
+    if (! other.intentions.empty()) {
         for (intVecIterator i = other.intentions.begin();
-             i != other.intentions.end(); i++) {
+                i != other.intentions.end(); i++) {
             if (*i > 0) {
                 othernode = net->findSegment(*i)->getEnd()->getIndex();
                 if ((node == othernode) && (node > -1))
@@ -333,11 +385,11 @@ bool FGTrafficRecord::onRoute(FGGroundNetwork * net,
     }
     //if (other.currentPos > 0)
     //  othernode = net->findSegment(other.currentPos)->getEnd()->getIndex();
-    //if (intentions.size())
+    //if (! intentions.empty())
     //  {
     //    for (intVecIterator i = intentions.begin(); i != intentions.end(); i++)
     //    {
-    //      if (*i > 0) 
+    //      if (*i > 0)
     //        {
     //          node = net->findSegment(*i)->getEnd()->getIndex();
     //          if ((node == othernode) && (node > -1))
@@ -363,13 +415,13 @@ bool FGTrafficRecord::isOpposing(FGGroundNetwork * net,
         }
 
         for (intVecIterator i = intentions.begin(); i != intentions.end();
-             i++) {
+                i++) {
             if ((opp = net->findSegment(other.currentPos)->opposite())) {
                 if ((*i) > 0)
                     if (opp->getIndex() ==
-                        net->findSegment(*i)->getIndex()) {
+                            net->findSegment(*i)->getIndex()) {
                         if (net->findSegment(*i)->getStart()->getIndex() ==
-                            node) {
+                                node) {
                             {
                                 //cerr << "Found the node " << node << endl;
                                 return true;
@@ -377,19 +429,19 @@ bool FGTrafficRecord::isOpposing(FGGroundNetwork * net,
                         }
                     }
             }
-            if (other.intentions.size()) {
+            if (! other.intentions.empty()) {
                 for (intVecIterator j = other.intentions.begin();
-                     j != other.intentions.end(); j++) {
+                        j != other.intentions.end(); j++) {
                     // cerr << "Current segment 1 " << (*i) << endl;
                     if ((*i) > 0) {
                         if ((opp = net->findSegment(*i)->opposite())) {
                             if (opp->getIndex() ==
-                                net->findSegment(*j)->getIndex()) {
+                                    net->findSegment(*j)->getIndex()) {
                                 //cerr << "Nodes " << net->findSegment(*i)->getIndex()
                                 //   << " and  " << net->findSegment(*j)->getIndex()
                                 //   << " are opposites " << endl;
                                 if (net->findSegment(*i)->getStart()->
-                                    getIndex() == node) {
+                                        getIndex() == node) {
                                     {
                                         //cerr << "Found the node " << node << endl;
                                         return true;
@@ -405,6 +457,14 @@ bool FGTrafficRecord::isOpposing(FGGroundNetwork * net,
     return false;
 }
 
+bool FGTrafficRecord::isActive(int margin) const
+{
+    time_t now = globals->get_time_params()->get_cur_time();
+    time_t deptime = aircraft->getTrafficRef()->getDepartureTime();
+    return ((now + margin) > deptime);
+}
+
+
 void FGTrafficRecord::setSpeedAdjustment(double spd)
 {
     instruction.setChangeSpeed(true);
@@ -417,33 +477,14 @@ void FGTrafficRecord::setHeadingAdjustment(double heading)
     instruction.setHeading(heading);
 }
 
-bool FGTrafficRecord::pushBackAllowed()
+bool FGTrafficRecord::pushBackAllowed() const
 {
-    // With the user ATC / AI integration, checking whether the user's aircraft is near no longer works, because
-    // this will effectively block the user's aircraft itself from receiving pushback clearance. 
-    // So, what can we do?
-    /*
-    double course, az2, dist;
-    SGGeod curr(SGGeod::fromDegM(getLongitude(),
-                                 getLatitude(), getAltitude()));
-
-    double userLatitude = fgGetDouble("/position/latitude-deg");
-    double userLongitude = fgGetDouble("/position/longitude-deg");
-    SGGeod user(SGGeod::fromDeg(userLongitude, userLatitude));
-    SGGeodesy::inverse(curr, user, course, az2, dist);
-    //cerr << "Distance to user : " << dist << endl;
-    return (dist > 250);
-    */
-
-
-    // In essence, we should check whether the pusbback route itself, as well as the associcated
-    // taxiways near the pushback point are free of traffic. 
-    // To do so, we need to 
-    return true;
+    return allowPushback;
 }
 
 
 
+
 /***************************************************************************
  * FGATCInstruction
  *
@@ -463,7 +504,7 @@ FGATCInstruction::FGATCInstruction()
 }
 
 
-bool FGATCInstruction::hasInstruction()
+bool FGATCInstruction::hasInstruction() const
 {
     return (holdPattern || holdPosition || changeSpeed || changeHeading
             || changeAltitude || resolveCircularWait);
@@ -484,11 +525,14 @@ FGATCController::FGATCController()
     available = true;
     lastTransmission = 0;
     initialized = false;
+    lastTransmissionDirection = ATC_AIR_TO_GROUND;
+    group = NULL;
 }
 
 FGATCController::~FGATCController()
 {
-     //cerr << "running FGATController destructor" << endl;
+    FGATCManager *mgr = (FGATCManager*) globals->get_subsystem("ATC");
+    mgr->removeController(this);
 }
 
 string FGATCController::getGateName(FGAIAircraft * ref)
@@ -496,9 +540,9 @@ string FGATCController::getGateName(FGAIAircraft * ref)
     return ref->atGate();
 }
 
-bool FGATCController::isUserAircraft(FGAIAircraft* ac) 
-{ 
-    return (ac->getCallSign() == fgGetString("/sim/multiplay/callsign")) ? true : false; 
+bool FGATCController::isUserAircraft(FGAIAircraft* ac)
+{
+    return (ac->getCallSign() == fgGetString("/sim/multiplay/callsign")) ? true : false;
 };
 
 void FGATCController::transmit(FGTrafficRecord * rec, FGAirportDynamics *parent, AtcMsgId msgId,
@@ -542,7 +586,7 @@ void FGATCController::transmit(FGTrafficRecord * rec, FGAirportDynamics *parent,
         taxiFreq =
             rec->getAircraft()->getTrafficRef()->getDepartureAirport()->
             getDynamics()->getGroundFrequency(2);
-        towerFreq = 
+        towerFreq =
             rec->getAircraft()->getTrafficRef()->getDepartureAirport()->
             getDynamics()->getTowerFrequency(2);
         receiver =
@@ -592,11 +636,10 @@ void FGATCController::transmit(FGTrafficRecord * rec, FGAirportDynamics *parent,
             getRunwayClassFromTrafficType(fltType);
 
         rec->getAircraft()->getTrafficRef()->getDepartureAirport()->
-            getDynamics()->getActiveRunway(rwyClass, 1, activeRunway,
-                                           heading);
+        getDynamics()->getActiveRunway(rwyClass, 1, activeRunway,
+                                       heading);
         rec->getAircraft()->GetFlightPlan()->setRunway(activeRunway);
-        fp = rec->getAircraft()->getTrafficRef()->getDepartureAirport()->
-            getDynamics()->getSID(activeRunway, heading);
+        fp = NULL;
         rec->getAircraft()->GetFlightPlan()->setSID(fp);
         if (fp) {
             SID = fp->getName() + " departure";
@@ -688,17 +731,17 @@ void FGATCController::transmit(FGTrafficRecord * rec, FGAirportDynamics *parent,
     case MSG_REPORT_RUNWAY_HOLD_SHORT:
         activeRunway = rec->getAircraft()->GetFlightPlan()->getRunway();
         //activeRunway = "test";
-        text = receiver + ". Holding short runway " 
-                        + activeRunway 
-                        + ". " + sender;
+        text = receiver + ". Holding short runway "
+               + activeRunway
+               + ". " + sender;
         //text = "test1";
         //cerr << "1 Currently at leg " << rec->getLeg() << endl;
         break;
     case MSG_ACKNOWLEDGE_REPORT_RUNWAY_HOLD_SHORT:
         activeRunway = rec->getAircraft()->GetFlightPlan()->getRunway();
-        text = receiver + "Roger. Holding short runway " 
-        //                + activeRunway 
-                        + ". " + sender;
+        text = receiver + "Roger. Holding short runway "
+               //                + activeRunway
+               + ". " + sender;
         //text = "test2";
         //cerr << "2 Currently at leg " << rec->getLeg() << endl;
         break;
@@ -732,193 +775,39 @@ void FGATCController::transmit(FGTrafficRecord * rec, FGAirportDynamics *parent,
         // the relevant frequency.
         // Note that distance attenuation is currently not yet implemented
                 
-        if ((onBoardRadioFreqI0 == stationFreq)
-            || (onBoardRadioFreqI1 == stationFreq)) {
-               double snr = calculate_attenuation(rec, parent, ground_to_air);
-               if (snr <= 0)
-                       return;
-               if (snr > 0 && snr < 12) {
-                       //for low SNR values implement a way to make the conversation
-                       //hard to understand but audible
-                       string hash_noise = " ";
-                       int reps = fabs((int)snr - 11);
-                       int t_size = text.size();
-                       for (int n=1;n<=reps * 2;n++) {
-                               int pos = rand() % t_size -1;
-                               text.replace(pos,1, hash_noise);
-                       }
-                       
-               }
-               
+        if ((stationFreq > 0)&&
+            ((onBoardRadioFreqI0 == stationFreq)||
+             (onBoardRadioFreqI1 == stationFreq))) {
             if (rec->allowTransmissions()) {
-                fgSetString("/sim/messages/atc", text.c_str());
+               
+               if( fgGetBool( "/sim/radio/use-itm-attenuation", false ) ) {
+                       //cerr << "Using ITM radio propagation" << endl;
+                       FGRadioTransmission* radio = new FGRadioTransmission();
+                       SGGeod sender_pos;
+                       double sender_alt_ft, sender_alt;
+                       if(ground_to_air) {
+                  sender_pos = parent->parent()->geod();
+                                }
+                               else {
+                                     sender_alt_ft = rec->getAltitude();
+                                     sender_alt = sender_alt_ft * SG_FEET_TO_METER;
+                                     sender_pos= SGGeod::fromDegM( rec->getLongitude(),
+                                            rec->getLatitude(), sender_alt );
+                               }
+                               double frequency = ((double)stationFreq) / 100;
+                       radio->receiveATC(sender_pos, frequency, text, ground_to_air);
+                       delete radio;
+               }
+               else {
+                       fgSetString("/sim/messages/atc", text.c_str());
+               }
             }
         }
     } else {
-        FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc");
-        atc->getATCDialog()->addEntry(1, text);
-        
+        FGATCDialogNew::instance()->addEntry(1, text);
     }
 }
 
-double FGATCController::calculate_attenuation(FGTrafficRecord * rec, FGAirportDynamics *parent,
-                               int ground_to_air) {
-       //////////////////////////////////////////////////
-        ///  Implement radio attenuation               //
-        ///  based on the Longley-Rice propagation model//
-        //////////////////////////////////////////////////
-        
-        FGScenery * scenery = globals->get_scenery();
-        // player aircraft position
-        double own_lat = fgGetDouble("/position/latitude-deg");
-        double own_lon = fgGetDouble("/position/longitude-deg");
-        double own_alt_ft = fgGetDouble("/position/altitude-ft");
-        double own_alt= own_alt_ft * SG_FEET_TO_METER;
-        
-        cerr << "ITM:: pilot Lat: " << own_lat << ", Lon: " << own_lon << ", Alt: " << own_alt << endl;
-        
-        SGGeod own_pos = SGGeod::fromDegM( own_lon, own_lat, own_alt );
-        SGGeod max_own_pos = SGGeod::fromDegM( own_lon, own_lat, SG_MAX_ELEVATION_M );
-        SGGeoc center = SGGeoc::fromGeod( max_own_pos );
-        SGGeoc own_pos_c = SGGeoc::fromGeod( own_pos );
-        
-        // position of sender radio antenna (HAAT)
-        // sender can be aircraft or ground station
-        double ATC_HAAT = 30.0;
-        double Aircraft_HAAT = 7.0;
-        double sender_alt_ft,sender_alt;
-        double transceiver_height=0.0;
-        double receiver_height=0.0;
-        SGGeod sender_pos;
-        if(ground_to_air) {
-               sender_alt_ft = parent->getElevation();
-               sender_alt = sender_alt_ft * SG_FEET_TO_METER + ATC_HAAT;
-               sender_pos= SGGeod::fromDegM( parent->getLongitude(),
-                       parent->getLatitude(), sender_alt );
-       }
-       else {
-               sender_alt_ft = rec->getAltitude();
-               sender_alt = sender_alt_ft * SG_FEET_TO_METER + Aircraft_HAAT;
-               sender_pos= SGGeod::fromDegM( rec->getLongitude(),
-                       rec->getLatitude(), sender_alt );
-       }
-       SGGeoc sender_pos_c = SGGeoc::fromGeod( sender_pos );
-       cerr << "ITM:: sender Lat: " << parent->getLatitude() << ", Lon: " << parent->getLongitude() << ", Alt: " << sender_alt << endl;
-       
-        double point_distance= 90.0; // regular SRTM is 90 meters
-        double course = SGGeodesy::courseRad(own_pos_c, sender_pos_c);
-        double distance_m = SGGeodesy::distanceM(own_pos, sender_pos);
-        double probe_distance = 0.0;
-        
-        cerr << "ITM:: Distance: " << distance_m << endl;
-        
-        double max_points = distance_m / point_distance;
-        deque<double> _elevations;
-        
-        SGGeod probe_pilot = SGGeod::fromGeoc(center.advanceRadM( course, 0 ));
-        double elevation_under_pilot = 0.0;
-       if (scenery->get_elevation_m( probe_pilot, elevation_under_pilot, NULL )) {
-               receiver_height = own_alt - elevation_under_pilot;
-       }
-       _elevations.push_front(receiver_height);
-       
-       SGGeod probe_sender = SGGeod::fromGeoc(center.advanceRadM( course, distance_m ));
-        double elevation_under_sender = 0.0;
-       if (scenery->get_elevation_m( probe_sender, elevation_under_sender, NULL )) {
-               transceiver_height = sender_alt - elevation_under_sender;
-       }
-        
-        // If distance larger than this value (400 km), assume reception imposssible
-        // technically 400 km is no problem if LOS conditions exist,
-        // but we do this to spare resources
-        if (distance_m > 400000)
-               return -1.0;
-        
-        int e_size = (deque<unsigned>::size_type)max_points;
-        
-        while (_elevations.size() < e_size) {
-               probe_distance += point_distance;
-               SGGeod probe = SGGeod::fromGeoc(center.advanceRadM( course, probe_distance ));
-               
-               double elevation_m = 0.0;
-       
-               if (scenery->get_elevation_m( probe, elevation_m, NULL )) {
-                        _elevations.push_front(elevation_m);
-                        //cerr << "ITM:: Probe elev: " << elevation_m << endl;
-               }
-       }
-       
-       _elevations.push_front(transceiver_height);
-       double max_alt_between=0.0;
-       for( deque<double>::size_type i = 0; i < _elevations.size(); i++ ) {
-               if (_elevations[i] > max_alt_between) {
-                       max_alt_between = _elevations[i];
-               }
-       }
-       
-       double num_points= (double)_elevations.size();
-       cerr << "ITM:: Max alt between: " << max_alt_between << ", num points:" << num_points << endl;
-       _elevations.push_front(point_distance);
-       _elevations.push_front(num_points -1);
-       int size = _elevations.size();
-       double itm_elev[size];
-       for(int i=0;i<size;i++) {
-               itm_elev[i]=_elevations[i];
-               //cerr << "ITM:: itm_elev: " << _elevations[i] << endl;
-       }
-       
-       ////////////// ITM default parameters //////////////
-       // later perhaps take them from tile materials?
-       double eps_dielect=15.0;
-       double sgm_conductivity = 0.005;
-       double eno = 301.0;
-       double frq_mhz = 125.0;         // middle of bandplan
-       int radio_climate = 5;          // continental temperate
-       int pol=1;      // assuming vertical polarization
-       double conf = 0.90;     // my own tests in Radiomobile have worked best with these values
-       double rel = 0.80;      // ^^
-       double dbloss;
-       char strmode[150];
-       int errnum;
-       
-       /////////// radio parameters ///////////
-       double receiver_sensitivity = -112.0;   // typical AM receiver sensitivity in dBm
-       // AM transmitter power in dBm.
-       // Note this value is calculated from the typical final transistor stage output
-       // !!! small aircraft have portable transmitters which operate at 36 dBm output (4 Watts)
-       // later store this value in aircraft description
-       // ATC comms usually operate high power equipment, thus making the link asymetrical; this is ignored for now
-       if(ground_to_air)
-               double transmitter_power = 49.0;
-       else
-               double transmitter_power = 43.0;
-       if(ground_to_air)
-               double antenna_gain = 5.0; //pilot plane's antenna gain + Controller antenna gain
-       else
-               double antenna_gain = 2.0; //pilot plane's antenna gain + AI aircraft antenna gain
-       double link_budget = transmitter_power - receiver_sensitivity + antenna_gain;   
-       
-       
-       // first Fresnel zone radius
-       // frequency in the middle of the bandplan, more accuracy is not necessary
-       double fz_clr= 8.657 * sqrt(distance_m / 0.125);
-       
-       // TODO: If we clear the first Fresnel zone, we are into line of sight teritory
-
-       // else we need to calculate point to point link loss
-
-       point_to_point(itm_elev, sender_alt, own_alt,
-               eps_dielect, sgm_conductivity, eno, frq_mhz, radio_climate,
-               pol, conf, rel, dbloss, strmode, errnum);
-
-       cerr << "ITM:: Attenuation: " << dbloss << " dBm, " << strmode << ", Error: " << errnum << endl;
-       
-       //if (errnum !=0 && errnum !=1)
-       //      return -1;
-       double snr = link_budget - dbloss;
-       return snr;
-
-}
 
 string FGATCController::formatATCFrequency3_2(int freq)
 {
@@ -928,8 +817,8 @@ string FGATCController::formatATCFrequency3_2(int freq)
 }
 
 // TODO: Set transponder codes according to real-world routes.
-// The current version just returns a random string of four octal numbers. 
-string FGATCController::genTransponderCode(string fltRules)
+// The current version just returns a random string of four octal numbers.
+string FGATCController::genTransponderCode(const string& fltRules)
 {
     if (fltRules == "VFR") {
         return string("1200");
@@ -941,12 +830,12 @@ string FGATCController::genTransponderCode(string fltRules)
     }
 }
 
-void FGATCController::init() 
+void FGATCController::init()
 {
-   if (!initialized) {
-       FGATCManager *mgr = (FGATCManager*) globals->get_subsystem("ATC");
-       mgr->addController(this);
-       initialized = true;
+    if (!initialized) {
+        FGATCManager *mgr = (FGATCManager*) globals->get_subsystem("ATC");
+        mgr->addController(this);
+        initialized = true;
     }
 }
 
@@ -955,25 +844,34 @@ void FGATCController::init()
  *
  **************************************************************************/
 FGTowerController::FGTowerController(FGAirportDynamics *par) :
-FGATCController()
+        FGATCController()
 {
     parent = par;
 }
 
-// 
+FGTowerController::~FGTowerController()
+{
+    // to avoid the exception described in:
+    // https://sourceforge.net/p/flightgear/codetickets/1864/
+    // we want to ensure AI aircraft signing-off is a no-op now
+
+    clearTrafficControllers(activeTraffic);
+}
+
+//
 void FGTowerController::announcePosition(int id,
-                                         FGAIFlightPlan * intendedRoute,
-                                         int currentPosition, double lat,
-                                         double lon, double heading,
-                                         double speed, double alt,
-                                         double radius, int leg,
-                                         FGAIAircraft * ref)
+        FGAIFlightPlan * intendedRoute,
+        int currentPosition, double lat,
+        double lon, double heading,
+        double speed, double alt,
+        double radius, int leg,
+        FGAIAircraft * ref)
 {
     init();
     TrafficVectorIterator i = activeTraffic.begin();
     // Search whether the current id alread has an entry
     // This might be faster using a map instead of a vector, but let's start by taking a safe route
-    if (activeTraffic.size()) {
+    if (! activeTraffic.empty()) {
         //while ((i->getId() != id) && i != activeTraffic.end()) {
         while (i != activeTraffic.end()) {
             if (i->getId() == id) {
@@ -983,7 +881,7 @@ void FGTowerController::announcePosition(int id,
         }
     }
     // Add a new TrafficRecord if no one exsists for this aircraft.
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
+    if (i == activeTraffic.end() || (activeTraffic.empty())) {
         FGTrafficRecord rec;
         rec.setId(id);
 
@@ -994,9 +892,9 @@ void FGTowerController::announcePosition(int id,
         rec.setRadius(radius);
         rec.setAircraft(ref);
         activeTraffic.push_back(rec);
-        // Don't just schedule the aircraft for the tower controller, also assign if to the correct active runway. 
+        // Don't just schedule the aircraft for the tower controller, also assign if to the correct active runway.
         ActiveRunwayVecIterator rwy = activeRunways.begin();
-        if (activeRunways.size()) {
+        if (! activeRunways.empty()) {
             while (rwy != activeRunways.end()) {
                 if (rwy->getRunwayName() == intendedRoute->getRunway()) {
                     break;
@@ -1020,14 +918,14 @@ void FGTowerController::announcePosition(int id,
 }
 
 void FGTowerController::updateAircraftInformation(int id, double lat, double lon,
-                                                  double heading, double speed, double alt,
-                                                  double dt)
+        double heading, double speed, double alt,
+        double dt)
 {
     TrafficVectorIterator i = activeTraffic.begin();
     // Search whether the current id has an entry
     // This might be faster using a map instead of a vector, but let's start by taking a safe route
     TrafficVectorIterator current, closest;
-    if (activeTraffic.size()) {
+    if (! activeTraffic.empty()) {
         //while ((i->getId() != id) && i != activeTraffic.end()) {
         while (i != activeTraffic.end()) {
             if (i->getId() == id) {
@@ -1037,9 +935,9 @@ void FGTowerController::updateAircraftInformation(int id, double lat, double lon
         }
     }
 //    // update position of the current aircraft
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
-               "AI error: updating aircraft without traffic record");
+    if (i == activeTraffic.end() || (activeTraffic.empty())) {
+        SG_LOG(SG_ATC, SG_ALERT,
+               "AI error: updating aircraft without traffic record at " << SG_ORIGIN);
     } else {
         i->setPositionAndHeading(lat, lon, heading, speed, alt);
         current = i;
@@ -1048,8 +946,16 @@ void FGTowerController::updateAircraftInformation(int id, double lat, double lon
 
     // see if we already have a clearance record for the currently active runway
     // NOTE: dd. 2011-08-07: Because the active runway has been constructed in the announcePosition function, we may safely assume that is
-    // already exists here. So, we can simplify the current code. 
+    // already exists here. So, we can simplify the current code.
+    
     ActiveRunwayVecIterator rwy = activeRunways.begin();
+    //if (parent->getId() == fgGetString("/sim/presets/airport-id")) {
+    //    for (rwy = activeRunways.begin(); rwy != activeRunways.end(); rwy++) {
+    //        rwy->printDepartureCue();
+    //    }
+    //}
+    
+    rwy = activeRunways.begin();
     while (rwy != activeRunways.end()) {
         if (rwy->getRunwayName() == current->getRunway()) {
             break;
@@ -1072,20 +978,29 @@ void FGTowerController::updateAircraftInformation(int id, double lat, double lon
         }
     } */
     // only bother with aircraft that have a takeoff status of 2, since those are essentially under tower control
+    FGAIAircraft* ac= rwy->getFirstAircraftInDepartureCue();
+    if (ac->getTakeOffStatus() == 1) {
+        ac->setTakeOffStatus(2);
+    }
     if (current->getAircraft()->getTakeOffStatus() == 2) {
+        current -> setHoldPosition(false);
+    } else {
         current->setHoldPosition(true);
-        int clearanceId = rwy->getCleared();
-        if (clearanceId) {
-            if (id == clearanceId) {
-                current->setHoldPosition(false);
-            }
-        } else {
-            if (current->getAircraft() == rwy->getFirstAircraftInDepartureCue()) {
-                rwy->setCleared(id);
-            }
+    }
+    int clearanceId = rwy->getCleared();
+    if (clearanceId) {
+        if (id == clearanceId) {
+            current->setHoldPosition(false);
+        }
+    } else {
+        if (current->getAircraft() == rwy->getFirstAircraftInDepartureCue()) {
+            rwy->setCleared(id);
+            FGAIAircraft *ac = rwy->getFirstOfStatus(1);
+            if (ac)
+                ac->setTakeOffStatus(2);
         }
     }
-}
+} 
 
 
 void FGTowerController::signOff(int id)
@@ -1093,7 +1008,7 @@ void FGTowerController::signOff(int id)
     TrafficVectorIterator i = activeTraffic.begin();
     // Search search if the current id alread has an entry
     // This might be faster using a map instead of a vector, but let's start by taking a safe route
-    if (activeTraffic.size()) {
+    if (! activeTraffic.empty()) {
         //while ((i->getId() != id) && i != activeTraffic.end()) {
         while (i != activeTraffic.end()) {
             if (i->getId() == id) {
@@ -1104,7 +1019,7 @@ void FGTowerController::signOff(int id)
     }
     // If this aircraft has left the runway, we can clear the departure record for this runway
     ActiveRunwayVecIterator rwy = activeRunways.begin();
-    if (activeRunways.size()) {
+    if (! activeRunways.empty()) {
         //while ((rwy->getRunwayName() != i->getRunway()) && (rwy != activeRunways.end())) {
         while (rwy != activeRunways.end()) {
             if (rwy->getRunwayName() == i->getRunway()) {
@@ -1116,13 +1031,13 @@ void FGTowerController::signOff(int id)
             rwy->setCleared(0);
             rwy->updateDepartureCue();
         } else {
-            SG_LOG(SG_GENERAL, SG_ALERT,
-                   "AI error: Attempting to erase non-existing runway clearance record in FGTowerController::signoff");
+            SG_LOG(SG_ATC, SG_ALERT,
+                   "AI error: Attempting to erase non-existing runway clearance record in FGTowerController::signoff at " << SG_ORIGIN);
         }
     }
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
-               "AI error: Aircraft without traffic record is signing off from tower");
+    if (i == activeTraffic.end() || (activeTraffic.empty())) {
+        SG_LOG(SG_ATC, SG_ALERT,
+               "AI error: Aircraft without traffic record is signing off from tower at " << SG_ORIGIN);
     } else {
         i->getAircraft()->resetTakeOffStatus();
         i = activeTraffic.erase(i);
@@ -1132,7 +1047,7 @@ void FGTowerController::signOff(int id)
 
 // NOTE:
 // IF WE MAKE TRAFFICRECORD A MEMBER OF THE BASE CLASS
-// THE FOLLOWING THREE FUNCTIONS: SIGNOFF, HAS INSTRUCTION AND GETINSTRUCTION CAN 
+// THE FOLLOWING THREE FUNCTIONS: SIGNOFF, HAS INSTRUCTION AND GETINSTRUCTION CAN
 // BECOME DEVIRTUALIZED AND BE A MEMBER OF THE BASE ATCCONTROLLER CLASS
 // WHICH WOULD SIMPLIFY CODE MAINTENANCE.
 // Note that this function is probably obsolete
@@ -1141,7 +1056,7 @@ bool FGTowerController::hasInstruction(int id)
     TrafficVectorIterator i = activeTraffic.begin();
     // Search search if the current id has an entry
     // This might be faster using a map instead of a vector, but let's start by taking a safe route
-    if (activeTraffic.size()) {
+    if (! activeTraffic.empty()) {
         //while ((i->getId() != id) && i != activeTraffic.end()) {
         while (i != activeTraffic.end()) {
             if (i->getId() == id) {
@@ -1150,9 +1065,9 @@ bool FGTowerController::hasInstruction(int id)
             i++;
         }
     }
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
-               "AI error: checking ATC instruction for aircraft without traffic record");
+    if (i == activeTraffic.end() || activeTraffic.empty()) {
+        SG_LOG(SG_ATC, SG_ALERT,
+               "AI error: checking ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
     } else {
         return i->hasInstruction();
     }
@@ -1165,7 +1080,7 @@ FGATCInstruction FGTowerController::getInstruction(int id)
     TrafficVectorIterator i = activeTraffic.begin();
     // Search search if the current id has an entry
     // This might be faster using a map instead of a vector, but let's start by taking a safe route
-    if (activeTraffic.size()) {
+    if (! activeTraffic.empty()) {
         //while ((i->getId() != id) && i != activeTraffic.end()) {
         while (i != activeTraffic.end()) {
             if (i->getId() == id) {
@@ -1174,9 +1089,9 @@ FGATCInstruction FGTowerController::getInstruction(int id)
             i++;
         }
     }
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
-               "AI error: requesting ATC instruction for aircraft without traffic record");
+    if (i == activeTraffic.end() || activeTraffic.empty()) {
+        SG_LOG(SG_ATC, SG_ALERT,
+               "AI error: requesting ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
     } else {
         return i->getInstruction();
     }
@@ -1184,13 +1099,18 @@ FGATCInstruction FGTowerController::getInstruction(int id)
 }
 
 void FGTowerController::render(bool visible) {
-    //cerr << "FGTowerController::render function not yet implemented" << endl;
+    //std::cerr << "FGTowerController::render function not yet implemented" << std::endl;
 }
 
 string FGTowerController::getName() {
     return string(parent->getId() + "-tower");
 }
 
+void FGTowerController::update(double dt)
+{
+
+}
+
 
 
 /***************************************************************************
@@ -1198,24 +1118,29 @@ string FGTowerController::getName() {
  *
  **************************************************************************/
 FGStartupController::FGStartupController(FGAirportDynamics *par):
-    FGATCController()
+        FGATCController()
 {
     parent = par;
 }
 
+FGStartupController::~FGStartupController()
+{
+    clearTrafficControllers(activeTraffic);
+}
+
 void FGStartupController::announcePosition(int id,
-                                           FGAIFlightPlan * intendedRoute,
-                                           int currentPosition, double lat,
-                                           double lon, double heading,
-                                           double speed, double alt,
-                                           double radius, int leg,
-                                           FGAIAircraft * ref)
+        FGAIFlightPlan * intendedRoute,
+        int currentPosition, double lat,
+        double lon, double heading,
+        double speed, double alt,
+        double radius, int leg,
+        FGAIAircraft * ref)
 {
     init();
     TrafficVectorIterator i = activeTraffic.begin();
     // Search whether the current id alread has an entry
     // This might be faster using a map instead of a vector, but let's start by taking a safe route
-    if (activeTraffic.size()) {
+    if (! activeTraffic.empty()) {
         //while ((i->getId() != id) && i != activeTraffic.end()) {
         while (i != activeTraffic.end()) {
             if (i->getId() == id) {
@@ -1225,7 +1150,7 @@ void FGStartupController::announcePosition(int id,
         }
     }
     // Add a new TrafficRecord if no one exsists for this aircraft.
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
+    if (i == activeTraffic.end() || activeTraffic.empty()) {
         FGTrafficRecord rec;
         rec.setId(id);
 
@@ -1246,7 +1171,7 @@ void FGStartupController::announcePosition(int id,
 
 // NOTE:
 // IF WE MAKE TRAFFICRECORD A MEMBER OF THE BASE CLASS
-// THE FOLLOWING THREE FUNCTIONS: SIGNOFF, HAS INSTRUCTION AND GETINSTRUCTION CAN 
+// THE FOLLOWING THREE FUNCTIONS: SIGNOFF, HAS INSTRUCTION AND GETINSTRUCTION CAN
 // BECOME DEVIRTUALIZED AND BE A MEMBER OF THE BASE ATCCONTROLLER CLASS
 // WHICH WOULD SIMPLIFY CODE MAINTENANCE.
 // Note that this function is probably obsolete
@@ -1255,7 +1180,7 @@ bool FGStartupController::hasInstruction(int id)
     TrafficVectorIterator i = activeTraffic.begin();
     // Search search if the current id has an entry
     // This might be faster using a map instead of a vector, but let's start by taking a safe route
-    if (activeTraffic.size()) {
+    if (! activeTraffic.empty()) {
         //while ((i->getId() != id) && i != activeTraffic.end()) {
         while (i != activeTraffic.end()) {
             if (i->getId() == id) {
@@ -1264,9 +1189,9 @@ bool FGStartupController::hasInstruction(int id)
             i++;
         }
     }
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
-               "AI error: checking ATC instruction for aircraft without traffic record");
+    if (i == activeTraffic.end() || activeTraffic.empty()) {
+        SG_LOG(SG_ATC, SG_ALERT,
+               "AI error: checking ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
     } else {
         return i->hasInstruction();
     }
@@ -1279,7 +1204,7 @@ FGATCInstruction FGStartupController::getInstruction(int id)
     TrafficVectorIterator i = activeTraffic.begin();
     // Search search if the current id has an entry
     // This might be faster using a map instead of a vector, but let's start by taking a safe route
-    if (activeTraffic.size()) {
+    if (! activeTraffic.empty()) {
         //while ((i->getId() != id) && i != activeTraffic.end()) {
         while (i != activeTraffic.end()) {
             if (i->getId() == id) {
@@ -1288,9 +1213,9 @@ FGATCInstruction FGStartupController::getInstruction(int id)
             i++;
         }
     }
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
-               "AI error: requesting ATC instruction for aircraft without traffic record");
+    if (i == activeTraffic.end() || activeTraffic.empty()) {
+        SG_LOG(SG_ATC, SG_ALERT,
+               "AI error: requesting ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
     } else {
         return i->getInstruction();
     }
@@ -1302,7 +1227,7 @@ void FGStartupController::signOff(int id)
     TrafficVectorIterator i = activeTraffic.begin();
     // Search search if the current id alread has an entry
     // This might be faster using a map instead of a vector, but let's start by taking a safe route
-    if (activeTraffic.size()) {
+    if (! activeTraffic.empty()) {
         //while ((i->getId() != id) && i != activeTraffic.end()) {
         while (i != activeTraffic.end()) {
             if (i->getId() == id) {
@@ -1311,9 +1236,9 @@ void FGStartupController::signOff(int id)
             i++;
         }
     }
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
-               "AI error: Aircraft without traffic record is signing off from tower");
+    if (i == activeTraffic.end() || activeTraffic.empty()) {
+        SG_LOG(SG_ATC, SG_ALERT,
+               "AI error: Aircraft without traffic record is signing off from tower at " << SG_ORIGIN);
     } else {
         //cerr << i->getAircraft()->getCallSign() << " signing off from startupcontroller" << endl;
         i = activeTraffic.erase(i);
@@ -1321,21 +1246,20 @@ void FGStartupController::signOff(int id)
 }
 
 bool FGStartupController::checkTransmissionState(int st, time_t now, time_t startTime, TrafficVectorIterator i, AtcMsgId msgId,
-                               AtcMsgDir msgDir)
+        AtcMsgDir msgDir)
 {
     int state = i->getState();
     if ((state == st) && available) {
         if ((msgDir == ATC_AIR_TO_GROUND) && isUserAircraft(i->getAircraft())) {
-            
+
             //cerr << "Checking state " << st << " for " << i->getAircraft()->getCallSign() << endl;
-            static SGPropertyNode_ptr trans_num = globals->get_props()->getNode("/sim/atc/transmission-num", true);
+            SGPropertyNode_ptr trans_num = globals->get_props()->getNode("/sim/atc/transmission-num", true);
             int n = trans_num->getIntValue();
             if (n == 0) {
                 trans_num->setIntValue(-1);
-                 // PopupCallback(n);
-                 //cerr << "Selected transmission message " << n << endl;
-                 FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc");
-                 atc->getATCDialog()->removeEntry(1);
+                // PopupCallback(n);
+                //cerr << "Selected transmission message " << n << endl;
+                FGATCDialogNew::instance()->removeEntry(1);
             } else {
                 //cerr << "creading message for " << i->getAircraft()->getCallSign() << endl;
                 transmit(&(*i), &(*parent), msgId, msgDir, false);
@@ -1355,14 +1279,14 @@ bool FGStartupController::checkTransmissionState(int st, time_t now, time_t star
 }
 
 void FGStartupController::updateAircraftInformation(int id, double lat, double lon,
-                                                    double heading, double speed, double alt,
-                                                    double dt)
+        double heading, double speed, double alt,
+        double dt)
 {
     TrafficVectorIterator i = activeTraffic.begin();
     // Search search if the current id has an entry
     // This might be faster using a map instead of a vector, but let's start by taking a safe route
     TrafficVectorIterator current, closest;
-    if (activeTraffic.size()) {
+    if (! activeTraffic.empty()) {
         //while ((i->getId() != id) && i != activeTraffic.end()) {
         while (i != activeTraffic.end()) {
             if (i->getId() == id) {
@@ -1374,8 +1298,8 @@ void FGStartupController::updateAircraftInformation(int id, double lat, double l
 //    // update position of the current aircraft
 
     if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
-               "AI error: updating aircraft without traffic record");
+        SG_LOG(SG_ATC, SG_ALERT,
+               "AI error: updating aircraft without traffic record at " << SG_ORIGIN);
     } else {
         i->setPositionAndHeading(lat, lon, heading, speed, alt);
         current = i;
@@ -1384,11 +1308,12 @@ void FGStartupController::updateAircraftInformation(int id, double lat, double l
 
     int state = i->getState();
 
-    // The user controlled aircraft should have crased here, because it doesn't have a traffic reference. 
+    // The user controlled aircraft should have crased here, because it doesn't have a traffic reference.
     // NOTE: if we create a traffic schedule for the user aircraft, we can use this to plan a flight.
     time_t startTime = i->getAircraft()->getTrafficRef()->getDepartureTime();
-    time_t now = time(NULL) + fgGetLong("/sim/time/warp");
-    //cerr << i->getAircraft()->getTrafficRef()->getCallSign() 
+    time_t now = globals->get_time_params()->get_cur_time();
+
+    //cerr << i->getAircraft()->getTrafficRef()->getCallSign()
     //     << " is scheduled to depart in " << startTime-now << " seconds. Available = " << available
     //     << " at parking " << getGateName(i->getAircraft()) << endl;
 
@@ -1408,7 +1333,7 @@ void FGStartupController::updateAircraftInformation(int id, double lat, double l
     checkTransmissionState(7, now, (startTime + 180), i, MSG_REQUEST_PUSHBACK_CLEARANCE,                ATC_AIR_TO_GROUND);
 
 
-   
+
     if ((state == 8) && available) {
         if (now > startTime + 200) {
             if (i->pushBackAllowed()) {
@@ -1435,7 +1360,7 @@ static void WorldCoordinate(osg::Matrix& obj_pos, double lat,
                             double lon, double elev, double hdg, double slope)
 {
     SGGeod geod = SGGeod::fromDegM(lon, lat, elev);
-    obj_pos = geod.makeZUpFrame();
+    obj_pos = makeZUpFrame(geod);
     // hdg is not a compass heading, but a counter-clockwise rotation
     // around the Z axis
     obj_pos.preMult(osg::Matrix::rotate(hdg * SGD_DEGREES_TO_RADIANS,
@@ -1447,7 +1372,7 @@ static void WorldCoordinate(osg::Matrix& obj_pos, double lat,
 
 void FGStartupController::render(bool visible)
 {
-
+    //std::cerr << "Rendering startup controller" << std::endl;
     SGMaterialLib *matlib = globals->get_matlib();
     if (group) {
         //int nr = ;
@@ -1455,151 +1380,82 @@ void FGStartupController::render(bool visible)
         //while (group->getNumChildren()) {
         //  cerr << "Number of children: " << group->getNumChildren() << endl;
         //simgear::EffectGeode* geode = (simgear::EffectGeode*) group->getChild(0);
-          //osg::MatrixTransform *obj_trans = (osg::MatrixTransform*) group->getChild(0);
-           //geode->releaseGLObjects();
-           //group->removeChild(geode);
-           //delete geode;
+        //osg::MatrixTransform *obj_trans = (osg::MatrixTransform*) group->getChild(0);
+        //geode->releaseGLObjects();
+        //group->removeChild(geode);
+        //delete geode;
         group = 0;
     }
     if (visible) {
         group = new osg::Group;
         FGScenery * local_scenery = globals->get_scenery();
-        double elevation_meters = 0.0;
-        double elevation_feet = 0.0;
+        //double elevation_meters = 0.0;
+        //double elevation_feet = 0.0;
 
 
         //for ( FGTaxiSegmentVectorIterator i = segments.begin(); i != segments.end(); i++) {
         double dx = 0;
-        for   (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
-            // Handle start point
-            int pos = i->getCurrentPosition();
-            //cerr << "rendering for " << i->getAircraft()->getCallSign() << "pos = " << pos << endl;
-            if (pos > 0) {
-                FGTaxiSegment *segment  = parent->getGroundNetwork()->findSegment(pos);
-                SGGeod start(SGGeod::fromDeg((i->getLongitude()), (i->getLatitude())));
-                SGGeod end  (SGGeod::fromDeg(segment->getEnd()->getLongitude(), segment->getEnd()->getLatitude()));
-
-                double length = SGGeodesy::distanceM(start, end);
-                //heading = SGGeodesy::headingDeg(start->getGeod(), end->getGeod());
-
-                double az2, heading; //, distanceM;
-                SGGeodesy::inverse(start, end, heading, az2, length);
-                double coveredDistance = length * 0.5;
-                SGGeod center;
-                SGGeodesy::direct(start, heading, coveredDistance, center, az2);
-                //cerr << "Active Aircraft : Centerpoint = (" << center.getLatitudeDeg() << ", " << center.getLongitudeDeg() << "). Heading = " << heading << endl;
-                ///////////////////////////////////////////////////////////////////////////////
-                // Make a helper function out of this
-                osg::Matrix obj_pos;
-                osg::MatrixTransform *obj_trans = new osg::MatrixTransform;
-                obj_trans->setDataVariance(osg::Object::STATIC);
-                // Experimental: Calculate slope here, based on length, and the individual elevations
-                double elevationStart;
-                if (isUserAircraft((i)->getAircraft())) {
-                    elevationStart = fgGetDouble("/position/ground-elev-m");
-                } else {
-                    elevationStart = ((i)->getAircraft()->_getAltitude()); 
-                }
-                double elevationEnd   = segment->getEnd()->getElevation();
-                if (elevationEnd == 0) {
-                    SGGeod center2 = end;
-                    center2.setElevationM(SG_MAX_ELEVATION_M);
-                    if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
-                        elevation_feet = elevationEnd * SG_METER_TO_FEET + 0.5;
-                            //elevation_meters += 0.5;
-                    }
-                    else { 
-                        elevationEnd = parent->getElevation()+8+dx;
-                    }
-                    segment->getEnd()->setElevation(elevationEnd);
-                }
+        time_t now = globals->get_time_params()->get_cur_time();
 
-                double elevationMean  = (elevationStart + elevationEnd) / 2.0;
-                double elevDiff       = elevationEnd - elevationStart;
-               
-               double slope = atan2(elevDiff, length) * SGD_RADIANS_TO_DEGREES;
-                
-               //cerr << "1. Using mean elevation : " << elevationMean << " and " << slope << endl;
-
-                WorldCoordinate( obj_pos, center.getLatitudeDeg(), center.getLongitudeDeg(), elevationMean + 0.5, -(heading), slope );
-;
-
-                obj_trans->setMatrix( obj_pos );
-                //osg::Vec3 center(0, 0, 0)
-
-                float width = length /2.0;
-                osg::Vec3 corner(-width, 0, 0.25f);
-                osg::Vec3 widthVec(2*width + 1, 0, 0);
-                osg::Vec3 heightVec(0, 1, 0);
-                osg::Geometry* geometry;
-                geometry = osg::createTexturedQuadGeometry(corner, widthVec, heightVec);
-                simgear::EffectGeode* geode = new simgear::EffectGeode;
-                geode->setName("test");
-                geode->addDrawable(geometry);
-                //osg::Node *custom_obj;
-                SGMaterial *mat = matlib->find("UnidirectionalTaper");
-                if (mat)
-                    geode->setEffect(mat->get_effect());
-                obj_trans->addChild(geode);
-                // wire as much of the scene graph together as we can
-                //->addChild( obj_trans );
-                group->addChild( obj_trans );
-                /////////////////////////////////////////////////////////////////////
-            } else {
-                //cerr << "BIG FAT WARNING: current position is here : " << pos << endl;
-            }
-            for(intVecIterator j = (i)->getIntentions().begin(); j != (i)->getIntentions().end(); j++) {
-                osg::Matrix obj_pos;
-                int k = (*j);
-                if (k > 0) {
-                    //cerr << "rendering for " << i->getAircraft()->getCallSign() << "intention = " << k << endl;
+        for   (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
+            if (i->isActive(300)) {
+                // Handle start point
+                int pos = i->getCurrentPosition();
+                //cerr << "rendering for " << i->getAircraft()->getCallSign() << "pos = " << pos << endl;
+                if (pos > 0) {
+                    FGTaxiSegment *segment  = parent->getGroundNetwork()->findSegment(pos);
+                    SGGeod start(SGGeod::fromDeg((i->getLongitude()), (i->getLatitude())));
+                    SGGeod end  (segment->getEnd()->geod());
+
+                    double length = SGGeodesy::distanceM(start, end);
+                    //heading = SGGeodesy::headingDeg(start->geod(), end->geod());
+
+                    double az2, heading; //, distanceM;
+                    SGGeodesy::inverse(start, end, heading, az2, length);
+                    double coveredDistance = length * 0.5;
+                    SGGeod center;
+                    SGGeodesy::direct(start, heading, coveredDistance, center, az2);
+                    //cerr << "Active Aircraft : Centerpoint = (" << center.getLatitudeDeg() << ", " << center.getLongitudeDeg() << "). Heading = " << heading << endl;
+                    ///////////////////////////////////////////////////////////////////////////////
+                    // Make a helper function out of this
+                    osg::Matrix obj_pos;
                     osg::MatrixTransform *obj_trans = new osg::MatrixTransform;
                     obj_trans->setDataVariance(osg::Object::STATIC);
-                    FGTaxiSegment *segment  = parent->getGroundNetwork()->findSegment(k);
-
-                    double elevationStart = segment->getStart()->getElevation();
-                    double elevationEnd   = segment->getEnd  ()->getElevation();
-                    if (elevationStart == 0) {
-                        SGGeod center2 = segment->getStart()->getGeod();
-                        center2.setElevationM(SG_MAX_ELEVATION_M);
-                        if (local_scenery->get_elevation_m( center2, elevationStart, NULL )) {
-                            elevation_feet = elevationStart * SG_METER_TO_FEET + 0.5;
-                            //elevation_meters += 0.5;
-                        }
-                        else { 
-                            elevationStart = parent->getElevation()+8+dx;
-                        }
-                        segment->getStart()->setElevation(elevationStart);
+                    // Experimental: Calculate slope here, based on length, and the individual elevations
+                    double elevationStart;
+                    if (isUserAircraft((i)->getAircraft())) {
+                        elevationStart = fgGetDouble("/position/ground-elev-m");
+                    } else {
+                        elevationStart = ((i)->getAircraft()->_getAltitude() * SG_FEET_TO_METER);
                     }
-                    if (elevationEnd == 0) {
-                        SGGeod center2 = segment->getEnd()->getGeod();
+                    double elevationEnd   = segment->getEnd()->getElevationM();
+                    if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
+                        SGGeod center2 = end;
                         center2.setElevationM(SG_MAX_ELEVATION_M);
                         if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
-                            elevation_feet = elevationEnd * SG_METER_TO_FEET + 0.5;
+                            //elevation_feet = elevationEnd * SG_METER_TO_FEET + 0.5;
                             //elevation_meters += 0.5;
                         }
-                        else { 
-                            elevationEnd = parent->getElevation()+8+dx;
+                        else {
+                            elevationEnd = parent->getElevation();
                         }
                         segment->getEnd()->setElevation(elevationEnd);
                     }
+
                     double elevationMean  = (elevationStart + elevationEnd) / 2.0;
                     double elevDiff       = elevationEnd - elevationStart;
-                    double length         = segment->getLength();
-                    double slope = atan2(elevDiff, length) * SGD_RADIANS_TO_DEGREES;
-                
-                    //cerr << "2. Using mean elevation : " << elevationMean << " and " << slope << endl;
 
+                    double slope = atan2(elevDiff, length) * SGD_RADIANS_TO_DEGREES;
 
-                    WorldCoordinate( obj_pos, segment->getLatitude(), segment->getLongitude(), elevationMean + 0.5, -(segment->getHeading()), slope );
+                    //cerr << "1. Using mean elevation : " << elevationMean << " and " << slope << endl;
 
-                    //WorldCoordinate( obj_pos, segment->getLatitude(), segment->getLongitude(), parent->getElevation()+8+dx, -(segment->getHeading()) );
+                    WorldCoordinate( obj_pos, center.getLatitudeDeg(), center.getLongitudeDeg(), elevationMean + 0.5 + dx, -(heading), slope );
+                    ;
 
                     obj_trans->setMatrix( obj_pos );
                     //osg::Vec3 center(0, 0, 0)
 
-                    float width = segment->getLength() /2.0;
+                    float width = length /2.0;
                     osg::Vec3 corner(-width, 0, 0.25f);
                     osg::Vec3 widthVec(2*width + 1, 0, 0);
                     osg::Vec3 heightVec(0, 1, 0);
@@ -1609,18 +1465,102 @@ void FGStartupController::render(bool visible)
                     geode->setName("test");
                     geode->addDrawable(geometry);
                     //osg::Node *custom_obj;
-                    SGMaterial *mat = matlib->find("UnidirectionalTaper");
+                    SGMaterial *mat;
+                    if (segment->hasBlock(now)) {
+                        mat = matlib->find("UnidirectionalTaperRed", center);
+                    } else {
+                        mat = matlib->find("UnidirectionalTaperGreen", center);
+                    }
                     if (mat)
                         geode->setEffect(mat->get_effect());
                     obj_trans->addChild(geode);
                     // wire as much of the scene graph together as we can
                     //->addChild( obj_trans );
                     group->addChild( obj_trans );
+                    /////////////////////////////////////////////////////////////////////
                 } else {
-                    //cerr << "BIG FAT WARNING: k is here : " << pos << endl;
+                    //cerr << "BIG FAT WARNING: current position is here : " << pos << endl;
+                }
+                for (intVecIterator j = (i)->getIntentions().begin(); j != (i)->getIntentions().end(); j++) {
+                    osg::Matrix obj_pos;
+                    int k = (*j);
+                    if (k > 0) {
+                        //cerr << "rendering for " << i->getAircraft()->getCallSign() << "intention = " << k << endl;
+                        osg::MatrixTransform *obj_trans = new osg::MatrixTransform;
+                        obj_trans->setDataVariance(osg::Object::STATIC);
+                        FGTaxiSegment *segment  = parent->getGroundNetwork()->findSegment(k);
+
+                        double elevationStart = segment->getStart()->getElevationM();
+                        double elevationEnd   = segment->getEnd  ()->getElevationM();
+                        if ((elevationStart == 0) || (elevationStart == parent->getElevation())) {
+                            SGGeod center2 = segment->getStart()->geod();
+                            center2.setElevationM(SG_MAX_ELEVATION_M);
+                            if (local_scenery->get_elevation_m( center2, elevationStart, NULL )) {
+                                //elevation_feet = elevationStart * SG_METER_TO_FEET + 0.5;
+                                //elevation_meters += 0.5;
+                            }
+                            else {
+                                elevationStart = parent->getElevation();
+                            }
+                            segment->getStart()->setElevation(elevationStart);
+                        }
+                        if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
+                            SGGeod center2 = segment->getEnd()->geod();
+                            center2.setElevationM(SG_MAX_ELEVATION_M);
+                            if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
+                                //elevation_feet = elevationEnd * SG_METER_TO_FEET + 0.5;
+                                //elevation_meters += 0.5;
+                            }
+                            else {
+                                elevationEnd = parent->getElevation();
+                            }
+                            segment->getEnd()->setElevation(elevationEnd);
+                        }
+
+                        double elevationMean  = (elevationStart + elevationEnd) / 2.0;
+                        double elevDiff       = elevationEnd - elevationStart;
+                        double length         = segment->getLength();
+                        double slope = atan2(elevDiff, length) * SGD_RADIANS_TO_DEGREES;
+
+                        //cerr << "2. Using mean elevation : " << elevationMean << " and " << slope << endl;
+
+                        SGGeod segCenter(segment->getCenter());
+                        WorldCoordinate( obj_pos, segCenter.getLatitudeDeg(),
+                                        segCenter.getLongitudeDeg(), elevationMean + 0.5 + dx, -(segment->getHeading()), slope );
+
+                        //WorldCoordinate( obj_pos, segment->getLatitude(), segment->getLongitude(), parent->getElevation()+8+dx, -(segment->getHeading()) );
+
+                        obj_trans->setMatrix( obj_pos );
+                        //osg::Vec3 center(0, 0, 0)
+
+                        float width = segment->getLength() /2.0;
+                        osg::Vec3 corner(-width, 0, 0.25f);
+                        osg::Vec3 widthVec(2*width + 1, 0, 0);
+                        osg::Vec3 heightVec(0, 1, 0);
+                        osg::Geometry* geometry;
+                        geometry = osg::createTexturedQuadGeometry(corner, widthVec, heightVec);
+                        simgear::EffectGeode* geode = new simgear::EffectGeode;
+                        geode->setName("test");
+                        geode->addDrawable(geometry);
+                        //osg::Node *custom_obj;
+                        SGMaterial *mat;
+                        if (segment->hasBlock(now)) {
+                            mat = matlib->find("UnidirectionalTaperRed", segCenter);
+                        } else {
+                            mat = matlib->find("UnidirectionalTaperGreen", segCenter);
+                        }
+                        if (mat)
+                            geode->setEffect(mat->get_effect());
+                        obj_trans->addChild(geode);
+                        // wire as much of the scene graph together as we can
+                        //->addChild( obj_trans );
+                        group->addChild( obj_trans );
+                    } else {
+                        //cerr << "BIG FAT WARNING: k is here : " << pos << endl;
+                    }
                 }
+                dx += 0.2;
             }
-            //dx += 0.1;
         }
         globals->get_scenery()->get_scene_graph()->addChild(group);
     }
@@ -1630,31 +1570,42 @@ string FGStartupController::getName() {
     return string(parent->getId() + "-startup");
 }
 
+void FGStartupController::update(double dt)
+{
+
+}
+
+
 
 /***************************************************************************
  * class FGApproachController
  *
  **************************************************************************/
 FGApproachController::FGApproachController(FGAirportDynamics *par):
-FGATCController()
+        FGATCController()
 {
     parent = par;
 }
 
-// 
+FGApproachController::~FGApproachController()
+{
+    clearTrafficControllers(activeTraffic);
+}
+
+//
 void FGApproachController::announcePosition(int id,
-                                            FGAIFlightPlan * intendedRoute,
-                                            int currentPosition,
-                                            double lat, double lon,
-                                            double heading, double speed,
-                                            double alt, double radius,
-                                            int leg, FGAIAircraft * ref)
+        FGAIFlightPlan * intendedRoute,
+        int currentPosition,
+        double lat, double lon,
+        double heading, double speed,
+        double alt, double radius,
+        int leg, FGAIAircraft * ref)
 {
     init();
     TrafficVectorIterator i = activeTraffic.begin();
     // Search whether the current id alread has an entry
     // This might be faster using a map instead of a vector, but let's start by taking a safe route
-    if (activeTraffic.size()) {
+    if (! activeTraffic.empty()) {
         //while ((i->getId() != id) && i != activeTraffic.end()) {
         while (i != activeTraffic.end()) {
             if (i->getId() == id) {
@@ -1664,7 +1615,7 @@ void FGApproachController::announcePosition(int id,
         }
     }
     // Add a new TrafficRecord if no one exsists for this aircraft.
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
+    if (i == activeTraffic.end() || activeTraffic.empty()) {
         FGTrafficRecord rec;
         rec.setId(id);
 
@@ -1680,14 +1631,14 @@ void FGApproachController::announcePosition(int id,
 }
 
 void FGApproachController::updateAircraftInformation(int id, double lat, double lon,
-                                                     double heading, double speed, double alt,
-                                                     double dt)
+        double heading, double speed, double alt,
+        double dt)
 {
     TrafficVectorIterator i = activeTraffic.begin();
     // Search search if the current id has an entry
     // This might be faster using a map instead of a vector, but let's start by taking a safe route
     TrafficVectorIterator current, closest;
-    if (activeTraffic.size()) {
+    if (! activeTraffic.empty()) {
         //while ((i->getId() != id) && i != activeTraffic.end()) {
         while (i != activeTraffic.end()) {
             if (i->getId() == id) {
@@ -1697,9 +1648,9 @@ void FGApproachController::updateAircraftInformation(int id, double lat, double
         }
     }
 //    // update position of the current aircraft
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
-               "AI error: updating aircraft without traffic record");
+    if (i == activeTraffic.end() || activeTraffic.empty()) {
+        SG_LOG(SG_ATC, SG_ALERT,
+               "AI error: updating aircraft without traffic record at " << SG_ORIGIN);
     } else {
         i->setPositionAndHeading(lat, lon, heading, speed, alt);
         current = i;
@@ -1736,7 +1687,7 @@ void FGApproachController::signOff(int id)
     TrafficVectorIterator i = activeTraffic.begin();
     // Search search if the current id alread has an entry
     // This might be faster using a map instead of a vector, but let's start by taking a safe route
-    if (activeTraffic.size()) {
+    if (! activeTraffic.empty()) {
         //while ((i->getId() != id) && i != activeTraffic.end()) {
         while (i != activeTraffic.end()) {
             if (i->getId() == id) {
@@ -1745,14 +1696,18 @@ void FGApproachController::signOff(int id)
             i++;
         }
     }
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
-               "AI error: Aircraft without traffic record is signing off from approach");
+    if (i == activeTraffic.end() || activeTraffic.empty()) {
+        SG_LOG(SG_ATC, SG_ALERT,
+               "AI error: Aircraft without traffic record is signing off from approach at " << SG_ORIGIN);
     } else {
         i = activeTraffic.erase(i);
     }
 }
 
+void FGApproachController::update(double dt)
+{
+
+}
 
 
 
@@ -1761,7 +1716,7 @@ bool FGApproachController::hasInstruction(int id)
     TrafficVectorIterator i = activeTraffic.begin();
     // Search search if the current id has an entry
     // This might be faster using a map instead of a vector, but let's start by taking a safe route
-    if (activeTraffic.size()) {
+    if (! activeTraffic.empty()) {
         //while ((i->getId() != id) && i != activeTraffic.end()) {
         while (i != activeTraffic.end()) {
             if (i->getId() == id) {
@@ -1770,9 +1725,9 @@ bool FGApproachController::hasInstruction(int id)
             i++;
         }
     }
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
-               "AI error: checking ATC instruction for aircraft without traffic record");
+    if (i == activeTraffic.end() || activeTraffic.empty()) {
+        SG_LOG(SG_ATC, SG_ALERT,
+               "AI error: checking ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
     } else {
         return i->hasInstruction();
     }
@@ -1795,8 +1750,8 @@ FGATCInstruction FGApproachController::getInstruction(int id)
         }
     }
     if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
-               "AI error: requesting ATC instruction for aircraft without traffic record");
+        SG_LOG(SG_ATC, SG_ALERT,
+               "AI error: requesting ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
     } else {
         return i->getInstruction();
     }
@@ -1804,7 +1759,7 @@ FGATCInstruction FGApproachController::getInstruction(int id)
 }
 
 
-ActiveRunway *FGApproachController::getRunway(string name)
+ActiveRunway *FGApproachController::getRunway(const string& name)
 {
     ActiveRunwayVecIterator rwy = activeRunways.begin();
     if (activeRunways.size()) {
@@ -1824,7 +1779,7 @@ ActiveRunway *FGApproachController::getRunway(string name)
 }
 
 void FGApproachController::render(bool visible) {
-    //cerr << "FGApproachController::render function not yet implemented" << endl;
+    //std::cerr << "FGApproachController::render function not yet implemented" << std::endl;
 }