Remove/comment out obsolete code.
Refactor ATCmgr(-old) into ATISmgr(-new), only keeping the COM radio / ATIS
support.
#include <Airports/simple.hxx>
FGATC::FGATC() :
+ freq(0),
+ _currentStation(NULL),
+ range(0),
+ _voice(true),
_playing(false),
- _voiceOK(false),
_sgr(NULL),
+#ifdef OLD_ATC_MGR
freqClear(true),
receiving(false),
respond(false),
runResponseCounter(false),
_runReleaseCounter(false),
responseReqd(false),
- _type(INVALID),
- _display(false),
// Transmission timing stuff
pending_transmission(""),
- _timeout(0),
+#endif
+ _type(INVALID),
+ _display(false)
+#ifdef OLD_ATC_MGR
+ ,_timeout(0),
_pending(false),
_transmit(false),
_transmitting(false),
_counter(0.0),
_max_count(5.0)
+#endif
{
SGSoundMgr *smgr = globals->get_soundmgr();
_sgr = smgr->find("atc", true);
- _sgr->tie_to_listener();
+ _sgr->tie_to_listener();
- _volume = fgGetNode("/sim/sound/atc/volume", true);
+ _masterVolume = fgGetNode("/sim/sound/atc/volume", true);
_enabled = fgGetNode("/sim/sound/atc/enabled", true);
_atc_external = fgGetNode("/sim/sound/atc/external-view", true);
_internal = fgGetNode("/sim/current-view/internal", true);
// Derived classes wishing to use the response counter should
// call this from their own Update(...).
void FGATC::Update(double dt) {
+
+#ifdef ENABLE_AUDIO_SUPPORT
+ bool active = _atc_external->getBoolValue() ||
+ _internal->getBoolValue();
+
+ if ( active && _enabled->getBoolValue() ) {
+ _sgr->set_volume( _masterVolume->getFloatValue() );
+ _sgr->resume(); // no-op if already in resumed state
+ } else {
+ _sgr->suspend();
+ }
+#endif
+
+#ifdef OLD_ATC_MGR
if(runResponseCounter) {
//cout << responseCounter << '\t' << responseTime << '\n';
if(responseCounter >= responseTime) {
}
}
-#ifdef ENABLE_AUDIO_SUPPORT
- bool active = _atc_external->getBoolValue() ||
- _internal->getBoolValue();
-
- if ( active && _enabled->getBoolValue() ) {
- _sgr->set_volume( _volume->getFloatValue() );
- _sgr->resume(); // no-op if already in resumed state
- } else {
- _sgr->suspend();
- }
-#endif
-
if(_transmit) {
_counter = 0.0;
_max_count = 5.0; // FIXME - hardwired length of message - need to calculate it!
}
_counter += dt;
}
+#endif
}
+#ifdef OLD_ATC_MGR
void FGATC::ReceiveUserCallback(int code) {
SG_LOG(SG_ATC, SG_WARN, "WARNING - whichever ATC class was intended to receive callback code " << code << " didn't get it!!!");
}
freqClear = true;
}
}
+#endif
void FGATC::SetStation(flightgear::CommStation* sta) {
- switch (sta->type()) {
- case FGPositioned::FREQ_ATIS: _type = ATIS; break;
- case FGPositioned::FREQ_AWOS: _type = AWOS; break;
- default:
- throw sg_exception("unsupported comm station type");
+ if (_currentStation == sta)
+ return;
+ _currentStation = sta;
+
+ if (sta)
+ {
+ switch (sta->type()) {
+ case FGPositioned::FREQ_ATIS: _type = ATIS; break;
+ case FGPositioned::FREQ_AWOS: _type = AWOS; break;
+ default:
+ sta = NULL;
+ break;
+ }
+ }
+
+ if (sta == NULL)
+ {
+ range = 0;
+ ident = "";
+ name = "";
+ freq = 0;
+
+ SetNoDisplay();
+ Update(0); // one last update
+ }
+ else
+ {
+ _geod = sta->geod();
+ _cart = sta->cart();
+
+ range = sta->rangeNm();
+ ident = sta->airport()->ident();
+ name = sta->airport()->name();
+ freq = sta->freqKHz();
+ SetDisplay();
}
-
- _geod = sta->geod();
- _cart = sta->cart();
- range = sta->rangeNm();
- ident = sta->airport()->ident();
- name = sta->airport()->name();
- freq = sta->freqKHz();
}
// Render a transmission
// The repeating flag indicates whether the message should be repeated continuously or played once.
void FGATC::Render(string& msg, const float volume,
const string& refname, const bool repeating) {
- if (volume < 0.05)
+ if ((!_display) ||(volume < 0.05))
{
NoRender(refname);
return;
fgSetString("/sim/messages/atc", msg.c_str());
#ifdef ENABLE_AUDIO_SUPPORT
- _voice = (_voiceOK && fgGetBool("/sim/sound/voice"));
- if(_voice) {
- size_t len;
- void* buf = _vPtr->WriteMessage((char*)msg.c_str(), &len);
- NoRender(refname);
- if(buf) {
- try {
+ bool useVoice = _voice && fgGetBool("/sim/sound/voice") && fgGetBool("/sim/sound/atc/enabled");
+ SGSoundSample *simple = _sgr->find(refname);
+ if(useVoice) {
+ if (simple && (_currentMsg == msg))
+ {
+ simple->set_volume(volume);
+ }
+ else
+ {
+ _currentMsg = msg;
+ size_t len;
+ void* buf = NULL;
+ if (!_vPtr)
+ _vPtr = GetVoicePointer();
+ if (_vPtr)
+ buf = _vPtr->WriteMessage((char*)msg.c_str(), &len);
+ NoRender(refname);
+ if(buf) {
+ try {
// >>> Beware: must pass a (new) object to the (add) method,
// >>> because the (remove) method is going to do a (delete)
// >>> whether that's what you want or not.
- SGSoundSample *simple = new SGSoundSample(&buf, len, 8000);
- simple->set_volume(volume);
- _sgr->add(simple, refname);
- _sgr->play(refname, repeating);
- } catch ( sg_io_exception &e ) {
- SG_LOG(SG_ATC, SG_ALERT, e.getFormattedMessage());
- }
+ simple = new SGSoundSample(&buf, len, 8000);
+ simple->set_volume(volume);
+ _sgr->add(simple, refname);
+ _sgr->play(refname, repeating);
+ } catch ( sg_io_exception &e ) {
+ SG_LOG(SG_ATC, SG_ALERT, e.getFormattedMessage());
+ }
+ }
}
}
+ else
+ if (simple)
+ {
+ NoRender(refname);
+ }
#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
+
+ if (!useVoice)
+ {
+ // first rip the underscores and the pause hints out of the string - these are for the convenience of the voice parser
for(unsigned int i = 0; i < msg.length(); ++i) {
if((msg.substr(i,1) == "_") || (msg.substr(i,1) == "/")) {
msg[i] = ' ';
}
}
}
- _playing = true;
+ _playing = true;
}
void FGATC::NoRender(const string& refname) {
if(_playing) {
if(_voice) {
-#ifdef ENABLE_AUDIO_SUPPORT
+#ifdef ENABLE_AUDIO_SUPPORT
_sgr->stop(refname);
_sgr->remove(refname);
#endif
}
}
+#ifdef OLD_ATC_MGR
// Generate the text of a message from its parameters and the current context.
string FGATC::GenText(const string& m, int c) {
return("");
a.cart = SGVec3d::fromGeod(a.geod);
return fin >> skipeol;
}
-
+#endif
class CommStation;
}
-// Convert a frequency in MHz to tens of kHz
-// so we can use it e.g. as an index into commlist_freq
-//
-// If freq > 1000 assume it's already in tens of KHz;
-// otherwise assume MHz.
-//
-// Note: 122.375 must be rounded DOWN to 12237
-// in order to be consistent with apt.dat et cetera.
-inline int kHz10(double freq)
-{
- if (freq > 1000.) return int(freq);
- return int(freq*100.0 + 0.25);
-}
-
// Possible types of ATC type that the radios may be tuned to.
// INVALID implies not tuned in to anything.
enum atc_type {
INVALID /* must be last element; see ATC_NUM_TYPES */
};
+#ifdef OLD_ATC_MGR
const int ATC_NUM_TYPES = 1 + INVALID;
// DCL - new experimental ATC data store
};
std::ostream& operator << (std::ostream& os, atc_type atc);
+#endif
class FGATC {
- friend class FGATCMgr;
+ friend class FGATISMgr;
public:
FGATC();
// wish to use the response timer functionality.
virtual void Update(double dt);
- // Recieve a coded callback from the ATC menu system based on the user's selection
- virtual void ReceiveUserCallback(int code);
-
// Indicate that this instance should output to the display if appropriate
inline void SetDisplay() { _display = true; }
// Indicate that this instance should not output to the display
inline void SetNoDisplay() { _display = false; }
+#ifdef OLD_ATC_MGR
+ // Receive a coded callback from the ATC menu system based on the user's selection
+ virtual void ReceiveUserCallback(int code);
+
// Generate the text of a message from its parameters and the current context.
virtual std::string GenText(const std::string& m, int c);
// 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
- inline atc_type GetType() { return _type; }
- // Set the core ATC data
- void SetStation(flightgear::CommStation* sta);
inline int get_freq() const { return freq; }
inline void set_freq(const int fq) {freq = fq;}
inline int get_range() const { return range; }
inline void set_range(const int rg) {range = rg;}
+#endif
+ // Return the type of ATC station that the class represents
+ inline atc_type GetType() { return _type; }
+
+ // Set the core ATC data
+ void SetStation(flightgear::CommStation* sta);
+
inline const std::string& get_ident() { return ident; }
inline void set_ident(const std::string& id) { ident = id; }
inline const std::string& get_name() { return name; }
inline void set_name(const std::string& nm) { name = nm; }
-
+
protected:
// Render a transmission
// Requires the sound manager refname if audio, else "".
void NoRender(const std::string& refname);
+ virtual FGATCVoice* GetVoicePointer() = 0;
+
SGGeod _geod;
SGVec3d _cart;
int freq;
- std::map<std::string,int> active_on;
-
+ flightgear::CommStation* _currentStation;
+
int range;
std::string ident; // Code of the airport its at.
std::string name; // Name transmitted in the broadcast.
+ std::string _currentMsg; // Current message being transmitted
-
// 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
+ bool _playing; // Indicates a message in progress
FGATCVoice* _vPtr;
SGSharedPtr<SGSampleGroup> _sgr; // default sample group;
-
+#ifdef OLD_ATC_MGR
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
double _releaseTime;
double _releaseCounter;
+ std::string pending_transmission; // derived classes set this string before calling Transmit(...)
+#endif
atc_type _type;
bool _display; // Flag to indicate whether we should be outputting to the ATC display.
- std::string pending_transmission; // derived classes set this string before calling Transmit(...)
-
+
private:
+
+#ifdef OLD_ATC_MGR
// Transmission timing stuff.
double _timeout;
bool _pending;
bool _transmitting; // we are transmitting
double _counter;
double _max_count;
+#endif
- SGPropertyNode_ptr _volume;
+ SGPropertyNode_ptr _masterVolume;
SGPropertyNode_ptr _enabled;
SGPropertyNode_ptr _atc_external;
SGPropertyNode_ptr _internal;
};
+#ifdef OLD_ATC_MGR
std::istream& operator>> ( std::istream& fin, ATCData& a );
+#endif
#endif // _FG_ATC_HXX
+++ /dev/null
-// ATCmgr.cxx - Implementation of FGATCMgr - a global Flightgear ATC manager.
-//
-// Written by David Luff, started February 2002.
-//
-// Copyright (C) 2002 David C Luff - david.luff@nottingham.ac.uk
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <simgear/misc/sg_path.hxx>
-#include <simgear/debug/logstream.hxx>
-#include <simgear/structure/exception.hxx>
-
-#include <Airports/simple.hxx>
-#include <ATC/CommStation.hxx>
-#include <Main/fg_props.hxx>
-
-#include "ATCmgr.hxx"
-#include "ATCutils.hxx"
-#include "atis.hxx"
-
-using flightgear::CommStation;
-
-FGATCMgr::FGATCMgr() :
- initDone(false),
- atc_list(new atc_list_type),
-#ifdef ENABLE_AUDIO_SUPPORT
- voice(true),
- voiceOK(false),
- v1(0)
-#else
- voice(false),
-#endif
-{
- globals->set_ATC_mgr(this);
-}
-
-FGATCMgr::~FGATCMgr() {
- globals->set_ATC_mgr(NULL);
- delete v1;
-}
-
-void FGATCMgr::bind() {
-}
-
-void FGATCMgr::unbind() {
-}
-
-void FGATCMgr::init() {
- //cout << "ATCMgr::init called..." << endl;
-
- lon_node = fgGetNode("/position/longitude-deg", true);
- lat_node = fgGetNode("/position/latitude-deg", true);
- elev_node = fgGetNode("/position/altitude-ft", true);
- atc_list_itr = atc_list->begin();
-
- // Search for connected ATC stations once per 0.8 seconds or so
- // globals->get_event_mgr()->add( "fgATCSearch()", fgATCSearch,
- // FGEvent::FG_EVENT_READY, 800);
- //
- // For some reason the above doesn't compile - including Time/event.hxx stops compilation.
- // Is this still true after the reorganization of the event managar??
- // -EMH-
-
- initDone = true;
- //cout << "ATCmgr::init done!" << endl;
-}
-
-void FGATCMgr::update(double dt) {
- if(!initDone) {
- init();
- SG_LOG(SG_ATC, SG_WARN, "Warning - ATCMgr::update(...) called before ATCMgr::init()");
- }
-
- //cout << "Entering update..." << endl;
- //Traverse the list of active stations.
- //Only update one class per update step to avoid the whole ATC system having to calculate between frames.
- //Eventually we should only update every so many steps.
- //cout << "In FGATCMgr::update - atc_list.size = " << atc_list->size() << endl;
- if(atc_list->size()) {
- if(atc_list_itr == atc_list->end()) {
- atc_list_itr = atc_list->begin();
- }
- //cout << "Updating " << (*atc_list_itr)->get_ident() << ' ' << (*atc_list_itr)->GetType() << '\n';
- //cout << "Freq = " << (*atc_list_itr)->get_freq() << '\n';
- //cout << "Updating...\n";
- (*atc_list_itr).second->Update(dt * atc_list->size());
- //cout << "Done ATC update..." << endl;
- ++atc_list_itr;
- }
-
-#ifdef ATC_TEST
- //cout << "ATC_LIST: " << atc_list->size() << ' ';
- for(atc_list_iterator it = atc_list->begin(); it != atc_list->end(); it++) {
- cout << (*it)->get_ident() << ' ';
- }
- //cout << '\n';
-#endif
-
- // Search the tuned frequencies every now and then - this should be done with the event scheduler
- static int i = 0; // Very ugly - but there should only ever be one instance of FGATCMgr.
- if(i == 15) {
- //cout << "About to search navcomm1" << endl;
- FreqSearch("comm", 0);
- FreqSearch("nav", 0);
- }
- if(i == 30) {
- //cout << "About to search navcomm2" << endl;
- FreqSearch("comm", 1);
- FreqSearch("nav", 1);
- i = 0;
- }
- ++i;
-
- //cout << "comm1 type = " << comm_type[0] << '\n';
- //cout << "Leaving update..." << endl;
-}
-
-typedef map<string,int> MSI;
-
-void FGATCMgr::ZapOtherService(const string ncunit, const string svc_name){
- for (atc_list_iterator svc = atc_list->begin(); svc != atc_list->end(); svc++) {
-
- if (svc->first != svc_name) {
- MSI &actv = svc->second->active_on;
- // OK, we have found some OTHER service;
- // see if it is (was) active on our unit:
- if (!actv.count(ncunit)) continue;
- //cout << "Eradicating '" << svc->first << "' from: " << ncunit << endl;
- actv.erase(ncunit);
- if (!actv.size()) {
- //cout << "Eradicating service: '" << svc->first << "'" << endl;
- svc->second->SetNoDisplay();
- svc->second->Update(0); // one last update
- SG_LOG(SG_ATC, SG_INFO, "would have erased ATC service:" << svc->second->get_name()<< "/"
- << svc->second->get_ident());
- // delete svc->second;
- atc_list->erase(svc);
- // ALL pointers into the ATC list are now invalid,
- // so let's reset them:
- atc_list_itr = atc_list->begin();
- }
- break; // cannot be duplicates in the active list
- }
- }
-}
-
-// Find in list - return a currently active ATC pointer given ICAO code and type
-// Return NULL if the given service is not in the list
-// - *** THE CALLING FUNCTION MUST CHECK FOR THIS ***
-FGATC* FGATCMgr::FindInList(const string& id, const atc_type& tp) {
- string ndx = id + decimalNumeral(tp);
- if (!atc_list->count(ndx)) return 0;
- return (*atc_list)[ndx];
-}
-
-// Return a pointer to an appropriate voice for a given type of ATC
-// creating the voice if necessary - ie. make sure exactly one copy
-// of every voice in use exists in memory.
-//
-// TODO - in the future this will get more complex and dole out country/airport
-// specific voices, and possible make sure that the same voice doesn't get used
-// at different airports in quick succession if a large enough selection are available.
-FGATCVoice* FGATCMgr::GetVoicePointer(const atc_type& type) {
- // TODO - implement me better - maintain a list of loaded voices and other voices!!
- if(voice) {
- switch(type) {
- case ATIS: case AWOS:
-#ifdef ENABLE_AUDIO_SUPPORT
- // Delayed loading fo all available voices, needed because the
- // soundmanager might not be initialized (at all) at this point.
- // For now we'll do one hardwired one
-
- /* I've loaded the voice even if /sim/sound/pause is true
- * since I know no way of forcing load of the voice if the user
- * subsequently switches /sim/sound/audible to true.
- * (which is the right thing to do -- CLO) :-)
- */
- if (!voiceOK && fgGetBool("/sim/sound/working")) {
- v1 = new FGATCVoice;
- try {
- voiceOK = v1->LoadVoice("default");
- voice = voiceOK;
- } catch ( sg_io_exception & e) {
- voiceOK = false;
- SG_LOG(SG_ATC, SG_ALERT, "Unable to load default voice : "
- << e.getFormattedMessage().c_str());
- voice = false;
- delete v1;
- v1 = 0;
- }
- }
-#endif
- if(voiceOK) {
- return(v1);
- }
- case TOWER:
- return(NULL);
- case APPROACH:
- return(NULL);
- case GROUND:
- return(NULL);
- default:
- return(NULL);
- }
- return(NULL);
- } else {
- return(NULL);
- }
-}
-
-// Search for ATC stations by frequency
-void FGATCMgr::FreqSearch(const string navcomm, const int unit) {
-
-
- string ncunit = navcomm + "[" + decimalNumeral(unit) + "]";
- string commbase = "/instrumentation/" + ncunit;
- string commfreq = commbase + "/frequencies/selected-mhz";
- SGPropertyNode_ptr comm_node = fgGetNode(commfreq.c_str(), false);
-
- //cout << "FreqSearch: " << ncunit
- // << " node: " << comm_node << endl;
- if (!comm_node) return; // no such radio unit
-
- ATCData data;
- // Note: 122.375 must be rounded DOWN to 12237
- // in order to be consistent with apt.dat et cetera.
- int freqKhz = static_cast<int>(comm_node->getDoubleValue() * 100.0 + 0.25);
-
- _aircraftPos = SGGeod::fromDegFt(lon_node->getDoubleValue(),
- lat_node->getDoubleValue(), elev_node->getDoubleValue());
-
- class RangeFilter : public CommStation::Filter {
- public:
- RangeFilter( const SGGeod & pos ) :
- CommStation::Filter(),
- _cart(SGVec3d::fromGeod(pos)),
- _pos(pos)
- {}
-
- virtual bool pass(FGPositioned* aPos) const
- {
- flightgear::CommStation * stn = dynamic_cast<flightgear::CommStation*>(aPos);
- if( NULL == stn ) return false;
- // do the range check in cartesian space, since the distances are potentially
- // large enough that the geodetic functions become unstable
- // (eg, station on opposite side of the planet)
- double rangeM = SGMiscd::max( stn->rangeNm(), 10.0 ) * SG_NM_TO_METER;
- double d2 = distSqr( aPos->cart(), _cart);
-
- return d2 <= (rangeM * rangeM);
- }
- private:
- SGVec3d _cart;
- SGGeod _pos;
- };
-
- RangeFilter rangeFilter(_aircraftPos );
-
- CommStation* sta = CommStation::findByFreq(freqKhz, _aircraftPos, &rangeFilter );
- if (!sta) {
- ZapOtherService(ncunit, "x x x");
- return;
- }
-
- // Get rid of any *other* service that was on this radio unit:
- FGPositioned::Type ty = sta->type();
- string svc_name = sta->ident() + FGPositioned::nameForType(ty);
- ZapOtherService(ncunit, svc_name);
- // See if the service already exists, possibly connected to
- // some other radio unit:
- if (atc_list->count(svc_name)) {
- // make sure the service knows it's tuned on this radio:
- FGATC* svc = (*atc_list)[svc_name];
- svc->active_on[ncunit] = 1;
- svc->SetDisplay();
- return;
- }
-
- // This was a switch-case statement but the compiler didn't like
- // the new variable creation with it.
- if(ty == FGPositioned::FREQ_ATIS || ty == FGPositioned::FREQ_AWOS) {
- (*atc_list)[svc_name] = new FGATIS;
- FGATC* svc = (*atc_list)[svc_name];
- if(svc != NULL) {
- svc->SetStation(sta);
- svc->active_on[ncunit] = 1;
- svc->SetDisplay();
- svc->Init();
- }
- }
-
-}
+++ /dev/null
-// ATCMgr.hxx - definition of FGATCMgr
-// - a global management class for FlightGear generated ATC
-//
-// Written by David Luff, started February 2002.
-//
-// Copyright (C) 2002 David C Luff - david.luff@nottingham.ac.uk
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-#ifndef _FG_ATCMGR_HXX
-#define _FG_ATCMGR_HXX
-
-#include <simgear/structure/subsystem_mgr.hxx>
-
-#include <string>
-#include <list>
-#include <map>
-
-#include "ATC.hxx"
-
-class FGATCMgr : public SGSubsystem
-{
-
-private:
-
- bool initDone; // Hack - guard against update getting called before init
-
- // A list of pointers to all currently active ATC classes
- typedef std::map<std::string,FGATC*> atc_list_type;
- typedef atc_list_type::iterator atc_list_iterator;
- typedef atc_list_type::const_iterator atc_list_const_iterator;
-
- // Everything put in this list should be created dynamically
- // on the heap and ***DELETED WHEN REMOVED!!!!!***
- atc_list_type* atc_list;
- atc_list_iterator atc_list_itr;
- // Any member function of FGATCMgr is permitted to leave this iterator pointing
- // at any point in or at the end of the list.
- // Hence any new access must explicitly first check for atc_list.end() before dereferencing.
-
- // Position of the Users Aircraft
- SGGeod _aircraftPos;
-
- // Pointers to current users position
- SGPropertyNode_ptr lon_node;
- SGPropertyNode_ptr lat_node;
- SGPropertyNode_ptr elev_node;
-
- //FGATIS atis;
-
- // Voice related stuff
- bool voice; // Flag - true if we are using voice
-#ifdef ENABLE_AUDIO_SUPPORT
- bool voiceOK; // Flag - true if at least one voice has loaded OK
- FGATCVoice* v1;
-#endif
-
-public:
-
- FGATCMgr();
- ~FGATCMgr();
-
- void init();
-
- void bind();
-
- void unbind();
-
- void update(double dt);
-
-
- // Return a pointer to an appropriate voice for a given type of ATC
- // creating the voice if necessary - ie. make sure exactly one copy
- // of every voice in use exists in memory.
- //
- // TODO - in the future this will get more complex and dole out country/airport
- // specific voices, and possible make sure that the same voice doesn't get used
- // at different airports in quick succession if a large enough selection are available.
- FGATCVoice* GetVoicePointer(const atc_type& type);
-
- atc_type GetComm1ATCType() { return(INVALID/* kludge */); }
- FGATC* GetComm1ATCPointer() { return(0/* kludge */); }
- atc_type GetComm2ATCType() { return(INVALID); }
- FGATC* GetComm2ATCPointer() { return(0/* kludge */); }
-
-
-private:
-
- // Remove a class from the atc_list and delete it from memory
- // *if* no other comm channel or AI plane is using it.
- void ZapOtherService(const std::string ncunit, const std::string svc_name);
-
- // Return a pointer to a class in the list given ICAO code and type
- // Return NULL if the given service is not in the list
- // - *** THE CALLING FUNCTION MUST CHECK FOR THIS ***
- FGATC* FindInList(const std::string& id, const atc_type& tp);
-
- // Search the specified radio for stations on the same frequency and in range.
- void FreqSearch(const std::string navcomm, const int unit);
-};
-
-#endif // _FG_ATCMGR_HXX
--- /dev/null
+// ATISmgr.cxx - Implementation of FGATISMgr - a global Flightgear ATIS manager.
+//
+// Written by David Luff, started February 2002.
+//
+// Copyright (C) 2002 David C Luff - david.luff@nottingham.ac.uk
+// Copyright (C) 2012 Thorsten Brehm
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <simgear/misc/sg_path.hxx>
+#include <simgear/debug/logstream.hxx>
+#include <simgear/structure/exception.hxx>
+
+#include <Airports/simple.hxx>
+#include <ATC/CommStation.hxx>
+#include <Main/fg_props.hxx>
+
+#include "ATISmgr.hxx"
+#include "ATCutils.hxx"
+#include "atis.hxx"
+
+using flightgear::CommStation;
+
+FGATISMgr::FGATISMgr() :
+ _currentUnit(0),
+ _maxCommRadios(2),
+#ifdef ENABLE_AUDIO_SUPPORT
+ voice(true),
+ voice1(0)
+#else
+ voice(false)
+#endif
+{
+ globals->set_ATIS_mgr(this);
+}
+
+FGATISMgr::~FGATISMgr()
+{
+ globals->set_ATIS_mgr(NULL);
+
+ for (unsigned int unit = 0;unit < _maxCommRadios; ++unit)
+ {
+ delete radios[unit].station;
+ radios[unit].station = NULL;
+ }
+
+#ifdef ENABLE_AUDIO_SUPPORT
+ delete voice1;
+#endif
+}
+
+void FGATISMgr::bind()
+{
+}
+
+void FGATISMgr::unbind()
+{
+}
+
+void FGATISMgr::init()
+{
+ lon_node = fgGetNode("/position/longitude-deg", true);
+ lat_node = fgGetNode("/position/latitude-deg", true);
+ elev_node = fgGetNode("/position/altitude-ft", true);
+
+ for (unsigned int unit = 0;unit < _maxCommRadios; ++unit)
+ {
+ CommRadioData data;
+ string ncunit = "comm[" + decimalNumeral(unit) + "]";
+ string commbase = "/instrumentation/" + ncunit;
+ string commfreq = commbase + "/frequencies/selected-mhz";
+
+ data.freq = fgGetNode(commfreq.c_str(), true);
+ data.station = new FGATIS(commbase);
+ radios.push_back(data);
+ }
+}
+
+void FGATISMgr::update(double dt)
+{
+ // update only runs every now and then (1-2 per second)
+ if (++_currentUnit >= _maxCommRadios)
+ _currentUnit = 0;
+
+ FGATC* pStation = radios[_currentUnit].station;
+ if (pStation)
+ pStation->Update(dt * _maxCommRadios);
+
+ // Search the tuned frequencies
+ FreqSearch(_currentUnit);
+}
+
+// Return a pointer to an appropriate voice for a given type of ATC
+// creating the voice if necessary - i.e. make sure exactly one copy
+// of every voice in use exists in memory.
+//
+// TODO - in the future this will get more complex and dole out country/airport
+// specific voices, and possible make sure that the same voice doesn't get used
+// at different airports in quick succession if a large enough selection are available.
+FGATCVoice* FGATISMgr::GetVoicePointer(const atc_type& type)
+{
+ // TODO - implement me better - maintain a list of loaded voices and other voices!!
+ if(voice)
+ {
+ switch(type)
+ {
+ case ATIS: case AWOS:
+#ifdef ENABLE_AUDIO_SUPPORT
+ // Delayed loading for all available voices, needed because the
+ // sound manager might not be initialized (at all) at this point.
+ // For now we'll do one hard-wired one
+
+ /* I've loaded the voice even if /sim/sound/pause is true
+ * since I know no way of forcing load of the voice if the user
+ * subsequently switches /sim/sound/audible to true.
+ * (which is the right thing to do -- CLO) :-)
+ */
+ if (!voice1 && fgGetBool("/sim/sound/working")) {
+ voice1 = new FGATCVoice;
+ try {
+ voice = voice1->LoadVoice("default");
+ } catch ( sg_io_exception & e) {
+ SG_LOG(SG_ATC, SG_ALERT, "Unable to load default voice : "
+ << e.getFormattedMessage().c_str());
+ voice = false;
+ delete voice1;
+ voice1 = 0;
+ }
+ }
+ if (voice)
+ return voice1;
+#endif
+ return NULL;
+ case TOWER:
+ return NULL;
+ case APPROACH:
+ return NULL;
+ case GROUND:
+ return NULL;
+ default:
+ return NULL;
+ }
+ }
+
+ return NULL;
+}
+
+class RangeFilter : public CommStation::Filter
+{
+public:
+ RangeFilter( const SGGeod & pos ) :
+ CommStation::Filter(),
+ _cart(SGVec3d::fromGeod(pos)),
+ _pos(pos)
+ {
+ }
+
+ virtual bool pass(FGPositioned* aPos) const
+ {
+ flightgear::CommStation * stn = dynamic_cast<flightgear::CommStation*>(aPos);
+ if( NULL == stn )
+ return false;
+
+ // do the range check in cartesian space, since the distances are potentially
+ // large enough that the geodetic functions become unstable
+ // (eg, station on opposite side of the planet)
+ double rangeM = SGMiscd::max( stn->rangeNm(), 10.0 ) * SG_NM_TO_METER;
+ double d2 = distSqr( aPos->cart(), _cart);
+
+ return d2 <= (rangeM * rangeM);
+ }
+private:
+ SGVec3d _cart;
+ SGGeod _pos;
+};
+
+// Search for ATC stations by frequency
+void FGATISMgr::FreqSearch(const unsigned int unit)
+{
+ double frequency = radios[unit].freq->getDoubleValue();
+
+ // Note: 122.375 must be rounded DOWN to 12237
+ // in order to be consistent with apt.dat et cetera.
+ int freqKhz = static_cast<int>(frequency * 100.0 + 0.25);
+
+ _aircraftPos = SGGeod::fromDegFt(lon_node->getDoubleValue(),
+ lat_node->getDoubleValue(), elev_node->getDoubleValue());
+
+ RangeFilter rangeFilter(_aircraftPos );
+ CommStation* sta = CommStation::findByFreq(freqKhz, _aircraftPos, &rangeFilter );
+ radios[unit].station->SetStation(sta);
+}
--- /dev/null
+// ATISmgr.hxx - definition of FGATISMgr
+// - a global management class for FlightGear generated ATIS
+//
+// Written by David Luff, started February 2002.
+//
+// Copyright (C) 2002 David C Luff - david.luff@nottingham.ac.uk
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+#ifndef _FG_ATCMGR_HXX
+#define _FG_ATCMGR_HXX
+
+#include <simgear/structure/subsystem_mgr.hxx>
+
+#include <string>
+#include <list>
+#include <map>
+
+#include "ATC.hxx"
+
+namespace flightgear
+{
+ class CommStation;
+}
+
+typedef struct
+{
+ SGPropertyNode_ptr freq;
+ FGATC* station;
+} CommRadioData;
+
+class FGATISMgr : public SGSubsystem
+{
+
+private:
+ // A vector containing all comm radios
+ typedef std::vector<CommRadioData> radio_list_type;
+ radio_list_type radios;
+
+ // Any member function of FGATISMgr is permitted to leave this iterator pointing
+ // at any point in or at the end of the list.
+ // Hence any new access must explicitly first check for atc_list.end() before dereferencing.
+
+ // Position of the Users Aircraft
+ SGGeod _aircraftPos;
+
+ // Pointers to current users position
+ SGPropertyNode_ptr lon_node;
+ SGPropertyNode_ptr lat_node;
+ SGPropertyNode_ptr elev_node;
+
+ unsigned int _currentUnit;
+ unsigned int _maxCommRadios;
+
+ // Voice related stuff
+ bool voice; // Flag - true if we are using voice
+#ifdef ENABLE_AUDIO_SUPPORT
+ FGATCVoice* voice1;
+#endif
+
+public:
+ FGATISMgr();
+ ~FGATISMgr();
+
+ void init();
+
+ void bind();
+
+ void unbind();
+
+ void update(double dt);
+
+ // Return a pointer to an appropriate voice for a given type of ATC
+ // creating the voice if necessary - i.e. make sure exactly one copy
+ // of every voice in use exists in memory.
+ //
+ // TODO - in the future this will get more complex and dole out country/airport
+ // specific voices, and possible make sure that the same voice doesn't get used
+ // at different airports in quick succession if a large enough selection are available.
+ FGATCVoice* GetVoicePointer(const atc_type& type);
+
+private:
+ // Search the specified radio for stations on the same frequency and in range.
+ void FreqSearch(const unsigned int unit);
+};
+
+#endif // _FG_ATCMGR_HXX
ATC.cxx
atis.cxx
ATCVoice.cxx
- ATCmgr.cxx
+ ATISmgr.cxx
ATCutils.cxx
ATCProjection.cxx
)
ATC.hxx
atis.hxx
ATCVoice.hxx
- ATCmgr.hxx
+ ATISmgr.hxx
ATCutils.hxx
ATCProjection.hxx
atis_lexicon.hxx
#include "ATCutils.hxx"
-#include "ATCmgr.hxx"
+#include "ATISmgr.hxx"
using std::string;
using std::map;
using boost::ref;
using boost::tie;
-FGATIS::FGATIS() :
+FGATIS::FGATIS(const string& commbase) :
transmission(""),
trans_ident(""),
old_volume(0),
msg_OK(0),
attention(0),
_prev_display(0),
- refname("atis")
+ _commbase(commbase)
{
- FGATCMgr* pAtcMgr = globals->get_ATC_mgr();
- if (!pAtcMgr)
- {
- SG_LOG(SG_ATC, SG_ALERT, "ERROR! No ATC manager! Oops...");
- _vPtr = NULL;
- }
- else
- _vPtr = pAtcMgr->GetVoicePointer(ATIS);
- _voiceOK = (_vPtr == NULL ? false : true);
- if (!(_type != ATIS || _type == AWOS)) {
- SG_LOG(SG_ATC, SG_ALERT, "ERROR - _type not ATIS or AWOS in atis.cxx");
- }
fgTie("/environment/attention", this, (int_getter)0, &FGATIS::attend);
///////////////
fgUntie("/environment/attention");
}
+FGATCVoice* FGATIS::GetVoicePointer()
+{
+ FGATISMgr* pAtisMgr = globals->get_ATIS_mgr();
+ if (!pAtisMgr)
+ {
+ SG_LOG(SG_ATC, SG_ALERT, "ERROR! No ATIS manager! Oops...");
+ return NULL;
+ }
+
+ return pAtisMgr->GetVoicePointer(ATIS);
+}
+
void FGATIS::Init() {
// Nothing to see here. Move along.
}
void FGATIS::Update(double dt) {
cur_time = globals->get_time_params()->get_cur_time();
msg_OK = (msg_time < cur_time);
+
#ifdef ATIS_TEST
if (msg_OK || _display != _prev_display) {
cout << "ATIS Update: " << _display << " " << _prev_display
msg_time = cur_time;
}
#endif
- if(_display) {
- double volume(0);
- for (map<string,int>::iterator act = active_on.begin();
- act != active_on.end(); act++) {
- string prop = "/instrumentation/" + act->first + "/volume";
- volume += globals->get_props()->getDoubleValue(prop.c_str());
- }
+
+ if(_display)
+ {
+ string prop = _commbase + "/volume";
+ double volume = globals->get_props()->getDoubleValue(prop.c_str());
// Check if we need to update the message
// - basically every hour and if the weather changes significantly at the station
// If !_prev_display, the radio had been detuned for a while and our
// "transmission" variable was lost when we were de-instantiated.
- int rslt = GenTransmission(!_prev_display, attention);
+ int changed = GenTransmission(!_prev_display, attention);
TreeOut(msg_OK);
- if (rslt || volume != old_volume) {
+ if (changed || volume != old_volume) {
//cout << "ATIS calling ATC::render volume: " << volume << endl;
- Render(transmission, volume, refname, true);
+ Render(transmission, volume, _commbase, true);
old_volume = volume;
}
} else {
// We shouldn't be displaying
//cout << "ATIS.CXX - calling NoRender()..." << endl;
- NoRender(refname);
+ NoRender(_commbase);
}
_prev_display = _display;
attention = 0;
return 1;
}
-// Put the transmission into the property tree,
-// possibly in multiple places if multiple radios
-// are tuned to the same ATIS.
+// Put the transmission into the property tree.
// You can see it by pointing a web browser
// at the property tree. The second comm radio is:
// http://localhost:5400/instrumentation/comm[1]
//
// (Also, if in debug mode, dump it to the console.)
void FGATIS::TreeOut(int msg_OK){
- for (map<string,int>::iterator act = active_on.begin();
- act != active_on.end();
- act++){
- string prop = "/instrumentation/" + act->first + "/atis";
+ string prop = _commbase + "/atis";
globals->get_props()->setStringValue(prop.c_str(),
("<pre>\n" + transmission_readable + "</pre>\n").c_str());
-#ifdef ATIS_TEST
- if (msg_OK) cout << "**** ATIS active on: " << prop << endl;
-#endif
- }
-#ifdef ATIS_TEST
- if (msg_OK) cout << transmission_readable << endl;
-#endif
+ SG_LOG(SG_ATC, SG_DEBUG, "**** ATIS active on: " << prop <<
+ "transmission: " << transmission_readable);
}
bool _prev_display; // Previous value of _display flag
MSS _remap; // abbreviations to be expanded
+ std::string _commbase;
+
// Aircraft position
// ATIS is actually a special case in that unlike other ATC eg.tower it doesn't actually know about
// or the whereabouts of the aircraft it is transmitting to. However, to ensure consistancy of
//SGPropertyNode_ptr airplane_lat_node;
//SGPropertyNode_ptr airplane_elev_node;
- public:
+public:
- FGATIS(void);
+ FGATIS(const std::string& commbase);
~FGATIS(void);
virtual void Init();
void attend (int);
//inline void set_type(const atc_type tp) {type = tp;}
inline const std::string& get_trans_ident() { return trans_ident; }
- inline void set_refname(const std::string& r) { refname = r; }
-
- private:
-
- std::string refname; // Holds the refname of a transmission in progress
+protected:
+ virtual FGATCVoice* GetVoicePointer();
+
+private:
+
// Generate the ATIS transmission text:
int GenTransmission(const int regen, const int special);
#include <AIModel/AIManager.hxx>
-#include <ATCDCL/ATCmgr.hxx>
+#include <ATCDCL/ATISmgr.hxx>
#include <ATC/atc_mgr.hxx>
#include <Autopilot/route_mgr.hxx>
////////////////////////////////////////////////////////////////////
fgGetBool("/sim/rendering/bump-mapping", false);
-
-
////////////////////////////////////////////////////////////////////
- // Initialise the ATC Manager
- // Note that this is old stuff, but might be necessesary for the
+ // Initialise the ATIS Manager
+ // Note that this is old stuff, but is necessary for the
// current ATIS implementation. Therefore, leave it in here
// until the ATIS system is ported over to make use of the ATIS
// sub system infrastructure.
////////////////////////////////////////////////////////////////////
- globals->add_subsystem("ATC-old", new FGATCMgr, SGSubsystemMgr::INIT);
+ globals->add_subsystem("ATIS", new FGATISMgr, SGSubsystemMgr::INIT, 0.4);
////////////////////////////////////////////////////////////////////
// Initialize the ATC subsystem
////////////////////////////////////////////////////////////////////
globals->add_subsystem("ATC", new FGATCManager, SGSubsystemMgr::POST_FDM);
- ////////////////////////////////////////////////////////////////////
- // Initialise the ATIS Subsystem
- ////////////////////////////////////////////////////////////////////
- //globals->add_subsystem("atis", new FGAtisManager, SGSubsystemMgr::POST_FDM);
-
////////////////////////////////////////////////////////////////////
// Initialize multiplayer subsystem
#include <Aircraft/controls.hxx>
#include <Airports/runways.hxx>
-#include <ATCDCL/ATCmgr.hxx>
+#include <ATCDCL/ATISmgr.hxx>
#include <Autopilot/route_mgr.hxx>
#include <Cockpit/panel.hxx>
#include <GUI/FGFontCache.hxx>
matlib( NULL ),
route_mgr( NULL ),
current_panel( NULL ),
- ATC_mgr( NULL ),
+ ATIS_mgr( NULL ),
controls( NULL ),
viewmgr( NULL ),
commands( SGCommandMgr::instance() ),
delete route_mgr;
current_panel = NULL;
- delete ATC_mgr;
+ delete ATIS_mgr;
if (controls)
{
class SGSubsystem;
class SGSoundMgr;
-class FGATCMgr;
+class FGATISMgr;
class FGAircraftModel;
class FGControls;
class FGFlightPlanDispatcher;
SGSharedPtr<FGPanel> current_panel;
// ATC manager
- FGATCMgr *ATC_mgr;
+ FGATISMgr *ATIS_mgr;
// control input state
FGControls *controls;
inline SGMaterialLib *get_matlib() const { return matlib; }
inline void set_matlib( SGMaterialLib *m ) { matlib = m; }
- inline FGATCMgr *get_ATC_mgr() const { return ATC_mgr; }
- inline void set_ATC_mgr( FGATCMgr *a ) {ATC_mgr = a; }
+ inline FGATISMgr *get_ATIS_mgr() const { return ATIS_mgr; }
+ inline void set_ATIS_mgr( FGATISMgr *a ) {ATIS_mgr = a; }
inline FGPanel *get_current_panel() const { return current_panel; }
void set_current_panel( FGPanel *cp );
// Class references
#include <simgear/scene/model/modellib.hxx>
#include <simgear/scene/material/matlib.hxx>
-#include <simgear/scene/model/animation.hxx>
-#include <simgear/scene/sky/sky.hxx>
-#include <simgear/structure/event_mgr.hxx>
#include <simgear/props/AtomicChangeListener.hxx>
#include <simgear/props/props.hxx>
#include <simgear/timing/sg_time.hxx>
-#include <simgear/timing/timestamp.hxx>
#include <simgear/magvar/magvar.hxx>
-#include <simgear/math/sg_random.h>
#include <simgear/io/raw_socket.hxx>
#include <simgear/scene/tsync/terrasync.hxx>
+#include <simgear/sound/soundmgr_openal.hxx>
+#include <simgear/math/SGMath.hxx>
+#include <simgear/math/sg_random.h>
-#include <Time/light.hxx>
-#include <Aircraft/replay.hxx>
#include <Aircraft/controls.hxx>
#include <Model/panelnode.hxx>
-#include <Model/acmodel.hxx>
#include <Scenery/scenery.hxx>
#include <Scenery/tilemgr.hxx>
#include <Sound/fg_fx.hxx>
-#include <Sound/beacon.hxx>
-#include <Sound/morse.hxx>
-#include <Sound/fg_fx.hxx>
-#include <ATCDCL/ATCmgr.hxx>
#include <Time/TimeManager.hxx>
-#include <Environment/environment_mgr.hxx>
#include <GUI/gui.h>
-#include <GUI/new_gui.hxx>
-#include <MultiPlayer/multiplaymgr.hxx>
#include <Viewer/CameraGroup.hxx>
-#include <Viewer/viewer.hxx>
#include <Viewer/WindowSystemAdapter.hxx>
#include <Viewer/splash.hxx>
#include <Viewer/renderer.hxx>
using namespace flightgear;
using std::cerr;
+using std::vector;
// Specify our current idle function state. This is used to run all
// our initializations out of the idle callback so that we can get a