- 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;
|
lastUpdate = 0;
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
avWindHeading [i] = 0;
|
//avWindHeading [i] = 0;
|
||||||
avWindSpeed [i] = 0;
|
//avWindSpeed [i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,8 +78,8 @@ FGAirportDynamics::FGAirportDynamics(const FGAirportDynamics& other) :
|
||||||
lastUpdate = other.lastUpdate;
|
lastUpdate = other.lastUpdate;
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
avWindHeading [i] = other.avWindHeading[i];
|
//avWindHeading [i] = other.avWindHeading[i];
|
||||||
avWindSpeed [i] = other.avWindSpeed [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();
|
windSpeed = stationweather.get_wind_speed_kt();
|
||||||
windHeading = stationweather.get_wind_from_heading_deg();
|
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;
|
string scheduleName;
|
||||||
//cerr << "finding active Runway for" << _ap->getId() << endl;
|
//cerr << "finding active Runway for" << _ap->getId() << endl;
|
||||||
//cerr << "Nr of seconds since day start << " << dayStart << 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;
|
//cerr << "A"<< endl;
|
||||||
currSched = rwyPrefs.getSchedule(trafficType.c_str());
|
currSched = rwyPrefs.getSchedule(trafficType.c_str());
|
||||||
if (!(currSched))
|
if (!(currSched))
|
||||||
return;
|
return;
|
||||||
//cerr << "B"<< endl;
|
//cerr << "B"<< endl;
|
||||||
scheduleName = currSched->getName(dayStart);
|
scheduleName = currSched->getName(dayStart);
|
||||||
maxTail = currSched->getTailWind ();
|
maxTail = currSched->getTailWind ();
|
||||||
|
@ -446,21 +395,34 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s
|
||||||
if (!(currRunwayGroup))
|
if (!(currRunwayGroup))
|
||||||
return;
|
return;
|
||||||
nrActiveRunways = currRunwayGroup->getNrActiveRunways();
|
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(),
|
currRunwayGroup->setActive(_ap->getId(),
|
||||||
windSpeed,
|
windSpeed,
|
||||||
windHeading,
|
windHeading,
|
||||||
maxTail,
|
maxTail,
|
||||||
maxCross,
|
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
|
// general aviation, one for commercial and one for military
|
||||||
// traffic.
|
// traffic.
|
||||||
currentlyActive.clear();
|
currentlyActive->clear();
|
||||||
nrActiveRunways = currRunwayGroup->getNrActiveRunways();
|
nrActiveRunways = currRunwayGroup->getNrActiveRunways();
|
||||||
|
//cerr << "Choosing runway for " << trafficType << endl;
|
||||||
for (int i = 0; i < nrActiveRunways; i++)
|
for (int i = 0; i < nrActiveRunways; i++)
|
||||||
{
|
{
|
||||||
type = "unknown"; // initialize to something other than landing or takeoff
|
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")
|
if (type == "landing")
|
||||||
{
|
{
|
||||||
landing.push_back(name);
|
landing.push_back(name);
|
||||||
currentlyActive.push_back(name);
|
currentlyActive->push_back(name);
|
||||||
//cerr << "Landing " << name << endl;
|
//cerr << "Landing " << name << endl;
|
||||||
}
|
}
|
||||||
if (type == "takeoff")
|
if (type == "takeoff")
|
||||||
{
|
{
|
||||||
takeoff.push_back(name);
|
takeoff.push_back(name);
|
||||||
currentlyActive.push_back(name);
|
currentlyActive->push_back(name);
|
||||||
//cerr << "takeoff " << name << endl;
|
//cerr << "takeoff " << name << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//cerr << endl;
|
||||||
}
|
}
|
||||||
if (action == 1) // takeoff
|
if (action == 1) // takeoff
|
||||||
{
|
{
|
||||||
|
@ -505,8 +468,7 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s
|
||||||
{ //fallback
|
{ //fallback
|
||||||
runway = chooseRunwayFallback();
|
runway = chooseRunwayFallback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//runway = globals->get_runways()->search(_ap->getId(), int(windHeading));
|
//runway = globals->get_runways()->search(_ap->getId(), int(windHeading));
|
||||||
//cerr << "Seleceted runway: " << runway << endl;
|
//cerr << "Seleceted runway: " << runway << endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,14 +50,15 @@ private:
|
||||||
string prevTrafficType;
|
string prevTrafficType;
|
||||||
stringVec landing;
|
stringVec landing;
|
||||||
stringVec takeoff;
|
stringVec takeoff;
|
||||||
stringVec currentlyActive;
|
stringVec milActive, comActive, genActive, ulActive;
|
||||||
|
stringVec *currentlyActive;
|
||||||
|
|
||||||
// Experimental keep a running average of wind dir and speed to prevent
|
// Experimental keep a running average of wind dir and speed to prevent
|
||||||
// Erratic runway changes.
|
// Erratic runway changes.
|
||||||
// Note: I should add these to the copy constructor and assigment operator to be
|
// Note: I should add these to the copy constructor and assigment operator to be
|
||||||
// constistent
|
// constistent
|
||||||
double avWindHeading [10];
|
//double avWindHeading [10];
|
||||||
double avWindSpeed [10];
|
//double avWindSpeed [10];
|
||||||
|
|
||||||
string chooseRunwayFallback();
|
string chooseRunwayFallback();
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,12 @@ void FGRunwayPreferenceXMLLoader::endElement (const char * name) {
|
||||||
_pref->setMilTimes(currTimes);
|
_pref->setMilTimes(currTimes);
|
||||||
currTimes.clear();
|
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"))) {
|
if (!(strcmp(name, "takeoff"))) {
|
||||||
//cerr << "Adding takeoff: " << value << endl;
|
//cerr << "Adding takeoff: " << value << endl;
|
||||||
|
|
|
@ -237,7 +237,7 @@ void RunwayGroup::setActive(const string &aptId,
|
||||||
{
|
{
|
||||||
|
|
||||||
name = rwyList[j].getRwyList(i);
|
name = rwyList[j].getRwyList(i);
|
||||||
//cerr << "Name of Runway: " << name << endl;
|
//cerr << "Name of Runway: " << name;
|
||||||
if (globals->get_runways()->search( aptId,
|
if (globals->get_runways()->search( aptId,
|
||||||
name,
|
name,
|
||||||
&rwy))
|
&rwy))
|
||||||
|
@ -252,21 +252,22 @@ void RunwayGroup::setActive(const string &aptId,
|
||||||
hdgDiff *= ((2*M_PI)/360.0); // convert to radians
|
hdgDiff *= ((2*M_PI)/360.0); // convert to radians
|
||||||
crossWind = windSpeed * sin(hdgDiff);
|
crossWind = windSpeed * sin(hdgDiff);
|
||||||
tailWind = -windSpeed * cos(hdgDiff);
|
tailWind = -windSpeed * cos(hdgDiff);
|
||||||
//cerr << "Tailwind : " << tailWind << endl;
|
//cerr << ". Tailwind : " << tailWind;
|
||||||
//cerr << "Crosswnd : " << crossWind << endl;
|
//cerr << ". Crosswnd : " << crossWind;
|
||||||
if ((tailWind > maxTail) || (crossWind > maxCross))
|
if ((tailWind > maxTail) || (crossWind > maxCross))
|
||||||
{
|
{
|
||||||
//cerr << "Invalid : " << endl;
|
//cerr << ". [Invalid] " << endl;
|
||||||
validSelection = false;
|
validSelection = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//cerr << "Valid : " << endl;;
|
//cerr << ". [Valid] ";
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
SG_LOG( SG_GENERAL, SG_INFO, "Failed to find runway " << name << " at " << aptId );
|
SG_LOG( SG_GENERAL, SG_INFO, "Failed to find runway " << name << " at " << aptId );
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
//cerr << endl;
|
||||||
}
|
}
|
||||||
if (validSelection)
|
if (validSelection)
|
||||||
{
|
{
|
||||||
|
|
|
@ -135,6 +135,7 @@ private:
|
||||||
ScheduleTime comTimes; // Commercial Traffic;
|
ScheduleTime comTimes; // Commercial Traffic;
|
||||||
ScheduleTime genTimes; // General Aviation;
|
ScheduleTime genTimes; // General Aviation;
|
||||||
ScheduleTime milTimes; // Military Traffic;
|
ScheduleTime milTimes; // Military Traffic;
|
||||||
|
ScheduleTime ulTimes; // Ultralight Traffic
|
||||||
|
|
||||||
PreferenceList preferences;
|
PreferenceList preferences;
|
||||||
|
|
||||||
|
@ -157,6 +158,7 @@ public:
|
||||||
void setMilTimes(ScheduleTime& t) { milTimes = t; };
|
void setMilTimes(ScheduleTime& t) { milTimes = t; };
|
||||||
void setGenTimes(ScheduleTime& t) { genTimes = t; };
|
void setGenTimes(ScheduleTime& t) { genTimes = t; };
|
||||||
void setComTimes(ScheduleTime& t) { comTimes = t; };
|
void setComTimes(ScheduleTime& t) { comTimes = t; };
|
||||||
|
void setULTimes (ScheduleTime& t) { ulTimes = t; };
|
||||||
|
|
||||||
void addRunwayGroup(RunwayGroup& g) { preferences.push_back(g); };
|
void addRunwayGroup(RunwayGroup& g) { preferences.push_back(g); };
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue