Progress towards AI/ATC communication without speaking all at once
This commit is contained in:
parent
ea0751eaa2
commit
380c69c8a0
7 changed files with 263 additions and 90 deletions
|
@ -319,7 +319,8 @@ void FGAILocalTraffic::Update(double dt) {
|
||||||
trns += buf;
|
trns += buf;
|
||||||
trns += " ";
|
trns += " ";
|
||||||
trns += plane.callsign;
|
trns += plane.callsign;
|
||||||
Transmit(trns);
|
pending_transmission = trns;
|
||||||
|
Transmit(30.0);
|
||||||
responseCounter = 0.0;
|
responseCounter = 0.0;
|
||||||
contactTower = false;
|
contactTower = false;
|
||||||
changeFreq = true;
|
changeFreq = true;
|
||||||
|
@ -414,7 +415,8 @@ void FGAILocalTraffic::Update(double dt) {
|
||||||
holdingShort = false;
|
holdingShort = false;
|
||||||
string trns = "Cleared for take-off ";
|
string trns = "Cleared for take-off ";
|
||||||
trns += plane.callsign;
|
trns += plane.callsign;
|
||||||
Transmit(trns);
|
pending_transmission = trns;
|
||||||
|
Transmit();
|
||||||
StartTaxi();
|
StartTaxi();
|
||||||
}
|
}
|
||||||
//cout << "^" << flush;
|
//cout << "^" << flush;
|
||||||
|
@ -476,7 +478,8 @@ void FGAILocalTraffic::Update(double dt) {
|
||||||
trns += plane.callsign;
|
trns += plane.callsign;
|
||||||
trns += " on apron parking request taxi for traffic pattern";
|
trns += " on apron parking request taxi for traffic pattern";
|
||||||
//cout << "trns = " << trns << endl;
|
//cout << "trns = " << trns << endl;
|
||||||
Transmit(trns);
|
pending_transmission = trns;
|
||||||
|
Transmit();
|
||||||
taxiRequestCleared = false;
|
taxiRequestCleared = false;
|
||||||
taxiRequestPending = true;
|
taxiRequestPending = true;
|
||||||
}
|
}
|
||||||
|
@ -504,6 +507,9 @@ void FGAILocalTraffic::Update(double dt) {
|
||||||
fgSetDouble("/AI/Local1/ortho-x", (ortho.ConvertToLocal(pos)).x());
|
fgSetDouble("/AI/Local1/ortho-x", (ortho.ConvertToLocal(pos)).x());
|
||||||
fgSetDouble("/AI/Local1/ortho-y", (ortho.ConvertToLocal(pos)).y());
|
fgSetDouble("/AI/Local1/ortho-y", (ortho.ConvertToLocal(pos)).y());
|
||||||
fgSetDouble("/AI/Local1/elev", pos.elev() * SG_METER_TO_FEET);
|
fgSetDouble("/AI/Local1/elev", pos.elev() * SG_METER_TO_FEET);
|
||||||
|
|
||||||
|
// And finally, call parent for transmission rendering
|
||||||
|
FGAIPlane::Update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAILocalTraffic::RegisterTransmission(int code) {
|
void FGAILocalTraffic::RegisterTransmission(int code) {
|
||||||
|
@ -947,7 +953,8 @@ void FGAILocalTraffic::TransmitPatternPositionReport(void) {
|
||||||
// And add the airport name again
|
// And add the airport name again
|
||||||
trns += tower->get_name();
|
trns += tower->get_name();
|
||||||
|
|
||||||
Transmit(trns);
|
pending_transmission = trns; // FIXME - make up pending_transmission natively
|
||||||
|
Transmit(90.0); // Assume a report of this leg will be invalid if we can't transmit within a minute and a half.
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAILocalTraffic::ExitRunway(Point3D orthopos) {
|
void FGAILocalTraffic::ExitRunway(Point3D orthopos) {
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
#include <simgear/math/point3d.hxx>
|
#include <simgear/math/point3d.hxx>
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
#include <simgear/sound/soundmgr.hxx>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
SG_USING_STD(string);
|
SG_USING_STD(string);
|
||||||
|
@ -32,12 +33,73 @@ SG_USING_STD(string);
|
||||||
|
|
||||||
FGAIPlane::FGAIPlane() {
|
FGAIPlane::FGAIPlane() {
|
||||||
leg = LEG_UNKNOWN;
|
leg = LEG_UNKNOWN;
|
||||||
|
tuned_station = NULL;
|
||||||
|
pending_transmission = "";
|
||||||
|
_timeout = 0;
|
||||||
|
_pending = false;
|
||||||
|
_callback = NULL;
|
||||||
|
_transmit = false;
|
||||||
|
_transmitting = false;
|
||||||
|
voice = false;
|
||||||
|
playing = false;
|
||||||
|
voiceOK = false;
|
||||||
|
vPtr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
FGAIPlane::~FGAIPlane() {
|
FGAIPlane::~FGAIPlane() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAIPlane::Update(double dt) {
|
void FGAIPlane::Update(double dt) {
|
||||||
|
if(_pending) {
|
||||||
|
if(tuned_station) {
|
||||||
|
if(tuned_station->FreqClear()) {
|
||||||
|
_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.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Not tuned to ATC - Just go ahead and transmit
|
||||||
|
_pending = false;
|
||||||
|
_transmit = true;
|
||||||
|
_transmitting = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This turns on rendering if on the same freq as the user
|
||||||
|
// TODO - turn it off if user switches to another freq - keep track of where in message we are etc.
|
||||||
|
if(_transmit) {
|
||||||
|
double user_freq0 = fgGetDouble("/radios/comm[0]/frequencies/selected-mhz");
|
||||||
|
//comm1 is not used yet.
|
||||||
|
_counter = 0.0;
|
||||||
|
_max_count = 5.0; // FIXME - hardwired length of message - need to calculate it!
|
||||||
|
|
||||||
|
if(freq == user_freq0) {
|
||||||
|
//cout << "Transmitting..." << endl;
|
||||||
|
// we are on the same frequency, so check distance to the user plane
|
||||||
|
if(1) {
|
||||||
|
// For now assume in range !!!
|
||||||
|
// TODO - implement range checking
|
||||||
|
Render(plane.callsign, false);
|
||||||
|
_transmit = false;
|
||||||
|
_transmitting = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(_transmitting) {
|
||||||
|
if(_counter >= _max_count) {
|
||||||
|
NoRender(plane.callsign);
|
||||||
|
_transmitting = false;
|
||||||
|
}
|
||||||
|
_counter += dt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAIPlane::Bank(double angle) {
|
void FGAIPlane::Bank(double angle) {
|
||||||
|
@ -55,23 +117,85 @@ void FGAIPlane::LevelWings(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAIPlane::Transmit(string msg) {
|
void FGAIPlane::Transmit(ai_plane_callback_t callback) {
|
||||||
SG_LOG(SG_ATC, SG_INFO, "Transmit called, msg = " << msg);
|
SG_LOG(SG_ATC, SG_INFO, "Transmit called for plane " << plane.callsign << ", msg = " << pending_transmission);
|
||||||
double user_freq0 = fgGetDouble("/radios/comm[0]/frequencies/selected-mhz");
|
_pending = true;
|
||||||
//double user_freq0 = ("/radios/comm[0]/frequencies/selected-mhz");
|
_callback = callback;
|
||||||
//comm1 is not used yet.
|
_timeout = 0.0;
|
||||||
|
}
|
||||||
if(freq == user_freq0) {
|
|
||||||
//cout << "Transmitting..." << endl;
|
void FGAIPlane::Transmit(double timeout, ai_plane_callback_t callback) {
|
||||||
// we are on the same frequency, so check distance to the user plane
|
SG_LOG(SG_ATC, SG_INFO, "Timed transmit called for plane " << plane.callsign << ", msg = " << pending_transmission);
|
||||||
if(1) {
|
_pending = true;
|
||||||
// For now (testing) assume in range !!!
|
_callback = callback;
|
||||||
// TODO - implement range checking
|
_timeout = timeout;
|
||||||
globals->get_ATC_display()->RegisterSingleMessage(msg, 0);
|
}
|
||||||
}
|
|
||||||
|
void FGAIPlane::ImmediateTransmit(ai_plane_callback_t callback) {
|
||||||
|
Render(plane.callsign, false);
|
||||||
|
if(_callback) {
|
||||||
|
(*_callback)();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render a transmission
|
||||||
|
// Outputs the transmission either on screen or as audio depending on user preference
|
||||||
|
// The refname is a string to identify this sample to the sound manager
|
||||||
|
// The repeating flag indicates whether the message should be repeated continuously or played once.
|
||||||
|
void FGAIPlane::Render(string refname, bool repeating) {
|
||||||
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
|
voice = (voiceOK && fgGetBool("/sim/sound/audible")
|
||||||
|
&& fgGetBool("/sim/sound/voice"));
|
||||||
|
if(voice) {
|
||||||
|
int len;
|
||||||
|
unsigned char* buf = vPtr->WriteMessage((char*)pending_transmission.c_str(), len, voice);
|
||||||
|
if(voice) {
|
||||||
|
SGSimpleSound* simple = new SGSimpleSound(buf, len);
|
||||||
|
// TODO - at the moment the volume is always set off comm1
|
||||||
|
// and can't be changed after the transmission has started.
|
||||||
|
simple->set_volume(5.0 * fgGetDouble("/radios/comm[0]/volume"));
|
||||||
|
globals->get_soundmgr()->add(simple, refname);
|
||||||
|
if(repeating) {
|
||||||
|
globals->get_soundmgr()->play_looped(refname);
|
||||||
|
} else {
|
||||||
|
globals->get_soundmgr()->play_once(refname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete[] buf;
|
||||||
|
}
|
||||||
|
#endif // ENABLE_AUDIO_SUPPORT
|
||||||
|
if(!voice) {
|
||||||
|
// first rip the underscores and the pause hints out of the string - these are for the convienience of the voice parser
|
||||||
|
for(unsigned int i = 0; i < pending_transmission.length(); ++i) {
|
||||||
|
if((pending_transmission.substr(i,1) == "_") || (pending_transmission.substr(i,1) == "/")) {
|
||||||
|
pending_transmission[i] = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
globals->get_ATC_display()->RegisterSingleMessage(pending_transmission, 0.0);
|
||||||
|
}
|
||||||
|
playing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Cease rendering a transmission.
|
||||||
|
void FGAIPlane::NoRender(string refname) {
|
||||||
|
if(playing) {
|
||||||
|
if(voice) {
|
||||||
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
|
globals->get_soundmgr()->stop(refname);
|
||||||
|
globals->get_soundmgr()->remove(refname);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
globals->get_ATC_display()->CancelRepeatingMessage();
|
||||||
|
}
|
||||||
|
playing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
void FGAIPlane::RegisterTransmission(int code) {
|
void FGAIPlane::RegisterTransmission(int code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ public:
|
||||||
virtual ~FGAIPlane();
|
virtual ~FGAIPlane();
|
||||||
|
|
||||||
// Run the internal calculations
|
// Run the internal calculations
|
||||||
virtual void Update(double dt);
|
void Update(double dt);
|
||||||
|
|
||||||
// Send a transmission *TO* the AIPlane.
|
// Send a transmission *TO* the AIPlane.
|
||||||
// FIXME int code is a hack - eventually this will receive Alexander's coded messages.
|
// FIXME int code is a hack - eventually this will receive Alexander's coded messages.
|
||||||
|
@ -85,6 +85,9 @@ public:
|
||||||
LandingType GetLandingOption();
|
LandingType GetLandingOption();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// callback type for derived classes to use
|
||||||
|
typedef void (*ai_plane_callback_t) (void);
|
||||||
|
|
||||||
PlaneRec plane;
|
PlaneRec plane;
|
||||||
|
|
||||||
double mag_hdg; // degrees - the heading that the physical aircraft is *pointing*
|
double mag_hdg; // degrees - the heading that the physical aircraft is *pointing*
|
||||||
|
@ -106,12 +109,47 @@ protected:
|
||||||
// Make radio transmission - this simply sends the transmission for physical rendering if the users
|
// Make radio transmission - this simply sends the transmission for physical rendering if the users
|
||||||
// aircraft is on the same frequency and in range. It is up to the derived classes to let ATC know
|
// aircraft is on the same frequency and in range. It is up to the derived classes to let ATC know
|
||||||
// what is going on.
|
// what is going on.
|
||||||
void Transmit(string msg);
|
string pending_transmission; // derived classes set this string before calling Transmit(...)
|
||||||
|
FGATC* tuned_station; // and this if they are tuned to ATC
|
||||||
|
|
||||||
|
// Transmit a message when channel becomes free of other dialog
|
||||||
|
void Transmit(ai_plane_callback_t callback = NULL);
|
||||||
|
|
||||||
|
// Transmit a message if channel becomes free within timeout (seconds). timeout of zero implies no limit
|
||||||
|
void Transmit(double timeout, ai_plane_callback_t callback = NULL);
|
||||||
|
|
||||||
|
// Transmit regardless of other dialog on the channel eg emergency
|
||||||
|
void ImmediateTransmit(ai_plane_callback_t callback = NULL);
|
||||||
|
|
||||||
void Bank(double angle);
|
void Bank(double angle);
|
||||||
void LevelWings(void);
|
void LevelWings(void);
|
||||||
|
|
||||||
PatternLeg leg;
|
PatternLeg leg;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _pending;
|
||||||
|
double _timeout;
|
||||||
|
ai_plane_callback_t _callback;
|
||||||
|
bool _transmit; // we are to transmit
|
||||||
|
bool _transmitting; // we are transmitting
|
||||||
|
double _counter;
|
||||||
|
double _max_count;
|
||||||
|
|
||||||
|
// Render a transmission (in string pending_transmission)
|
||||||
|
// Outputs the transmission either on screen or as audio depending on user preference
|
||||||
|
// The refname is a string to identify this sample to the sound manager
|
||||||
|
// The repeating flag indicates whether the message should be repeated continuously or played once.
|
||||||
|
void Render(string refname, bool repeating);
|
||||||
|
|
||||||
|
// Cease rendering a transmission.
|
||||||
|
// Requires the sound manager refname if audio, else "".
|
||||||
|
void NoRender(string refname);
|
||||||
|
|
||||||
|
// Rendering related stuff
|
||||||
|
bool voice; // Flag - true if we are using voice
|
||||||
|
bool playing; // Indicates a message in progress
|
||||||
|
bool voiceOK; // Flag - true if at least one voice has loaded OK
|
||||||
|
FGATCVoice* vPtr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _FG_AI_PLANE_HXX
|
#endif // _FG_AI_PLANE_HXX
|
||||||
|
|
|
@ -29,6 +29,10 @@
|
||||||
#include "ATC.hxx"
|
#include "ATC.hxx"
|
||||||
#include "ATCdisplay.hxx"
|
#include "ATCdisplay.hxx"
|
||||||
|
|
||||||
|
FGATC::FGATC() {
|
||||||
|
freqClear = true;
|
||||||
|
}
|
||||||
|
|
||||||
FGATC::~FGATC() {
|
FGATC::~FGATC() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +43,7 @@ void FGATC::AddPlane(string pid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int FGATC::RemovePlane() {
|
int FGATC::RemovePlane() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGATC::SetDisplay() {
|
void FGATC::SetDisplay() {
|
||||||
|
@ -49,7 +53,7 @@ void FGATC::SetNoDisplay() {
|
||||||
}
|
}
|
||||||
|
|
||||||
atc_type FGATC::GetType() {
|
atc_type FGATC::GetType() {
|
||||||
return INVALID;
|
return INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGATC::SetData(ATCData* d) {
|
void FGATC::SetData(ATCData* d) {
|
||||||
|
@ -70,9 +74,9 @@ void FGATC::SetData(ATCData* d) {
|
||||||
// The refname is a string to identify this sample to the sound manager
|
// The refname is a string to identify this sample to the sound manager
|
||||||
// The repeating flag indicates whether the message should be repeated continuously or played once.
|
// The repeating flag indicates whether the message should be repeated continuously or played once.
|
||||||
void FGATC::Render(string msg, string refname, bool repeating) {
|
void FGATC::Render(string msg, string refname, bool repeating) {
|
||||||
#ifdef ENABLE_AUDIO_SUPPORT
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
voice = (voiceOK && fgGetBool("/sim/sound/audible")
|
voice = (voiceOK && fgGetBool("/sim/sound/audible")
|
||||||
&& fgGetBool("/sim/sound/voice"));
|
&& fgGetBool("/sim/sound/voice"));
|
||||||
if(voice) {
|
if(voice) {
|
||||||
int len;
|
int len;
|
||||||
unsigned char* buf = vPtr->WriteMessage((char*)msg.c_str(), len, voice);
|
unsigned char* buf = vPtr->WriteMessage((char*)msg.c_str(), len, voice);
|
||||||
|
@ -90,7 +94,7 @@ void FGATC::Render(string msg, string refname, bool repeating) {
|
||||||
}
|
}
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
}
|
}
|
||||||
#endif // ENABLE_AUDIO_SUPPORT
|
#endif // ENABLE_AUDIO_SUPPORT
|
||||||
if(!voice) {
|
if(!voice) {
|
||||||
// first rip the underscores and the pause hints out of the string - these are for the convienience of the voice parser
|
// first rip the underscores and the pause hints out of the string - these are for the convienience of the voice parser
|
||||||
for(unsigned int i = 0; i < msg.length(); ++i) {
|
for(unsigned int i = 0; i < msg.length(); ++i) {
|
||||||
|
@ -108,10 +112,10 @@ void FGATC::Render(string msg, string refname, bool repeating) {
|
||||||
void FGATC::NoRender(string refname) {
|
void FGATC::NoRender(string refname) {
|
||||||
if(playing) {
|
if(playing) {
|
||||||
if(voice) {
|
if(voice) {
|
||||||
#ifdef ENABLE_AUDIO_SUPPORT
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
globals->get_soundmgr()->stop(refname);
|
globals->get_soundmgr()->stop(refname);
|
||||||
globals->get_soundmgr()->remove(refname);
|
globals->get_soundmgr()->remove(refname);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
globals->get_ATC_display()->CancelRepeatingMessage();
|
globals->get_ATC_display()->CancelRepeatingMessage();
|
||||||
}
|
}
|
||||||
|
@ -120,21 +124,14 @@ void FGATC::NoRender(string refname) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream& operator << (ostream& os, atc_type atc) {
|
ostream& operator << (ostream& os, atc_type atc) {
|
||||||
switch(atc) {
|
switch(atc) {
|
||||||
case(INVALID):
|
case(INVALID): return(os << "INVALID");
|
||||||
return(os << "INVALID");
|
case(ATIS): return(os << "ATIS");
|
||||||
case(ATIS):
|
case(GROUND): return(os << "GROUND");
|
||||||
return(os << "ATIS");
|
case(TOWER): return(os << "TOWER");
|
||||||
case(GROUND):
|
case(APPROACH): return(os << "APPROACH");
|
||||||
return(os << "GROUND");
|
case(DEPARTURE): return(os << "DEPARTURE");
|
||||||
case(TOWER):
|
case(ENROUTE): return(os << "ENROUTE");
|
||||||
return(os << "TOWER");
|
}
|
||||||
case(APPROACH):
|
return(os << "ERROR - Unknown switch in atc_type operator << ");
|
||||||
return(os << "APPROACH");
|
|
||||||
case(DEPARTURE):
|
|
||||||
return(os << "DEPARTURE");
|
|
||||||
case(ENROUTE):
|
|
||||||
return(os << "ENROUTE");
|
|
||||||
}
|
|
||||||
return(os << "ERROR - Unknown switch in atc_type operator << ");
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,13 +58,13 @@ struct PlaneRec {
|
||||||
// Possible types of ATC type that the radios may be tuned to.
|
// Possible types of ATC type that the radios may be tuned to.
|
||||||
// INVALID implies not tuned in to anything.
|
// INVALID implies not tuned in to anything.
|
||||||
enum atc_type {
|
enum atc_type {
|
||||||
INVALID,
|
INVALID,
|
||||||
ATIS,
|
ATIS,
|
||||||
GROUND,
|
GROUND,
|
||||||
TOWER,
|
TOWER,
|
||||||
APPROACH,
|
APPROACH,
|
||||||
DEPARTURE,
|
DEPARTURE,
|
||||||
ENROUTE
|
ENROUTE
|
||||||
};
|
};
|
||||||
|
|
||||||
// DCL - new experimental ATC data store
|
// DCL - new experimental ATC data store
|
||||||
|
@ -98,28 +98,39 @@ struct RunwayDetails {
|
||||||
ostream& operator << (ostream& os, atc_type atc);
|
ostream& operator << (ostream& os, atc_type atc);
|
||||||
|
|
||||||
class FGATC {
|
class FGATC {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual ~FGATC();
|
FGATC();
|
||||||
|
virtual ~FGATC();
|
||||||
// Run the internal calculations
|
|
||||||
virtual void Update(double dt);
|
// Run the internal calculations
|
||||||
|
virtual void Update(double dt);
|
||||||
// Add plane to a stack
|
|
||||||
virtual void AddPlane(string pid);
|
// Add plane to a stack
|
||||||
|
virtual void AddPlane(string pid);
|
||||||
// Remove plane from stack
|
|
||||||
virtual int RemovePlane();
|
// Remove plane from stack
|
||||||
|
virtual int RemovePlane();
|
||||||
// Indicate that this instance should output to the display if appropriate
|
|
||||||
virtual void SetDisplay();
|
// Indicate that this instance should output to the display if appropriate
|
||||||
|
virtual void SetDisplay();
|
||||||
// Indicate that this instance should not output to the display
|
|
||||||
virtual void SetNoDisplay();
|
// Indicate that this instance should not output to the display
|
||||||
|
virtual void SetNoDisplay();
|
||||||
// Return the type of ATC station that the class represents
|
|
||||||
virtual atc_type GetType();
|
// Returns true if OK to transmit on this frequency
|
||||||
|
inline bool FreqClear() { return freqClear; }
|
||||||
|
// Indicate that the frequency is in use
|
||||||
|
inline void FreqInUse() { freqClear = false; }
|
||||||
|
// Under development!!
|
||||||
|
// The idea is that AI traffic or the user ATC dialog box calls FreqInUse() when they begin transmitting,
|
||||||
|
// and that the tower control sets freqClear back to true following a reply.
|
||||||
|
// AI traffic should check FreqClear() is true prior to transmitting.
|
||||||
|
// The user will just have to wait for a gap in dialog as in real life.
|
||||||
|
|
||||||
|
// Return the type of ATC station that the class represents
|
||||||
|
virtual atc_type GetType();
|
||||||
|
|
||||||
// Set the core ATC data
|
// Set the core ATC data
|
||||||
void SetData(ATCData* d);
|
void SetData(ATCData* d);
|
||||||
|
@ -145,18 +156,18 @@ public:
|
||||||
inline const char* get_name() {return name.c_str();}
|
inline const char* get_name() {return name.c_str();}
|
||||||
inline void set_name(const string nm) {name = nm;}
|
inline void set_name(const string nm) {name = nm;}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Render a transmission
|
// Render a transmission
|
||||||
// Outputs the transmission either on screen or as audio depending on user preference
|
// Outputs the transmission either on screen or as audio depending on user preference
|
||||||
// The refname is a string to identify this sample to the sound manager
|
// The refname is a string to identify this sample to the sound manager
|
||||||
// The repeating flag indicates whether the message should be repeated continuously or played once.
|
// The repeating flag indicates whether the message should be repeated continuously or played once.
|
||||||
void Render(string msg, string refname, bool repeating);
|
void Render(string msg, string refname, bool repeating);
|
||||||
|
|
||||||
// Cease rendering a transmission.
|
// Cease rendering a transmission.
|
||||||
// Requires the sound manager refname if audio, else "".
|
// Requires the sound manager refname if audio, else "".
|
||||||
void NoRender(string refname);
|
void NoRender(string refname);
|
||||||
|
|
||||||
double lon, lat, elev;
|
double lon, lat, elev;
|
||||||
double x, y, z;
|
double x, y, z;
|
||||||
int freq;
|
int freq;
|
||||||
|
@ -169,6 +180,8 @@ protected:
|
||||||
bool playing; // Indicates a message in progress
|
bool playing; // Indicates a message in progress
|
||||||
bool voiceOK; // Flag - true if at least one voice has loaded OK
|
bool voiceOK; // Flag - true if at least one voice has loaded OK
|
||||||
FGATCVoice* vPtr;
|
FGATCVoice* vPtr;
|
||||||
|
|
||||||
|
bool freqClear; // Flag to indicate if the frequency is clear of ongoing dialog
|
||||||
};
|
};
|
||||||
|
|
||||||
inline istream&
|
inline istream&
|
||||||
|
@ -177,7 +190,7 @@ operator >> ( istream& fin, ATCData& a )
|
||||||
double f;
|
double f;
|
||||||
char ch;
|
char ch;
|
||||||
char tp;
|
char tp;
|
||||||
|
|
||||||
fin >> tp;
|
fin >> tp;
|
||||||
|
|
||||||
switch(tp) {
|
switch(tp) {
|
||||||
|
@ -201,7 +214,7 @@ operator >> ( istream& fin, ATCData& a )
|
||||||
a.type = INVALID;
|
a.type = INVALID;
|
||||||
return fin >> skipeol;
|
return fin >> skipeol;
|
||||||
}
|
}
|
||||||
|
|
||||||
fin >> a.lat >> a.lon >> a.elev >> f >> a.range
|
fin >> a.lat >> a.lon >> a.elev >> f >> a.range
|
||||||
>> a.ident;
|
>> a.ident;
|
||||||
|
|
||||||
|
|
|
@ -1248,6 +1248,10 @@ void FGTower::ReportRunwayVacated(string ID) {
|
||||||
//cout << "Report Runway Vacated Called...\n";
|
//cout << "Report Runway Vacated Called...\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGTower::ReportDownwind(string ID) {
|
||||||
|
// Tell the plane reporting what number she is in the circuit
|
||||||
|
}
|
||||||
|
|
||||||
ostream& operator << (ostream& os, tower_traffic_type ttt) {
|
ostream& operator << (ostream& os, tower_traffic_type ttt) {
|
||||||
switch(ttt) {
|
switch(ttt) {
|
||||||
case(CIRCUIT): return(os << "CIRCUIT");
|
case(CIRCUIT): return(os << "CIRCUIT");
|
||||||
|
|
|
@ -124,6 +124,7 @@ public:
|
||||||
void ReportGoingAround(string ID);
|
void ReportGoingAround(string ID);
|
||||||
void ReportRunwayVacated(string ID);
|
void ReportRunwayVacated(string ID);
|
||||||
void ReportReadyForDeparture(string ID);
|
void ReportReadyForDeparture(string ID);
|
||||||
|
void ReportDownwind(string ID);
|
||||||
|
|
||||||
// Contact tower when at a hold short for departure - for now we'll assume plane - maybe vehicles might want to cross runway eventually?
|
// Contact tower when at a hold short for departure - for now we'll assume plane - maybe vehicles might want to cross runway eventually?
|
||||||
void ContactAtHoldShort(PlaneRec plane, FGAIPlane* requestee, tower_traffic_type operation);
|
void ContactAtHoldShort(PlaneRec plane, FGAIPlane* requestee, tower_traffic_type operation);
|
||||||
|
@ -146,15 +147,6 @@ public:
|
||||||
bool GetCrosswindConstraint(double& cpos);
|
bool GetCrosswindConstraint(double& cpos);
|
||||||
bool GetDownwindConstraint(double& dpos);
|
bool GetDownwindConstraint(double& dpos);
|
||||||
bool GetBaseConstraint(double& bpos);
|
bool GetBaseConstraint(double& bpos);
|
||||||
|
|
||||||
// Returns true if OK to transmit on this frequency
|
|
||||||
inline bool FreqClear() { return freqClear; }
|
|
||||||
// Indicate that the frequency is in use
|
|
||||||
inline void FreqInUse() { freqClear = false; }
|
|
||||||
// The idea is that AI traffic or the user ATC dialog box calls FreqInUse() when they begin transmitting,
|
|
||||||
// and that the tower control sets freqClear back to true following a reply.
|
|
||||||
// AI traffic should check FreqClear() is true prior to transmitting.
|
|
||||||
// The user will just have to wait for a gap in dialog as in real life.
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FGATCMgr* ATCmgr;
|
FGATCMgr* ATCmgr;
|
||||||
|
@ -198,8 +190,6 @@ private:
|
||||||
bool display; // Flag to indicate whether we should be outputting to the ATC display.
|
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.
|
bool displaying; // Flag to indicate whether we are outputting to the ATC display.
|
||||||
|
|
||||||
bool freqClear; // Flag to indicate if the frequency is clear of ongoing dialog
|
|
||||||
|
|
||||||
double timeSinceLastDeparture; // Time in seconds since last departure from active rwy.
|
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.
|
bool departed; // set true when the above needs incrementing with time, false when it doesn't.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue