Push some of the ATIS logic into AirportDynamics, in preparation for ATIS being owned by the airport
This commit is contained in:
parent
b0985c6b02
commit
d5f81f0eac
6 changed files with 66 additions and 105 deletions
|
@ -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 =
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include <Main/fg_props.hxx>
|
||||
#include <Main/globals.hxx>
|
||||
#include <Airports/runways.hxx>
|
||||
#include <Airports/dynamics.hxx>
|
||||
|
||||
|
||||
#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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <Main/globals.hxx>
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <Airports/runways.hxx>
|
||||
#include <ATCDCL/ATCutils.hxx>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -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<int>((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));
|
||||
}
|
||||
|
|
|
@ -22,24 +22,15 @@
|
|||
#ifndef _AIRPORT_DYNAMICS_HXX_
|
||||
#define _AIRPORT_DYNAMICS_HXX_
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
#include <simgear/xml/easyxml.hxx>
|
||||
|
||||
#include <ATC/trafficcontrol.hxx>
|
||||
#include "parking.hxx"
|
||||
#include "groundnetwork.hxx"
|
||||
#include "runwayprefs.hxx"
|
||||
#include "sidstar.hxx"
|
||||
|
||||
//typedef vector<float> DoubleVec;
|
||||
//typedef vector<float>::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; // </TOWER>
|
||||
intVec freqApproach; // </APPROACH>
|
||||
|
||||
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);
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
_dynamics = new FGAirportDynamics(this);
|
||||
XMLLoader::load(_dynamics);
|
||||
|
||||
FGRunwayPreference rwyPrefs(this);
|
||||
XMLLoader::load(&rwyPrefs);
|
||||
_dynamics->setRwyUse(rwyPrefs);
|
||||
|
||||
//FGSidStar SIDs(this);
|
||||
XMLLoader::load(_dynamics->getSIDs());
|
||||
}
|
||||
FGRunwayPreference rwyPrefs(this);
|
||||
XMLLoader::load(&rwyPrefs);
|
||||
_dynamics->setRwyUse(rwyPrefs);
|
||||
XMLLoader::load(_dynamics->getSIDs());
|
||||
|
||||
return _dynamics;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue