]> git.mxchange.org Git - flightgear.git/blobdiff - src/Airports/runwayprefs.cxx
Merge branch 'next' of gitorious.org:fg/flightgear into next
[flightgear.git] / src / Airports / runwayprefs.cxx
index 1672acf3b5baf4a953dc2ec6ae5cd73d0c664580..8337d31f9fad3e60c7c8ea5430536fa4fe8bed47 100644 (file)
@@ -17,7 +17,7 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //
 // $Id$
 
 #endif
 
 #include <math.h>
-//#include <algorithm>
 
 #include <simgear/compiler.h>
 
-//#include <plib/sg.h>
-//#include <plib/ul.h>
-
-//#include <Environment/environment_mgr.hxx>
-//#include <Environment/environment.hxx>
-//#include <simgear/misc/sg_path.hxx>
-//#include <simgear/props/props.hxx>
-//#include <simgear/structure/subsystem_mgr.hxx>
 #include <simgear/debug/logstream.hxx>
 #include <Main/globals.hxx>
-//#include <Main/fg_props.hxx>
 #include <Airports/runways.hxx>
 
 #include "runwayprefs.hxx"
+#include "simple.hxx"
 
 /******************************************************************************
  * ScheduleTime
@@ -117,7 +108,7 @@ string ScheduleTime::getName(time_t dayStart)
       //couldn't find one so return 0;
       //cerr << "Returning 0 " << endl;
     }
-    return string(0);
+    return string("");
 }                            
 /******************************************************************************
  * RunwayList
@@ -193,14 +184,15 @@ RunwayGroup& RunwayGroup:: operator= (const RunwayGroup &other)
   return *this;
 }
 
-void RunwayGroup::setActive(const string &aptId
+void RunwayGroup::setActive(const FGAirport* airport
                            double windSpeed, 
                            double windHeading, 
                            double maxTail, 
-                           double maxCross)
+                           double maxCross,
+                           stringVec *currentlyActive)
 {
 
-  FGRunway rwy;
+  FGRunway* rwy;
   int activeRwys = rwyList.size(); // get the number of runways active
   int nrOfPreferences;
   // bool found = true;
@@ -209,24 +201,40 @@ void RunwayGroup::setActive(const string &aptId,
   double crossWind;
   double tailWind;
   string name;
+  //stringVec names;
+  int bestMatch = 0, bestChoice = 0;
 
   if (activeRwys > 0)
-    {
+    {  
+      // Now downward iterate across all the possible preferences
+      // starting by the least preferred choice working toward the most preferred choice
+
       nrOfPreferences = rwyList[0].getRwyList()->size();
-      for (int i = 0; i < nrOfPreferences; i++)
+      bool validSelection = true;
+      bool foundValidSelection = false;
+      for (int i = nrOfPreferences-1; i >= 0; i--)
        {
-         bool validSelection = true;
+         int match = 0;
+         
+
+         // Test each runway listed in the preference to see if it's possible to use
+         // If one runway of the selection isn't allowed, we need to exclude this
+         // preference, however, we don't want to stop right there, because we also
+         // don't want to randomly swap runway preferences, unless there is a need to. 
+         //
+         validSelection = true;
          for (int j = 0; j < activeRwys; j++)
-           {
-             //cerr << "I J " << i << " " << j << endl;
-             name = rwyList[j].getRwyList(i);
-             //cerr << "Name of Runway: " << name << endl;
-             if (globals->get_runways()->search( aptId, 
-                                                 name, 
-                                                 &rwy))
-               {
-                 //cerr << "Succes" << endl;
-                 hdgDiff = fabs(windHeading - rwy._heading);
+    {
+      string ident(rwyList[j].getRwyList(i));
+      if (!airport->hasRunwayWithIdent(ident)) {
+        SG_LOG(SG_GENERAL, SG_WARN, "no such runway:" << ident << " at " << airport->ident());
+        continue;
+      }
+      
+            rwy = airport->getRunwayByIdent(ident);
+       
+                         //cerr << "Succes" << endl;
+                 hdgDiff = fabs(windHeading - rwy->headingDeg());
                  //cerr << "Wind Heading: " << windHeading << "Runway Heading: " <<rwy._heading << endl;
                  //cerr << "Wind Speed  : " << windSpeed << endl;
                  if (hdgDiff > 180)
@@ -235,23 +243,43 @@ void RunwayGroup::setActive(const string &aptId,
                  hdgDiff *= ((2*M_PI)/360.0); // convert to radians
                  crossWind = windSpeed * sin(hdgDiff);
                  tailWind  = -windSpeed * cos(hdgDiff);
-                 //cerr << "Tailwind : " << tailWind << endl;
-                 //cerr << "Crosswnd : " << crossWind << endl;
+                 //cerr << ". Tailwind : " << tailWind;
+                 //cerr << ". Crosswnd : " << crossWind;
                  if ((tailWind > maxTail) || (crossWind > maxCross))
-                   validSelection = false;
-               }else {
-                 SG_LOG( SG_GENERAL, SG_INFO, "Failed to find runway " << name << " at " << aptId );
-                 exit(1);
-               }
-
-           }
-         if (validSelection)
+                   {
+                     //cerr << ". [Invalid] " << endl;
+                     validSelection = false;
+                  }
+                 else 
+                   {
+                     //cerr << ". [Valid] ";
+                 }
+                             //cerr << endl;
+    } // of active runways iteration
+      
+         if (validSelection) 
            {
-             //cerr << "Valid runay selection : " << i << endl;
-             nrActive = activeRwys;
-             active = i;
-             return;
-           }
+             //cerr << "Valid selection  : " << i << endl;;
+             foundValidSelection = true;
+             for (stringVecIterator it = currentlyActive->begin(); 
+                  it != currentlyActive->end(); it++)
+               {
+                 if ((*it) == name)
+                   match++;
+               }
+             if (match >= bestMatch) {
+               bestMatch = match;
+               bestChoice = i;
+             }
+           } 
+         //cerr << "Preference " << i << " bestMatch " << bestMatch << " choice " << bestChoice << endl;
+       }
+      if (foundValidSelection)
+       {
+         //cerr << "Valid runay selection : " << bestChoice << endl;
+         nrActive = activeRwys;
+         active = bestChoice;
+         return;
        }
       // If this didn't work, due to heavy winds, try again
       // but select only one landing and one takeoff runway. 
@@ -271,31 +299,19 @@ void RunwayGroup::setActive(const string &aptId,
          bool validSelection = true;
          for (int j = 0; j < 2; j++)
            {
-             //cerr << "I J " << i << " " << j << endl;
-             name = rwyList[choice[j]].getRwyList(i);
-             //cerr << "Name of Runway: " << name << endl;
-             if (globals->get_runways()->search( aptId, 
-                                                 name, 
-                                                 &rwy))
-               {
+        name = rwyList[choice[j]].getRwyList(i);
+        rwy = airport->getRunwayByIdent(name);
+        
                  //cerr << "Succes" << endl;
-                 hdgDiff = fabs(windHeading - rwy._heading);
-                 //cerr << "Wind Heading: " << windHeading << "Runway Heading: " <<rwy._heading << endl;
-                 //cerr << "Wind Speed  : " << windSpeed << endl;
+                 hdgDiff = fabs(windHeading - rwy->headingDeg());
                  if (hdgDiff > 180)
                    hdgDiff = 360 - hdgDiff;
-                 //cerr << "Heading diff: " << hdgDiff << endl;
                  hdgDiff *= ((2*M_PI)/360.0); // convert to radians
                  crossWind = windSpeed * sin(hdgDiff);
                  tailWind  = -windSpeed * cos(hdgDiff);
-                 //cerr << "Tailwind : " << tailWind << endl;
-                 //cerr << "Crosswnd : " << crossWind << endl;
                  if ((tailWind > maxTail) || (crossWind > maxCross))
                    validSelection = false;
-               }else {
-                 SG_LOG( SG_GENERAL, SG_INFO, "Failed to find runway " << name << " at " << aptId );
-                 exit(1);
-               }
+               
 
            }
          if (validSelection)
@@ -308,19 +324,7 @@ void RunwayGroup::setActive(const string &aptId,
        }
     }
   active = -1;
-  //RunwayListVectorIterator i; // = rwlist.begin();
-  //stringVecIterator j;
-  //for (i = rwyList.begin(); i != rwyList.end(); i++)
-  //  {
-  //    cerr << i->getType();
-  //    for (j = i->getRwyList()->begin(); j != i->getRwyList()->end(); j++)
-  //   {                                 
-  //     cerr << (*j);
-  //   }
-  //    cerr << endl;
-  //  }
-  //for (int
-
+  nrActive = 0;
 }
 
 void RunwayGroup::getActive(int i, string &name, string &type)
@@ -343,7 +347,8 @@ void RunwayGroup::getActive(int i, string &name, string &type)
 /*****************************************************************************
  * FGRunway preference
  ****************************************************************************/
