]> git.mxchange.org Git - flightgear.git/commitdiff
Cleanup of ATCDCL
authorTorsten Dreyer <torsten@t3r.de>
Wed, 30 Apr 2014 08:22:51 +0000 (10:22 +0200)
committerTorsten Dreyer <torsten@t3r.de>
Wed, 30 Apr 2014 08:22:51 +0000 (10:22 +0200)
- move FGATCAlignedProjection class as AlignedProjection
  to dclgps, the only place where it's currently used
- remove now obsolete files in ATCDCL

19 files changed:
src/ATCDCL/ATC.cxx [deleted file]
src/ATCDCL/ATC.hxx [deleted file]
src/ATCDCL/ATCProjection.cxx [deleted file]
src/ATCDCL/ATCProjection.hxx [deleted file]
src/ATCDCL/ATCVoice.cxx [deleted file]
src/ATCDCL/ATCVoice.hxx [deleted file]
src/ATCDCL/ATCutils.cxx [deleted file]
src/ATCDCL/ATCutils.hxx [deleted file]
src/ATCDCL/ATISmgr.cxx [deleted file]
src/ATCDCL/ATISmgr.hxx [deleted file]
src/ATCDCL/CMakeLists.txt [deleted file]
src/ATCDCL/atis.cxx [deleted file]
src/ATCDCL/atis.hxx [deleted file]
src/ATCDCL/atis_lexicon.hxx [deleted file]
src/ATCDCL/atis_remap.hxx [deleted file]
src/CMakeLists.txt
src/Instrumentation/KLN89/kln89.cxx
src/Instrumentation/dclgps.cxx
src/Instrumentation/dclgps.hxx

