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 << "Nr of seconds since day start << " << dayStart << endl;
+
ScheduleTime *currSched;
//cerr << "A"<< endl;
currSched = rwyPrefs.getSchedule(trafficType.c_str());
return;
nrActiveRunways = currRunwayGroup->getNrActiveRunways();
//cerr << "Nr of Active Runways = " << nrActiveRunways << endl;
- currRunwayGroup->setActive(_id, averageWindSpeed, averageWindHeading, maxTail, maxCross);
+
+ //
+ currRunwayGroup->setActive(_id,
+ windSpeed,
+ windHeading,
+ maxTail,
+ maxCross,
+ ¤tlyActive);
+
+ // 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++)
{
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;
}
}
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
double windSpeed,
double windHeading,
double maxTail,
- double maxCross)
+ double maxCross,
+ stringVec *currentlyActive)
{
FGRunway rwy;
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.
+ //
+
for (int j = 0; j < activeRwys; j++)
{
- //cerr << "I J " << i << " " << j << endl;
+ validSelection = true;
name = rwyList[j].getRwyList(i);
//cerr << "Name of Runway: " << name << endl;
if (globals->get_runways()->search( aptId,
//cerr << "Tailwind : " << tailWind << endl;
//cerr << "Crosswnd : " << crossWind << endl;
if ((tailWind > maxTail) || (crossWind > maxCross))
- validSelection = false;
+ {
+ //cerr << "Invalid : ";
+ validSelection = false;
+ }
+ else
+ {
+ //cerr << "Valid : ";
+ }
}else {
- SG_LOG( SG_GENERAL, SG_INFO, "Failed to find runway " << name << " at " << aptId );
- exit(1);
- }
-
+ SG_LOG( SG_GENERAL, SG_INFO, "Failed to find runway " << name << " at " << aptId );
+ exit(1);
+ }
}
- if (validSelection)
+ if (validSelection)
{
- //cerr << "Valid runay selection : " << i << endl;
- nrActive = activeRwys;
- active = i;
- return;
- }
+ //cerr << "Valid : ";
+ 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.
{
//cerr << "Succes" << endl;
hdgDiff = fabs(windHeading - rwy._heading);
- //cerr << "Wind Heading: " << windHeading << "Runway Heading: " <<rwy._heading << endl;
- //cerr << "Wind Speed : " << windSpeed << endl;
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 {
}
}
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)