1
0
Fork 0

- 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:
durk 2007-07-21 11:05:20 +00:00
parent 3a0b1286ff
commit 721d849c79
5 changed files with 44 additions and 72 deletions

View file

@ -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,
&currentlyActive);
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;
}

View file

@ -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();

View file

@ -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;

View file

@ -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)
{

View file

@ -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); };
};