]> git.mxchange.org Git - flightgear.git/commitdiff
ATISMgr clean-up / improvements
authorThorstenB <brehmt@gmail.com>
Sun, 15 Jul 2012 18:05:10 +0000 (20:05 +0200)
committerThorstenB <brehmt@gmail.com>
Tue, 17 Jul 2012 17:32:12 +0000 (19:32 +0200)
Adds serviceable/operable properties to comm radio.
Obey comm radio power source (no power => no radio => no ATIS).
Also further clean-up to stuff belonging to former ATCmgr module.

src/ATCDCL/ATC.cxx
src/ATCDCL/ATC.hxx
src/ATCDCL/ATISmgr.cxx
src/ATCDCL/ATISmgr.hxx
src/ATCDCL/atis.cxx
src/ATCDCL/atis.hxx

index 0f0e0f9e4973aa0f4b2c4e4de87900bc045e20fb..5e03ca38308419a2dfc0895befd876ad90251376 100644 (file)
@@ -77,7 +77,7 @@ FGATC::~FGATC() {
 #ifndef OLD_ATC_MGR
 // 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) {
 
 #ifdef ENABLE_AUDIO_SUPPORT
     bool active = _atc_external->getBoolValue() ||
@@ -117,7 +117,7 @@ void FGATC::SetStation(flightgear::CommStation* sta) {
         freq = 0;
 
         SetNoDisplay();
-        Update(0);     // one last update
+        update(0);     // one last update
     }
     else
     {
index f709c1dcc41dbe33fe791077caeecbcc911cdca6..e57ebabd7d8a245df0606164c2bfbe4f8d8af7b6 100644 (file)
@@ -90,17 +90,17 @@ std::ostream& operator << (std::ostream& os, atc_type atc);
 class FGATC {
        friend class FGATISMgr;
 public:
-       
+
        FGATC();
        virtual ~FGATC();
-       
-       virtual void Init()=0;
-  
+
+       virtual void init()=0;
+
        // Run the internal calculations
        // Derived classes should call this method from their own Update methods if they 
        // wish to use the response timer functionality.
-       virtual void Update(double dt);
-       
+       virtual void update(double dt);
+
        // Indicate that this instance should output to the display if appropriate 
        inline void SetDisplay() { _display = true; }
        
@@ -141,7 +141,7 @@ public:
        inline atc_type GetType() { return _type; }
 
        // Set the core ATC data
-    void SetStation(flightgear::CommStation* sta);
+       void SetStation(flightgear::CommStation* sta);
 
        inline const std::string& get_ident() { return ident; }
        inline void set_ident(const std::string& id) { ident = id; }
index 0df65051e8bb95b402805172d01ed3d0c82d7057..1c5dc8ca7936dc2a23b40219ce2f8009dacc2341 100644 (file)
 #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(4),
+    _maxCommRadios(4)
 #ifdef ENABLE_AUDIO_SUPPORT
-    voice(true),
-    voice1(0)
-#else
-    voice(false)
+    ,useVoice(true),
+    voice(0)
 #endif
 {
     globals->set_ATIS_mgr(this);
@@ -56,58 +49,36 @@ FGATISMgr::~FGATISMgr()
 
     for (unsigned int unit = 0;unit < _maxCommRadios; ++unit)
     {
-        delete radios[unit].station;
-        radios[unit].station = NULL;
+        delete radios[unit];
+        radios[unit] = NULL;
     }
 
 #ifdef ENABLE_AUDIO_SUPPORT
-    delete voice1;
+    delete voice;
 #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;
         if (unit < _maxCommRadios/2)
-            ncunit = "comm[" + decimalNumeral(unit) + "]";
+            radios.push_back(new FGATIS("comm", unit));
         else
-            ncunit = "nav[" + decimalNumeral(unit - _maxCommRadios/2) + "]";
-        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);
+            radios.push_back(new FGATIS("nav", unit - _maxCommRadios/2));
     }
 }
 
+
 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);
+    FGATC* commRadio = radios[_currentUnit];
+    if (commRadio)
+        commRadio->update(dt * _maxCommRadios);
 }
 
 // Return a pointer to an appropriate voice for a given type of ATC
