- Added ultra-light traffic is now a separate traffic class that can have its
own preferential runway support. In future versions, we might want to condider having a more generic mechanism for this. - Keep a history of active runway for each class, so that runway assignments are more consistent after whether updates or time-related schedule changes.
This commit is contained in:
parent
3a0b1286ff
commit
721d849c79
5 changed files with 44 additions and 72 deletions
|
@ -56,8 +56,8 @@ FGAirportDynamics::FGAirportDynamics(FGAirport* ap) :
|
|||
lastUpdate = 0;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
avWindHeading [i] = 0;
|
||||
avWindSpeed [i] = 0;
|
||||
//avWindHeading [i] = 0;
|
||||
//avWindSpeed [i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,8 +78,8 @@ FGAirportDynamics::FGAirportDynamics(const FGAirportDynamics& other) :
|
|||
lastUpdate = other.lastUpdate;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
avWindHeading [i] = other.avWindHeading[i];
|
||||
avWindSpeed [i] = other.avWindSpeed [i];
|
||||
//avWindHeading [i] = other.avWindHeading[i];
|
||||
//avWindSpeed [i] = other.avWindSpeed [i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -373,57 +373,6 @@ 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;
|
||||
// }
|
||||
|
||||
// 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" << _ap->getId() << endl;
|
||||
//cerr << "Nr of seconds since day start << " << dayStart << endl;
|
||||
|
@ -432,7 +381,7 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s
|
|||
//cerr << "A"<< endl;
|
||||
currSched = rwyPrefs.getSchedule(trafficType.c_str());
|
||||
if (!(currSched))
|
||||
return;
|
||||
return;
|
||||
//cerr << "B"<< endl;
|
||||
scheduleName = currSched->getName(dayStart);
|
||||
maxTail = currSched->getTailWind ();
|
||||
|
@ -446,21 +395,34 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s
|
|||
if (!(currRunwayGroup))
|
||||
return;
|
||||
nrActiveRunways = currRunwayGroup->getNrActiveRunways();
|
||||
//cerr << "Nr of Active Runways = " << nrActiveRunways << endl;
|
||||
|
||||
// Keep a history of the currently active runways, to ensure
|
||||
// that an already established selection of runways will not
|
||||
// be overridden once a more preferred selection becomes
|
||||
// available as that can lead to random runway swapping.
|
||||
if (trafficType == "com") {
|
||||
currentlyActive = &comActive;
|
||||
} else if (trafficType == "gen") {
|
||||
currentlyActive = &genActive;
|
||||
} else if (trafficType == "mil") {
|
||||
currentlyActive = &milActive;
|
||||
} else if (trafficType == "ul") {
|
||||
currentlyActive = &ulActive;
|
||||
}
|
||||
//
|
||||
currRunwayGroup->setActive(_ap->getId(),
|
||||
windSpeed,
|
||||
windHeading,
|
||||
maxTail,
|
||||
maxCross,
|
||||
¤tlyActive);
|
||||
currentlyActive);
|
||||
|
||||
// Note that I SHOULD keep three lists in memory, one for
|
||||
// Note that I SHOULD keep multiple lists in memory, one for
|
||||
// general aviation, one for commercial and one for military
|
||||
// traffic.
|
||||
currentlyActive.clear();
|
||||
currentlyActive->clear();
|
||||
nrActiveRunways = currRunwayGroup->getNrActiveRunways();
|
||||
//cerr << "Choosing runway for " << trafficType << endl;
|
||||
for (int i = 0; i < nrActiveRunways; i++)
|
||||
{
|
||||
type = "unknown"; // initialize to something other than landing or takeoff
|
||||
|
@ -468,16 +430,17 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s
|
|||
if (type == "landing")
|
||||
{
|
||||
landing.push_back(name);
|
||||
currentlyActive.push_back(name);
|
||||
currentlyActive->push_back(name);
|
||||
//cerr << "Landing " << name << endl;
|
||||
}
|
||||
if (type == "takeoff")
|
||||
{
|
||||
takeoff.push_back(name);
|
||||
currentlyActive.push_back(name);
|
||||
currentlyActive->push_back(name);
|
||||
//cerr << "takeoff " << name << endl;
|
||||
}
|
||||
}
|
||||
//cerr << endl;
|
||||
}
|
||||
if (action == 1) // takeoff
|
||||
{
|
||||
|
@ -505,8 +468,7 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s
|
|||
{ //fallback
|
||||
runway = chooseRunwayFallback();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//runway = globals->get_runways()->search(_ap->getId(), int(windHeading));
|
||||
//cerr << "Seleceted runway: " << runway << endl;
|
||||
}
|
||||
|
|
|
@ -50,14 +50,15 @@ private:
|
|||
string prevTrafficType;
|
||||
stringVec landing;
|
||||
stringVec takeoff;
|
||||
stringVec currentlyActive;
|
||||
stringVec milActive, comActive, genActive, ulActive;
|
||||
stringVec *currentlyActive;
|
||||
|
||||
// Experimental keep a running average of wind dir and speed to prevent
|
||||
// Erratic runway changes.
|
||||
// Note: I should add these to the copy constructor and assigment operator to be
|
||||
// constistent
|
||||
double avWindHeading [10];
|
||||
double avWindSpeed [10];
|
||||
//double avWindHeading [10];
|
||||
//double avWindSpeed [10];
|
||||
|
||||
string chooseRunwayFallback();
|
||||
|
||||
|
|
|
@ -114,6 +114,12 @@ void FGRunwayPreferenceXMLLoader::endElement (const char * name) {
|
|||
_pref->setMilTimes(currTimes);
|
||||
currTimes.clear();
|
||||
}
|
||||
if (!(strcmp(name, "ul"))) { // Military Traffic
|
||||
//cerr << "Setting time table for military traffic" << endl;
|
||||
_pref->setULTimes(currTimes);
|
||||
currTimes.clear();
|
||||
}
|
||||
|
||||
|
||||
if (!(strcmp(name, "takeoff"))) {
|
||||
//cerr << "Adding takeoff: " << value << endl;
|
||||
|
|
|
@ -237,7 +237,7 @@ void RunwayGroup::setActive(const string &aptId,
|
|||
{
|
||||
|
||||
name = rwyList[j].getRwyList(i);
|
||||
//cerr << "Name of Runway: " << name << endl;
|
||||
//cerr << "Name of Runway: " << name;
|
||||
if (globals->get_runways()->search( aptId,
|
||||
name,
|
||||
&rwy))
|
||||
|
@ -252,21 +252,22 @@ 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))
|
||||
{
|
||||
//cerr << "Invalid : " << endl;
|
||||
//cerr << ". [Invalid] " << endl;
|
||||
validSelection = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//cerr << "Valid : " << endl;;
|
||||
//cerr << ". [Valid] ";
|
||||
}
|
||||
}else {
|
||||
SG_LOG( SG_GENERAL, SG_INFO, "Failed to find runway " << name << " at " << aptId );
|
||||
exit(1);
|
||||
}
|
||||
//cerr << endl;
|
||||
}
|
||||
if (validSelection)
|
||||
{
|
||||
|
|
|
@ -135,6 +135,7 @@ private:
|
|||
ScheduleTime comTimes; // Commercial Traffic;
|
||||
ScheduleTime genTimes; // General Aviation;
|
||||
ScheduleTime milTimes; // Military Traffic;
|
||||
ScheduleTime ulTimes; // Ultralight Traffic
|
||||
|
||||
PreferenceList preferences;
|
||||
|
||||
|
@ -157,6 +158,7 @@ public:
|
|||
void setMilTimes(ScheduleTime& t) { milTimes = t; };
|
||||
void setGenTimes(ScheduleTime& t) { genTimes = t; };
|
||||
void setComTimes(ScheduleTime& t) { comTimes = t; };
|
||||
void setULTimes (ScheduleTime& t) { ulTimes = t; };
|
||||
|
||||
void addRunwayGroup(RunwayGroup& g) { preferences.push_back(g); };
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue