]> git.mxchange.org Git - flightgear.git/blobdiff - src/Airports/dynamics.cxx
Thomas Foerster:
[flightgear.git] / src / Airports / dynamics.cxx
index 517e25bea3f3cda7458f9bcb9c914b351514bb29..c1958fe2d18cd102321239a581633e67976c232d 100644 (file)
@@ -39,7 +39,6 @@
 #include <Main/globals.hxx>
 #include <Main/fg_props.hxx>
 #include <Airports/runways.hxx>
-#include <simgear/xml/easyxml.hxx>
 
 #include STL_STRING
 #include <vector>
@@ -49,34 +48,26 @@ SG_USING_STD(vector);
 SG_USING_STD(sort);
 SG_USING_STD(random_shuffle);
 
-#include "parking.hxx"
-#include "groundnetwork.hxx"
-#include "runwayprefs.hxx"
+#include "simple.hxx"
 #include "dynamics.hxx"
 
-/********** FGAirport Dynamics *********************************************/
-
-FGAirportDynamics::FGAirportDynamics(double lat, double lon, double elev, string id) :
-  _latitude(lat),
-  _longitude(lon),
-  _elevation(elev),
-  _id(id)
-{
+FGAirportDynamics::FGAirportDynamics(FGAirport* ap) :
+  _ap(ap), rwyPrefs(ap) {
   lastUpdate = 0;
   for (int i = 0; i < 10; i++)
-    {
-      avWindHeading [i] = 0;
-      avWindSpeed   [i] = 0;
-    }
+     {
+       avWindHeading [i] = 0;
+       avWindSpeed   [i] = 0;
+     }
 }
 
-
 // Note that the ground network should also be copied
-FGAirportDynamics::FGAirportDynamics(const FGAirportDynamics& other) 
+FGAirportDynamics::FGAirportDynamics(const FGAirportDynamics& other) :
+  rwyPrefs(other.rwyPrefs)
 {
   for (FGParkingVecConstIterator ip= other.parkings.begin(); ip != other.parkings.end(); ip++)
     parkings.push_back(*(ip));
-  rwyPrefs = other.rwyPrefs;
+  // rwyPrefs = other.rwyPrefs;
   lastUpdate = other.lastUpdate;
   
   stringVecConstIterator il;
@@ -95,7 +86,6 @@ FGAirportDynamics::FGAirportDynamics(const FGAirportDynamics& other)
 // Destructor
 FGAirportDynamics::~FGAirportDynamics()
 {
-  
 }
 
 
@@ -113,6 +103,8 @@ void FGAirportDynamics::init()
   // add the gate positions to the ground network. 
   groundNetwork.addNodes(&parkings);
   groundNetwork.init();
+  groundNetwork.setTowerController(&towerController);
+  groundNetwork.setParent(_ap);
 }
 
 bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, double *heading, int *gateId, double rad, const string &flType, const string &acType, const string &airline)
@@ -134,9 +126,9 @@ bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, double *he
   
   if (parkings.begin() == parkings.end())
     {
-      //cerr << "Could not find parking spot at " << _id << endl;
-      *lat = _latitude;
-      *lon = _longitude;
+      //cerr << "Could not find parking spot at " << _ap->getId() << endl;
+      *lat = _ap->getLatitude();
+      *lon = _ap->getLongitude();
       *heading = 0;
       found = true;
     }
@@ -165,11 +157,19 @@ bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, double *he
              continue;
            }
          else // Airline code doesn't match
-           if (i->getCodes().find(airline, 0) == string::npos)
-             {
-               available = false;
-               continue;
-             }
+           {
+             //cerr << "Code = " << airline << ": Codes " << i->getCodes();
+             if (i->getCodes().find(airline, 0) == string::npos)
+               {
+                 available = false;
+                 //cerr << "Unavailable" << endl;
+                 continue;
+               }
+             else
+               {
+                 //cerr << "Available" << endl;
+               }
+           }
          // Type doesn't match
          if (i->getType() != flType)
            {
@@ -266,13 +266,13 @@ bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, double *he
     }
   if (!found)
     {
-      //cerr << "Traffic overflow at" << _id 
+      //cerr << "Traffic overflow at" << _ap->getId() 
       //          << ". flType = " << flType 
       //          << ". airline = " << airline 
       //          << " Radius = " <<rad
       //          << endl;
-      *lat = _latitude;
-      *lon = _longitude;
+      *lat = _ap->getLatitude();
+      *lon = _ap->getLongitude();
       *heading = 0;
       *gateId  = -1;
       //exit(1);
@@ -284,8 +284,8 @@ void FGAirportDynamics::getParking (int id, double *lat, double* lon, double *he
 {
   if (id < 0)
     {
-      *lat = _latitude;
-      *lon = _longitude;
+      *lat = _ap->getLatitude();
+      *lon = _ap->getLongitude();
       *heading = 0;
     }
   else
@@ -297,7 +297,7 @@ void FGAirportDynamics::getParking (int id, double *lat, double* lon, double *he
            {
              *lat     = i->getLatitude();
              *lon     = i->getLongitude();
-             *heading = i->getLongitude();
+             *heading = i->getHeading();
            }
        }
     }
@@ -333,119 +333,6 @@ void FGAirportDynamics::releaseParking(int id)
     }
 }
   
