]> git.mxchange.org Git - flightgear.git/blobdiff - src/ATC/trafficcontrol.cxx
Autopilot: fix wrong warning for unknown node
[flightgear.git] / src / ATC / trafficcontrol.cxx
index 8a1e996e7d5b47f8cd9e2a6b7eddb0d86cdcebcc..65d60ae529dca95546b4223598560420792df6b0 100644 (file)
@@ -25,6 +25,7 @@
 #endif
 
 #include <algorithm>
+#include <cstdio>
 
 #include <osg/Geode>
 #include <osg/Geometry>
@@ -34,6 +35,7 @@
 #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 <Scenery/scenery.hxx>
 
 #include "trafficcontrol.hxx"
 #include <Traffic/TrafficMgr.hxx>
 #include <Airports/groundnetwork.hxx>
 #include <Airports/dynamics.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
+#include <Radio/radio.hxx>
+#include <signal.h>
 
 using std::sort;
+using std::string;
+using std::cout;
+using std::endl;
 
 /***************************************************************************
  * ActiveRunway
@@ -58,7 +65,7 @@ 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 {
@@ -173,7 +180,9 @@ FGTrafficRecord::FGTrafficRecord():
         allowTransmission(true),
         allowPushback(true),
         priority(0),
-        latitude(0), longitude(0), heading(0), speed(0), altitude(0), radius(0)
+        timer(0),
+        latitude(0), longitude(0), heading(0), speed(0), altitude(0), radius(0),
+        aircraft(NULL)
 {
 }
 
@@ -182,17 +191,11 @@ void FGTrafficRecord::setPositionAndIntentions(int pos,
 {
 
     currentPos = pos;
-    if (intentions.size()) {
+    if (! intentions.empty()) {
         intVecIterator i = intentions.begin();
         if ((*i) != pos) {
-            SG_LOG(SG_GENERAL, SG_ALERT,
+            SG_LOG(SG_ATC, SG_ALERT,
                    "Error in FGTrafficRecord::setPositionAndIntentions at " << SG_ORIGIN);
-            //cerr << "Pos : " << pos << " Curr " << *(intentions.begin())  << endl;
-            for (intVecIterator i = intentions.begin();
-                    i != intentions.end(); i++) {
-                //cerr << (*i) << " ";
-            }
-            //cerr << endl;
         }
         intentions.erase(i);
     } else {
@@ -200,21 +203,11 @@ 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);
 }
 /**
  * Check if another aircraft is ahead of the current one, and on the same
@@ -230,7 +223,7 @@ 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();
@@ -240,7 +233,7 @@ bool FGTrafficRecord::checkPositionAndIntentions(FGTrafficRecord & other)
     //     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)))
@@ -284,18 +277,18 @@ int FGTrafficRecord::crosses(FGGroundNetwork * net,
         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++) {
             if ((*i) > 0) {
@@ -307,7 +300,7 @@ int FGTrafficRecord::crosses(FGGroundNetwork * net,
             }
         }
     }
-    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++) {
@@ -339,7 +332,7 @@ 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++) {
             if (*i > 0) {
@@ -351,7 +344,7 @@ 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++)
     //    {
@@ -395,7 +388,7 @@ bool FGTrafficRecord::isOpposing(FGGroundNetwork * net,
                         }
                     }
             }
-            if (other.intentions.size()) {
+            if (! other.intentions.empty()) {
                 for (intVecIterator j = other.intentions.begin();
                         j != other.intentions.end(); j++) {
                     // cerr << "Current segment 1 " << (*i) << endl;
@@ -423,7 +416,7 @@ bool FGTrafficRecord::isOpposing(FGGroundNetwork * net,
     return false;
 }
 
-bool FGTrafficRecord::isActive(int margin)
+bool FGTrafficRecord::isActive(int margin) const
 {
     time_t now = time(NULL) + fgGetLong("/sim/time/warp");
     time_t deptime = aircraft->getTrafficRef()->getDepartureTime();
@@ -443,7 +436,7 @@ void FGTrafficRecord::setHeadingAdjustment(double heading)
     instruction.setHeading(heading);
 }
 
-bool FGTrafficRecord::pushBackAllowed()
+bool FGTrafficRecord::pushBackAllowed() const
 {
     return allowPushback;
 }
@@ -470,7 +463,7 @@ FGATCInstruction::FGATCInstruction()
 }
 
 
-bool FGATCInstruction::hasInstruction()
+bool FGATCInstruction::hasInstruction() const
 {
     return (holdPattern || holdPosition || changeSpeed || changeHeading
             || changeAltitude || resolveCircularWait);
@@ -491,6 +484,8 @@ FGATCController::FGATCController()
     available = true;
     lastTransmission = 0;
     initialized = false;
+    lastTransmissionDirection = ATC_AIR_TO_GROUND;
+    group = NULL;
 }
 
 FGATCController::~FGATCController()
@@ -508,7 +503,7 @@ bool FGATCController::isUserAircraft(FGAIAircraft* ac)
     return (ac->getCallSign() == fgGetString("/sim/multiplay/callsign")) ? true : false;
 };
 
-void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
+void FGATCController::transmit(FGTrafficRecord * rec, FGAirportDynamics *parent, AtcMsgId msgId,
                                AtcMsgDir msgDir, bool audible)
 {
     string sender, receiver;
@@ -529,6 +524,7 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
     FGAIFlightPlan *fp;
     string fltRules;
     string instructionText;
+    int ground_to_air=0;
 
     //double commFreqD;
     sender = rec->getAircraft()->getTrafficRef()->getCallSign();
@@ -569,6 +565,7 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
         string tmp = sender;
         sender = receiver;
         receiver = tmp;
+        ground_to_air=1;
     }
     switch (msgId) {
     case MSG_ANNOUNCE_ENGINE_START:
@@ -600,8 +597,7 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
         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";
@@ -736,10 +732,33 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
         // Display ATC message only when one of the radios is tuned
         // the relevant frequency.
         // Note that distance attenuation is currently not yet implemented
-        if ((onBoardRadioFreqI0 == stationFreq)
-                || (onBoardRadioFreqI1 == stationFreq)) {
+                
+        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 {
@@ -747,6 +766,7 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
     }
 }
 
+
 string FGATCController::formatATCFrequency3_2(int freq)
 {
     char buffer[7];
@@ -756,7 +776,7 @@ 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)
+string FGATCController::genTransponderCode(const string& fltRules)
 {
     if (fltRules == "VFR") {
         return string("1200");
@@ -800,7 +820,7 @@ void FGTowerController::announcePosition(int id,
     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) {
@@ -810,7 +830,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);
 
@@ -823,7 +843,7 @@ void FGTowerController::announcePosition(int id,
         activeTraffic.push_back(rec);
         // 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;
@@ -854,7 +874,7 @@ void FGTowerController::updateAircraftInformation(int id, double lat, double lon
     // 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) {
@@ -864,8 +884,8 @@ 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,
+    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);
@@ -878,11 +898,11 @@ void FGTowerController::updateAircraftInformation(int id, double lat, double lon
     // 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();
-        //}
-    }
+    //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()) {
@@ -937,7 +957,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) {
@@ -948,7 +968,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()) {
@@ -960,12 +980,12 @@ void FGTowerController::signOff(int id)
             rwy->setCleared(0);
             rwy->updateDepartureCue();
         } else {
-            SG_LOG(SG_GENERAL, SG_ALERT,
+            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,
+    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();
@@ -985,7 +1005,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) {
@@ -994,8 +1014,8 @@ bool FGTowerController::hasInstruction(int id)
             i++;
         }
     }
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
+    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();
@@ -1009,7 +1029,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) {
@@ -1018,8 +1038,8 @@ FGATCInstruction FGTowerController::getInstruction(int id)
             i++;
         }
     }
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
+    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();
@@ -1064,7 +1084,7 @@ void FGStartupController::announcePosition(int id,
     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) {
@@ -1074,7 +1094,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);
 
@@ -1104,7 +1124,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) {
@@ -1113,8 +1133,8 @@ bool FGStartupController::hasInstruction(int id)
             i++;
         }
     }
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
+    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();
@@ -1128,7 +1148,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) {
@@ -1137,8 +1157,8 @@ FGATCInstruction FGStartupController::getInstruction(int id)
             i++;
         }
     }
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
+    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();
@@ -1151,7 +1171,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) {
@@ -1160,8 +1180,8 @@ void FGStartupController::signOff(int id)
             i++;
         }
     }
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
+    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;
@@ -1177,7 +1197,7 @@ bool FGStartupController::checkTransmissionState(int st, time_t now, time_t star
         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);
@@ -1186,13 +1206,13 @@ bool FGStartupController::checkTransmissionState(int st, time_t now, time_t star
                 FGATCDialogNew::instance()->removeEntry(1);
             } else {
                 //cerr << "creading message for " << i->getAircraft()->getCallSign() << endl;
-                transmit(&(*i), msgId, msgDir, false);
+                transmit(&(*i), &(*parent), msgId, msgDir, false);
                 return false;
             }
         }
         if (now > startTime) {
             //cerr << "Transmitting startup msg" << endl;
-            transmit(&(*i), msgId, msgDir, true);
+            transmit(&(*i), &(*parent), msgId, msgDir, true);
             i->updateState();
             lastTransmission = now;
             available = false;
@@ -1210,7 +1230,7 @@ void FGStartupController::updateAircraftInformation(int id, double lat, double l
     // 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) {
@@ -1222,7 +1242,7 @@ 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,
+        SG_LOG(SG_ATC, SG_ALERT,
                "AI error: updating aircraft without traffic record at " << SG_ORIGIN);
     } else {
         i->setPositionAndHeading(lat, lon, heading, speed, alt);
@@ -1261,11 +1281,11 @@ void FGStartupController::updateAircraftInformation(int id, double lat, double l
         if (now > startTime + 200) {
             if (i->pushBackAllowed()) {
                 i->allowRepeatedTransmissions();
-                transmit(&(*i), MSG_PERMIT_PUSHBACK_CLEARANCE,
+                transmit(&(*i), &(*parent), MSG_PERMIT_PUSHBACK_CLEARANCE,
                          ATC_GROUND_TO_AIR, true);
                 i->updateState();
             } else {
-                transmit(&(*i), MSG_HOLD_PUSHBACK_CLEARANCE,
+                transmit(&(*i), &(*parent), MSG_HOLD_PUSHBACK_CLEARANCE,
                          ATC_GROUND_TO_AIR, true);
                 i->suppressRepeatedTransmissions();
             }
@@ -1283,7 +1303,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,
@@ -1312,12 +1332,13 @@ void FGStartupController::render(bool visible)
     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;
+        time_t now = time(NULL) + fgGetLong("/sim/time/warp");
         for   (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
             if (i->isActive(300)) {
                 // Handle start point
@@ -1326,10 +1347,10 @@ void FGStartupController::render(bool visible)
                 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()));
+                    SGGeod end  (segment->getEnd()->geod());
 
                     double length = SGGeodesy::distanceM(start, end);
-                    //heading = SGGeodesy::headingDeg(start->getGeod(), end->getGeod());
+                    //heading = SGGeodesy::headingDeg(start->geod(), end->geod());
 
                     double az2, heading; //, distanceM;
                     SGGeodesy::inverse(start, end, heading, az2, length);
@@ -1349,12 +1370,12 @@ void FGStartupController::render(bool visible)
                     } else {
                         elevationStart = ((i)->getAircraft()->_getAltitude() * SG_FEET_TO_METER);
                     }
-                    double elevationEnd   = segment->getEnd()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
+                    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 {
@@ -1387,7 +1408,7 @@ void FGStartupController::render(bool visible)
                     geode->addDrawable(geometry);
                     //osg::Node *custom_obj;
                     SGMaterial *mat;
-                    if (segment->hasBlock()) {
+                    if (segment->hasBlock(now)) {
                         mat = matlib->find("UnidirectionalTaperRed");
                     } else {
                         mat = matlib->find("UnidirectionalTaperGreen");
@@ -1411,13 +1432,13 @@ void FGStartupController::render(bool visible)
                         obj_trans->setDataVariance(osg::Object::STATIC);
                         FGTaxiSegment *segment  = parent->getGroundNetwork()->findSegment(k);
 
-                        double elevationStart = segment->getStart()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
-                        double elevationEnd   = segment->getEnd  ()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
+                        double elevationStart = segment->getStart()->getElevationM();
+                        double elevationEnd   = segment->getEnd  ()->getElevationM();
                         if ((elevationStart == 0) || (elevationStart == parent->getElevation())) {
-                            SGGeod center2 = segment->getStart()->getGeod();
+                            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_feet = elevationStart * SG_METER_TO_FEET + 0.5;
                                 //elevation_meters += 0.5;
                             }
                             else {
@@ -1426,10 +1447,10 @@ void FGStartupController::render(bool visible)
                             segment->getStart()->setElevation(elevationStart);
                         }
                         if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
-                            SGGeod center2 = segment->getEnd()->getGeod();
+                            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_feet = elevationEnd * SG_METER_TO_FEET + 0.5;
                                 //elevation_meters += 0.5;
                             }
                             else {
@@ -1445,8 +1466,9 @@ void FGStartupController::render(bool visible)
 
                         //cerr << "2. Using mean elevation : " << elevationMean << " and " << slope << endl;
 
-
-                        WorldCoordinate( obj_pos, segment->getLatitude(), segment->getLongitude(), elevationMean + 0.5 + dx, -(segment->getHeading()), slope );
+                        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()) );
 
@@ -1464,7 +1486,7 @@ void FGStartupController::render(bool visible)
                         geode->addDrawable(geometry);
                         //osg::Node *custom_obj;
                         SGMaterial *mat;
-                        if (segment->hasBlock()) {
+                        if (segment->hasBlock(now)) {
                             mat = matlib->find("UnidirectionalTaperRed");
                         } else {
                             mat = matlib->find("UnidirectionalTaperGreen");
@@ -1520,7 +1542,7 @@ void FGApproachController::announcePosition(int id,
     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) {
@@ -1530,7 +1552,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);
 
@@ -1553,7 +1575,7 @@ void FGApproachController::updateAircraftInformation(int id, double lat, double
     // 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) {
@@ -1563,8 +1585,8 @@ 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,
+    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);
@@ -1602,7 +1624,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) {
@@ -1611,8 +1633,8 @@ void FGApproachController::signOff(int id)
             i++;
         }
     }
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
+    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);
@@ -1631,7 +1653,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) {
@@ -1640,8 +1662,8 @@ bool FGApproachController::hasInstruction(int id)
             i++;
         }
     }
-    if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
+    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();
@@ -1665,7 +1687,7 @@ FGATCInstruction FGApproachController::getInstruction(int id)
         }
     }
     if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
-        SG_LOG(SG_GENERAL, SG_ALERT,
+        SG_LOG(SG_ATC, SG_ALERT,
                "AI error: requesting ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
     } else {
         return i->getInstruction();
@@ -1674,7 +1696,7 @@ FGATCInstruction FGApproachController::getInstruction(int id)
 }
 
 
-ActiveRunway *FGApproachController::getRunway(string name)
+ActiveRunway *FGApproachController::getRunway(const string& name)
 {
     ActiveRunwayVecIterator rwy = activeRunways.begin();
     if (activeRunways.size()) {