diff --git a/src/ATCDCL/ATC.cxx b/src/ATCDCL/ATC.cxx
deleted file mode 100644 (file)
index 2236619..0000000
+++ /dev/null
@@ -1,413 +0,0 @@
-// Implementation of FGATC - ATC subsystem base class.
-//
-// 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 "ATC.hxx"
-
-#include <iostream>
-
-#include <simgear/sound/soundmgr_openal.hxx>
-#include <simgear/sound/sample_group.hxx>
-#include <simgear/structure/exception.hxx>
-
-#include <Main/globals.hxx>
-#include <Main/fg_props.hxx>
-#include <ATC/CommStation.hxx>
-#include <Airports/airport.hxx>
-
-FGATC::FGATC() :
-    freq(0),
-    _currentStation(NULL),
-    range(0),
-    _voice(true),
-    _playing(false),
-    _sgr(NULL),
-    _type(INVALID),
-    _display(false)
-#ifdef OLD_ATC_MGR
-    ,freqClear(true),
-    receiving(false),
-    respond(false),
-    responseID(""),
-    runResponseCounter(false),
-    _runReleaseCounter(false),
-    responseReqd(false),
-    // Transmission timing stuff
-    pending_transmission(""),
-    _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();
-
-    _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);
-}
-
-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) {
-
-    // TODO This doesn't really do anything specific to this instance.
-    // All FGATCs share the same "_sgr" sound group. So this really should
-    // only be done once for all FGATCs.
-#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
-}
-#endif
-
-void FGATC::SetStation(flightgear::CommStation* sta) {
-    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();
-    }
-}
-
-// 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 FGATC::Render(std::string& msg, const float volume,
-                   const std::string& refname, const bool repeating) {
-    if ((!_display) ||(volume < 0.05))
-    {
-        NoRender(refname);
-        return;
-    }
-
-    if (repeating)
-        fgSetString("/sim/messages/atis", msg.c_str());
-    else
-        fgSetString("/sim/messages/atc", msg.c_str());
-
-#ifdef ENABLE_AUDIO_SUPPORT
-    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;
-            FGATCVoice* 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.
-                    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);
-    }
-#else
-    bool useVoice = false;
-#endif    // ENABLE_AUDIO_SUPPORT
-
-    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;
-}
-
-
-// Cease rendering a transmission.
-void FGATC::NoRender(const std::string& refname) {
-    if(_playing) {
-        if(_voice) {
-#ifdef ENABLE_AUDIO_SUPPORT
-            _sgr->stop(refname);
-            _sgr->remove(refname);
-#endif
-        }
-        _playing = false;
-    }
-}
-
-#ifdef OLD_ATC_MGR
-// 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
-
-    if(runResponseCounter) {
-        //cout << responseCounter << '\t' << responseTime << '\n';
-        if(responseCounter >= responseTime) {
-            runResponseCounter = false;
-            respond = true;
-            //cout << "RESPOND\n";
-        } else {
-            responseCounter += dt;
-        }
-    }
-
-    if(_runReleaseCounter) {
-        if(_releaseCounter >= _releaseTime) {
-            freqClear = true;
-            _runReleaseCounter = false;
-        } else {
-            _releaseCounter += dt;
-        }
-    }
-
-    // Transmission stuff cribbed from AIPlane.cxx
-    if(_pending) {
-        if(GetFreqClear()) {
-            //cout << "TUNED STATION FREQ CLEAR\n";
-            SetFreqInUse();
-            _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.
-                }
-            }
-        }
-    }
-
-    if(_transmit) {
-        _counter = 0.0;
-        _max_count = 5.0;        // FIXME - hardwired length of message - need to calculate it!
-
-        //cout << "Transmission = " << pending_transmission << '\n';
-        if(_display) {
-            //Render(pending_transmission, ident, false);
-            Render(pending_transmission);
-        }
-        _transmit = false;
-        _transmitting = true;
-    } else if(_transmitting) {
-        if(_counter >= _max_count) {
-            //NoRender(plane.callsign);  commented out since at the moment NoRender is designed just to stop repeating messages,
-            // and this will be primarily used on single messages.
-            _transmitting = false;
-            //if(tuned_station) tuned_station->NotifyTransmissionFinished(plane.callsign);
-            // TODO - need to let the plane the transmission is aimed at that it's finished.
-            // However, for now we'll just release the frequency since if we don't it all goes pear-shaped
-            _releaseCounter = 0.0;
-            _releaseTime = 0.9;
-            _runReleaseCounter = true;
-        }
-        _counter += dt;
-    }
-}
-
-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!!!");
-}
-
-void FGATC::SetResponseReqd(const string& rid) {
-    receiving = false;
-    responseReqd = true;
-    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??
-    responseID = rid;
-    runResponseCounter = true;
-    responseCounter = 0.0;
-    responseTime = 1.8;        // TODO - randomize this slightly.
-}
-
-void FGATC::NotifyTransmissionFinished(const string& rid) {
-    //cout << "Transmission finished, callsign = " << rid << '\n';
-    receiving = false;
-    responseID = rid;
-    if(responseReqd) {
-        runResponseCounter = true;
-        responseCounter = 0.0;
-        responseTime = 1.2;    // TODO - randomize this slightly, and allow it to be dependent on the transmission and how busy the ATC is.
-        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??
-    } else {
-        freqClear = true;
-    }
-}
-
-// Generate the text of a message from its parameters and the current context.
-string FGATC::GenText(const string& m, int c) {
-    return("");
-}
-
-ostream& operator << (ostream& os, atc_type atc) {
-    switch(atc) {
-        case(AWOS):       return(os << "AWOS");
-        case(ATIS):       return(os << "ATIS");
-        case(GROUND):     return(os << "GROUND");
-        case(TOWER):      return(os << "TOWER");
-        case(APPROACH):   return(os << "APPROACH");
-        case(DEPARTURE):  return(os << "DEPARTURE");
-        case(ENROUTE):    return(os << "ENROUTE");
-        case(INVALID):    return(os << "INVALID");
-    }
-    return(os << "ERROR - Unknown switch in atc_type operator << ");
-}
-
-std::istream& operator >> ( std::istream& fin, ATCData& a )
-{
-    double f;
-    char ch;
-    char tp;
-
-    fin >> tp;
-
-    switch(tp) {
-    case 'I':
-        a.type = ATIS;
-        break;
-    case 'T':
-        a.type = TOWER;
-        break;
-    case 'G':
-        a.type = GROUND;
-        break;
-    case 'A':
-        a.type = APPROACH;
-        break;
-    case '[':
-        a.type = INVALID;
-        return fin >> skipeol;
-    default:
-        SG_LOG(SG_ATC, SG_ALERT, "Warning - unknown type \'" << tp << "\' found whilst reading ATC frequency data!\n");
-        a.type = INVALID;
-        return fin >> skipeol;
-    }
-
-    double lat, lon, elev;
-
-    fin >> lat >> lon >> elev >> f >> a.range >> a.ident;
-    a.geod = SGGeod::fromDegM(lon, lat, elev);
-    a.name = "";
-    fin >> ch;
-    if(ch != '"') a.name += ch;
-    while(1) {
-        //in >> noskipws
-        fin.unsetf(std::ios::skipws);
-        fin >> ch;
-        if((ch == '"') || (ch == 0x0A)) {
-            break;
-        }   // we shouldn't need the 0x0A but it makes a nice safely in case someone leaves off the "
-        a.name += ch;
-    }
-    fin.setf(std::ios::skipws);
-    //cout << "Comm name = " << a.name << '\n';
-
-    a.freq = (int)(f*100.0 + 0.5);
-
-    // cout << a.ident << endl;
-
-    // generate cartesian coordinates
-    a.cart = SGVec3d::fromGeod(a.geod);
-    return fin >> skipeol;
-}
-#endif
diff --git a/src/ATCDCL/ATC.hxx b/src/ATCDCL/ATC.hxx
deleted file mode 100644 (file)
index 6a0918a..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-// FGATC - abstract base class for the various actual atc classes 
-// such as FGATIS, FGTower etc.
-//
-// Written by David Luff, started Feburary 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_ATC_HXX
-#define _FG_ATC_HXX
-
-#include <simgear/constants.h>
-#include <simgear/compiler.h>
-#include <simgear/props/props.hxx>
-#include <simgear/misc/sgstream.hxx>
-#include <simgear/math/sg_geodesy.hxx>
-#include <simgear/debug/logstream.hxx>
-#include <simgear/structure/SGSharedPtr.hxx>
-
-#include <iosfwd>
-#include <string>
-
-#include "ATCVoice.hxx"
-
-class SGSampleGroup;
-
-namespace flightgear
-{
-    class CommStation;
-}
-
-// Possible types of ATC type that the radios may be tuned to.
-// INVALID implies not tuned in to anything.
-enum atc_type {
-       AWOS,
-       ATIS,
-       GROUND,
-       TOWER,
-       APPROACH,
-       DEPARTURE,
-       ENROUTE,
-       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
-struct ATCData {
-       ATCData() : type(INVALID), cart(0, 0, 0), freq(0), range(0) {}
-       atc_type type;
-       SGGeod geod;
-       SGVec3d cart;
-       unsigned short int freq;
-       unsigned short int range;
-       std::string ident;
-       std::string name;
-};
-
-// perhaps we could use an FGRunway instead of this.
-// That wouldn't cache the orthopos though.
-struct RunwayDetails {
-       RunwayDetails() : end1ortho(0, 0, 0), end2ortho(0, 0, 0), hdg(0), length(-1), width(-1) {}
-       SGGeod threshold_pos;
-       SGVec3d end1ortho;      // ortho projection end1 (the threshold ATM)
-       SGVec3d end2ortho;      // ortho projection end2 (the take off end in the current hardwired scheme)
-       double hdg;             // true runway heading
-       double length;  // In *METERS*
-       double width;   // ditto
-       std::string rwyID;
-       int patternDirection;   // -1 for left, 1 for right
-};
-
-std::ostream& operator << (std::ostream& os, atc_type atc);
-#endif
-
-class FGATC {
-       friend class FGATISMgr;
-public:
-
-       FGATC();
-       virtual ~FGATC();
-
-       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);
-
-       // 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);
-       
-       // Returns true if OK to transmit on this frequency
-       inline bool GetFreqClear() { return freqClear; }
-       // Indicate that the frequency is in use
-       inline void SetFreqInUse() { freqClear = false; receiving = true; }
-       // Transmission to the ATC is finished and a response is required
-       void SetResponseReqd(const std::string& rid);
-       // Transmission finished - let ATC decide if a response is reqd and clear freq if necessary
-       void NotifyTransmissionFinished(const std::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 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.
-       
-       
-
-       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
-       // 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(std::string& msg, const float volume = 1.0, 
-                   const std::string& refname = "", bool repeating = false);
-       
-       // Cease rendering all transmission from this station.
-       // Requires the sound manager refname if audio, else "".
-       void NoRender(const std::string& refname);
-       
-       virtual FGATCVoice* GetVoicePointer() = 0;
-
-       SGGeod _geod;
-       SGVec3d _cart;
-       int freq;
-       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
-
-       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
-       
-       
-       double responseTime; // Time to take from end of request transmission to beginning of response
-                                                // The idea is that this will be slightly random.
-       
-       bool respond;   // Flag to indicate now is the time to respond - ie set following the count down of the response timer.
-       std::string responseID; // ID of the plane to respond to
-       bool runResponseCounter;        // Flag to indicate the response counter should be run
-       double responseCounter; // counter to implement the above
-       // Derived classes only need monitor this flag, and use the response ID, as long as they call FGATC::Update(...)
-       bool _runReleaseCounter;        // A timer for releasing the frequency after giving the message enough time to display
-       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.
-
-private:
-
-#ifdef OLD_ATC_MGR
-       // Transmission timing stuff.
-       double _timeout;
-       bool _pending;
-       bool _transmit;         // we are to transmit
-       bool _transmitting;     // we are transmitting
-       double _counter;
-       double _max_count;
-#endif
-
-       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
diff --git a/src/ATCDCL/ATCProjection.cxx b/src/ATCDCL/ATCProjection.cxx
deleted file mode 100644 (file)
index ecc08cc..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-// ATCProjection.cxx - A convenience projection class for the ATC/AI system.
-//
-// Written by David Luff, started 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 "ATCProjection.hxx"
-#include <math.h>
-#include <simgear/constants.h>
-
-FGATCAlignedProjection::FGATCAlignedProjection() {
-    _origin.setLatitudeRad(0);
-    _origin.setLongitudeRad(0);
-    _origin.setElevationM(0);
-    _correction_factor = cos(_origin.getLatitudeRad());
-}
-
-FGATCAlignedProjection::FGATCAlignedProjection(const SGGeod& centre, double heading) {
-    _origin = centre;
-    _theta = heading * SG_DEGREES_TO_RADIANS;
-    _correction_factor = cos(_origin.getLatitudeRad());
-}
-
-FGATCAlignedProjection::~FGATCAlignedProjection() {
-}
-
-void FGATCAlignedProjection::Init(const SGGeod& centre, double heading) {
-    _origin = centre;
-    _theta = heading * SG_DEGREES_TO_RADIANS;
-    _correction_factor = cos(_origin.getLatitudeRad());
-}
-
-SGVec3d FGATCAlignedProjection::ConvertToLocal(const SGGeod& pt) {
-    // convert from lat/lon to orthogonal
-    double delta_lat = pt.getLatitudeRad() - _origin.getLatitudeRad();
-    double delta_lon = pt.getLongitudeRad() - _origin.getLongitudeRad();
-    double y = sin(delta_lat) * SG_EQUATORIAL_RADIUS_M;
-    double x = sin(delta_lon) * SG_EQUATORIAL_RADIUS_M * _correction_factor;
-
-    // Align
-    if(_theta != 0.0) {
-        double xbar = x;
-        x = x*cos(_theta) - y*sin(_theta);
-        y = (xbar*sin(_theta)) + (y*cos(_theta));
-    }
-
-    return SGVec3d(x, y, pt.getElevationM());
-}
-
-SGGeod FGATCAlignedProjection::ConvertFromLocal(const SGVec3d& pt) {
-    // de-align
-    double thi = _theta * -1.0;
-    double x = pt.x()*cos(thi) - pt.y()*sin(thi);
-    double y = (pt.x()*sin(thi)) + (pt.y()*cos(thi));
-
-    // convert from orthogonal to lat/lon
-    double delta_lat = asin(y / SG_EQUATORIAL_RADIUS_M);
-    double delta_lon = asin(x / SG_EQUATORIAL_RADIUS_M) / _correction_factor;
-
-    return SGGeod::fromRadM(_origin.getLongitudeRad()+delta_lon, _origin.getLatitudeRad()+delta_lat, pt.z());
-}
diff --git a/src/ATCDCL/ATCProjection.hxx b/src/ATCDCL/ATCProjection.hxx
deleted file mode 100644 (file)
index 94dfb92..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-// ATCProjection.hxx - A convenience projection class for the ATC/AI system.
-//
-// Written by David Luff, started 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_ATC_PROJECTION_HXX
-#define _FG_ATC_PROJECTION_HXX
-
-#include <simgear/math/SGMath.hxx>
-
-// FGATCAlignedProjection - a class to project an area local to a runway onto an orthogonal co-ordinate system
-// with the origin at the threshold and the runway aligned with the y axis.
-class FGATCAlignedProjection {
-
-public:
-    FGATCAlignedProjection();
-    FGATCAlignedProjection(const SGGeod& centre, double heading);
-    ~FGATCAlignedProjection();
-
-    void Init(const SGGeod& centre, double heading);
-
-    // Convert a lat/lon co-ordinate (degrees) to the local projection (meters)
-    SGVec3d ConvertToLocal(const SGGeod& pt);
-
-    // Convert a local projection co-ordinate (meters) to lat/lon (degrees)
-    SGGeod ConvertFromLocal(const SGVec3d& pt);
-
-private:
-    SGGeod _origin;    // lat/lon of local area origin (the threshold)
-    double _theta;     // the rotation angle for alignment in radians
-    double _correction_factor; // Reduction in surface distance per degree of longitude due to latitude.  Saves having to do a cos() every call.
-
-};
-
-#endif // _FG_ATC_PROJECTION_HXX
diff --git a/src/ATCDCL/ATCVoice.cxx b/src/ATCDCL/ATCVoice.cxx
deleted file mode 100644 (file)
index 71f15e5..0000000
+++ /dev/null
@@ -1,297 +0,0 @@
-// FGATCVoice.cxx - a class to encapsulate an ATC voice
-//
-// Written by David Luff, started November 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 "ATCVoice.hxx"
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <fstream>
-#include <vector>
-#include <algorithm>
-
-#include <simgear/sound/soundmgr_openal.hxx>
-#include <simgear/sound/sample_openal.hxx>
-#include <simgear/misc/sg_dir.hxx>
-
-#include <simgear/misc/sg_path.hxx>
-#include <simgear/debug/logstream.hxx>
-#include <simgear/misc/sgstream.hxx>
-#include <simgear/math/sg_random.h>
-
-#include <Main/globals.hxx>
-
-using namespace std;
-
-FGATCVoice::FGATCVoice() :
-    rawSoundData(0),
-    rawDataSize(0),
-    SoundData(0)
-{
-}
-
-FGATCVoice::~FGATCVoice() {
-    if (rawSoundData)
-        free( rawSoundData );
-    delete SoundData;
-}
-
-// Load all data for the requested voice.
-// Return true if successful.
-bool FGATCVoice::LoadVoice(const string& voicename)
-{
-    rawDataSize = 0;
-    if (rawSoundData)
-        free(rawSoundData);
-    rawSoundData = NULL;
-
-    // determine voice directory
-    SGPath voicepath = globals->get_fg_root();
-    voicepath.append( "ATC" );
-    voicepath.append( "voices" );
-    voicepath.append( voicename );
-
-    simgear::Dir d(voicepath);
-    if (!d.exists())
-    {
-        SG_LOG(SG_ATC, SG_ALERT, "Unable to load ATIS voice. No such directory: " << voicepath.str());
-        return false;
-    }
-
-    // load all files from the voice's directory
-    simgear::PathList paths = d.children(simgear::Dir::TYPE_FILE);
-    bool Ok = false;
-    for (unsigned int i=0; i<paths.size(); ++i)
-    {
-        if (paths[i].lower_extension() == "vce")
-            Ok |= AppendVoiceFile(voicepath, paths[i].file_base());
-    }
-
-    if (!Ok)
-    {
-        SG_LOG(SG_ATC, SG_ALERT, "Unable to load ATIS voice. Files are invalid or no files in directory: " << voicepath.str());
-    }
-
-    // ok when at least some files loaded fine
-    return Ok;
-}
-
-// load a voice file and append it to the current word database
-bool FGATCVoice::AppendVoiceFile(const SGPath& basepath, const string& file)
-{
-    size_t offset = 0;
-
-    SG_LOG(SG_ATC, SG_INFO, "Loading ATIS voice file: " << file);
-
-    // path to compressed voice file
-    SGPath path(basepath);
-    path.append(file + ".wav.gz");
-
-    // load wave data
-    SGSoundMgr *smgr = globals->get_soundmgr();
-    int format, freq;
-    void *data;
-    size_t size;
-    if (!smgr->load(path.str(), &data, &format, &size, &freq))
-        return false;
-
-    // append to existing data
-    if (!rawSoundData)
-        rawSoundData = (char*)data;
-    else
-    {
-        rawSoundData = (char*) realloc(rawSoundData, rawDataSize + size);
-        // new data starts behind existing sound data
-        offset = rawDataSize;
-        if (!rawSoundData)
-        {
-            SG_LOG(SG_ATC, SG_ALERT, "Out of memory. Cannot load file " << path.str());
-            rawDataSize = 0;
-            return false;
-        }
-        // append to existing sound data
-        memcpy(rawSoundData+offset, data, size);
-        free(data);
-        data = NULL;
-    }
-    rawDataSize += size;
-
-#ifdef VOICE_TEST
-       cout << "ATCVoice:  format: " << format
-                       << "  size: " << rawDataSize << endl;
-#endif
-
-       // load and parse index file (.vce)
-       return ParseVoiceIndex(basepath, file, offset);
-}
-
-// Load and parse a voice index file (.vce)
-bool FGATCVoice::ParseVoiceIndex(const SGPath& basepath, const string& file, size_t globaloffset)
-{
-       // path to voice index file
-       SGPath path(basepath);
-       path.append(file + ".vce");
-       
-       // Now load the word data
-       std::ifstream fin;
-       fin.open(path.c_str(), ios::in);
-       if(!fin) {
-               SG_LOG(SG_ATC, SG_ALERT, "Unable to open input file " << path.c_str());
-               return(false);
-       }
-       SG_LOG(SG_ATC, SG_INFO, "Opened word data file " << path.c_str() << " OK...");
-
-       char numwds[10];
-       char wrd[100];
-       string wrdstr;
-       char wrdOffsetStr[20];
-       char wrdLengthStr[20];
-       unsigned int wrdOffset;         // Offset into the raw sound data that the word sample begins
-       unsigned int wrdLength;         // Length of the word sample in bytes
-       WordData wd;
-
-       // first entry: number of words in the index
-       fin >> numwds;
-       unsigned int numwords = atoi(numwds);
-       //cout << numwords << '\n';
-
-       // now load each word, its file offset and length
-       for(unsigned int i=0; i < numwords; ++i) {
-           // read data
-               fin >> wrd;
-               fin >> wrdOffsetStr;
-               fin >> wrdLengthStr;
-
-               wrdstr    = wrd;
-               wrdOffset = atoi(wrdOffsetStr);
-               wrdLength = atoi(wrdLengthStr);
-
-               // store word in map
-               wd.offset = wrdOffset + globaloffset;
-               wd.length = wrdLength;
-               wordMap[wrdstr] = wd;
-
-               // post-process words
-               string ws2 = wrdstr;
-               for(string::iterator p = ws2.begin(); p != ws2.end(); p++){
-                   *p = tolower(*p);
-                   if (*p == '-')
-                       *p = '_';
-               }
-
-               // store alternative version of word (lowercase/no hyphen)
-               if (wrdstr != ws2)
-                   wordMap[ws2] = wd;
-
-               //cout << wrd << "\t\t" << wrdOffset << "\t\t" << wrdLength << '\n';
-               //cout << i << '\n';
-       }
-
-       fin.close();
-       return(true);
-}
-
-
-// Given a desired message, return a string containing the
-// sound-sample data
-void* FGATCVoice::WriteMessage(const string& message, size_t* len) {
-       
-       // What should we do here?
-       // First - parse the message into a list of tokens.
-       // Sort the tokens into those we understand and those we don't.
-       // Add all the raw lengths of the token sound data, allocate enough space, and fill it with the rqd data.
-
-       vector<char> sound;
-       const char delimiters[] = " \t.,;:\"\n";
-       string::size_type token_start = message.find_first_not_of(delimiters);
-       while(token_start != string::npos) {
-               string::size_type token_end = message.find_first_of(delimiters, token_start);
-               string token;
-               if (token_end == string::npos) {
-                       token = message.substr(token_start);
-                       token_start = string::npos;
-               } else {
-                       token = message.substr(token_start, token_end - token_start);
-                       token_start = message.find_first_not_of(delimiters, token_end);
-               }
-
-                if (token == "/_") continue;
-
-               for(string::iterator t = token.begin(); t != token.end(); t++) {
-                       // canonicalize the token, to match what's in the index
-                       *t = (*t == '-') ? '_' : tolower(*t);
-               }
-               SG_LOG(SG_ATC, SG_DEBUG, "voice synth: token: '"
-                    << token << "'");
-
-               atc_word_map_const_iterator wordIt = wordMap.find(token);
-               if(wordIt == wordMap.end()) {
-                       // Oh dear - the token isn't in the sound file
-                       SG_LOG(SG_ATC, SG_ALERT, "voice synth: word '"
-                               << token << "' not found");
-               } else {
-                       const WordData& word = wordIt->second;
-                       /*
-                       *  Sanity check for corrupt/mismatched sound data input - avoids a seg fault
-                       *  (As long as the calling function checks the return value!!)
-                       *  This check should be left in even when the default Flightgear files are known
-                       *  to be OK since it checks for mis-indexing of voice files by 3rd party developers.
-                       */
-                       if((word.offset + word.length) > rawDataSize) {
-                               SG_LOG(SG_ATC, SG_ALERT, "ERROR - mismatch between ATC .wav and .vce file in ATCVoice.cxx\n");
-                               SG_LOG(SG_ATC, SG_ALERT, "Offset + length: " << word.offset + word.length
-                                       << " exceeds rawdata size: " << rawDataSize << endl);
-
-                               *len = 0;
-                               return 0;
-                       }
-                       sound.insert(sound.end(), rawSoundData + word.offset, rawSoundData + word.offset + word.length);
-               }
-       }
-
-       // Check for no tokens found else slScheduler can be crashed
-       *len = sound.size();
-       if (*len == 0) {
-               return 0;
-       }
-
-       char* data = (char*)malloc(*len);
-       if (data == 0) {
-               SG_LOG(SG_ATC, SG_ALERT, "ERROR - could not allocate " << *len << " bytes of memory for ATIS sound\n");
-               *len = 0;
-               return 0;
-       }
-
-       // randomize start position
-       unsigned int offsetIn = (unsigned int)(*len * sg_random());
-       if (offsetIn > 0 && offsetIn < *len) {
-               copy(sound.begin() + offsetIn, sound.end(), data);
-               copy(sound.begin(), sound.begin() + offsetIn, data + *len - offsetIn);
-       } else {
-               copy(sound.begin(), sound.end(), data);
-       }
-
-       return data;
-}
diff --git a/src/ATCDCL/ATCVoice.hxx b/src/ATCDCL/ATCVoice.hxx
deleted file mode 100644 (file)
index 55fe68a..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-// FGATCVoice.hxx - a class to encapsulate an ATC voice
-//
-// Written by David Luff, started November 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_ATC_VOICE
-#define _FG_ATC_VOICE
-
-#include <simgear/compiler.h>
-#include <simgear/structure/SGSharedPtr.hxx>
-
-#include <map>
-#include <string>
-
-class SGSoundSample;
-class SGPath;
-
-struct WordData {
-       unsigned int offset;    // Offset of beginning of word sample into raw sound sample
-       unsigned int length;    // Byte length of word sample
-};
-
-typedef std::map < std::string, WordData > atc_word_map_type;
-typedef atc_word_map_type::iterator atc_word_map_iterator;
-typedef atc_word_map_type::const_iterator atc_word_map_const_iterator;
-
-class FGATCVoice {
-
-public:
-
-       FGATCVoice();
-       ~FGATCVoice();
-
-       // Load the two voice files - one containing the raw sound data (.wav) and one containing the word positions (.vce).
-       // Return true if successful.   
-       bool LoadVoice(const std::string& voicename);
-       
-       // Given a desired message, return a pointer to the data buffer and write the buffer length into len.
-       // Sets len to something other than 0 if the returned buffer is valid.
-       void* WriteMessage(const std::string& message, size_t *len);
-
-private:
-       bool AppendVoiceFile(const SGPath& basepath, const std::string& file);
-       bool ParseVoiceIndex(const SGPath& basepath, const std::string& file, size_t globaloffset);
-
-       // the sound and word position data
-       char* rawSoundData;
-       size_t rawDataSize;
-        SGSharedPtr<SGSoundSample> SoundData;
-
-       // A map of words vs. byte position and length in rawSoundData
-       atc_word_map_type wordMap;
-
-};
-
-#endif // _FG_ATC_VOICE
diff --git a/src/ATCDCL/ATCutils.cxx b/src/ATCDCL/ATCutils.cxx
deleted file mode 100644 (file)
index 2960401..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-// ATCutils.cxx - Utility functions for the ATC / AI system
-//
-// Written by David Luff, started March 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 <sstream>
-#include <cstdlib>
-
-#include <simgear/constants.h>
-#include <simgear/misc/sg_path.hxx>
-#include <simgear/debug/logstream.hxx>
-
-#include <Airports/runways.hxx>
-#include <Main/globals.hxx>
-
-#include "ATCutils.hxx"
-#include "ATCProjection.hxx"
-
-static const string nums[10] = {"zero", "one", "two", "three", "four",
-                               "five", "six", "seven", "eight", "niner"}; 
-
-static const string letters[LTRS] = {
-    "alpha",    "bravo",    "charlie",   "delta",     "echo",
-    "foxtrot",  "golf",     "hotel",     "india",     "juliet",
-    "kilo",     "lima",     "mike",      "november",  "oscar",
-    "papa",     "quebec",   "romeo",     "sierra",    "tango",
-    "uniform",  "victor",   "whiskey",   "xray",      "yankee",    "zulu"
-};
-
-// Convert any number to spoken digits
-string ConvertNumToSpokenDigits(const string &n) {
-       //cout << "n = " << n << endl;
-       static const string pt = "decimal";
-       string str = "";
-       
-       for(unsigned int i=0; i<n.length(); ++i) {
-               //cout << "n.substr(" << i << ",1 = " << n.substr(i,1) << endl;
-               if(n.substr(i,1) == " ") {
-                       // do nothing
-               } else if(n.substr(i,1) == ".") {
-                       str += pt;
-               } else {
-                       str += nums[atoi((n.substr(i,1)).c_str())];
-               }
-               if(i != (n.length()-1)) {       // ie. don't add a space at the end.
-                       str += " ";
-               }
-       }
-       return(str);
-}
-
-// Convert an integer to a decimal numeral string
-string decimalNumeral(const int& n) {
-       std::ostringstream buf;
-       buf << n;
-       return buf.str();
-}
-
-// Convert an integer to spoken digits
-string ConvertNumToSpokenDigits(const int& n) {
-       return ConvertNumToSpokenDigits(decimalNumeral(n));
-}
-
-
-// Assumes we get a string of digits optionally appended with L, R or C
-// eg 1 7L 29R 36
-// Anything else is not guaranteed to be handled correctly!
-string ConvertRwyNumToSpokenString(const string &rwy) {
-  string rslt;
-  for (size_t ii = 0; ii < rwy.length(); ii++){
-    if (rslt.length()) rslt += " ";
-    string ch = rwy.substr(ii,1);
-    if (isdigit(ch[0])) rslt += ConvertNumToSpokenDigits(atoi(ch.c_str()));
-    else if (ch == "R") rslt += "right";
-    else if (ch == "C") rslt += "center";
-    else if (ch == "L") rslt += "left";
-    else {
-      rslt += GetPhoneticLetter(ch[0]);
-      SG_LOG(SG_ATC, SG_WARN, "WARNING: Unknown suffix '" << ch 
-         << "' in runway " << rwy << " in ConvertRwyNumToSpokenString(...)");
-    }
-  }
-  return rslt;
-}
-       
-
-// Return the phonetic letter of a letter represented as an integer 1->26
-string GetPhoneticLetter(const int i) {
-       return(letters[i % LTRS]);
-}
-
-// Return the phonetic letter of a character in the range a-z or A-Z.
-// Currently always returns prefixed by lowercase.
-string GetPhoneticLetter(const char c) {
-       return GetPhoneticLetter(int(tolower(c) - 'a'));
-}
-
-// Get the compass direction associated with a heading in degrees
-// Currently returns 8 direction resolution (N, NE, E etc...)
-// Might be modified in future to return 4, 8 or 16 resolution but defaulting to 8. 
-string GetCompassDirection(double h) {
-       while(h < 0.0) h += 360.0;
-       while(h > 360.0) h -= 360.0;
-       if(h < 22.5 || h > 337.5) {
-               return("North");
-       } else if(h < 67.5) {
-               return("North-East");
-       } else if(h < 112.5) {
-               return("East");
-       } else if(h < 157.5) {
-               return("South-East");
-       } else if(h < 202.5) {
-               return("South");
-       } else if(h < 247.5) {
-               return("South-West");
-       } else if(h < 292.5) {
-               return("West");
-       } else {
-               return("North-West");
-       }
-}
-
-//================================================================================================================
-
-// Given two positions (lat & lon in degrees), get the HORIZONTAL separation (in meters)
-double dclGetHorizontalSeparation(const SGGeod& pos1, const SGGeod& pos2) {
-       double x;       //East-West separation
-       double y;       //North-South separation
-       double z;       //Horizontal separation - z = sqrt(x^2 + y^2)
-       
-       double lat1 = pos1.getLatitudeRad();
-       double lon1 = pos1.getLongitudeRad();
-       double lat2 = pos2.getLatitudeRad();
-       double lon2 = pos2.getLongitudeRad();
-       
-       y = sin(fabs(lat1 - lat2)) * SG_EQUATORIAL_RADIUS_M;
-       x = sin(fabs(lon1 - lon2)) * SG_EQUATORIAL_RADIUS_M * (cos((lat1 + lat2) / 2.0));
-       z = sqrt(x*x + y*y);
-       
-       return(z);
-}
-
-// Given a point and a line, get the HORIZONTAL shortest distance from the point to a point on the line.
-// Expects to be fed orthogonal co-ordinates, NOT lat & lon !
-// The units of the separation will be those of the input.
-double dclGetLinePointSeparation(double px, double py, double x1, double y1, double x2, double y2) {
-       double vecx = x2-x1;
-       double vecy = y2-y1;
-       double magline = sqrt(vecx*vecx + vecy*vecy);
-       double u = ((px-x1)*(x2-x1) + (py-y1)*(y2-y1)) / (magline * magline);
-       double x0 = x1 + u*(x2-x1);
-       double y0 = y1 + u*(y2-y1);
-       vecx = px - x0;
-       vecy = py - y0;
-       double d = sqrt(vecx*vecx + vecy*vecy);
-       if(d < 0) {
-               d *= -1;
-       }
-       return(d);
-}
-
-// Given a position (lat/lon/elev), heading and vertical angle (degrees), and distance (meters), calculate the new position.
-// This function assumes the world is spherical.  If geodetic accuracy is required use the functions is sg_geodesy instead!
-// Assumes that the ground is not hit!!!  Expects heading and angle in degrees, distance in meters. 
-SGGeod dclUpdatePosition(const SGGeod& pos, double heading, double angle, double distance) {
-    // FIXME: use SGGeodesy instead ...
-
-       //cout << setprecision(10) << pos.lon() << ' ' << pos.lat() << '\n';
-       heading *= DCL_DEGREES_TO_RADIANS;
-       angle *= DCL_DEGREES_TO_RADIANS;
-       double lat = pos.getLatitudeRad();
-       double lon = pos.getLongitudeRad();
-       double elev = pos.getElevationM();
-       //cout << setprecision(10) << lon*DCL_RADIANS_TO_DEGREES << ' ' << lat*DCL_RADIANS_TO_DEGREES << '\n';
-       
-       double horiz_dist = distance * cos(angle);
-       double vert_dist = distance * sin(angle);
-       
-       double north_dist = horiz_dist * cos(heading);
-       double east_dist = horiz_dist * sin(heading);
-       
-       //cout << distance << ' ' << horiz_dist << ' ' << vert_dist << ' ' << north_dist << ' ' << east_dist << '\n';
-       
-       double delta_lat = asin(north_dist / (double)SG_EQUATORIAL_RADIUS_M);
-       double delta_lon = asin(east_dist / (double)SG_EQUATORIAL_RADIUS_M) * (1.0 / cos(lat));  // I suppose really we should use the average of the original and new lat but we'll assume that this will be good enough.
-       //cout << delta_lon*DCL_RADIANS_TO_DEGREES << ' ' << delta_lat*DCL_RADIANS_TO_DEGREES << '\n';
-       lat += delta_lat;
-       lon += delta_lon;
-       elev += vert_dist;
-       //cout << setprecision(10) << lon*DCL_RADIANS_TO_DEGREES << ' ' << lat*DCL_RADIANS_TO_DEGREES << '\n';
-       
-       //cout << setprecision(15) << DCL_DEGREES_TO_RADIANS * DCL_RADIANS_TO_DEGREES << '\n';
-       
-       return SGGeod::fromRadM(lon, lat, elev);
-}
-
-// Get a heading in degrees from one lat/lon to another.
-// This function assumes the world is spherical.  If geodetic accuracy is required use the functions is sg_geodesy instead!
-// Warning - at the moment we are not checking for identical points - currently it returns 0 in this instance.
-double GetHeadingFromTo(const SGGeod& A, const SGGeod& B) {
-       double latA = A.getLatitudeRad();
-       double lonA = A.getLongitudeRad();
-       double latB = B.getLatitudeRad();
-       double lonB = B.getLongitudeRad();
-       double xdist = sin(lonB - lonA) * (double)SG_EQUATORIAL_RADIUS_M * cos((latA+latB)/2.0);
-       double ydist = sin(latB - latA) * (double)SG_EQUATORIAL_RADIUS_M;
-       double heading = atan2(xdist, ydist) * DCL_RADIANS_TO_DEGREES;
-       return heading < 0.0 ? heading + 360 : heading;
-}
-
-// Given a heading (in degrees), bound it from 0 -> 360
-void dclBoundHeading(double &hdg) {
-       while(hdg < 0.0) {
-               hdg += 360.0;
-       }
-       while(hdg > 360.0) {
-               hdg -= 360.0;
-       }
-}
-
-// smallest difference between two angles in degrees
-// difference is negative if a1 > a2 and positive if a2 > a1
-double GetAngleDiff_deg( const double &a1, const double &a2) {
-  
-  double a3 = a2 - a1;
-  while (a3 < 180.0) a3 += 360.0;
-  while (a3 > 180.0) a3 -= 360.0;
-
-  return a3;
-}
-
-// Runway stuff
-// Given (lon/lat/elev) and an FGRunway struct, determine if the point lies on the runway
-bool OnRunway(const SGGeod& pt, const FGRunwayBase* rwy) {
-       FGATCAlignedProjection ortho;
-       SGGeod centre = SGGeod::fromDegM(rwy->longitude(), rwy->latitude(), 0); // We don't need the elev
-       ortho.Init(centre, rwy->headingDeg());
-       
-       SGVec3d xyc = ortho.ConvertToLocal(centre);
-       SGVec3d xyp = ortho.ConvertToLocal(pt);
-       
-       //cout << "Length offset = " << fabs(xyp.y() - xyc.y()) << '\n';
-       //cout << "Width offset = " << fabs(xyp.x() - xyc.x()) << '\n';
-       
-       if((fabs(xyp.y() - xyc.y()) < ((rwy->lengthFt()/2.0) + 5.0)) 
-               && (fabs(xyp.x() - xyc.x()) < (rwy->widthFt()/2.0))) {
-               return(true);
-       }
-       
-       return(false);
-}
-
diff --git a/src/ATCDCL/ATCutils.hxx b/src/ATCDCL/ATCutils.hxx
deleted file mode 100644 (file)
index 478ba7e..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-// ATCutils.hxx - Utility functions for the ATC / AI subsytem
-//
-// Written by David Luff, started March 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.
-
-#include <Airports/airport.hxx>
-#include <Airports/runways.hxx>
-
-#include <math.h>
-#include <string>
-using std::string;
-
-// These are defined here because I had a problem with SG_DEGREES_TO_RADIANS
-#define DCL_PI  3.1415926535f
-#define DCL_DEGREES_TO_RADIANS  (DCL_PI/180.0)
-#define DCL_RADIANS_TO_DEGREES  (180.0/DCL_PI)
-
-/*******************************
-*
-*  Communication functions
-*
-********************************/
-
-// Convert any number to spoken digits
-string ConvertNumToSpokenDigits(const string &n);
-
-// Convert an integer to spoken digits
-string ConvertNumToSpokenDigits(const int& n);
-string decimalNumeral(const int& n);
-
-// Convert rwy number string to a spoken-style string
-// eg "15L" to "one five left"
-// Assumes we get a string of digits optionally appended with R, L, or C
-// eg 1 7L 29R 36
-string ConvertRwyNumToSpokenString(const string &s);
-
-const int LTRS(26);
-// Return the phonetic letter of a letter represented as an integer 0..25
-string GetPhoneticLetter(const int i);
-
-// Return the phonetic letter of a character in the range a-z or A-Z.
-// Currently always returns prefixed by lowercase.
-string GetPhoneticLetter(char c);
-
-// Get the compass direction associated with a heading in degrees
-// Currently returns 8 direction resolution (N, NE, E etc...)
-// Might be modified in future to return 4, 8 or 16 resolution but defaulting to 8. 
-string GetCompassDirection(double h);
-
-/*******************************
-*
-*  Positional functions
-*
-********************************/
-
-// Given two positions (lat & lon in degrees), get the HORIZONTAL separation (in meters)
-double dclGetHorizontalSeparation(const SGGeod& pos1, const SGGeod& pos2);
-
-// Given a point and a line, get the HORIZONTAL shortest distance from the point to a point on the line.
-// Expects to be fed orthogonal co-ordinates, NOT lat & lon !
-double dclGetLinePointSeparation(double px, double py, double x1, double y1, double x2, double y2);
-
-// Given a position (lat/lon/elev), heading, vertical angle, and distance, calculate the new position.
-// Assumes that the ground is not hit!!!  Expects heading and angle in degrees, distance in meters.
-SGGeod dclUpdatePosition(const SGGeod& pos, double heading, double angle, double distance);
-
-// Get a heading from one lat/lon to another (in degrees)
-double GetHeadingFromTo(const SGGeod& A, const SGGeod& B);
-
-// Given a heading (in degrees), bound it from 0 -> 360
-void dclBoundHeading(double &hdg);
-
-// smallest difference between two angles in degrees
-// difference is negative if a1 > a2 and positive if a2 > a1
-double GetAngleDiff_deg( const double &a1, const double &a2);
-
-/****************
-*
-*   Runways
-*
-****************/
-
-// Given (lon/lat/elev) and an FGRunway struct, determine if the point lies on the runway
-bool OnRunway(const SGGeod& pt, const FGRunwayBase* rwy);
-
diff --git a/src/ATCDCL/ATISmgr.cxx b/src/ATCDCL/ATISmgr.cxx
deleted file mode 100644 (file)
index abb7490..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-// 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 <Main/fg_props.hxx>
-
-#include "ATISmgr.hxx"
-#include "atis.hxx"
-
-FGATISMgr::FGATISMgr() :
-    _currentUnit(0),
-    _maxCommRadios(4)
-#ifdef ENABLE_AUDIO_SUPPORT
-    ,useVoice(true),
-    voice(0)
-#endif
-{
-    globals->set_ATIS_mgr(this);
-}
-
-FGATISMgr::~FGATISMgr()
-{
-    globals->set_ATIS_mgr(NULL);
-
-    for (unsigned int unit = 0;unit < radios.size(); ++unit) {
-        delete radios[unit];
-    }
-
-#ifdef ENABLE_AUDIO_SUPPORT
-    delete voice;
-#endif
-}
-
-void FGATISMgr::init()
-{
-    for (unsigned int unit = 0;unit < _maxCommRadios; ++unit)
-    {
-        if (unit < _maxCommRadios/2)
-            radios.push_back(new FGATIS("comm", unit));
-        else
-            radios.push_back(new FGATIS("nav", unit - _maxCommRadios/2));
-    }
-}
-
-void FGATISMgr::reinit()
-{
-#ifdef ENABLE_AUDIO_SUPPORT
-    if ((voiceName != "")&&
-        (voiceName != fgGetString("/sim/atis/voice", "default")))
-    {
-        voiceName = fgGetString("/sim/atis/voice", "default");
-        delete voice;
-        voice = NULL;
-        useVoice = true;
-    }
-#endif
-}
-
-void FGATISMgr::update(double dt)
-{
-    // update only runs every now and then (1-2 per second)
-    if (++_currentUnit >= _maxCommRadios)
-        _currentUnit = 0;
-
-    FGATC* commRadio = radios[_currentUnit];
-    if (commRadio)
-        commRadio->update(dt * _maxCommRadios);
-}
-
-// 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)
-{
-#ifdef ENABLE_AUDIO_SUPPORT
-    // TODO - implement me better - maintain a list of loaded voices and other voices!!
-    if(useVoice)
-    {
-        switch(type)
-        {
-        case ATIS: case AWOS:
-            // 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 (!voice && fgGetBool("/sim/sound/working")) {
-                voice = new FGATCVoice;
-                voiceName = fgGetString("/sim/atis/voice", "default");
-                try {
-                    useVoice = voice->LoadVoice(voiceName);
-                } catch ( sg_io_exception & e) {
-                    SG_LOG(SG_ATC, SG_ALERT, "Unable to load voice '" << voiceName << "': "
-                                            << e.getFormattedMessage().c_str());
-                    useVoice = false;
-                    delete voice;
-                    voice = 0;
-                }
-            }
-            return voice;
-        case TOWER:
-            return NULL;
-        case APPROACH:
-            return NULL;
-        case GROUND:
-            return NULL;
-        default:
-            return NULL;
-        }
-    }
-#endif
-
-    return NULL;
-}
diff --git a/src/ATCDCL/ATISmgr.hxx b/src/ATCDCL/ATISmgr.hxx
deleted file mode 100644 (file)
index 29aaef4..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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_ATISMGR_HXX
-#define _FG_ATISMGR_HXX
-
-#include <vector>
-
-#include <simgear/structure/subsystem_mgr.hxx>
-
-#include "ATC.hxx"
-
-class FGATISMgr : public SGSubsystem
-{
-private:
-    // A vector containing all comm radios
-    std::vector<FGATC*> radios;
-
-    unsigned int _currentUnit;
-    unsigned int _maxCommRadios;
-
-#ifdef ENABLE_AUDIO_SUPPORT
-    bool useVoice;  // Flag - true if we are using voice
-    FGATCVoice* voice;
-    std::string voiceName; // currently loaded voice name
-#endif
-
-public:
-    FGATISMgr();
-    ~FGATISMgr();
-
-    void init();
-    void reinit();
-    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:
-};
-
-#endif  // _FG_ATISMGR_HXX
diff --git a/src/ATCDCL/CMakeLists.txt b/src/ATCDCL/CMakeLists.txt
deleted file mode 100644 (file)
index 98d253a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-include(FlightGearComponent)
-
-set(SOURCES
-       ATCProjection.cxx
-       )
-
-set(HEADERS
-       ATCProjection.hxx
-       )
-       
-flightgear_component(ATCDCL "${SOURCES}" "${HEADERS}")
diff --git a/src/ATCDCL/atis.cxx b/src/ATCDCL/atis.cxx
deleted file mode 100644 (file)
index 3cdfa80..0000000
+++ /dev/null
@@ -1,1030 +0,0 @@
-// atis.cxx - routines to generate the ATIS info string
-// This is the implementation of the FGATIS class
-//
-// Written by David Luff, started October 2001.
-// Extended by Thorsten Brehm, October 2012.
-//
-// Copyright (C) 2001  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.
-
-/////
-///// TODO:  _Cumulative_ sky coverage.
-///// TODO:  wind _gust_
-///// TODO:  more-sensible encoding of voice samples
-/////       u-law?  outright synthesis?
-/////
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include "atis.hxx"
-#include "atis_lexicon.hxx"
-
-#include <simgear/compiler.h>
-#include <simgear/math/sg_random.h>
-#include <simgear/misc/sg_path.hxx>
-#include <simgear/misc/strutils.hxx>
-
-#include <stdlib.h> // atoi()
-#include <stdio.h>  // sprintf
-#include <string>
-#include <iostream>
-
-#include <boost/tuple/tuple.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/algorithm/string/case_conv.hpp>
-
-#include <Environment/environment_mgr.hxx>
-#include <Environment/environment.hxx>
-#include <Environment/atmosphere.hxx>
-
-#include <Main/fg_props.hxx>
-#include <Main/globals.hxx>
-#include <Airports/runways.hxx>
-#include <Airports/dynamics.hxx>
-
-#include <ATC/CommStation.hxx>
-#include <Navaids/navrecord.hxx>
-
-#include "ATCutils.hxx"
-#include "ATISmgr.hxx"
-
-using std::string;
-using std::map;
-using std::cout;
-using std::cout;
-using boost::ref;
-using boost::tie;
-using flightgear::CommStation;
-
-FGATIS::FGATIS(const std::string& name, int num) :
-  _name(name),
-  _num(num),
-  _cb_attention(this, &FGATIS::attend, fgGetNode("/environment/attention", true)),
-  transmission(""),
-  trans_ident(""),
-  old_volume(0),
-  atis_failed(false),
-  msg_time(0),
-  cur_time(0),
-  msg_OK(0),
-  _attention(false),
-  _check_transmission(true),
-  _prev_display(0),
-  _time_before_search_sec(0),
-  _last_frequency(0)
-{
-  _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 ...
-// ... although having it in a .hxx file is better than nothing.
-//
-// Load the remap list from the .hxx file:
-  using namespace lex;
-
-  # define NIL ""
-  # define REMAP(from,to) _remap[#from] = to;
-  # include "atis_remap.hxx"
-  # undef REMAP
-  # undef NIL
-
-  #ifdef ATIS_TEST
-    SG_LOG(SG_ATC, SG_ALERT, "ATIS initialized");
-  #endif
-
-    _report.psl = 0;
-}
-
-// Hint:
-// http://localhost:5400/environment/attention?value=1&submit=update
-
-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::reinit()
-{
-    _time_before_search_sec = 0;
-    _check_transmission = true;
-}
-
-void
-FGATIS::attend(SGPropertyNode* node)
-{
-  if (node->getBoolValue())
-      _attention = true;
-#ifdef ATMO_TEST
-  int flag = fgGetInt("/sim/logging/atmo");
-  if (flag) {
-    FGAltimeter().check_model();
-    FGAltimeter().dump_stack();
-  }
-#endif
-}
-
-
-// Main update function - checks whether we are displaying or not the correct message.
-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
-      << "  len: " << transmission.length()
-      << "  oldvol: " << old_volume
-      << "  dt: " << dt << endl;
-    msg_time = cur_time;
-  }
-#endif
-
-  double volume = 0;
-  if ((_electrical->getDoubleValue() > 8) && _serviceable->getBoolValue())
-  {
-      // radio is switched on and OK
-      if (_operable.valid())
-          _operable->setBoolValue(true);
-
-      _check_transmission |= search(dt);
-
-      if (_display)
-      {
-          volume = _volume->getDoubleValue();
-      }
-  }
-  else
-  {
-      // radio is OFF
-      if (_operable.valid())
-          _operable->setBoolValue(false);
-      _time_before_search_sec = 0;
-  }
-
-  if (volume > 0.05)
-  {
-    bool changed = false;
-    if (_check_transmission)
-    {
-        _check_transmission = false;
-        // 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 (genTransmission(!_prev_display, _attention))
-        {
-            // update output property
-            treeOut(msg_OK);
-            changed = true;
-        }
-    }
-
-    if (changed || volume != old_volume) {
-      // audio output enabled
-      Render(transmission, volume, _name, true);
-      old_volume = volume;
-    }
-    _prev_display = _display;
-  } else {
-    // silence
-    NoRender(_name);
-    _prev_display = false;
-  }
-  _attention = false;
-
-  FGATC::update(dt);
-}
-
-// Replace all occurrences of a given word.
-// Words in the original string must be separated by hyphens (not spaces).
-// We check for the word as given, and for the all-caps version thereof.
-string replace_word(const string _orig, const string _www, const string _nnn){
-// The following are so we can match words at the beginning
-// and end of the string.
-  string orig = "-" + _orig + "-";
-  string www = "-" + _www + "-";
-  string nnn = "-" + _nnn + "-";
-
-  size_t where(0);
-  for ( ; (where = orig.find(www, where)) != string::npos ; ) {
-    orig.replace(where, www.length(), nnn);
-    where += nnn.length();
-  }
-  
-  www = simgear::strutils::uppercase(www);
-  for ( ; (where = orig.find(www, where)) != string::npos ; ) {
-    orig.replace(where, www.length(), nnn);
-    where += nnn.length();
-  }
-  where = orig.length();
-  return orig.substr(1, where-2);
-}
-
-// Normally the interval is 1 hour, 
-// but you can shorten it for testing.
-const int minute(60);          // measured in seconds
-#ifdef ATIS_TEST
-  const int ATIS_interval(2*minute);
-#else
-  const int ATIS_interval(60*minute);
-#endif
-
-// FIXME:  This is heuristic.  It gets the right answer for
-// more than 90% of the world's airports, which is a lot
-// better than nothing ... but it's not 100%.
-// We know "most" of the world uses millibars,
-// but the US, Canada and *some* other places use inches of mercury,
-// but (a) we have not implemented a reliable method of
-// ascertaining which airports are in the US, let alone
-// (b) ascertaining which other places use inches.
-//
-bool Apt_US_CA(const string id)
-{
-    // Assume all IDs have length 3 or 4.
-    // No counterexamples have been seen.
-    if (id.length() == 4) {
-        if (id.substr(0,1) == "K") return true;
-        if (id.substr(0,2) == "CY") return true;
-    }
-    for (string::const_iterator ptr = id.begin(); ptr != id.end();  ptr++) {
-        if (isdigit(*ptr)) return true;
-    }
-    return false;
-}
-
-// voice spacers
-static const string BRK = ".\n";
-static const string PAUSE = " / ";
-
-/** Generate the actual broadcast ATIS transmission.
-*   'regen' triggers a regeneration of the /current/ transmission.
-*   'forceUpdate' generates a new transmission, with a new sequence.
-*   Returns 1 if we actually generated something.
-*/
-bool FGATIS::genTransmission(const int regen, bool forceUpdate)
-{
-    using namespace lex;
-
-    // ATIS updated hourly, AWOS updated more frequently
-    int interval = _type == ATIS ? ATIS_interval : 2*minute;
-
-    // check if pressure has changed significantly and we need to update ATIS
-    double Psl = fgGetDouble("/environment/pressure-sea-level-inhg");
-    if (fabs(Psl-_report.psl) >= 0.15)
-        forceUpdate = true;
-
-    FGAirport* apt = FGAirport::findByIdent(ident);
-    int sequence = apt->getDynamics()->updateAtisSequence(interval, forceUpdate);
-    if (!regen && sequence > LTRS) {
-        //xx      if (msg_OK) cout << "ATIS:  no change: " << sequence << endl;
-        //xx    msg_time = cur_time;
-        return false;   // no change since last time
-    }
-
-    _report.psl = Psl;
-    transmission = "";
-
-    // collect data and create report
-    createReport(apt);
-
-    // add facility name
-    genFacilityInfo();
-
-    if (_type == ATIS) {
-        // ATIS phraseology starts with "... airport information"
-        transmission += airport_information + " ";
-    } else {
-        // AWOS
-        transmission += Automated_weather_observation + " ";
-    }
-
-    string phonetic_seq_string = GetPhoneticLetter(sequence);  // Add the sequence letter
-    transmission += phonetic_seq_string + BRK;
-
-    genTimeInfo();
-
-    // some warnings may appear at the beginning
-    genWarnings(-1);
-
-    if (_type == ATIS) // as opposed to AWOS
-        genRunwayInfo(apt);
-
-    // some warnings may appear after runway info
-    genWarnings(0);
-
-    // transition level
-    genTransitionLevel(apt);
-
-    // weather
-    if (!_report.concise)
-        transmission += Weather + BRK;
-
-    genWindInfo();
-
-    // clouds and visibility
-    {
-        string vis_info, cloud_info;
-        bool v = genVisibilityInfo(vis_info);
-        bool c = genCloudInfo(cloud_info);
-        _report.cavok = !(v || c);
-        if (!_report.cavok)
-        {
-            // there is some visibility or cloud restriction
-            transmission += vis_info + cloud_info;
-        }
-        else
-        {
-            // Abbreviation CAVOK vs full "clouds and visibility..." does not really depend on
-            // US vs rest of the world, it really seems to depend on the airport. Just use
-            // it as a heuristic.
-            if ((_report.US_CA)||(_report.concise))
-                transmission += cav_ok + BRK;
-            else
-                transmission += clouds_and_visibility_OK + BRK;
-        }
-    }
-
-    // precipitation
-    genPrecipitationInfo();
-
-    // temperature
-    genTemperatureInfo();
-
-    // pressure
-    genPressureInfo();
-
-    // TODO check whether "no significant change" applies - somehow...
-    transmission += No_sig + BRK; // sounds better with festival than "nosig"
-
-    // some warnings may appear at the very end
-    genWarnings(1);
-
-    if ((!_report.concise)|| _report.US_CA)
-        transmission += Advise_on_initial_contact_you_have_information;
-    else
-        transmission += information;
-    transmission += " " + phonetic_seq_string + ".";
-
-    if (!_report.US_CA)
-    {
-        // non-US ATIS ends with "out!"
-        transmission += " " + out;
-    }
-
-    // Pause in between two messages must be 3-5 seconds
-    transmission += " / / / / / / / / ";
-
-    /////////////////////////////////////////////////////////
-    // post-processing
-    /////////////////////////////////////////////////////////
-    transmission_readable = transmission;
-
-    // Take the previous readable string and munge it to
-    // be relatively-more acceptable to the primitive tts system.
-    // Note that : ; and . are among the token-delimiters recognized
-    // by the tts system.
-    for (size_t where;;) {
-        where = transmission.find_first_of(":.");
-        if (where == string::npos) break;
-        transmission.replace(where, 1, PAUSE);
-    }
-
-    return true;
-}
-
-/** Collect (most of) the data and create report.
- */
-void FGATIS::createReport(const FGAirport* apt)
-{
-    // check country
-    _report.US_CA = Apt_US_CA(ident);
-
-    // switch to enable brief ATIS message (really depends on the airport)
-    _report.concise = fgGetBool("/sim/atis/concise-reports", false);
-
-    _report.ils = false;
-
-    // time information
-    string time_str = fgGetString("sim/time/gmt-string");
-    // Warning - this is fragile if the time string format changes
-    _report.hours = time_str.substr(0,2).c_str();
-    _report.mins  = time_str.substr(3,2).c_str();
-
-    // pressure/temperature
-    {
-        double press, temp;
-        double Tsl = fgGetDouble("/environment/temperature-sea-level-degc");
-        tie(press, temp) = PT_vs_hpt(_geod.getElevationM(), _report.psl*atmodel::inHg, Tsl + atmodel::freezing);
-  #if 0
-        SG_LOG(SG_ATC, SG_ALERT, "Field P: " << press << "  T: " << temp);
-        SG_LOG(SG_ATC, SG_ALERT, "based on elev " << elev
-                                  << "  Psl: " << Psl
-                                  << "  Tsl: " << Tsl);
-  #endif
-        _report.qnh = FGAtmo().QNH(_geod.getElevationM(), press);
-        _report.temp = int(SGMiscd::round(FGAtmo().fake_T_vs_a_us(_geod.getElevationFt(), Tsl)));
-    }
-
-    // dew point
-    double dpsl = fgGetDouble("/environment/dewpoint-sea-level-degc");
-    _report.dewpoint = int(SGMiscd::round(FGAtmo().fake_dp_vs_a_us(dpsl, _geod.getElevationFt())));
-
-    // precipitation
-    _report.rain_norm = fgGetDouble("environment/rain-norm");
-    _report.snow_norm = fgGetDouble("environment/snow-norm");
-
-    // NOTAMs
-    _report.notam = 0;
-    if (fgGetBool("/sim/atis/random-notams", true))
-    {
-        _report.notam = fgGetInt("/sim/atis/notam-id", 0); // fixed NOTAM for testing/debugging only
-        if (!_report.notam)
-        {
-            // select pseudo-random NOTAM (changes every hour, differs for each airport)
-            char cksum = 0;
-            string name = apt->getName();
-            for(string::iterator p = name.begin(); p != name.end(); p++)
-            {
-                cksum += *p;
-            }
-            cksum ^= atoi(_report.hours.c_str());
-            _report.notam = cksum % 12; // 12 intentionally higher than number of available NOTAMs, so they don't appear too often
-            // debugging
-            //fgSetInt("/sim/atis/selected-notam", _report.notam);
-        }
-    }
-}
-
-void FGATIS::genPrecipitationInfo(void)
-{
-    using namespace lex;
-
-    double rain_norm = _report.rain_norm;
-    double snow_norm = _report.snow_norm;
-
-    // report rain or snow - which ever is worse
-    if (rain_norm > 0.7)
-        transmission += heavy    + " " + rain + BRK;
-    else
-    if (snow_norm > 0.7)
-        transmission += heavy    + " " + snow + BRK;
-    else
-    if (rain_norm > 0.4)
-        transmission += moderate + " " + rain + BRK;
-    else
-    if (snow_norm > 0.4)
-        transmission += moderate + " " + snow + BRK;
-    else
-    if (rain_norm > 0.2)
-        transmission += light    + " " + rain + BRK;
-    else
-    if (snow_norm > 0.05)
-        transmission += light    + " " + snow + BRK;
-    else
-    if (rain_norm > 0.05)
-        transmission += light    + " " + drizzle + BRK;
-}
-
-void FGATIS::genTimeInfo(void)
-{
-    using namespace lex;
-
-    if (!_report.concise)
-        transmission += Time + " ";
-
-    // speak each digit separately:
-    transmission += ConvertNumToSpokenDigits(_report.hours + _report.mins);
-    transmission += " " + zulu + BRK;
-}
-
-bool FGATIS::genVisibilityInfo(string& vis_info)
-{
-    using namespace lex;
-
-    double visibility = fgGetDouble("/environment/config/boundary/entry[0]/visibility-m");
-    bool IsMax = false;
-    bool USE_KM = !_report.US_CA;
-
-    vis_info += Visibility + ": ";
-    if (USE_KM)
-    {
-        visibility /= 1000.0;    // convert to statute miles
-        // integer kilometers
-        if (visibility >= 9.5)
-        {
-            visibility = 10;
-            IsMax = true;
-        }
-        snprintf(buf, sizeof(buf), "%i", int(.5 + visibility));
-        // "kelometers" instead of "kilometers" since the festival language generator doesn't get it right otherwise
-        vis_info += ConvertNumToSpokenDigits(buf) + " " + kelometers;
-    }
-    else
-    {
-        visibility /= atmodel::sm;    // convert to statute miles
-        if (visibility < 0.25) {
-          vis_info += less_than_one_quarter;
-        } else if (visibility < 0.5) {
-          vis_info += one_quarter;
-        } else if (visibility < 0.75) {
-          vis_info += one_half;
-        } else if (visibility < 1.0) {
-          vis_info += three_quarters;
-        } else if (visibility >= 1.5 && visibility < 2.0) {
-          vis_info += one_and_one_half;
-        } else {
-          // integer miles
-          if (visibility > 9.5)
-          {
-              visibility = 10;
-              IsMax = true;
-          }
-          snprintf(buf, sizeof(buf), "%i", int(.5 + visibility));
-          vis_info += ConvertNumToSpokenDigits(buf);
-        }
-    }
-    if (IsMax)
-    {
-        vis_info += " " + or_more;
-    }
-    vis_info += BRK;
-    return !IsMax;
-}
-
-void FGATIS::addTemperature(int Temp)
-{
-    if (Temp < 0)
-        transmission += lex::minus + " ";
-    else
-    if (Temp > 0)
-    {
-        transmission += lex::plus + " ";
-    }
-    snprintf(buf, sizeof(buf), "%i", abs(Temp));
-    transmission += ConvertNumToSpokenDigits(buf);
-    if (_report.US_CA)
-        transmission += " " + lex::Celsius;
-}
-
-void FGATIS::genTemperatureInfo()
-{
-    // temperature
-    transmission += lex::Temperature + ": ";
-    addTemperature(_report.temp);
-
-    // dewpoint
-    transmission += BRK + lex::Dewpoint + ": ";
-    addTemperature(_report.dewpoint);
-
-    transmission += BRK;
-}
-
-bool FGATIS::genCloudInfo(string& cloud_info)
-{
-    using namespace lex;
-
-    bool did_some = false;
-    bool did_ceiling = false;
-
-    for (int layer = 0; layer <= 4; layer++) {
-      snprintf(buf, sizeof(buf), "/environment/clouds/layer[%i]/coverage", layer);
-      string coverage = fgGetString(buf);
-      if (coverage == clear)
-          continue;
-      snprintf(buf, sizeof(buf), "/environment/clouds/layer[%i]/thickness-ft", layer);
-      if (fgGetDouble(buf) == 0)
-          continue;
-      snprintf(buf, sizeof(buf), "/environment/clouds/layer[%i]/elevation-ft", layer);
-      double ceiling = int(fgGetDouble(buf) - _geod.getElevationFt());
-      if (ceiling > 12000)
-          continue;
-
-  // BEWARE:  At the present time, the environment system has no
-  // way (so far as I know) to represent a "thin broken" or
-  // "thin overcast" layer.  If/when such things are implemented
-  // in the environment system, code will have to be written here
-  // to handle them.
-
-      // First, do the prefix if any:
-      if (coverage == scattered || coverage == few) {
-        if (!did_some) {
-          if (_report.concise)
-              cloud_info += Clouds + ": ";
-          else
-              cloud_info += Sky_condition + ": ";
-          did_some = true;
-        }
-      } else /* must be a ceiling */  if (!did_ceiling) {
-        cloud_info += "   " + Ceiling + ": ";
-        did_ceiling = true;
-        did_some = true;
-      } else {
-        cloud_info += "   ";    // no prefix required
-      }
-      int cig00  = int(SGMiscd::round(ceiling/100));  // hundreds of feet
-      if (cig00) {
-        int cig000 = cig00/10;
-        cig00 -= cig000*10;       // just the hundreds digit
-        if (cig000) {
-          snprintf(buf, sizeof(buf), "%i", cig000);
-          cloud_info += ConvertNumToSpokenDigits(buf);
-          cloud_info += " " + thousand + " ";
-        }
-        if (cig00) {
-          snprintf(buf, sizeof(buf), "%i", cig00);
-          cloud_info += ConvertNumToSpokenDigits(buf);
-          cloud_info += " " + hundred + " ";
-        }
-      } else {
-        // Should this be "sky obscured?"
-        cloud_info += " " + zero + " ";     // not "zero hundred"
-      }
-      cloud_info += coverage + BRK;
-    }
-    if (!did_some)
-        cloud_info += "   " + Sky + " " + clear + BRK;
-    return did_some;
-}
-
-void FGATIS::genFacilityInfo(void)
-{
-    if ((!_report.US_CA)&&(!_report.concise))
-    {
-        // UK CAA radiotelephony manual indicates ATIS transmissions start
-        // with "This is ...", while US just starts with airport name.
-        transmission += lex::This_is + " ";
-    }
-
-    // SG_LOG(SG_ATC, SG_ALERT, "ATIS: facility name: " << name);
-
-    // Note that at this point, multi-word facility names
-    // will sometimes contain hyphens, not spaces.
-    std::vector<std::string> name_words;
-    boost::split(name_words, name, boost::is_any_of(" -"));
-
-    for( std::vector<string>::const_iterator wordp = name_words.begin();
-                  wordp != name_words.end(); wordp++) {
-      string word(*wordp);
-    // Remap some abbreviations that occur in apt.dat, to
-    // make things nicer for the text-to-speech system:
-      for (MSS::const_iterator replace = _remap.begin();
-            replace != _remap.end(); replace++) {
-        // Due to inconsistent capitalisation in the apt.dat file, we need
-        // to do a case-insensitive comparison here.
-        string tmp1 = word, tmp2 = replace->first;
-        boost::algorithm::to_lower(tmp1);
-        boost::algorithm::to_lower(tmp2);
-        if (tmp1 == tmp2) {
-          word = replace->second;
-          break;
-        }
-      }
-      transmission += word + " ";
-    }
-}
-
-void FGATIS::genWindInfo(void)
-{
-    using namespace lex;
-
-    transmission += Wind + ": ";
-
-    double wind_speed = fgGetDouble("/environment/config/boundary/entry[0]/wind-speed-kt");
-    double wind_dir = fgGetDouble("/environment/config/boundary/entry[0]/wind-from-heading-deg");
-    while (wind_dir <= 0) wind_dir += 360;
-    // The following isn't as bad a kludge as it might seem.
-    // It combines the magvar at the /aircraft/ location with
-    // the wind direction in the environment/config array.
-    // But if the aircraft is close enough to the station to
-    // be receiving the ATIS signal, this should be a good-enough
-    // approximation.  For more-distant aircraft, the wind_dir
-    // shouldn't be corrected anyway.
-    // The less-kludgy approach would be to use the magvar associated
-    // with the station, but that is not tabulated in the stationweather
-    // structure as it stands, and computing it would be expensive.
-    // Also note that as it stands, there is only one environment in
-    // the entire FG universe, so the aircraft environment is the same
-    // as the station environment anyway.
-    wind_dir -= fgGetDouble("/environment/magnetic-variation-deg");       // wind_dir now magnetic
-    if (wind_speed == 0) {
-        // Force west-facing rwys to be used in no-wind situations
-        // which is consistent with Flightgear's initial setup:
-        wind_dir = 270;
-        transmission += " " + light_and_variable;
-    } else {
-        // FIXME: get gust factor in somehow
-        snprintf(buf, sizeof(buf), "%03.0f", 5*SGMiscd::round(wind_dir/5));
-        transmission += ConvertNumToSpokenDigits(buf);
-        if (!_report.concise)
-            transmission += " " + degrees;
-        transmission += " ";
-        snprintf(buf, sizeof(buf), "%1.0f", wind_speed);
-        transmission += at + " " + ConvertNumToSpokenDigits(buf);
-        if (!_report.concise)
-            transmission += " " + knots;
-    }
-    transmission += BRK;
-}
-
-void FGATIS::genTransitionLevel(const FGAirport* apt)
-{
-    double hPa = _report.qnh/atmodel::mbar;
-
-    /* Transition level is the flight level above which aircraft must use standard pressure and below
-     * which airport pressure settings must be used.
-     * Following definitions are taken from German ATIS:
-     *      QNH <=  977 hPa: TRL 80
-     *      QNH <= 1013 hPa: TRL 70
-     *      QNH >  1013 hPa: TRL 60
-     * (maybe differs slightly for other countries...)
-     */
-    int tl = 60;
-    if (hPa <= 977)
-        tl = 80;
-    else
-    if (hPa <= 1013)
-        tl = 70;
-
-    // add an offset to the transition level for high altitude airports (just guessing here,
-    // seems reasonable)
-    double elevationFt = apt->getElevation();
-    int e = int(elevationFt / 1000.0);
-    if (e >= 3)
-    {
-        // TL steps in 10(00)ft
-        tl += (e-2)*10;
-    }
-
-    snprintf(buf, sizeof(buf), "%02i", tl);
-    transmission += lex::Transition_level + ": " + ConvertNumToSpokenDigits(buf) + BRK;
-}
-
-void FGATIS::genPressureInfo(void)
-{
-    using namespace lex;
-
-    // hectopascal for most of the world (not US, not CA)
-    if(!_report.US_CA) {
-        double hPa = _report.qnh/atmodel::mbar;
-        transmission += QNH + ": ";
-        snprintf(buf, sizeof(buf), "%03.0f", _report.qnh / atmodel::mbar);
-        transmission += ConvertNumToSpokenDigits(buf);
-        // "hectopascal" replaced "millibars" in new ATIS standard since 2011
-        if  ((!_report.concise)||(hPa < 1000))
-            transmission += " " + hectopascal; // "hectopascal" must be provided for values below 1000 (to avoid confusion with inHg)
-
-        // Many (European) airports (with lots of US traffic?) provide both, hPa and inHg announcements.
-        // Europeans keep the "decimal" in inHg readings to make the distinction to hPa even more apparent.
-        // hPa/inHg separated by "equals" or "or" with some airports
-        if (_report.concise)
-            transmission += " " + equals + " ";
-        else
-            transmission += " " + Or + " ";
-        snprintf(buf, sizeof(buf), "%04.2f", _report.qnh / atmodel::inHg);
-        transmission += ConvertNumToSpokenDigits(buf);
-        if (!_report.concise)
-            transmission += " " + inches;
-        transmission += BRK;
-    } else {
-        // use inches of mercury for US/CA
-        transmission += Altimeter + ": ";
-        double asetting = _report.qnh / atmodel::inHg;
-        // shift two decimal places, US/CA airports omit the "decimal" in inHg settings
-        asetting *= 100.;
-        snprintf(buf, sizeof(buf), "%04.0f", asetting);
-        transmission += ConvertNumToSpokenDigits(buf);
-    }
-
-    transmission += BRK;
-}
-
-void FGATIS::genRunwayInfo(const FGAirport* apt)
-{
-    using namespace lex;
-
-    if (!apt)
-        return;
-
-    FGRunway* rwy = apt->getActiveRunwayForUsage();
-    if (!rwy)
-        return;
-
-    string rwy_no = rwy->ident();
-    if(rwy_no != "NN")
-    {
-        FGNavRecord* ils = rwy->ILS();
-        if (ils)
-        {
-            _report.ils = true;
-            transmission += Expect_I_L_S_approach + " "+ runway + " "+ConvertRwyNumToSpokenString(rwy_no) + BRK;
-            if (fgGetBool("/sim/atis/announce-ils-frequency", false))
-            {
-                // this is handy - but really non-standard (so disabled by default)
-                snprintf(buf, sizeof(buf), "%5.2f", ils->get_freq()/100.0);
-                transmission += I_L_S + " " + ConvertNumToSpokenDigits(buf) + BRK;
-            }
-        }
-        else
-        {
-            transmission += Expect_visual_approach + " "+ runway + " "+ConvertRwyNumToSpokenString(rwy_no) + BRK;
-        }
-
-        transmission += Landing_and_departing_runway + " ";
-        transmission += ConvertRwyNumToSpokenString(rwy_no) + BRK;
-    #ifdef ATIS_TEST
-        if (msg_OK) {
-          msg_time = cur_time;
-          cout << "In atis.cxx, r.rwy_no: " << rwy_no
-             << " wind_dir: " << wind_dir << endl;
-        }
-    #endif
-    }
-}
-
-void FGATIS::genWarnings(int position)
-{
-    using namespace lex;
-    bool dayTime = (fgGetDouble("/sim/time/sun-angle-rad") < 1.57);
-
-    if (position == -1) // warnings at beginning of ATIS
-    {
-        // bird related warnings at day-time only (birds are VFR-only! ;-) )
-        if (dayTime)
-        {
-            if (_report.notam == 1)
-                transmission += Attention + ": " + flock_of_birds + " " + in_the_vicinity_of_the_airport + BRK;
-            else
-            if (_report.notam == 2)
-                transmission += Attention + ": " + bird_activity + " " + in_the_vicinity_of_the_airport + BRK;
-        }
-    }
-    else
-    if (position == 0)  // warnings after runway messages
-    {
-        if ((_report.notam == 3)&&(_report.ils))
-        {
-            // "__I_LS_" necessary to trick the language generator into pronouncing it properly
-            transmission += Attention + ": " + short_time__I_LS_interference_possible_by_taxiing_aircraft + BRK;
-        }
-    }
-    else
-    if (position == 1) // warnings at the end of the report
-    {
-        // "runway wet-wet-wet" warning in heavy rain
-        if (_report.rain_norm > 0.6)
-        {
-            // "wet" is repeated 3 times in ATIS warnings, since the word is difficult
-            // to understand over radio - but the message is important.
-            transmission += runway_wet + " " + wet + " " + wet + BRK;
-        }
-
-        if (_report.notam == 4)
-        {
-            // intentional: "reed" instead of "read" since festival gets it wrong otherwise
-            transmission += reed_back_all_runway_hold_instructions + BRK;
-        }
-        else
-        if ((_report.notam == 5)&& _report.cavok && dayTime &&
-            (_report.rain_norm == 0) && (_report.snow_norm == 0)) // ;-)
-        {
-            transmission += Attention + ": " + glider_operation_in_sector + BRK;
-        }
-    }
-}
-
-// 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)
-{
-    _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);
-    }
-
-    virtual CommStation::Type minType() const
-    {
-      return CommStation::FREQ_ATIS;
-    }
-
-    virtual CommStation::Type maxType() const
-    {
-      return CommStation::FREQ_AWOS;
-    }
-
-private:
-    SGVec3d _cart;
-    SGGeod _pos;
-};
-
-// Search for ATC stations by frequency
-bool FGATIS::search(double dt)
-{
-    double frequency = _freq->getDoubleValue();
-
-    // Note:  122.375 must be rounded DOWN to 122370
-    // in order to be consistent with apt.dat et cetera.
-    int freqKhz = 10 * static_cast<int>(frequency * 100 + 0.25);
-
-    // only search tuned frequencies when necessary
-    _time_before_search_sec -= dt;
-
-    // throttle frequency searches
-    if ((freqKhz == _last_frequency)&&(_time_before_search_sec > 0))
-        return false;
-
-    _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);
-
-    return true;
-}
diff --git a/src/ATCDCL/atis.hxx b/src/ATCDCL/atis.hxx
deleted file mode 100644 (file)
index 525001f..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-// atis.hxx -- ATIS class
-//
-// Written by David Luff, started October 2001.
-// Based on nav.hxx by Curtis Olson, started April 2000.
-//
-// Copyright (C) 2001  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_ATIS_HXX
-#define _FG_ATIS_HXX
-
-#include <string>
-#include <iosfwd>
-
-#include <simgear/compiler.h>
-#include <simgear/timing/sg_time.hxx>
-#include <simgear/props/props.hxx>
-
-#include "ATC.hxx"
-
-class FGAirport;
-
-typedef std::map<std::string,std::string> MSS;
-
-class FGATIS : public FGATC {
-
-    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;
-
-    SGPropertyChangeCallback<FGATIS> _cb_attention;
-
-    // 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;
-    bool _attention;
-    bool _check_transmission;
-
-    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;
-
-    // temporary buffer for string conversions
-    char buf[100];
-
-    // data for the current ATIS report
-    struct
-    {
-        std::string phonetic_seq_string;
-        bool    US_CA;
-        bool    cavok;
-        bool    concise;
-        bool    ils;
-        int     temp;
-        int     dewpoint;
-        double  psl;
-        double  qnh;
-        double  rain_norm, snow_norm;
-        int     notam;
-        std::string hours,mins;
-    } _report;
-
-public:
-
-    FGATIS(const std::string& name, int num);
-
-    void init();
-    void reinit();
-
-    void attend(SGPropertyNode* node);
-
-    //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:
-
-    void createReport       (const FGAirport* apt);
-
-    /** generate the ATIS transmission text */
-    bool genTransmission    (const int regen, bool forceUpdate);
-    void genTimeInfo        (void);
-    void genFacilityInfo    (void);
-    void genPrecipitationInfo(void);
-    bool genVisibilityInfo  (std::string& vis_info);
-    bool genCloudInfo       (std::string& cloud_info);
-    void genWindInfo        (void);
-    void genTemperatureInfo (void);
-    void genTransitionLevel (const FGAirport* apt);
-    void genPressureInfo    (void);
-    void genRunwayInfo      (const FGAirport* apt);
-    void genWarnings        (int position);
-
-    void addTemperature     (int Temp);
-
-    // 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.
-    bool search(double dt);
-
-    friend std::istream& operator>> ( std::istream&, FGATIS& );
-};
-
-typedef int (FGATIS::*int_getter)() const;
-
-#endif // _FG_ATIS_HXX
diff --git a/src/ATCDCL/atis_lexicon.hxx b/src/ATCDCL/atis_lexicon.hxx
deleted file mode 100644 (file)
index ef6f027..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-#ifndef _FG_ATIS_LEXICON_HXX
-#define _FG_ATIS_LEXICON_HXX
-
-#include <string>
-
-// NOTE:  This file serves as a database.
-// It is read by some utility programs that synthesize
-// the library of spoken words.
-
-#define Q(word) const std::string word(#word);
-
-namespace lex {
-Q(Airport)
-Q(Airfield)
-Q(Airbase)
-Q(Junior)
-Q(Celsius)
-Q(Wind)
-Q(zulu)
-Q(zulu_weather)
-Q(Automated_weather_observation)
-Q(Weather)
-Q(airport_information)
-Q(International)
-Q(Regional)
-Q(County)
-Q(Municipal)
-Q(Memorial)
-Q(Field)
-Q(Air_Force_Base)
-Q(Army_Air_Field)
-Q(Marine_Corps_Air_Station)
-Q(light_and_variable)
-Q(at)
-Q(thousand)
-Q(hundred)
-Q(zero)
-Q(Temperature)
-Q(clear)
-Q(isolated)
-Q(few)
-Q(scattered)
-Q(broken)
-Q(overcast)
-Q(thin)
-Q(Sky_condition)
-Q(Sky)
-Q(Clouds)
-Q(Ceiling)
-Q(minus)
-Q(Dewpoint)
-Q(Visibility)
-Q(less_than_one_quarter)
-Q(one_quarter)
-Q(one_half)
-Q(three_quarters)
-Q(one_and_one_half)
-Q(Altimeter)
-Q(QNH)
-Q(Landing_and_departing_runway)
-Q(Advise_on_initial_contact_you_have_information)
-Q(This_is)
-Q(information)
-Q(millibars)
-Q(hectopascal)
-Q(inches)
-Q(I_L_S)
-Q(visual)
-Q(cav_ok)
-Q(clouds_and_visibility_OK)
-Q(out)
-Q(equals)
-Q(Expect_I_L_S_approach)
-Q(Expect_visual_approach)
-Q(Transition_level)
-Q(No_sig)
-Q(Time)
-Q(kelometers)
-Q(Attention)
-Q(flock_of_birds)
-Q(bird_activity)
-Q(in_the_vicinity_of_the_airport)
-Q(short_time__I_LS_interference_possible_by_taxiing_aircraft)
-Q(reed_back_all_runway_hold_instructions)
-Q(glider_operation_in_sector)
-Q(airport)
-Q(runway_wet)
-Q(runway_in_use)
-Q(arrivals)
-Q(runway)
-Q(runways)
-Q(expect)
-Q(approach)
-Q(departures)
-Q(wet)
-Q(ice)
-Q(closed)
-Q(light)
-Q(moderate)
-Q(heavy)
-Q(rain)
-Q(drizzle)
-Q(snow)
-Q(fog)
-Q(plus)
-Q(hours)
-Q(variable)
-Q(from)
-Q(Or)
-Q(And)
-Q(to)
-Q(maximum)
-Q(between)
-Q(degrees)
-Q(or_more)
-Q(left)
-Q(right)
-Q(center)
-Q(knots)
-}
-
-#undef Q
-#endif // _FG_ATIS_LEXICON_HXX
diff --git a/src/ATCDCL/atis_remap.hxx b/src/ATCDCL/atis_remap.hxx
deleted file mode 100644 (file)
index 2497197..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// NOTE:  This file serves as a database.
-// It is read by some utility programs that synthesize
-// the library of spoken words.
-
-REMAP(Intl,  International)
-REMAP(Rgnl,  Regional)
-REMAP(Co,    County)
-REMAP(Muni,  Municipal)
-REMAP(Mem,   Memorial)
-REMAP(Meml,  Memorial)
-REMAP(Apt,   Airport)
-REMAP(Arpt,  Airport)
-REMAP(Fld,   Field)
-REMAP(AFLD,  Airfield)
-REMAP(AFB,   Air_Force_Base)
-REMAP(AB,    Airbase)
-REMAP(AAF,   Army_Air_Field)
-REMAP(MCAS,  Marine_Corps_Air_Station)
-REMAP(JR,    Junior)
-REMAP(GKI,   NIL)
index b09b6a348cd5bfb728588a4eb7c69a461f09291b..2c2d83e05becaa639f2b898a720d8e412e115fac 100644 (file)
@@ -7,7 +7,6 @@ foreach( mylibfolder
                Airports
                Aircraft
                ATC
-               ATCDCL
                Canvas
                Radio
                Autopilot
index 858869fbd331163823f648f42ba91bf73be1900c..c0c72773e85a9e87094a8877caced2702470744e 100644 (file)
@@ -44,8 +44,6 @@
 #include "kln89_symbols.hxx"
 #include <iostream>
 
-#include <ATCDCL/ATCProjection.hxx>
-
 #include <Main/fg_props.hxx>
 #include <simgear/structure/commands.hxx>
 #include <Airports/airport.hxx>
@@ -763,7 +761,7 @@ void KLN89::DrawMap(bool draw_avs) {
        double mapScaleMeters = _mapScale * (_mapScaleUnits == 0 ? SG_NM_TO_METER : 1000);
        
        // TODO - use an aligned projection when either DTK or TK up!
-       FGATCAlignedProjection mapProj(SGGeod::fromRad(_gpsLon, _gpsLat), _mapHeading);
+       AlignedProjection mapProj(SGGeod::fromRad(_gpsLon, _gpsLat), _mapHeading);
        double meter_per_pix = (_mapOrientation == 0 ? mapScaleMeters / 20.0f : mapScaleMeters / 29.0f);
 //     SGGeod bottomLeft = mapProj.ConvertFromLocal(SGVec3d(gps_max(-57.0 * meter_per_pix, -50000), gps_max((_mapOrientation == 0 ? -20.0 * meter_per_pix : -11.0 * meter_per_pix), -25000), 0.0));
 //     SGGeod topRight = mapProj.ConvertFromLocal(SGVec3d(gps_min(54.0 * meter_per_pix, 50000), gps_min((_mapOrientation == 0 ? 20.0 * meter_per_pix : 29.0 * meter_per_pix), 25000), 0.0));
index c0d8d34664122d9f7bd816875031d2a5a5b640d7..8444b5c51b15d698f6915dd66d0816e17a9593c7 100644 (file)
@@ -1564,3 +1564,54 @@ double DCLGPS::CalcCrossTrackDeviation(const GPSWaypoint& wp1, const GPSWaypoint
                          * sin(GetGreatCircleCourse(wp1.lat, wp1.lon, _gpsLat, _gpsLon) - GetGreatCircleCourse(wp1.lat, wp1.lon, wp2.lat, wp2.lon)));
        return(Rad2Nm(xtd));
 }
+
+AlignedProjection::AlignedProjection() 
+{
+    SGGeod g; // ctor initializes to zero
+    Init( g, 0.0 );
+}
+
+AlignedProjection::AlignedProjection(const SGGeod& centre, double heading) 
+{
+    Init( centre, heading );
+}
+
+AlignedProjection::~AlignedProjection() {
+}
+
+void AlignedProjection::Init(const SGGeod& centre, double heading) {
+    _origin = centre;
+    _theta = heading * SG_DEGREES_TO_RADIANS;
+    _correction_factor = cos(_origin.getLatitudeRad());
+}
+
+SGVec3d AlignedProjection::ConvertToLocal(const SGGeod& pt) {
+    // convert from lat/lon to orthogonal
+    double delta_lat = pt.getLatitudeRad() - _origin.getLatitudeRad();
+    double delta_lon = pt.getLongitudeRad() - _origin.getLongitudeRad();
+    double y = sin(delta_lat) * SG_EQUATORIAL_RADIUS_M;
+    double x = sin(delta_lon) * SG_EQUATORIAL_RADIUS_M * _correction_factor;
+
+    // Align
+    if(_theta != 0.0) {
+        double xbar = x;
+        x = x*cos(_theta) - y*sin(_theta);
+        y = (xbar*sin(_theta)) + (y*cos(_theta));
+    }
+
+    return SGVec3d(x, y, pt.getElevationM());
+}
+
+SGGeod AlignedProjection::ConvertFromLocal(const SGVec3d& pt) {
+    // de-align
+    double thi = _theta * -1.0;
+    double x = pt.x()*cos(thi) - pt.y()*sin(thi);
+    double y = (pt.x()*sin(thi)) + (pt.y()*cos(thi));
+
+    // convert from orthogonal to lat/lon
+    double delta_lat = asin(y / SG_EQUATORIAL_RADIUS_M);
+    double delta_lon = asin(x / SG_EQUATORIAL_RADIUS_M) / _correction_factor;
+
+    return SGGeod::fromRadM(_origin.getLongitudeRad()+delta_lon, _origin.getLatitudeRad()+delta_lat, pt.z());
+}
+
index a49fafda864c0ffc2a9936c61272ac8164fc7789..4febcd64e51a1e5d2b91dc7a50ed2bb07dca6237 100644 (file)
@@ -166,6 +166,30 @@ private:
     int _min;
 };
 
+// AlignedProjection - a class to project an area local to a runway onto an orthogonal co-ordinate system
+// with the origin at the threshold and the runway aligned with the y axis.
+class AlignedProjection {
+
+public:
+    AlignedProjection();
+    AlignedProjection(const SGGeod& centre, double heading);
+    ~AlignedProjection();
+
+    void Init(const SGGeod& centre, double heading);
+
+    // Convert a lat/lon co-ordinate (degrees) to the local projection (meters)
+    SGVec3d ConvertToLocal(const SGGeod& pt);
+
+    // Convert a local projection co-ordinate (meters) to lat/lon (degrees)
+    SGGeod ConvertFromLocal(const SGVec3d& pt);
+
+private:
+    SGGeod _origin;    // lat/lon of local area origin (the threshold)
+    double _theta;     // the rotation angle for alignment in radians
+    double _correction_factor; // Reduction in surface distance per degree of longitude due to latitude.  Saves having to do a cos() every call.
+
+};
+
 // ------------------------------------------------------------------------------
 
 // TODO - merge generic GPS functions instead and split out KLN specific stuff.