-FGRunwayPreference::FGRunwayPreference()
+FGRunwayPreference::FGRunwayPreference(FGAirport* ap) : 
+  _ap(ap)
 {
   //cerr << "Running default Constructor" << endl;
   initialized = false;
@@ -352,16 +357,11 @@ FGRunwayPreference::FGRunwayPreference()
 FGRunwayPreference::FGRunwayPreference(const FGRunwayPreference &other)
 {
   initialized = other.initialized;
-  value = other.value;
-  scheduleName = other.scheduleName;
 
   comTimes = other.comTimes; // Commercial Traffic;
   genTimes = other.genTimes; // General Aviation;
   milTimes = other.milTimes; // Military Traffic;
-  currTimes= other.currTimes; // Needed for parsing;
 
-  rwyList = other.rwyList;
-  rwyGroup = other.rwyGroup;
   PreferenceListConstIterator i;
   for (i = other.preferences.begin(); i != other.preferences.end(); i++)
     preferences.push_back(*i);
@@ -370,16 +370,11 @@ FGRunwayPreference::FGRunwayPreference(const FGRunwayPreference &other)
 FGRunwayPreference & FGRunwayPreference::operator= (const FGRunwayPreference &other)
 {
   initialized = other.initialized;
-  value = other.value;
-  scheduleName = other.scheduleName;
   
   comTimes = other.comTimes; // Commercial Traffic;
   genTimes = other.genTimes; // General Aviation;
   milTimes = other.milTimes; // Military Traffic;
-  currTimes= other.currTimes; // Needed for parsing;
   
-  rwyList = other.rwyList;
-  rwyGroup = other.rwyGroup;
   PreferenceListConstIterator i;
   preferences.clear();
   for (i = other.preferences.begin(); i != other.preferences.end(); i++)
@@ -414,142 +409,6 @@ RunwayGroup *FGRunwayPreference::getGroup(const string &groupName)
     return 0;
 }
 
-void  FGRunwayPreference::startXML () {
-  //  cout << "Start XML" << endl;
-}
-
-void  FGRunwayPreference::endXML () {
-  cout << "End XML" << endl;
-}
-
-void  FGRunwayPreference::startElement (const char * name, const XMLAttributes &atts) {
-  //cout << "StartElement " << name << endl;
-  value = string("");
-  if (!(strcmp(name, "wind"))) {
-    //cerr << "Will be processing Wind" << endl;
-    for (int i = 0; i < atts.size(); i++)
-      {
-       //cout << "  " << atts.getName(i) << '=' << atts.getValue(i) << endl; 
-       //attname = atts.getName(i);
-       if (atts.getName(i) == string("tail")) {
-         //cerr << "Tail Wind = " << atts.getValue(i) << endl;
-         currTimes.setTailWind(atof(atts.getValue(i)));
-       }       
-       if (atts.getName(i) == string("cross")) {
-         //cerr << "Cross Wind = " << atts.getValue(i) << endl;
-         currTimes.setCrossWind(atof(atts.getValue(i)));
-       }
-     }
-  }
-    if (!(strcmp(name, "time"))) {
-      //cerr << "Will be processing time" << endl;     
-    for (int i = 0; i < atts.size(); i++)
-      {
-       if (atts.getName(i) == string("start")) {
-         //cerr << "Start Time = " << atts.getValue(i) << endl;
-         currTimes.addStartTime(processTime(atts.getValue(i)));
-       }
-       if (atts.getName(i) == string("end")) {
-         //cerr << "End time = " << atts.getValue(i) << endl;
-         currTimes.addEndTime(processTime(atts.getValue(i)));
-       }
-       if (atts.getName(i) == string("schedule")) {
-         //cerr << "Schedule Name  = " << atts.getValue(i) << endl;
-         currTimes.addScheduleName(atts.getValue(i));
-       }       
-    }
-  }
-  if (!(strcmp(name, "takeoff"))) {
-    rwyList.clear();
-  }
-  if  (!(strcmp(name, "landing")))
-    {
-      rwyList.clear();
-    }
-  if (!(strcmp(name, "schedule"))) {
-    for (int i = 0; i < atts.size(); i++)
-      {
-       //cout << "  " << atts.getName(i) << '=' << atts.getValue(i) << endl; 
-       //attname = atts.getName(i);
-       if (atts.getName(i) == string("name")) {
-         //cerr << "Schedule name = " << atts.getValue(i) << endl;
-         scheduleName = atts.getValue(i);
-       }
-      }
-  }
-}
-
-//based on a string containing hour and minute, return nr seconds since day start.
-time_t FGRunwayPreference::processTime(const string &tme)
-{
-  string hour   = tme.substr(0, tme.find(":",0));
-  string minute = tme.substr(tme.find(":",0)+1, tme.length());
-
-  //cerr << "hour = " << hour << " Minute = " << minute << endl;
-  return (atoi(hour.c_str()) * 3600 + atoi(minute.c_str()) * 60);
-}
-
-void  FGRunwayPreference::endElement (const char * name) {
-  //cout << "End element " << name << endl;
-  if (!(strcmp(name, "rwyuse"))) {
-    initialized = true;
-  }
-  if (!(strcmp(name, "com"))) { // Commercial Traffic
-    //cerr << "Setting time table for commerical traffic" << endl;
-    comTimes = currTimes;
-    currTimes.clear();
-  }
-  if (!(strcmp(name, "gen"))) { // General Aviation
-    //cerr << "Setting time table for general aviation" << endl;
-    genTimes = currTimes;
-    currTimes.clear();
-  }  
-  if (!(strcmp(name, "mil"))) { // Military Traffic
-    //cerr << "Setting time table for military traffic" << endl;
-    genTimes = currTimes;
-    currTimes.clear();
-  }
-
-  if (!(strcmp(name, "takeoff"))) {
-    //cerr << "Adding takeoff: " << value << endl;
-    rwyList.set(name, value);
-    rwyGroup.add(rwyList);
-  }
-  if (!(strcmp(name, "landing"))) {
-    //cerr << "Adding landing: " << value << endl;
-    rwyList.set(name, value);
-    rwyGroup.add(rwyList);
-  }
-  if (!(strcmp(name, "schedule"))) {
-    //cerr << "Adding schedule" << scheduleName << endl;
-    rwyGroup.setName(scheduleName);
-    //rwyGroup.addRunways(rwyList);
-    preferences.push_back(rwyGroup);
-    rwyGroup.clear();
-    //exit(1);
-  }
-}
-
-void  FGRunwayPreference::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("");
-  value += token;
-}
-
-void  FGRunwayPreference::pi (const char * target, const char * data) {
-  //cout << "Processing instruction " << target << ' ' << data << endl;
-}
-
-void  FGRunwayPreference::warning (const char * message, int line, int column) {
-  cout << "Warning: " << message << " (" << line << ',' << column << ')'   
-       << endl;
-}
-
-void  FGRunwayPreference::error (const char * message, int line, int column) {
-  cout << "Error: " << message << " (" << line << ',' << column << ')'
-       << endl;
-}
+ string FGRunwayPreference::getId() { 
+   return _ap->getId(); 
+ };