@@ -119,13 +90,13 @@ void FGATISMgr::update(double dt)
 // at different airports in quick succession if a large enough selection are available.
 FGATCVoice* FGATISMgr::GetVoicePointer(const atc_type& type)
 {
+#ifdef ENABLE_AUDIO_SUPPORT
     // TODO - implement me better - maintain a list of loaded voices and other voices!!
-    if(voice)
+    if(useVoice)
     {
         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
@@ -135,22 +106,19 @@ FGATCVoice* FGATISMgr::GetVoicePointer(const atc_type& type)
              *  subsequently switches /sim/sound/audible to true.
              *  (which is the right thing to do -- CLO) :-)
              */
-            if (!voice1 && fgGetBool("/sim/sound/working")) {
-                voice1 = new FGATCVoice;
+            if (!voice && fgGetBool("/sim/sound/working")) {
+                voice = new FGATCVoice;
                 try {
-                    voice = voice1->LoadVoice("default");
+                    useVoice = voice->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;
+                    useVoice = false;
+                    delete voice;
+                    voice = 0;
                 }
             }
-            if (voice)
-                return voice1;
-#endif
-            return NULL;
+            return voice;
         case TOWER:
             return NULL;
         case APPROACH:
@@ -161,52 +129,7 @@ FGATCVoice* FGATISMgr::GetVoicePointer(const atc_type& type)
             return NULL;
         }
     }
+#endif
 
     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);
-}
index 75ef3a30f98ef255b98742ca054714c4515423c2..716044f83fdc3a59f8aa4426df0165154180023c 100644 (file)
 // 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
+#ifndef _FG_ATISMGR_HXX
+#define _FG_ATISMGR_HXX
 
-#include <simgear/structure/subsystem_mgr.hxx>
+#include <vector>
 
-#include <string>
-#include <list>
-#include <map>
+#include <simgear/structure/subsystem_mgr.hxx>
 
 #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;
+    std::vector<FGATC*> radios;
 
     unsigned int _currentUnit;
     unsigned int _maxCommRadios;
-       
-    // Voice related stuff
-    bool voice;                        // Flag - true if we are using voice
+
 #ifdef ENABLE_AUDIO_SUPPORT
-    FGATCVoice* voice1;
+    bool useVoice;  // Flag - true if we are using voice
+    FGATCVoice* voice;
 #endif
 
 public:
@@ -75,11 +47,6 @@ public:
     ~FGATISMgr();
 
     void init();
-
-    void bind();
-
-    void unbind();
-
     void update(double dt);
 
     // Return a pointer to an appropriate voice for a given type of ATC
@@ -92,8 +59,6 @@ public:
     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
+#endif  // _FG_ATISMGR_HXX
index 95acc757b3dd33e01b05270faa915cd77fcd3465..36f2f66f03708b412efe629574e8abd08f60f847 100644 (file)
@@ -55,6 +55,7 @@
 #include <Airports/runways.hxx>
 #include <Airports/dynamics.hxx>
 
+#include <ATC/CommStation.hxx>
 
 #include "ATCutils.hxx"
 #include "ATISmgr.hxx"
@@ -65,8 +66,11 @@ using std::cout;
 using std::cout;
 using boost::ref;
 using boost::tie;
+using flightgear::CommStation;
 
-FGATIS::FGATIS(const string& commbase) :
+FGATIS::FGATIS(const std::string& name, int num) :
+  _name(name),
+  _num(num),
   transmission(""),
   trans_ident(""),
   old_volume(0),
@@ -74,10 +78,37 @@ FGATIS::FGATIS(const string& commbase) :
   msg_OK(0),
   attention(0),
   _prev_display(0),
-  _commbase(commbase)
+  _time_before_search_sec(0),
+  _last_frequency(0)
 {
   fgTie("/environment/attention", this, (int_getter)0, &FGATIS::attend);
 
+  _root         = fgGetNode("/instrumentation", true)->getNode(_name, num, true);
+  _volume       = _root->getNode("volume",true);
+  _serviceable  = _root->getNode("serviceable",true);
+
+  if (name != "nav")
+  {
+      // only drive "operable" for non-nav instruments (nav radio drives this separately)
+      _operable = _root->getNode("operable",true);
+      _operable->setBoolValue(false);
+  }
+
+  _electrical   = fgGetNode("/systems/electrical/outputs",true)->getNode(_name,num, true);
+  _atis         = _root->getNode("atis",true);
+  _freq         = _root->getNode("frequencies/selected-mhz",true);
+
+  // current position
+  _lon_node  = fgGetNode("/position/longitude-deg", true);
+  _lat_node  = fgGetNode("/position/latitude-deg",  true);
+  _elev_node = fgGetNode("/position/altitude-ft",   true);
+
+  // backward compatibility: some properties may not exist (but default to "ON")
+  if (!_serviceable->hasValue())
+      _serviceable->setBoolValue(true);
+  if (!_electrical->hasValue())
+      _electrical->setDoubleValue(24.0);
+
 ///////////////
 // FIXME:  This would be more flexible and more extensible
 // if the mappings were taken from an XML file, not hard-coded ...
@@ -115,7 +146,7 @@ FGATCVoice* FGATIS::GetVoicePointer()
     return pAtisMgr->GetVoicePointer(ATIS);
 }
 
