1
0
Fork 0

Start adding a better framework for ATC-initiated communication. There should be no user-visible change from this commit

This commit is contained in:
daveluff 2004-03-10 16:01:17 +00:00
parent 1e3a4f312b
commit 7a044b3faa
10 changed files with 144 additions and 68 deletions

View file

@ -24,6 +24,7 @@
#include <simgear/sound/soundmgr.hxx>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include "ATC.hxx"
@ -38,6 +39,18 @@ FGATC::FGATC() {
responseID = "";
responseReqd = false;
_type = INVALID;
_display = false;
_displaying = false;
// Transmission timing stuff
pending_transmission = "";
_timeout = 0;
_pending = false;
_callback_code = 0;
_transmit = false;
_transmitting = false;
_counter = 0.0;
_max_count = 5.0;
}
FGATC::~FGATC() {
@ -64,6 +77,54 @@ void FGATC::Update(double dt) {
_releaseCounter += dt;
}
}
// Transmission stuff cribbed from AIPlane.cxx
if(_pending) {
if(GetFreqClear()) {
//cout << "TUNED STATION FREQ CLEAR\n";
SetFreqInUse();
_pending = false;
_transmit = true;
_transmitting = false;
} else {
if(_timeout > 0.0) { // allows count down to be avoided by initially setting it to zero
_timeout -= dt;
if(_timeout <= 0.0) {
_timeout = 0.0;
_pending = false;
// timed out - don't render.
}
}
}
}
if(_transmit) {
_counter = 0.0;
_max_count = 5.0; // FIXME - hardwired length of message - need to calculate it!
//cout << "Transmission = " << pending_transmission << '\n';
if(_display) {
//Render(pending_transmission, ident, false);
// At the moment Render only works for ATIS
globals->get_ATC_display()->RegisterSingleMessage(pending_transmission);
}
// Run the callback regardless of whether on same freq as user or not.
//cout << "_callback_code = " << _callback_code << '\n';
if(_callback_code) {
ProcessCallback(_callback_code);
}
_transmit = false;
_transmitting = true;
} else if(_transmitting) {
if(_counter >= _max_count) {
//NoRender(plane.callsign); commented out since at the moment NoRender is designed just to stop repeating messages,
// and this will be primarily used on single messages.
_transmitting = false;
//if(tuned_station) tuned_station->NotifyTransmissionFinished(plane.callsign);
// TODO - need to let the plane the transmission is aimed at that it's finished.
}
_counter += dt;
}
}
void FGATC::ReceiveUserCallback(int code) {
@ -96,6 +157,36 @@ void FGATC::NotifyTransmissionFinished(string rid) {
}
}
void FGATC::Transmit(int callback_code) {
SG_LOG(SG_ATC, SG_INFO, "Transmit called by " << ident << " " << _type << ", msg = " << pending_transmission);
_pending = true;
_callback_code = callback_code;
_timeout = 0.0;
}
void FGATC::ConditionalTransmit(double timeout, int callback_code) {
SG_LOG(SG_ATC, SG_INFO, "Timed transmit called by " << ident << " " << _type << ", msg = " << pending_transmission);
_pending = true;
_callback_code = callback_code;
_timeout = timeout;
}
void FGATC::ImmediateTransmit(int callback_code) {
SG_LOG(SG_ATC, SG_INFO, "Immediate transmit called by " << ident << " " << _type << ", msg = " << pending_transmission);
if(_display) {
//Render(pending_transmission, ident, false);
// At the moment Render doesn't work except for ATIS
globals->get_ATC_display()->RegisterSingleMessage(pending_transmission);
}
if(callback_code) {
ProcessCallback(callback_code);
}
}
// Derived classes should override this.
void FGATC::ProcessCallback(int code) {
}
void FGATC::AddPlane(string pid) {
}
@ -103,12 +194,6 @@ int FGATC::RemovePlane() {
return 0;
}
void FGATC::SetDisplay() {
}
void FGATC::SetNoDisplay() {
}
void FGATC::SetData(ATCData* d) {
lon = d->lon;
lat = d->lat;

View file

@ -123,10 +123,10 @@ public:
virtual int RemovePlane();
// Indicate that this instance should output to the display if appropriate
virtual void SetDisplay();
inline void SetDisplay() { _display = true; }
// Indicate that this instance should not output to the display
virtual void SetNoDisplay();
inline void SetNoDisplay() { _display = false; }
// Generate the text of a message from its parameters and the current context.
virtual string GenText(const string& m, int c);
@ -186,6 +186,17 @@ protected:
// Requires the sound manager refname if audio, else "".
void NoRender(string refname);
// Transmit a message when channel becomes free of other dialog
void Transmit(int callback_code = 0);
// Transmit a message if channel becomes free within timeout (seconds). timeout of zero implies no limit
void ConditionalTransmit(double timeout, int callback_code = 0);
// Transmit regardless of other dialog on the channel eg emergency
void ImmediateTransmit(int callback_code = 0);
virtual void ProcessCallback(int code);
double lon, lat, elev;
double x, y, z;
int freq;
@ -199,7 +210,8 @@ protected:
bool playing; // Indicates a message in progress
bool voiceOK; // Flag - true if at least one voice has loaded OK
FGATCVoice* vPtr;
string pending_transmission; // derived classes set this string before calling Transmit(...)
bool freqClear; // Flag to indicate if the frequency is clear of ongoing dialog
bool receiving; // Flag to indicate we are receiving a transmission
bool responseReqd; // Flag to indicate we should be responding to a request/report
@ -213,6 +225,20 @@ protected:
bool _runReleaseCounter; // A timer for releasing the frequency after giving the message enough time to display
double _releaseTime;
double _releaseCounter;
bool _display; // Flag to indicate whether we should be outputting to the ATC display.
bool _displaying; // Flag to indicate whether we are outputting to the ATC display.
private:
// Transmission timing stuff.
bool _pending;
double _timeout;
int _callback_code; // A callback code to be notified and processed by the derived classes
// A value of zero indicates no callback required
bool _transmit; // we are to transmit
bool _transmitting; // we are transmitting
double _counter;
double _max_count;
};
inline istream&

