X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=src%2FAirports%2Fdynamics.cxx;h=a7d450ccfdce240d84f655ec5439cafee0f19758;hb=721d849c79d7f90afcceac7a5fe7057cc95d8bcf;hp=70bc8505698492e5a59b3affa5d9ef0d0c6ffb93;hpb=31621f50af4549045db8b458952d3f6fb78dfc42;p=flightgear.git diff --git a/src/Airports/dynamics.cxx b/src/Airports/dynamics.cxx index 70bc85056..a7d450ccf 100644 --- a/src/Airports/dynamics.cxx +++ b/src/Airports/dynamics.cxx @@ -14,7 +14,7 @@ // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ @@ -39,7 +39,6 @@ #include
#include
#include -#include #include STL_STRING #include @@ -49,34 +48,26 @@ SG_USING_STD(vector); SG_USING_STD(sort); SG_USING_STD(random_shuffle); -#include "parking.hxx" -#include "groundnetwork.hxx" -#include "runwayprefs.hxx" +#include "simple.hxx" #include "dynamics.hxx" -/********** FGAirport Dynamics *********************************************/ - -FGAirportDynamics::FGAirportDynamics(double lat, double lon, double elev, string id) : - _latitude(lat), - _longitude(lon), - _elevation(elev), - _id(id) -{ +FGAirportDynamics::FGAirportDynamics(FGAirport* ap) : + _ap(ap), rwyPrefs(ap) { lastUpdate = 0; for (int i = 0; i < 10; i++) - { - avWindHeading [i] = 0; - avWindSpeed [i] = 0; - } + { + //avWindHeading [i] = 0; + //avWindSpeed [i] = 0; + } } - // Note that the ground network should also be copied -FGAirportDynamics::FGAirportDynamics(const FGAirportDynamics& other) +FGAirportDynamics::FGAirportDynamics(const FGAirportDynamics& other) : + rwyPrefs(other.rwyPrefs) { for (FGParkingVecConstIterator ip= other.parkings.begin(); ip != other.parkings.end(); ip++) parkings.push_back(*(ip)); - rwyPrefs = other.rwyPrefs; + // rwyPrefs = other.rwyPrefs; lastUpdate = other.lastUpdate; stringVecConstIterator il; @@ -87,15 +78,14 @@ 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]; } } // Destructor FGAirportDynamics::~FGAirportDynamics() { - } @@ -113,6 +103,8 @@ void FGAirportDynamics::init() // add the gate positions to the ground network. groundNetwork.addNodes(&parkings); groundNetwork.init(); + groundNetwork.setTowerController(&towerController); + groundNetwork.setParent(_ap); } bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, double *heading, int *gateId, double rad, const string &flType, const string &acType, const string &airline) @@ -134,9 +126,9 @@ bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, double *he if (parkings.begin() == parkings.end()) { - //cerr << "Could not find parking spot at " << _id << endl; - *lat = _latitude; - *lon = _longitude; + //cerr << "Could not find parking spot at " << _ap->getId() << endl; + *lat = _ap->getLatitude(); + *lon = _ap->getLongitude(); *heading = 0; found = true; } @@ -165,11 +157,19 @@ bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, double *he continue; } else // Airline code doesn't match - if (i->getCodes().find(airline, 0) == string::npos) - { - available = false; - continue; - } + { + //cerr << "Code = " << airline << ": Codes " << i->getCodes(); + if (i->getCodes().find(airline, 0) == string::npos) + { + available = false; + //cerr << "Unavailable" << endl; + continue; + } + else + { + //cerr << "Available" << endl; + } + } // Type doesn't match if (i->getType() != flType) { @@ -266,13 +266,13 @@ bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, double *he } if (!found) { - //cerr << "Traffic overflow at" << _id + //cerr << "Traffic overflow at" << _ap->getId() // << ". flType = " << flType // << ". airline = " << airline // << " Radius = " <getLatitude(); + *lon = _ap->getLongitude(); *heading = 0; *gateId = -1; //exit(1); @@ -284,8 +284,8 @@ void FGAirportDynamics::getParking (int id, double *lat, double* lon, double *he { if (id < 0) { - *lat = _latitude; - *lon = _longitude; + *lat = _ap->getLatitude(); + *lon = _ap->getLongitude(); *heading = 0; } else @@ -297,7 +297,7 @@ void FGAirportDynamics::getParking (int id, double *lat, double* lon, double *he { *lat = i->getLatitude(); *lon = i->getLongitude(); - *heading = i->getLongitude(); + *heading = i->getHeading(); } } } @@ -333,119 +333,6 @@ void FGAirportDynamics::releaseParking(int id) } } -void FGAirportDynamics::startXML () { - //cout << "Start XML" << endl; -} - -void FGAirportDynamics::endXML () { - //cout << "End XML" << endl; -} - -void FGAirportDynamics::startElement (const char * name, const XMLAttributes &atts) { - // const char *attval; - FGParking park; - FGTaxiNode taxiNode; - FGTaxiSegment taxiSegment; - int index = 0; - taxiSegment.setIndex(index); - //cout << "Start element " << name << endl; - string attname; - string value; - string gateName; - string gateNumber; - string lat; - string lon; - if (name == string("Parking")) - { - for (int i = 0; i < atts.size(); i++) - { - //cout << " " << atts.getName(i) << '=' << atts.getValue(i) << endl; - attname = atts.getName(i); - if (attname == string("index")) - park.setIndex(atoi(atts.getValue(i))); - else if (attname == string("type")) - park.setType(atts.getValue(i)); - else if (attname == string("name")) - gateName = atts.getValue(i); - else if (attname == string("number")) - gateNumber = atts.getValue(i); - else if (attname == string("lat")) - park.setLatitude(atts.getValue(i)); - else if (attname == string("lon")) - park.setLongitude(atts.getValue(i)); - else if (attname == string("heading")) - park.setHeading(atof(atts.getValue(i))); - else if (attname == string("radius")) { - string radius = atts.getValue(i); - if (radius.find("M") != string::npos) - radius = radius.substr(0, radius.find("M",0)); - //cerr << "Radius " << radius < 600) || trafficType != prevTrafficType) + if ((abs((long)(dayStart - lastUpdate)) > 600) || trafficType != prevTrafficType) { landing.clear(); takeoff.clear(); - //lastUpdate = dayStart; + lastUpdate = dayStart; prevTrafficType = trafficType; FGEnvironment @@ -486,65 +373,15 @@ 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" << _id << endl; + //cerr << "finding active Runway for" << _ap->getId() << endl; //cerr << "Nr of seconds since day start << " << dayStart << endl; + ScheduleTime *currSched; //cerr << "A"<< endl; currSched = rwyPrefs.getSchedule(trafficType.c_str()); if (!(currSched)) - return; + return; //cerr << "B"<< endl; scheduleName = currSched->getName(dayStart); maxTail = currSched->getTailWind (); @@ -558,9 +395,34 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s if (!(currRunwayGroup)) return; nrActiveRunways = currRunwayGroup->getNrActiveRunways(); - //cerr << "Nr of Active Runways = " << nrActiveRunways << endl; - currRunwayGroup->setActive(_id, averageWindSpeed, averageWindHeading, maxTail, maxCross); + + // 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); + + // Note that I SHOULD keep multiple lists in memory, one for + // general aviation, one for commercial and one for military + // traffic. + 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 @@ -568,20 +430,26 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s 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; } } + //cerr << endl; } if (action == 1) // takeoff { 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 @@ -600,9 +468,8 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s { //fallback runway = chooseRunwayFallback(); } - } - - //runway = globals->get_runways()->search(_id, int(windHeading)); + } + //runway = globals->get_runways()->search(_ap->getId(), int(windHeading)); //cerr << "Seleceted runway: " << runway << endl; } } @@ -622,5 +489,25 @@ string FGAirportDynamics::chooseRunwayFallback() //which is consistent with Flightgear's initial setup. } - return globals->get_runways()->search(_id, int(windHeading)); + return globals->get_runways()->search(_ap->getId(), int(windHeading)); +} + +void FGAirportDynamics::addParking(FGParking& park) { + parkings.push_back(park); +} + +double FGAirportDynamics::getLatitude() const { + return _ap->getLatitude(); +} + +double FGAirportDynamics::getLongitude() const { + return _ap->getLongitude(); +} + +double FGAirportDynamics::getElevation() const { + return _ap->getElevation(); +} + +const string& FGAirportDynamics::getId() const { + return _ap->getId(); }