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; 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,
&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 // 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;
} }

View file

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

View file

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

View file

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

View file

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