Tweaks to the ATC/AI interaction framework
This commit is contained in:
parent
ee8eb7d6fe
commit
d5d9723d9b
4 changed files with 55 additions and 18 deletions
|
@ -37,7 +37,7 @@ FGAIPlane::FGAIPlane() {
|
||||||
pending_transmission = "";
|
pending_transmission = "";
|
||||||
_timeout = 0;
|
_timeout = 0;
|
||||||
_pending = false;
|
_pending = false;
|
||||||
_callback = NULL;
|
_callback_code = 0;
|
||||||
_transmit = false;
|
_transmit = false;
|
||||||
_transmitting = false;
|
_transmitting = false;
|
||||||
voice = false;
|
voice = false;
|
||||||
|
@ -53,6 +53,7 @@ void FGAIPlane::Update(double dt) {
|
||||||
if(_pending) {
|
if(_pending) {
|
||||||
if(tuned_station) {
|
if(tuned_station) {
|
||||||
if(tuned_station->GetFreqClear()) {
|
if(tuned_station->GetFreqClear()) {
|
||||||
|
tuned_station->SetFreqInUse();
|
||||||
_pending = false;
|
_pending = false;
|
||||||
_transmit = true;
|
_transmit = true;
|
||||||
_transmitting = false;
|
_transmitting = false;
|
||||||
|
@ -82,6 +83,7 @@ void FGAIPlane::Update(double dt) {
|
||||||
_counter = 0.0;
|
_counter = 0.0;
|
||||||
_max_count = 5.0; // FIXME - hardwired length of message - need to calculate it!
|
_max_count = 5.0; // FIXME - hardwired length of message - need to calculate it!
|
||||||
|
|
||||||
|
//cout << "Transmission = " << pending_transmission << '\n';
|
||||||
if(freq == user_freq0 || freq == user_freq1) {
|
if(freq == user_freq0 || freq == user_freq1) {
|
||||||
//cout << "Transmitting..." << endl;
|
//cout << "Transmitting..." << endl;
|
||||||
// we are on the same frequency, so check distance to the user plane
|
// we are on the same frequency, so check distance to the user plane
|
||||||
|
@ -93,10 +95,18 @@ void FGAIPlane::Update(double dt) {
|
||||||
_transmitting = true;
|
_transmitting = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
} else if(_transmitting) {
|
} else if(_transmitting) {
|
||||||
if(_counter >= _max_count) {
|
if(_counter >= _max_count) {
|
||||||
NoRender(plane.callsign);
|
NoRender(plane.callsign);
|
||||||
_transmitting = false;
|
_transmitting = false;
|
||||||
|
// For now we'll let ATC decide whether to respond
|
||||||
|
//if(tuned_station) tuned_station->SetResponseReqd(plane.callsign);
|
||||||
|
if(tuned_station) tuned_station->NotifyTransmissionFinished(plane.callsign);
|
||||||
}
|
}
|
||||||
_counter += dt;
|
_counter += dt;
|
||||||
}
|
}
|
||||||
|
@ -117,27 +127,31 @@ void FGAIPlane::LevelWings(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAIPlane::Transmit(ai_plane_callback_t callback) {
|
void FGAIPlane::Transmit(int callback_code) {
|
||||||
SG_LOG(SG_ATC, SG_INFO, "Transmit called for plane " << plane.callsign << ", msg = " << pending_transmission);
|
SG_LOG(SG_ATC, SG_INFO, "Transmit called for plane " << plane.callsign << ", msg = " << pending_transmission);
|
||||||
_pending = true;
|
_pending = true;
|
||||||
_callback = callback;
|
_callback_code = callback_code;
|
||||||
_timeout = 0.0;
|
_timeout = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAIPlane::Transmit(double timeout, ai_plane_callback_t callback) {
|
void FGAIPlane::ConditionalTransmit(double timeout, int callback_code) {
|
||||||
SG_LOG(SG_ATC, SG_INFO, "Timed transmit called for plane " << plane.callsign << ", msg = " << pending_transmission);
|
SG_LOG(SG_ATC, SG_INFO, "Timed transmit called for plane " << plane.callsign << ", msg = " << pending_transmission);
|
||||||
_pending = true;
|
_pending = true;
|
||||||
_callback = callback;
|
_callback_code = callback_code;
|
||||||
_timeout = timeout;
|
_timeout = timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAIPlane::ImmediateTransmit(ai_plane_callback_t callback) {
|
void FGAIPlane::ImmediateTransmit(int callback_code) {
|
||||||
Render(plane.callsign, false);
|
Render(plane.callsign, false);
|
||||||
if(_callback) {
|
if(callback_code) {
|
||||||
(*_callback)();
|
ProcessCallback(callback_code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Derived classes should override this.
|
||||||
|
void FGAIPlane::ProcessCallback(int code) {
|
||||||
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
|
|
@ -85,9 +85,6 @@ 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*
|
||||||
|
@ -113,23 +110,26 @@ protected:
|
||||||
FGATC* tuned_station; // and this if they are tuned to ATC
|
FGATC* tuned_station; // and this if they are tuned to ATC
|
||||||
|
|
||||||
// Transmit a message when channel becomes free of other dialog
|
// Transmit a message when channel becomes free of other dialog
|
||||||
void Transmit(ai_plane_callback_t callback = NULL);
|
void Transmit(int callback_code = 0);
|
||||||
|
|
||||||
// Transmit a message if channel becomes free within timeout (seconds). timeout of zero implies no limit
|
// 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);
|
void ConditionalTransmit(double timeout, int callback_code = 0);
|
||||||
|
|
||||||
// Transmit regardless of other dialog on the channel eg emergency
|
// Transmit regardless of other dialog on the channel eg emergency
|
||||||
void ImmediateTransmit(ai_plane_callback_t callback = NULL);
|
void ImmediateTransmit(int callback_code = 0);
|
||||||
|
|
||||||
void Bank(double angle);
|
void Bank(double angle);
|
||||||
void LevelWings(void);
|
void LevelWings(void);
|
||||||
|
|
||||||
|
virtual void ProcessCallback(int code);
|
||||||
|
|
||||||
PatternLeg leg;
|
PatternLeg leg;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _pending;
|
bool _pending;
|
||||||
double _timeout;
|
double _timeout;
|
||||||
ai_plane_callback_t _callback;
|
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 _transmit; // we are to transmit
|
||||||
bool _transmitting; // we are transmitting
|
bool _transmitting; // we are transmitting
|
||||||
double _counter;
|
double _counter;
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
|
|
||||||
FGATC::FGATC() {
|
FGATC::FGATC() {
|
||||||
freqClear = true;
|
freqClear = true;
|
||||||
|
runResponseCounter = false;
|
||||||
|
responseReqd = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FGATC::~FGATC() {
|
FGATC::~FGATC() {
|
||||||
|
@ -38,10 +40,12 @@ FGATC::~FGATC() {
|
||||||
|
|
||||||
// Derived classes wishing to use the response counter should call this from their own Update(...).
|
// Derived classes wishing to use the response counter should call this from their own Update(...).
|
||||||
void FGATC::Update(double dt) {
|
void FGATC::Update(double dt) {
|
||||||
if(responseReqd) {
|
if(runResponseCounter) {
|
||||||
|
//cout << responseCounter << '\t' << responseTime << '\n';
|
||||||
if(responseCounter >= responseTime) {
|
if(responseCounter >= responseTime) {
|
||||||
responseReqd = false;
|
runResponseCounter = false;
|
||||||
respond = true;
|
respond = true;
|
||||||
|
//cout << "RESPOND\n";
|
||||||
} else {
|
} else {
|
||||||
responseCounter += dt;
|
responseCounter += dt;
|
||||||
}
|
}
|
||||||
|
@ -49,6 +53,7 @@ void FGATC::Update(double dt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGATC::SetResponseReqd(string rid) {
|
void FGATC::SetResponseReqd(string rid) {
|
||||||
|
receiving = false;
|
||||||
responseReqd = true;
|
responseReqd = true;
|
||||||
respond = false; // TODO - this ignores the fact that more than one plane could call this before response
|
respond = false; // TODO - this ignores the fact that more than one plane could call this before response
|
||||||
// Shouldn't happen with AI only, but user could confuse things??
|
// Shouldn't happen with AI only, but user could confuse things??
|
||||||
|
@ -57,6 +62,18 @@ void FGATC::SetResponseReqd(string rid) {
|
||||||
responseTime = 2.5; // TODO - randomize this slightly.
|
responseTime = 2.5; // TODO - randomize this slightly.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGATC::NotifyTransmissionFinished(string rid) {
|
||||||
|
receiving = false;
|
||||||
|
responseID = rid;
|
||||||
|
if(responseReqd) {
|
||||||
|
runResponseCounter = true;
|
||||||
|
responseCounter = 0.0;
|
||||||
|
responseTime = 2.5; // TODO - randomize this slightly.
|
||||||
|
} else {
|
||||||
|
freqClear = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FGATC::AddPlane(string pid) {
|
void FGATC::AddPlane(string pid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,9 +126,13 @@ public:
|
||||||
// Returns true if OK to transmit on this frequency
|
// Returns true if OK to transmit on this frequency
|
||||||
inline bool GetFreqClear() { return freqClear; }
|
inline bool GetFreqClear() { return freqClear; }
|
||||||
// Indicate that the frequency is in use
|
// Indicate that the frequency is in use
|
||||||
inline void SetFreqInUse() { freqClear = false; }
|
inline void SetFreqInUse() { freqClear = false; receiving = true; }
|
||||||
// Transmission to the ATC is finished and a response is required
|
// Transmission to the ATC is finished and a response is required
|
||||||
void SetResponseReqd(string rid);
|
void SetResponseReqd(string rid);
|
||||||
|
// Transmission finished - let ATC decide if a response is reqd and clear freq if necessary
|
||||||
|
void NotifyTransmissionFinished(string rid);
|
||||||
|
// Transmission finished and no response required
|
||||||
|
inline void ReleaseFreq() { freqClear = true; receiving = false; } // TODO - check that the plane releasing the freq is the right one etc.
|
||||||
// The above 3 funcs under development!!
|
// The above 3 funcs under development!!
|
||||||
// The idea is that AI traffic or the user ATC dialog box calls FreqInUse() when they begin transmitting,
|
// 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.
|
// and that the tower control sets freqClear back to true following a reply.
|
||||||
|
@ -188,7 +192,9 @@ protected:
|
||||||
FGATCVoice* vPtr;
|
FGATCVoice* vPtr;
|
||||||
|
|
||||||
bool freqClear; // Flag to indicate if the frequency is clear of ongoing dialog
|
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
|
bool responseReqd; // Flag to indicate we should be responding to a request/report
|
||||||
|
bool runResponseCounter; // Flag to indicate the response counter should be run
|
||||||
double responseTime; // Time to take from end of request transmission to beginning of response
|
double responseTime; // Time to take from end of request transmission to beginning of response
|
||||||
// The idea is that this will be slightly random.
|
// The idea is that this will be slightly random.
|
||||||
double responseCounter; // counter to implement the above
|
double responseCounter; // counter to implement the above
|
||||||
|
|
Loading…
Reference in a new issue