View file

@ -77,7 +77,6 @@ FGApproach::~FGApproach(){
}
void FGApproach::Init() {
display = false;
}

View file

@ -117,8 +117,6 @@ class FGApproach : public FGATC {
double active_rw_lat;
double active_rw_len;
bool display; // Flag to indicate whether we should be outputting to the display.
bool displaying; // Flag to indicate whether we are outputting to the display.
int num_planes; // number of planes on the stack
PlaneApp planes[max_planes]; // Array of planes
string transmission;
@ -160,12 +158,6 @@ public:
// Remove plane from stack if out of range
int RemovePlane();
//Indicate that this instance should be outputting to the ATC display
inline void SetDisplay(void) {display = true;}
//Indicate that this instance should not be outputting to the ATC display
inline void SetNoDisplay(void) {display = false;}
inline double get_bucket() const { return bucket; }
inline int get_pnum() const { return num_planes; }
inline string get_trans_ident() { return trans_ident; }

View file

@ -54,8 +54,6 @@ SG_USING_STD(cout);
#include "ATCmgr.hxx"
FGATIS::FGATIS() :
display(false),
displaying(false),
transmission(""),
trans_ident(""),
atis_failed(false),
@ -72,8 +70,8 @@ FGATIS::~FGATIS() {
// Main update function - checks whether we are displaying or not the correct message.
void FGATIS::Update(double dt) {
if(display) {
if(displaying) {
if(_display) {
if(_displaying) {
// Check if we need to update the message
// - basically every hour and if the weather changes significantly at the station
//globals->get_ATC_display()->ChangeRepeatingMessage(transmission);
@ -82,14 +80,14 @@ void FGATIS::Update(double dt) {
UpdateTransmission();
//cout << "ATIS.CXX - calling ATCMgr to render transmission..." << endl;
Render(transmission, refname, true);
displaying = true;
_displaying = true;
}
} else {
// We shouldn't be displaying
if(displaying) {
if(_displaying) {
//cout << "ATIS.CXX - calling NoRender()..." << endl;
NoRender(refname);
displaying = false;
_displaying = false;
}
}
}

View file

@ -53,8 +53,6 @@ SG_USING_STD(string);
class FGATIS : public FGATC {
//atc_type type;
bool display; // Flag to indicate whether we should be outputting to the ATC display.
bool displaying; // Flag to indicate whether we are outputting to the ATC display.
string transmission; // The actual ATIS transmission
// This is not stored in default.atis but is generated
// from the prevailing conditions when required.
@ -80,12 +78,6 @@ class FGATIS : public FGATC {
//run the ATIS instance
void Update(double dt);
//Indicate that this instance should be outputting to the ATC display
inline void SetDisplay(void) {display = true;}
//Indicate that this instance should not be outputting to the ATC display
inline void SetNoDisplay(void) {display = false;}
//inline void set_type(const atc_type tp) {type = tp;}
inline string get_trans_ident() { return trans_ident; }
inline void set_refname(string r) { refname = r; }

View file

@ -54,7 +54,6 @@ a_path::a_path() {
FGGround::FGGround() {
ATCmgr = globals->get_ATC_mgr();
_type = GROUND;
display = false;
networkLoadOK = false;
ground_traffic.erase(ground_traffic.begin(), ground_traffic.end());
ground_traffic_itr = ground_traffic.begin();
@ -69,7 +68,6 @@ FGGround::FGGround() {
FGGround::FGGround(string id) {
ATCmgr = globals->get_ATC_mgr();
display = false;
networkLoadOK = false;
ground_traffic.erase(ground_traffic.begin(), ground_traffic.end());
ground_traffic_itr = ground_traffic.begin();
@ -274,7 +272,6 @@ bool FGGround::LoadNetwork() {
}
void FGGround::Init() {
display = false;
untowered = false;
// Figure out which is the active runway - TODO - it would be better to have ground call tower
@ -318,7 +315,7 @@ void FGGround::Update(double dt) {
trns += " taxi holding point runway "; // TODO - add the holding point name
// eg " taxi holding point G2 runway "
trns += ConvertRwyNumToSpokenString(activeRwy);
if(display) {
if(_display) {
globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
}
g->planePtr->RegisterTransmission(1); // cleared to taxi
@ -336,7 +333,7 @@ void FGGround::Update(double dt) {
char buf[10];
sprintf(buf, "%.2f", f);
trns += buf;
if(display) {
if(_display) {
globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
}
g->planePtr->RegisterTransmission(2); // contact tower

View file

@ -232,8 +232,6 @@ public:
void Update(double dt);
inline string get_trans_ident() { return trans_ident; }
inline void SetDisplay() {display = true;}
inline void SetNoDisplay() {display = false;}
// Contact ground control on arrival, assumed to request any gate
//void NewArrival(plane_rec plane);
@ -313,8 +311,6 @@ private:
SGPropertyNode* wind_from_hdg; //degrees
SGPropertyNode* wind_speed_knots; //knots
bool display; // Flag to indicate whether we should be outputting to the ATC display.
bool displaying; // Flag to indicate whether we are outputting to the ATC display.
// for failure modeling
string trans_ident; // transmitted ident
bool ground_failed; // ground failed?

View file

@ -231,7 +231,6 @@ FGTower::~FGTower() {
void FGTower::Init() {
//cout << "Initialising tower " << ident << '\n';
display = false;
// Pointers to user's position
user_lon_node = fgGetNode("/position/longitude-deg", true);
@ -256,7 +255,7 @@ void FGTower::Init() {
ground = new FGGround(ident);
separateGround = false;
ground->Init();
if(display) {
if(_display) {
ground->SetDisplay();
} else {
ground->SetNoDisplay();
@ -268,7 +267,7 @@ void FGTower::Init() {
ground = new FGGround(ident);
separateGround = false;
ground->Init();
if(display) {
if(_display) {
ground->SetDisplay();
} else {
ground->SetNoDisplay();
@ -280,7 +279,7 @@ void FGTower::Init() {
ground = new FGGround(ident);
separateGround = false;
ground->Init();
if(display) {
if(_display) {
ground->SetDisplay();
} else {
ground->SetNoDisplay();
@ -407,7 +406,8 @@ void FGTower::Update(double dt) {
// The display stuff might have to get more clever than this when not separate
// since the tower and ground might try communicating simultaneously even though
// they're mean't to be the same contoller/frequency!!
if(display) {
// We could also get rid of this by overloading FGATC's Set(No)Display() functions.
if(_display) {
ground->SetDisplay();
} else {
ground->SetNoDisplay();
@ -503,7 +503,7 @@ void FGTower::Respond() {
}
}
trns += ConvertRwyNumToSpokenString(activeRwy);
if(display) {
if(_display) {
globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
} else {
//cout << "Not displaying, trns was " << trns << '\n';
@ -526,7 +526,7 @@ void FGTower::Respond() {
t->clearedToLand = true;
if(!t->isUser) t->planePtr->RegisterTransmission(7);
}
if(display) {
if(_display) {
globals->get_ATC_display()->RegisterSingleMessage(trns);
}
if(t->isUser) {
@ -562,7 +562,7 @@ void FGTower::Respond() {
// Not currently sure under which circumstances we do or don't bother transmitting this.
string trns = t->plane.callsign;
trns += " hold position";
if(display) {
if(_display) {
globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
}
// TODO - add some idea of what traffic is blocking him.
@ -600,7 +600,7 @@ void FGTower::Respond() {
trns += " continue approach";
t->clearedToLand = false;
}
if(display && disp) {
if(_display && disp) {
globals->get_ATC_display()->RegisterSingleMessage(trns);
}
t->finalAcknowledged = true;
@ -634,7 +634,7 @@ void FGTower::ProcessRunwayVacatedReport(TowerPlaneRec* t) {
if(!t->isUser) t->planePtr->RegisterTransmission(6); // TODO - this is a mega-hack!!
}
//cout << "trns = " << trns << '\n';
if(display) {
if(_display) {
globals->get_ATC_display()->RegisterSingleMessage(trns);
}
// Maybe we should check that the plane really *has* vacated the runway!
@ -741,7 +741,7 @@ void FGTower::ClearHoldingPlane(TowerPlaneRec* t) {
departed = false;
timeSinceLastDeparture = 0.0;
}
if(display) {
if(_display) {
globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
}
//cout << "Done ClearHoldingPlane " << endl;
@ -961,9 +961,8 @@ void FGTower::CheckCircuitList(double dt) {
// For now this should stop the AI plane landing on top of the user.
string trns = t->plane.callsign;
trns += " GO AROUND TRAFFIC ON RUNWAY I REPEAT GO AROUND";
if(display) {
globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
}
pending_transmission = trns;
ImmediateTransmit();
t->instructedToGoAround = true;
t->clearedToLand = false;
// Assume it complies!!!
@ -1082,9 +1081,8 @@ void FGTower::CheckApproachList(double dt) {
// For now this should stop the AI plane landing on top of the user.
string trns = t->plane.callsign;
trns += " GO AROUND TRAFFIC ON RUNWAY I REPEAT GO AROUND";
if(display) {
globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
}
pending_transmission = trns;
ImmediateTransmit();
t->instructedToGoAround = true;
t->clearedToLand = false;
t->nextOnRwy = false; // But note this is recalculated so don't rely on it
@ -1159,9 +1157,8 @@ void FGTower::CheckDepartureList(double dt) {
if(distout > 10000) {
string trns = t->plane.callsign;
trns += " You are now clear of my airspace, good day";
if(display) {
globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
}
pending_transmission = trns;
Transmit();
if(t->isUser) {
// Change the communication options
RemoveAllUserDialogOptions();

View file

@ -168,9 +168,6 @@ public:
// Get the pattern direction of the active rwy.
inline int GetPatternDirection() { return rwy.patternDirection; }
inline void SetDisplay() { display = true; }
inline void SetNoDisplay() { display = false; }
inline string get_trans_ident() { return trans_ident; }
inline FGGround* GetGroundPtr() { return ground; }
@ -247,9 +244,6 @@ private:
unsigned int update_count; // Convienince counter for speading computational load over several updates
unsigned int update_count_max; // ditto.
bool display; // Flag to indicate whether we should be outputting to the ATC display.
bool displaying; // Flag to indicate whether we are outputting to the ATC display.
double timeSinceLastDeparture; // Time in seconds since last departure from active rwy.
bool departed; // set true when the above needs incrementing with time, false when it doesn't.