-void FGATIS::Init() {
+void FGATIS::init() {
 // Nothing to see here.  Move along.
 }
 
@@ -134,7 +165,7 @@ FGATIS::attend (int attn)
 
 
 // Main update function - checks whether we are displaying or not the correct message.
-void FGATIS::Update(double dt) {
+void FGATIS::update(double dt) {
   cur_time = globals->get_time_params()->get_cur_time();
   msg_OK = (msg_time < cur_time);
 
@@ -148,28 +179,52 @@ void FGATIS::Update(double dt) {
   }
 #endif
 
-  if(_display)
+  double volume = 0;
+  if ((_electrical->getDoubleValue()>8) && _serviceable->getBoolValue())
+  {
+      _time_before_search_sec -= dt;
+      // radio is switched on and OK
+      if (_operable.valid())
+          _operable->setBoolValue(true);
+
+      // Search the tuned frequencies
+      search();
+
+      if (_display)
+      {
+          volume = _volume->getDoubleValue();
+      }
+  }
+  else
   {
-    string prop = _commbase + "/volume";
-    double volume = globals->get_props()->getDoubleValue(prop.c_str());
+      // radio is OFF
+      if (_operable.valid())
+          _operable->setBoolValue(false);
+      _time_before_search_sec = 0;
+  }
 
-// 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.
+  if (volume > 0.05)
+  {
+    // 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 changed = GenTransmission(!_prev_display, attention);
+
+    // update output property
     TreeOut(msg_OK);
+
     if (changed || volume != old_volume) {
-      //cout << "ATIS calling ATC::render  volume: " << volume << endl;
-      Render(transmission, volume, _commbase, true);
+      // audio output enabled
+      Render(transmission, volume, _name, true);
       old_volume = volume;
     }
+    _prev_display = _display;
   } else {
-// We shouldn't be displaying
-    //cout << "ATIS.CXX - calling NoRender()..." << endl;
-    NoRender(_commbase);
+    // silence
+    NoRender(_name);
+    _prev_display = false;
   }
-  _prev_display = _display;
   attention = 0;
 }
 
@@ -522,10 +577,74 @@ int FGATIS::GenTransmission(const int regen, const int special) {
 // http://localhost:5400/instrumentation/comm[1]
 //
 // (Also, if in debug mode, dump it to the console.)
-void FGATIS::TreeOut(int msg_OK){
-    string prop = _commbase + "/atis";
-    globals->get_props()->setStringValue(prop.c_str(),
-      ("<pre>\n" + transmission_readable + "</pre>\n").c_str());
-    SG_LOG(SG_ATC, SG_DEBUG, "**** ATIS active on: " << prop <<
+void FGATIS::TreeOut(int msg_OK)
+{
+    _atis->setStringValue("<pre>\n" + transmission_readable + "</pre>\n");
+    SG_LOG(SG_ATC, SG_DEBUG, "**** ATIS active on: " << _name <<
            "transmission: " << transmission_readable);
 }
+
+
+
+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 FGATIS::search(void)
+{
+    double frequency = _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);
+
+    // throttle frequency searches
+    if ((freqKhz == _last_frequency)&&(_time_before_search_sec > 0))
+        return;
+
+    _last_frequency = freqKhz;
+    _time_before_search_sec = 4.0;
+
+    // Position of the Users Aircraft
+    SGGeod aircraftPos = SGGeod::fromDegFt(_lon_node->getDoubleValue(),
+                                           _lat_node->getDoubleValue(),
+                                           _elev_node->getDoubleValue());
+
+    RangeFilter rangeFilter(aircraftPos );
+    CommStation* sta = CommStation::findByFreq(freqKhz, aircraftPos, &rangeFilter );
+    SetStation(sta);
+    if (sta && sta->airport())
+    {
+        SG_LOG(SG_ATC, SG_DEBUG, "FGATIS " << _name << ": " << sta->airport()->name());
+    }
+    else
+    {
+        SG_LOG(SG_ATC, SG_DEBUG, "FGATIS " << _name << ": no station.");
+    }
+}
index 8a79e9fb28d5f08400504dc59cb1224b01521d8d..bd67d8ec8be2df1712c1c1fda4744e310e4edee5 100644 (file)
 
 #include <simgear/compiler.h>
 #include <simgear/timing/sg_time.hxx>
+#include <simgear/props/props.hxx>
 
 #include "ATC.hxx"
 
-//DCL - a complete guess for now.
-#define FG_ATIS_DEFAULT_RANGE 30
-       
 typedef std::map<std::string,std::string> MSS;
 
 class FGATIS : public FGATC {
-       
-       //atc_type type;
-
-       // The actual ATIS transmission
-       // This is generated from the prevailing conditions when required.
-       // This is the version with markup, suitable for voice synthesis:
-       std::string transmission;
-       
-       // Same as above, but in a form more readable as text.
-       std::string transmission_readable;
-
-       // for failure modeling
-       std::string trans_ident;                // transmitted ident
-       double old_volume;
-       bool atis_failed;               // atis failed?
-       time_t msg_time;                // for moderating error messages
-       time_t cur_time;
-       int msg_OK;
-       int attention;
-       
-       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
-       // operation with the other ATC classes the ATIS class must calculate range to the aircraft in order
-       // to decide whether to render the transmission - hence the users plane details must be stored.
-       //SGPropertyNode_ptr airplane_lon_node; 
-       //SGPropertyNode_ptr airplane_lat_node;
-       //SGPropertyNode_ptr airplane_elev_node; 
-       
+
+    std::string        _name;
+    int                _num;
+
+    SGPropertyNode_ptr _root;
+    SGPropertyNode_ptr _volume;
+    SGPropertyNode_ptr _serviceable;
+    SGPropertyNode_ptr _operable;
+    SGPropertyNode_ptr _electrical;
+    SGPropertyNode_ptr _freq;
+    SGPropertyNode_ptr _atis;
+
+    // Pointers to current users position
+    SGPropertyNode_ptr _lon_node;
+    SGPropertyNode_ptr _lat_node;
+    SGPropertyNode_ptr _elev_node;
+
+    // The actual ATIS transmission
+    // This is generated from the prevailing conditions when required.
+    // This is the version with markup, suitable for voice synthesis:
+    std::string transmission;
+
+    // Same as above, but in a form more readable as text.
+    std::string transmission_readable;
+
+    // for failure modeling
+    std::string trans_ident; // transmitted ident
+    double old_volume;
+    bool atis_failed;        // atis failed?
+    time_t msg_time;         // for moderating error messages
+    time_t cur_time;
+    int msg_OK;
+    int attention;
+
+    bool _prev_display;      // Previous value of _display flag
+    MSS _remap;              // abbreviations to be expanded
+
+    // internal periodic station search timer
+    double _time_before_search_sec;
+    int _last_frequency;
+
 public:
-       
-       FGATIS(const std::string& commbase);
-       ~FGATIS(void);
-       virtual void Init();
-       void attend (int);
-
-       //run the ATIS instance
-       void Update(double dt);
-       
-       //inline void set_type(const atc_type tp) {type = tp;}
-       inline const std::string& get_trans_ident() { return trans_ident; }
-       
+
+    FGATIS(const std::string& name, int num);
+    ~FGATIS(void);
+    virtual void init();
+    void attend (int);
+
+    //run the ATIS instance
+    void update(double dt);
+
+    //inline void set_type(const atc_type tp) {type = tp;}
+    inline const std::string& get_trans_ident() { return trans_ident; }
+
 protected:
     virtual FGATCVoice* GetVoicePointer();
 
 private:
 
-       // Generate the ATIS transmission text:
-       int GenTransmission(const int regen, const int special);
-       
-       // Put the text into the property tree
-       // (and in debug mode, print it on the console):
-       void TreeOut(int msgOK);
+    // Generate the ATIS transmission text:
+    int GenTransmission(const int regen, const int special);
+
+    // Put the text into the property tree
+    // (and in debug mode, print it on the console):
+    void TreeOut(int msgOK);
+
+    // Search the specified radio for stations on the same frequency and in range.
+    void search(void);
 
-       friend std::istream& operator>> ( std::istream&, FGATIS& );
+    friend std::istream& operator>> ( std::istream&, FGATIS& );
 
 };