1
0
Fork 0

Tweaks to the ATC/AI interaction framework

This commit is contained in:
daveluff 2003-10-15 14:06:28 +00:00
parent ee8eb7d6fe
commit d5d9723d9b
4 changed files with 55 additions and 18 deletions

View file

@ -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

View file

@ -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;

View file

@ -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) {
} }

View file

@ -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