From d5f81f0eacfb8ab5f7a7767716454a12e687ce6d Mon Sep 17 00:00:00 2001 From: James Turner Date: Thu, 2 Jun 2011 23:28:40 +0100 Subject: [PATCH] Push some of the ATIS logic into AirportDynamics, in preparation for ATIS being owned by the airport --- src/ATC/trafficcontrol.cxx | 2 +- src/ATCDCL/atis.cxx | 48 +++---------------------------- src/ATCDCL/atis.hxx | 4 +-- src/Airports/dynamics.cxx | 59 ++++++++++++++++++++++---------------- src/Airports/dynamics.hxx | 36 +++++++++++------------ src/Airports/simple.cxx | 22 +++++++------- 6 files changed, 66 insertions(+), 105 deletions(-) diff --git a/src/ATC/trafficcontrol.cxx b/src/ATC/trafficcontrol.cxx index 8079933b1..f2ccd33ee 100644 --- a/src/ATC/trafficcontrol.cxx +++ b/src/ATC/trafficcontrol.cxx @@ -494,7 +494,7 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId, getName() + "-Ground"; atisInformation = rec->getAircraft()->getTrafficRef()->getDepartureAirport()-> - getDynamics()->getAtisInformation(); + getDynamics()->getAtisSequence(); break; case 4: receiver = diff --git a/src/ATCDCL/atis.cxx b/src/ATCDCL/atis.cxx index b2f358620..460cc31a8 100644 --- a/src/ATCDCL/atis.cxx +++ b/src/ATCDCL/atis.cxx @@ -53,6 +53,7 @@ #include
#include
#include +#include #include "ATCutils.hxx" @@ -228,47 +229,6 @@ int Apt_US_CA(const string id) { return 0; } -// Add structure and map for storing a log of atis transmissions -// made in this session of FlightGear. This allows the callsign -// to be allocated correctly wrt time. -typedef struct { - double tstamp; - int sequence; -} atis_transmission_type; - -typedef std::map < std::string, atis_transmission_type > atis_log_type; -typedef atis_log_type::iterator atis_log_iterator; -typedef atis_log_type::const_iterator atis_log_const_iterator; - -static atis_log_type atislog; - -int FGATIS::GetAtisSequence( const string& apt_id, - const double tstamp, const int interval, const int special) -{ - atis_transmission_type tran; - - if(atislog.find(apt_id) == atislog.end()) { // New station - tran.tstamp = tstamp - interval; -// Random number between 0 and 25 inclusive, i.e. 26 equiprobable outcomes: - tran.sequence = int(sg_random() * LTRS); - atislog[apt_id] = tran; - //cout << "New ATIS station: " << apt_id << " seq-1: " - // << tran.sequence << endl; - } - -// calculate the appropriate identifier and update the log - tran = atislog[apt_id]; - - int delta = int((tstamp - tran.tstamp) / interval); - tran.tstamp += delta * interval; - if (special && !delta) delta++; // a "special" ATIS update is required - tran.sequence = (tran.sequence + delta) % LTRS; - atislog[apt_id] = tran; - //if (delta) cout << "New ATIS sequence: " << tran.sequence - // << " Delta: " << delta << endl; - return(tran.sequence + (delta ? 0 : LTRS*1000)); -} - // Generate the actual broadcast ATIS transmission. // Regen means regenerate the /current/ transmission. // Special means generate a new transmission, with a new sequence. @@ -280,12 +240,12 @@ int FGATIS::GenTransmission(const int regen, const int special) { string BRK = ".\n"; string PAUSE = " / "; - double tstamp = atof(fgGetString("sim/time/elapsed-sec")); int interval = _type == ATIS ? ATIS_interval // ATIS updated hourly : 2*minute; // AWOS updated more frequently - - int sequence = GetAtisSequence(ident, tstamp, interval, special); + + FGAirport* apt = FGAirport::findByIdent(ident); + int sequence = apt->getDynamics()->updateAtisSequence(interval, special); if (!regen && sequence > LTRS) { //xx if (msg_OK) cout << "ATIS: no change: " << sequence << endl; //xx msg_time = cur_time; diff --git a/src/ATCDCL/atis.hxx b/src/ATCDCL/atis.hxx index 189b11106..0c6124b8d 100644 --- a/src/ATCDCL/atis.hxx +++ b/src/ATCDCL/atis.hxx @@ -95,9 +95,7 @@ class FGATIS : public FGATC { void TreeOut(int msgOK); friend std::istream& operator>> ( std::istream&, FGATIS& ); - - int GetAtisSequence( const std::string& apt_id, - const double tstamp, const int interval, const int special); + }; typedef int (FGATIS::*int_getter)() const; diff --git a/src/Airports/dynamics.cxx b/src/Airports/dynamics.cxx index 11cb454b9..69f8c051d 100644 --- a/src/Airports/dynamics.cxx +++ b/src/Airports/dynamics.cxx @@ -36,6 +36,7 @@ #include
#include
#include +#include #include #include @@ -49,33 +50,11 @@ using std::random_shuffle; #include "dynamics.hxx" FGAirportDynamics::FGAirportDynamics(FGAirport * ap): -_ap(ap), rwyPrefs(ap), SIDs(ap) +_ap(ap), rwyPrefs(ap), SIDs(ap), + atisSequenceIndex(-1), + atisSequenceTimeStamp(0.0) { lastUpdate = 0; - - // For testing only. This needs to be refined when we move ATIS functionality over. - atisInformation = "Sierra"; -} - -// Note that the ground network should also be copied -FGAirportDynamics:: -FGAirportDynamics(const FGAirportDynamics & other):rwyPrefs(other. - rwyPrefs), -SIDs(other.SIDs) -{ - for (FGParkingVecConstIterator ip = other.parkings.begin(); - ip != other.parkings.end(); ip++) - parkings.push_back(*(ip)); - // rwyPrefs = other.rwyPrefs; - lastUpdate = other.lastUpdate; - - stringVecConstIterator il; - for (il = other.landing.begin(); il != other.landing.end(); il++) - landing.push_back(*il); - for (il = other.takeoff.begin(); il != other.takeoff.end(); il++) - takeoff.push_back(*il); - lastUpdate = other.lastUpdate; - atisInformation = other.atisInformation; } // Destructor @@ -540,3 +519,33 @@ FGAIFlightPlan *FGAirportDynamics::getSID(string activeRunway, { return SIDs.getBest(activeRunway, heading); } + +const std::string FGAirportDynamics::getAtisSequence() +{ + if (atisSequenceIndex == -1) { + updateAtisSequence(1, false); + } + + return GetPhoneticLetter(atisSequenceIndex); +} + +int FGAirportDynamics::updateAtisSequence(int interval, bool forceUpdate) +{ + double now = globals->get_sim_time_sec(); + if (atisSequenceIndex == -1) { + // first computation + atisSequenceTimeStamp = now; + atisSequenceIndex = rand() % LTRS; // random initial sequence letters + return atisSequenceIndex; + } + + int steps = static_cast((now - atisSequenceTimeStamp) / interval); + atisSequenceTimeStamp += (interval * steps); + if (forceUpdate && (steps == 0)) { + ++steps; // a "special" ATIS update is required + } + + atisSequenceIndex = (atisSequenceIndex + steps) % LTRS; + // return a huge value if no update occurred + return (atisSequenceIndex + (steps ? 0 : LTRS*1000)); +} diff --git a/src/Airports/dynamics.hxx b/src/Airports/dynamics.hxx index 609218218..cf862054e 100644 --- a/src/Airports/dynamics.hxx +++ b/src/Airports/dynamics.hxx @@ -22,24 +22,15 @@ #ifndef _AIRPORT_DYNAMICS_HXX_ #define _AIRPORT_DYNAMICS_HXX_ - -#ifndef __cplusplus -# error This library requires C++ -#endif - -#include - #include #include "parking.hxx" #include "groundnetwork.hxx" #include "runwayprefs.hxx" #include "sidstar.hxx" -//typedef vector DoubleVec; -//typedef vector::iterator DoubleVecIterator; - +// forward decls class FGAirport; - +class FGEnvironment; class FGAirportDynamics { @@ -55,7 +46,7 @@ private: FGApproachController approachController; time_t lastUpdate; - string prevTrafficType; + std::string prevTrafficType; stringVec landing; stringVec takeoff; stringVec milActive, comActive, genActive, ulActive; @@ -67,14 +58,14 @@ private: intVec freqTower; // intVec freqApproach; // - string atisInformation; - - string chooseRunwayFallback(); - bool innerGetActiveRunway(const string &trafficType, int action, string &runway, double heading); - string chooseRwyByHeading(stringVec rwys, double heading); + int atisSequenceIndex; + double atisSequenceTimeStamp; + + std::string chooseRunwayFallback(); + bool innerGetActiveRunway(const std::string &trafficType, int action, std::string &runway, double heading); + std::string chooseRwyByHeading(stringVec rwys, double heading); public: FGAirportDynamics(FGAirport* ap); - FGAirportDynamics(const FGAirportDynamics &other); ~FGAirportDynamics(); void addAwosFreq (int val) { freqAwos.push_back(val); }; @@ -118,8 +109,13 @@ public: FGTowerController *getTowerController() { return &towerController; }; FGApproachController *getApproachController() { return &approachController; }; - const string& getAtisInformation() { return atisInformation; }; - int getGroundFrequency(unsigned leg); //{ return freqGround.size() ? freqGround[0] : 0; }; + int getGroundFrequency(unsigned leg); + + /// get current ATIS sequence letter + const std::string getAtisSequence(); + + /// get the current ATIS sequence number, updating it if necessary + int updateAtisSequence(int interval, bool forceUpdate); void setRwyUse(const FGRunwayPreference& ref); }; diff --git a/src/Airports/simple.cxx b/src/Airports/simple.cxx index f4f3d1adb..9df1cb254 100644 --- a/src/Airports/simple.cxx +++ b/src/Airports/simple.cxx @@ -96,20 +96,18 @@ bool FGAirport::isHeliport() const FGAirportDynamics * FGAirport::getDynamics() { - if (_dynamics != 0) { + if (_dynamics) { return _dynamics; - } else { - //cerr << "Trying to load dynamics for " << _id << endl; - _dynamics = new FGAirportDynamics(this); - XMLLoader::load(_dynamics); - - FGRunwayPreference rwyPrefs(this); - XMLLoader::load(&rwyPrefs); - _dynamics->setRwyUse(rwyPrefs); + } + + _dynamics = new FGAirportDynamics(this); + XMLLoader::load(_dynamics); - //FGSidStar SIDs(this); - XMLLoader::load(_dynamics->getSIDs()); - } + FGRunwayPreference rwyPrefs(this); + XMLLoader::load(&rwyPrefs); + _dynamics->setRwyUse(rwyPrefs); + XMLLoader::load(_dynamics->getSIDs()); + return _dynamics; } -- 2.39.5