-void  FGAirportDynamics::startXML () {
-  //cout << "Start XML" << endl;
-}
-
-void  FGAirportDynamics::endXML () {
-  //cout << "End XML" << endl;
-}
-
-void  FGAirportDynamics::startElement (const char * name, const XMLAttributes &atts) {
-  // const char *attval;
-  FGParking park;
-  FGTaxiNode taxiNode;
-  FGTaxiSegment taxiSegment;
-  int index = 0;
-  taxiSegment.setIndex(index);
-  //cout << "Start element " << name << endl;
-  string attname;
-  string value;
-  string gateName;
-  string gateNumber;
-  string lat;
-  string lon;
-  if (name == string("Parking"))
-    {
-      for (int i = 0; i < atts.size(); i++)
-       {
-         //cout << "  " << atts.getName(i) << '=' << atts.getValue(i) << endl; 
-         attname = atts.getName(i);
-         if (attname == string("index"))
-           park.setIndex(atoi(atts.getValue(i)));
-         else if (attname == string("type"))
-           park.setType(atts.getValue(i));
-        else if (attname == string("name"))
-          gateName = atts.getValue(i);
-         else if (attname == string("number"))
-           gateNumber = atts.getValue(i);
-         else if (attname == string("lat"))
-          park.setLatitude(atts.getValue(i));
-         else if (attname == string("lon"))
-           park.setLongitude(atts.getValue(i)); 
-         else if (attname == string("heading"))
-           park.setHeading(atof(atts.getValue(i)));
-         else if (attname == string("radius")) {
-           string radius = atts.getValue(i);
-           if (radius.find("M") != string::npos)
-             radius = radius.substr(0, radius.find("M",0));
-           //cerr << "Radius " << radius <<endl;
-           park.setRadius(atof(radius.c_str()));
-         }
-          else if (attname == string("airlineCodes"))
-            park.setCodes(atts.getValue(i));
-       }
-      park.setName((gateName+gateNumber));
-      parkings.push_back(park);
-    }
-  if (name == string("node")) 
-    {
-      for (int i = 0; i < atts.size() ; i++)
-       {
-         attname = atts.getName(i);
-         if (attname == string("index"))
-           taxiNode.setIndex(atoi(atts.getValue(i)));
-         if (attname == string("lat"))
-           taxiNode.setLatitude(atts.getValue(i));
-         if (attname == string("lon"))
-           taxiNode.setLongitude(atts.getValue(i));
-       }
-      groundNetwork.addNode(taxiNode);
-    }
-  if (name == string("arc")) 
-    {
-      taxiSegment.setIndex(++index);
-      for (int i = 0; i < atts.size() ; i++)
-       {
-         attname = atts.getName(i);
-         if (attname == string("begin"))
-           taxiSegment.setStartNodeRef(atoi(atts.getValue(i)));
-         if (attname == string("end"))
-           taxiSegment.setEndNodeRef(atoi(atts.getValue(i)));
-       }
-      groundNetwork.addSegment(taxiSegment);
-    }
-  // sort by radius, in asending order, so that smaller gates are first in the list
-}
-
-void  FGAirportDynamics::endElement (const char * name) {
-  //cout << "End element " << name << endl;
-
-}
-
-void  FGAirportDynamics::data (const char * s, int len) {
-  string token = string(s,len);
-  //cout << "Character data " << string(s,len) << endl;
-  //if ((token.find(" ") == string::npos && (token.find('\n')) == string::npos))
-    //value += token;
-  //else
-    //value = string("");
-}
-
-void  FGAirportDynamics::pi (const char * target, const char * data) {
-  //cout << "Processing instruction " << target << ' ' << data << endl;
-}
-
-void  FGAirportDynamics::warning (const char * message, int line, int column) {
-  cout << "Warning: " << message << " (" << line << ',' << column << ')'   
-       << endl;
-}
-
-void  FGAirportDynamics::error (const char * message, int line, int column) {
-  cout << "Error: " << message << " (" << line << ',' << column << ')'
-       << endl;
-}
-
 void FGAirportDynamics::setRwyUse(const FGRunwayPreference& ref)
 {
   rwyPrefs = ref;
@@ -471,11 +358,11 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s
       RunwayGroup *currRunwayGroup = 0;
       int nrActiveRunways = 0;
       time_t dayStart = fgGetLong("/sim/time/utc/day-seconds");
-      if (((dayStart - lastUpdate) > 600) || trafficType != prevTrafficType)
+      if ((abs((long)(dayStart - lastUpdate)) > 600) || trafficType != prevTrafficType)
        {
          landing.clear();
          takeoff.clear();
-         //lastUpdate = dayStart;
+         lastUpdate = dayStart;
          prevTrafficType = trafficType;
 
          FGEnvironment 
@@ -486,60 +373,61 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s
          
          windSpeed = stationweather.get_wind_speed_kt();
          windHeading = stationweather.get_wind_from_heading_deg();
-         double averageWindSpeed   = 0;
-         double averageWindHeading = 0;
-         double cosHeading         = 0;
-         double sinHeading         = 0;
-         // Initialize at the beginning of the next day or startup
-         if ((lastUpdate == 0) || (dayStart < lastUpdate))
-           {
-             for (int i = 0; i < 10; i++)
-               {
-                 avWindHeading [i] = windHeading;
-                 avWindSpeed   [i] = windSpeed;
-               }
-           }
-         else
-           {
-             if (windSpeed != avWindSpeed[9]) // update if new metar data 
-               {
-                 // shift the running average
-                 for (int i = 0; i < 9 ; i++)
-                   {
-                     avWindHeading[i] = avWindHeading[i+1];
-                     avWindSpeed  [i] = avWindSpeed  [i+1];
-                   }
-               } 
-             avWindHeading[9] = windHeading;
-             avWindSpeed  [9] = windSpeed;
-           }
+        //  double averageWindSpeed   = 0;
+//       double averageWindHeading = 0;
+//       double cosHeading         = 0;
+//       double sinHeading         = 0;
+//       // Initialize at the beginning of the next day or startup
+//       if ((lastUpdate == 0) || (dayStart < lastUpdate))
+//         {
+//           for (int i = 0; i < 10; i++)
+//             {
+//               avWindHeading [i] = windHeading;
+//               avWindSpeed   [i] = windSpeed;
+//             }
+//         }
+//       else
+//         {
+//           if (windSpeed != avWindSpeed[9]) // update if new metar data 
+//             {
+//               // shift the running average
+//               for (int i = 0; i < 9 ; i++)
+//                 {
+//                   avWindHeading[i] = avWindHeading[i+1];
+//                   avWindSpeed  [i] = avWindSpeed  [i+1];
+//                 }
+//             } 
+//           avWindHeading[9] = windHeading;
+//           avWindSpeed  [9] = windSpeed;
+//         }
          
-         for (int i = 0; i < 10; i++)
-           {
-             averageWindSpeed   += avWindSpeed   [i];
-             //averageWindHeading += avWindHeading [i];
-             cosHeading += cos(avWindHeading[i] * SG_DEGREES_TO_RADIANS);
-             sinHeading += sin(avWindHeading[i] * SG_DEGREES_TO_RADIANS);
-           }
-         averageWindSpeed   /= 10;
-         //averageWindHeading /= 10;
-         cosHeading /= 10;
-         sinHeading /= 10;
-         averageWindHeading = atan2(sinHeading, cosHeading) *SG_RADIANS_TO_DEGREES;
-         if (averageWindHeading < 0)
-           averageWindHeading += 360.0;
-         //cerr << "Wind Heading " << windHeading << " average " << averageWindHeading << endl;
-         //cerr << "Wind Speed   " << windSpeed   << " average " << averageWindSpeed   << endl;
-         lastUpdate = dayStart;
-             //if (wind_speed == 0) {
-         //  wind_heading = 270;        This forces West-facing rwys to be used in no-wind situations
-           // which is consistent with Flightgear's initial setup.
-         //}
+//       for (int i = 0; i < 10; i++)
+//         {
+//           averageWindSpeed   += avWindSpeed   [i];
+//           //averageWindHeading += avWindHeading [i];
+//           cosHeading += cos(avWindHeading[i] * SG_DEGREES_TO_RADIANS);
+//           sinHeading += sin(avWindHeading[i] * SG_DEGREES_TO_RADIANS);
+//         }
+//       averageWindSpeed   /= 10;
+//       //averageWindHeading /= 10;
+//       cosHeading /= 10;
+//       sinHeading /= 10;
+//       averageWindHeading = atan2(sinHeading, cosHeading) *SG_RADIANS_TO_DEGREES;
+//       if (averageWindHeading < 0)
+//         averageWindHeading += 360.0;
+//       //cerr << "Wind Heading " << windHeading << " average " << averageWindHeading << endl;
+//       //cerr << "Wind Speed   " << windSpeed   << " average " << averageWindSpeed   << endl;
+//       lastUpdate = dayStart;
+//           //if (wind_speed == 0) {
+//       //  wind_heading = 270;        This forces West-facing rwys to be used in no-wind situations
+//         // which is consistent with Flightgear's initial setup.
+//       //}
          
          //string rwy_no = globals->get_runways()->search(apt->getId(), int(wind_heading));
          string scheduleName;
-         //cerr << "finding active Runway for" << _id << endl;
+         //cerr << "finding active Runway for" << _ap->getId() << endl;
          //cerr << "Nr of seconds since day start << " << dayStart << endl;
+
          ScheduleTime *currSched;
          //cerr << "A"<< endl;
          currSched = rwyPrefs.getSchedule(trafficType.c_str());
@@ -559,7 +447,19 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s
            return;
          nrActiveRunways = currRunwayGroup->getNrActiveRunways();
          //cerr << "Nr of Active Runways = " << nrActiveRunways << endl; 
-         currRunwayGroup->setActive(_id, averageWindSpeed, averageWindHeading, maxTail, maxCross); 
+
+         // 
+         currRunwayGroup->setActive(_ap->getId(), 
+                                    windSpeed, 
+                                    windHeading, 
+                                    maxTail, 
+                                    maxCross, 
+                                    &currentlyActive); 
+
+         // Note that I SHOULD keep three lists in memory, one for 
+         // general aviation, one for commercial and one for military
+         // traffic.
+         currentlyActive.clear();
          nrActiveRunways = currRunwayGroup->getNrActiveRunways();
          for (int i = 0; i < nrActiveRunways; i++)
            {
@@ -568,11 +468,13 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s
              if (type == "landing")
                {
                  landing.push_back(name);
+                 currentlyActive.push_back(name);
                  //cerr << "Landing " << name << endl; 
                }
              if (type == "takeoff")
                {
                  takeoff.push_back(name);
+                 currentlyActive.push_back(name);
                  //cerr << "takeoff " << name << endl;
                }
            }
@@ -582,6 +484,9 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s
          int nr = takeoff.size();
          if (nr)
            {
+             // Note that the randomization below, is just a placeholder to choose between
+             // multiple active runways for this action. This should be
+             // under ATC control.
              runway = takeoff[(rand() %  nr)];
            }
          else
@@ -602,7 +507,7 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s
            }
        }
       
-      //runway = globals->get_runways()->search(_id, int(windHeading));
+      //runway = globals->get_runways()->search(_ap->getId(), int(windHeading));
       //cerr << "Seleceted runway: " << runway << endl;
     }
 }
@@ -622,5 +527,25 @@ string FGAirportDynamics::chooseRunwayFallback()
     //which is consistent with Flightgear's initial setup.
   }
   
-   return globals->get_runways()->search(_id, int(windHeading));
+   return globals->get_runways()->search(_ap->getId(), int(windHeading));
+}
+
+void FGAirportDynamics::addParking(FGParking& park) {
+  parkings.push_back(park);
+}
+
+double FGAirportDynamics::getLatitude() const {
+  return _ap->getLatitude();
+}
+
+double FGAirportDynamics::getLongitude() const {
+  return _ap->getLongitude();
+}
+
+double FGAirportDynamics::getElevation() const {
+  return _ap->getElevation();
+}
+
+const string& FGAirportDynamics::getId() const {
+  return _ap->getId();
 }