ATISMgr clean-up / improvements
Adds serviceable/operable properties to comm radio. Obey comm radio power source (no power => no radio => no ATIS). Also further clean-up to stuff belonging to former ATCmgr module.
This commit is contained in:
parent
ec739a17c2
commit
a2bd520a3b
6 changed files with 240 additions and 225 deletions
|
@ -77,7 +77,7 @@ FGATC::~FGATC() {
|
||||||
#ifndef OLD_ATC_MGR
|
#ifndef OLD_ATC_MGR
|
||||||
// Derived classes wishing to use the response counter should
|
// Derived classes wishing to use the response counter should
|
||||||
// call this from their own Update(...).
|
// call this from their own Update(...).
|
||||||
void FGATC::Update(double dt) {
|
void FGATC::update(double dt) {
|
||||||
|
|
||||||
#ifdef ENABLE_AUDIO_SUPPORT
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
bool active = _atc_external->getBoolValue() ||
|
bool active = _atc_external->getBoolValue() ||
|
||||||
|
@ -117,7 +117,7 @@ void FGATC::SetStation(flightgear::CommStation* sta) {
|
||||||
freq = 0;
|
freq = 0;
|
||||||
|
|
||||||
SetNoDisplay();
|
SetNoDisplay();
|
||||||
Update(0); // one last update
|
update(0); // one last update
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -94,12 +94,12 @@ public:
|
||||||
FGATC();
|
FGATC();
|
||||||
virtual ~FGATC();
|
virtual ~FGATC();
|
||||||
|
|
||||||
virtual void Init()=0;
|
virtual void init()=0;
|
||||||
|
|
||||||
// Run the internal calculations
|
// Run the internal calculations
|
||||||
// Derived classes should call this method from their own Update methods if they
|
// Derived classes should call this method from their own Update methods if they
|
||||||
// wish to use the response timer functionality.
|
// wish to use the response timer functionality.
|
||||||
virtual void Update(double dt);
|
virtual void update(double dt);
|
||||||
|
|
||||||
// Indicate that this instance should output to the display if appropriate
|
// Indicate that this instance should output to the display if appropriate
|
||||||
inline void SetDisplay() { _display = true; }
|
inline void SetDisplay() { _display = true; }
|
||||||
|
|
|
@ -27,24 +27,17 @@
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/structure/exception.hxx>
|
#include <simgear/structure/exception.hxx>
|
||||||
|
|
||||||
#include <Airports/simple.hxx>
|
|
||||||
#include <ATC/CommStation.hxx>
|
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
|
|
||||||
#include "ATISmgr.hxx"
|
#include "ATISmgr.hxx"
|
||||||
#include "ATCutils.hxx"
|
|
||||||
#include "atis.hxx"
|
#include "atis.hxx"
|
||||||
|
|
||||||
using flightgear::CommStation;
|
|
||||||
|
|
||||||
FGATISMgr::FGATISMgr() :
|
FGATISMgr::FGATISMgr() :
|
||||||
_currentUnit(0),
|
_currentUnit(0),
|
||||||
_maxCommRadios(4),
|
_maxCommRadios(4)
|
||||||
#ifdef ENABLE_AUDIO_SUPPORT
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
voice(true),
|
,useVoice(true),
|
||||||
voice1(0)
|
voice(0)
|
||||||
#else
|
|
||||||
voice(false)
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
globals->set_ATIS_mgr(this);
|
globals->set_ATIS_mgr(this);
|
||||||
|
@ -56,58 +49,36 @@ FGATISMgr::~FGATISMgr()
|
||||||
|
|
||||||
for (unsigned int unit = 0;unit < _maxCommRadios; ++unit)
|
for (unsigned int unit = 0;unit < _maxCommRadios; ++unit)
|
||||||
{
|
{
|
||||||
delete radios[unit].station;
|
delete radios[unit];
|
||||||
radios[unit].station = NULL;
|
radios[unit] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_AUDIO_SUPPORT
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
delete voice1;
|
delete voice;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGATISMgr::bind()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGATISMgr::unbind()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGATISMgr::init()
|
void FGATISMgr::init()
|
||||||
{
|
{
|
||||||
lon_node = fgGetNode("/position/longitude-deg", true);
|
|
||||||
lat_node = fgGetNode("/position/latitude-deg", true);
|
|
||||||
elev_node = fgGetNode("/position/altitude-ft", true);
|
|
||||||
|
|
||||||
for (unsigned int unit = 0;unit < _maxCommRadios; ++unit)
|
for (unsigned int unit = 0;unit < _maxCommRadios; ++unit)
|
||||||
{
|
{
|
||||||
CommRadioData data;
|
|
||||||
string ncunit;
|
|
||||||
if (unit < _maxCommRadios/2)
|
if (unit < _maxCommRadios/2)
|
||||||
ncunit = "comm[" + decimalNumeral(unit) + "]";
|
radios.push_back(new FGATIS("comm", unit));
|
||||||
else
|
else
|
||||||
ncunit = "nav[" + decimalNumeral(unit - _maxCommRadios/2) + "]";
|
radios.push_back(new FGATIS("nav", unit - _maxCommRadios/2));
|
||||||
string commbase = "/instrumentation/" + ncunit;
|
|
||||||
string commfreq = commbase + "/frequencies/selected-mhz";
|
|
||||||
|
|
||||||
data.freq = fgGetNode(commfreq.c_str(), true);
|
|
||||||
data.station = new FGATIS(commbase);
|
|
||||||
radios.push_back(data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FGATISMgr::update(double dt)
|
void FGATISMgr::update(double dt)
|
||||||
{
|
{
|
||||||
// update only runs every now and then (1-2 per second)
|
// update only runs every now and then (1-2 per second)
|
||||||
if (++_currentUnit >= _maxCommRadios)
|
if (++_currentUnit >= _maxCommRadios)
|
||||||
_currentUnit = 0;
|
_currentUnit = 0;
|
||||||
|
|
||||||
FGATC* pStation = radios[_currentUnit].station;
|
FGATC* commRadio = radios[_currentUnit];
|
||||||
if (pStation)
|
if (commRadio)
|
||||||
pStation->Update(dt * _maxCommRadios);
|
commRadio->update(dt * _maxCommRadios);
|
||||||
|
|
||||||
// Search the tuned frequencies
|
|
||||||
FreqSearch(_currentUnit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a pointer to an appropriate voice for a given type of ATC
|
// Return a pointer to an appropriate voice for a given type of ATC
|
||||||
|
@ -119,13 +90,13 @@ void FGATISMgr::update(double dt)
|
||||||
// at different airports in quick succession if a large enough selection are available.
|
// at different airports in quick succession if a large enough selection are available.
|
||||||
FGATCVoice* FGATISMgr::GetVoicePointer(const atc_type& type)
|
FGATCVoice* FGATISMgr::GetVoicePointer(const atc_type& type)
|
||||||
{
|
{
|
||||||
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
// TODO - implement me better - maintain a list of loaded voices and other voices!!
|
// TODO - implement me better - maintain a list of loaded voices and other voices!!
|
||||||
if(voice)
|
if(useVoice)
|
||||||
{
|
{
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case ATIS: case AWOS:
|
case ATIS: case AWOS:
|
||||||
#ifdef ENABLE_AUDIO_SUPPORT
|
|
||||||
// Delayed loading for all available voices, needed because the
|
// Delayed loading for all available voices, needed because the
|
||||||
// sound manager might not be initialized (at all) at this point.
|
// sound manager might not be initialized (at all) at this point.
|
||||||
// For now we'll do one hard-wired one
|
// For now we'll do one hard-wired one
|
||||||
|
@ -135,22 +106,19 @@ FGATCVoice* FGATISMgr::GetVoicePointer(const atc_type& type)
|
||||||
* subsequently switches /sim/sound/audible to true.
|
* subsequently switches /sim/sound/audible to true.
|
||||||
* (which is the right thing to do -- CLO) :-)
|
* (which is the right thing to do -- CLO) :-)
|
||||||
*/
|
*/
|
||||||
if (!voice1 && fgGetBool("/sim/sound/working")) {
|
if (!voice && fgGetBool("/sim/sound/working")) {
|
||||||
voice1 = new FGATCVoice;
|
voice = new FGATCVoice;
|
||||||
try {
|
try {
|
||||||
voice = voice1->LoadVoice("default");
|
useVoice = voice->LoadVoice("default");
|
||||||
} catch ( sg_io_exception & e) {
|
} catch ( sg_io_exception & e) {
|
||||||
SG_LOG(SG_ATC, SG_ALERT, "Unable to load default voice : "
|
SG_LOG(SG_ATC, SG_ALERT, "Unable to load default voice : "
|
||||||
<< e.getFormattedMessage().c_str());
|
<< e.getFormattedMessage().c_str());
|
||||||
voice = false;
|
useVoice = false;
|
||||||
delete voice1;
|
delete voice;
|
||||||
voice1 = 0;
|
voice = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (voice)
|
return voice;
|
||||||
return voice1;
|
|
||||||
#endif
|
|
||||||
return NULL;
|
|
||||||
case TOWER:
|
case TOWER:
|
||||||
return NULL;
|
return NULL;
|
||||||
case APPROACH:
|
case APPROACH:
|
||||||
|
@ -161,52 +129,7 @@ FGATCVoice* FGATISMgr::GetVoicePointer(const atc_type& type)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
class RangeFilter : public CommStation::Filter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RangeFilter( const SGGeod & pos ) :
|
|
||||||
CommStation::Filter(),
|
|
||||||
_cart(SGVec3d::fromGeod(pos)),
|
|
||||||
_pos(pos)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool pass(FGPositioned* aPos) const
|
|
||||||
{
|
|
||||||
flightgear::CommStation * stn = dynamic_cast<flightgear::CommStation*>(aPos);
|
|
||||||
if( NULL == stn )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// do the range check in cartesian space, since the distances are potentially
|
|
||||||
// large enough that the geodetic functions become unstable
|
|
||||||
// (eg, station on opposite side of the planet)
|
|
||||||
double rangeM = SGMiscd::max( stn->rangeNm(), 10.0 ) * SG_NM_TO_METER;
|
|
||||||
double d2 = distSqr( aPos->cart(), _cart);
|
|
||||||
|
|
||||||
return d2 <= (rangeM * rangeM);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
SGVec3d _cart;
|
|
||||||
SGGeod _pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Search for ATC stations by frequency
|
|
||||||
void FGATISMgr::FreqSearch(const unsigned int unit)
|
|
||||||
{
|
|
||||||
double frequency = radios[unit].freq->getDoubleValue();
|
|
||||||
|
|
||||||
// Note: 122.375 must be rounded DOWN to 12237
|
|
||||||
// in order to be consistent with apt.dat et cetera.
|
|
||||||
int freqKhz = static_cast<int>(frequency * 100.0 + 0.25);
|
|
||||||
|
|
||||||
_aircraftPos = SGGeod::fromDegFt(lon_node->getDoubleValue(),
|
|
||||||
lat_node->getDoubleValue(), elev_node->getDoubleValue());
|
|
||||||
|
|
||||||
RangeFilter rangeFilter(_aircraftPos );
|
|
||||||
CommStation* sta = CommStation::findByFreq(freqKhz, _aircraftPos, &rangeFilter );
|
|
||||||
radios[unit].station->SetStation(sta);
|
|
||||||
}
|
|
||||||
|
|
|
@ -19,55 +19,27 @@
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
#ifndef _FG_ATCMGR_HXX
|
#ifndef _FG_ATISMGR_HXX
|
||||||
#define _FG_ATCMGR_HXX
|
#define _FG_ATISMGR_HXX
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <simgear/structure/subsystem_mgr.hxx>
|
#include <simgear/structure/subsystem_mgr.hxx>
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <list>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include "ATC.hxx"
|
#include "ATC.hxx"
|
||||||
|
|
||||||
namespace flightgear
|
|
||||||
{
|
|
||||||
class CommStation;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
SGPropertyNode_ptr freq;
|
|
||||||
FGATC* station;
|
|
||||||
} CommRadioData;
|
|
||||||
|
|
||||||
class FGATISMgr : public SGSubsystem
|
class FGATISMgr : public SGSubsystem
|
||||||
{
|
{
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// A vector containing all comm radios
|
// A vector containing all comm radios
|
||||||
typedef std::vector<CommRadioData> radio_list_type;
|
std::vector<FGATC*> radios;
|
||||||
radio_list_type radios;
|
|
||||||
|
|
||||||
// Any member function of FGATISMgr is permitted to leave this iterator pointing
|
|
||||||
// at any point in or at the end of the list.
|
|
||||||
// Hence any new access must explicitly first check for atc_list.end() before dereferencing.
|
|
||||||
|
|
||||||
// Position of the Users Aircraft
|
|
||||||
SGGeod _aircraftPos;
|
|
||||||
|
|
||||||
// Pointers to current users position
|
|
||||||
SGPropertyNode_ptr lon_node;
|
|
||||||
SGPropertyNode_ptr lat_node;
|
|
||||||
SGPropertyNode_ptr elev_node;
|
|
||||||
|
|
||||||
unsigned int _currentUnit;
|
unsigned int _currentUnit;
|
||||||
unsigned int _maxCommRadios;
|
unsigned int _maxCommRadios;
|
||||||
|
|
||||||
// Voice related stuff
|
|
||||||
bool voice; // Flag - true if we are using voice
|
|
||||||
#ifdef ENABLE_AUDIO_SUPPORT
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
FGATCVoice* voice1;
|
bool useVoice; // Flag - true if we are using voice
|
||||||
|
FGATCVoice* voice;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -75,11 +47,6 @@ public:
|
||||||
~FGATISMgr();
|
~FGATISMgr();
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
void bind();
|
|
||||||
|
|
||||||
void unbind();
|
|
||||||
|
|
||||||
void update(double dt);
|
void update(double dt);
|
||||||
|
|
||||||
// Return a pointer to an appropriate voice for a given type of ATC
|
// Return a pointer to an appropriate voice for a given type of ATC
|
||||||
|
@ -92,8 +59,6 @@ public:
|
||||||
FGATCVoice* GetVoicePointer(const atc_type& type);
|
FGATCVoice* GetVoicePointer(const atc_type& type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Search the specified radio for stations on the same frequency and in range.
|
|
||||||
void FreqSearch(const unsigned int unit);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _FG_ATCMGR_HXX
|
#endif // _FG_ATISMGR_HXX
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
#include <Airports/runways.hxx>
|
#include <Airports/runways.hxx>
|
||||||
#include <Airports/dynamics.hxx>
|
#include <Airports/dynamics.hxx>
|
||||||
|
|
||||||
|
#include <ATC/CommStation.hxx>
|
||||||
|
|
||||||
#include "ATCutils.hxx"
|
#include "ATCutils.hxx"
|
||||||
#include "ATISmgr.hxx"
|
#include "ATISmgr.hxx"
|
||||||
|
@ -65,8 +66,11 @@ using std::cout;
|
||||||
using std::cout;
|
using std::cout;
|
||||||
using boost::ref;
|
using boost::ref;
|
||||||
using boost::tie;
|
using boost::tie;
|
||||||
|
using flightgear::CommStation;
|
||||||
|
|
||||||
FGATIS::FGATIS(const string& commbase) :
|
FGATIS::FGATIS(const std::string& name, int num) :
|
||||||
|
_name(name),
|
||||||
|
_num(num),
|
||||||
transmission(""),
|
transmission(""),
|
||||||
trans_ident(""),
|
trans_ident(""),
|
||||||
old_volume(0),
|
old_volume(0),
|
||||||
|
@ -74,10 +78,37 @@ FGATIS::FGATIS(const string& commbase) :
|
||||||
msg_OK(0),
|
msg_OK(0),
|
||||||
attention(0),
|
attention(0),
|
||||||
_prev_display(0),
|
_prev_display(0),
|
||||||
_commbase(commbase)
|
_time_before_search_sec(0),
|
||||||
|
_last_frequency(0)
|
||||||
{
|
{
|
||||||
fgTie("/environment/attention", this, (int_getter)0, &FGATIS::attend);
|
fgTie("/environment/attention", this, (int_getter)0, &FGATIS::attend);
|
||||||
|
|
||||||
|
_root = fgGetNode("/instrumentation", true)->getNode(_name, num, true);
|
||||||
|
_volume = _root->getNode("volume",true);
|
||||||
|
_serviceable = _root->getNode("serviceable",true);
|
||||||
|
|
||||||
|
if (name != "nav")
|
||||||
|
{
|
||||||
|
// only drive "operable" for non-nav instruments (nav radio drives this separately)
|
||||||
|
_operable = _root->getNode("operable",true);
|
||||||
|
_operable->setBoolValue(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
_electrical = fgGetNode("/systems/electrical/outputs",true)->getNode(_name,num, true);
|
||||||
|
_atis = _root->getNode("atis",true);
|
||||||
|
_freq = _root->getNode("frequencies/selected-mhz",true);
|
||||||
|
|
||||||
|
// current position
|
||||||
|
_lon_node = fgGetNode("/position/longitude-deg", true);
|
||||||
|
_lat_node = fgGetNode("/position/latitude-deg", true);
|
||||||
|
_elev_node = fgGetNode("/position/altitude-ft", true);
|
||||||
|
|
||||||
|
// backward compatibility: some properties may not exist (but default to "ON")
|
||||||
|
if (!_serviceable->hasValue())
|
||||||
|
_serviceable->setBoolValue(true);
|
||||||
|
if (!_electrical->hasValue())
|
||||||
|
_electrical->setDoubleValue(24.0);
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
// FIXME: This would be more flexible and more extensible
|
// FIXME: This would be more flexible and more extensible
|
||||||
// if the mappings were taken from an XML file, not hard-coded ...
|
// if the mappings were taken from an XML file, not hard-coded ...
|
||||||
|
@ -115,7 +146,7 @@ FGATCVoice* FGATIS::GetVoicePointer()
|
||||||
return pAtisMgr->GetVoicePointer(ATIS);
|
return pAtisMgr->GetVoicePointer(ATIS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGATIS::Init() {
|
void FGATIS::init() {
|
||||||
// Nothing to see here. Move along.
|
// Nothing to see here. Move along.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +165,7 @@ FGATIS::attend (int attn)
|
||||||
|
|
||||||
|
|
||||||
// Main update function - checks whether we are displaying or not the correct message.
|
// Main update function - checks whether we are displaying or not the correct message.
|
||||||
void FGATIS::Update(double dt) {
|
void FGATIS::update(double dt) {
|
||||||
cur_time = globals->get_time_params()->get_cur_time();
|
cur_time = globals->get_time_params()->get_cur_time();
|
||||||
msg_OK = (msg_time < cur_time);
|
msg_OK = (msg_time < cur_time);
|
||||||
|
|
||||||
|
@ -148,28 +179,52 @@ void FGATIS::Update(double dt) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(_display)
|
double volume = 0;
|
||||||
|
if ((_electrical->getDoubleValue()>8) && _serviceable->getBoolValue())
|
||||||
{
|
{
|
||||||
string prop = _commbase + "/volume";
|
_time_before_search_sec -= dt;
|
||||||
double volume = globals->get_props()->getDoubleValue(prop.c_str());
|
// radio is switched on and OK
|
||||||
|
if (_operable.valid())
|
||||||
|
_operable->setBoolValue(true);
|
||||||
|
|
||||||
// Check if we need to update the message
|
// Search the tuned frequencies
|
||||||
// - basically every hour and if the weather changes significantly at the station
|
search();
|
||||||
// If !_prev_display, the radio had been detuned for a while and our
|
|
||||||
// "transmission" variable was lost when we were de-instantiated.
|
if (_display)
|
||||||
|
{
|
||||||
|
volume = _volume->getDoubleValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// radio is OFF
|
||||||
|
if (_operable.valid())
|
||||||
|
_operable->setBoolValue(false);
|
||||||
|
_time_before_search_sec = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volume > 0.05)
|
||||||
|
{
|
||||||
|
// Check if we need to update the message
|
||||||
|
// - basically every hour and if the weather changes significantly at the station
|
||||||
|
// If !_prev_display, the radio had been detuned for a while and our
|
||||||
|
// "transmission" variable was lost when we were de-instantiated.
|
||||||
int changed = GenTransmission(!_prev_display, attention);
|
int changed = GenTransmission(!_prev_display, attention);
|
||||||
|
|
||||||
|
// update output property
|
||||||
TreeOut(msg_OK);
|
TreeOut(msg_OK);
|
||||||
|
|
||||||
if (changed || volume != old_volume) {
|
if (changed || volume != old_volume) {
|
||||||
//cout << "ATIS calling ATC::render volume: " << volume << endl;
|
// audio output enabled
|
||||||
Render(transmission, volume, _commbase, true);
|
Render(transmission, volume, _name, true);
|
||||||
old_volume = volume;
|
old_volume = volume;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// We shouldn't be displaying
|
|
||||||
//cout << "ATIS.CXX - calling NoRender()..." << endl;
|
|
||||||
NoRender(_commbase);
|
|
||||||
}
|
|
||||||
_prev_display = _display;
|
_prev_display = _display;
|
||||||
|
} else {
|
||||||
|
// silence
|
||||||
|
NoRender(_name);
|
||||||
|
_prev_display = false;
|
||||||
|
}
|
||||||
attention = 0;
|
attention = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,10 +577,74 @@ int FGATIS::GenTransmission(const int regen, const int special) {
|
||||||
// http://localhost:5400/instrumentation/comm[1]
|
// http://localhost:5400/instrumentation/comm[1]
|
||||||
//
|
//
|
||||||
// (Also, if in debug mode, dump it to the console.)
|
// (Also, if in debug mode, dump it to the console.)
|
||||||
void FGATIS::TreeOut(int msg_OK){
|
void FGATIS::TreeOut(int msg_OK)
|
||||||
string prop = _commbase + "/atis";
|
{
|
||||||
globals->get_props()->setStringValue(prop.c_str(),
|
_atis->setStringValue("<pre>\n" + transmission_readable + "</pre>\n");
|
||||||
("<pre>\n" + transmission_readable + "</pre>\n").c_str());
|
SG_LOG(SG_ATC, SG_DEBUG, "**** ATIS active on: " << _name <<
|
||||||
SG_LOG(SG_ATC, SG_DEBUG, "**** ATIS active on: " << prop <<
|
|
||||||
"transmission: " << transmission_readable);
|
"transmission: " << transmission_readable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class RangeFilter : public CommStation::Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RangeFilter( const SGGeod & pos ) :
|
||||||
|
CommStation::Filter(),
|
||||||
|
_cart(SGVec3d::fromGeod(pos)),
|
||||||
|
_pos(pos)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool pass(FGPositioned* aPos) const
|
||||||
|
{
|
||||||
|
flightgear::CommStation * stn = dynamic_cast<flightgear::CommStation*>(aPos);
|
||||||
|
if( NULL == stn )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// do the range check in cartesian space, since the distances are potentially
|
||||||
|
// large enough that the geodetic functions become unstable
|
||||||
|
// (eg, station on opposite side of the planet)
|
||||||
|
double rangeM = SGMiscd::max( stn->rangeNm(), 10.0 ) * SG_NM_TO_METER;
|
||||||
|
double d2 = distSqr( aPos->cart(), _cart);
|
||||||
|
|
||||||
|
return d2 <= (rangeM * rangeM);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
SGVec3d _cart;
|
||||||
|
SGGeod _pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Search for ATC stations by frequency
|
||||||
|
void FGATIS::search(void)
|
||||||
|
{
|
||||||
|
double frequency = _freq->getDoubleValue();
|
||||||
|
|
||||||
|
// Note: 122.375 must be rounded DOWN to 12237
|
||||||
|
// in order to be consistent with apt.dat et cetera.
|
||||||
|
int freqKhz = static_cast<int>(frequency * 100.0 + 0.25);
|
||||||
|
|
||||||
|
// throttle frequency searches
|
||||||
|
if ((freqKhz == _last_frequency)&&(_time_before_search_sec > 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_last_frequency = freqKhz;
|
||||||
|
_time_before_search_sec = 4.0;
|
||||||
|
|
||||||
|
// Position of the Users Aircraft
|
||||||
|
SGGeod aircraftPos = SGGeod::fromDegFt(_lon_node->getDoubleValue(),
|
||||||
|
_lat_node->getDoubleValue(),
|
||||||
|
_elev_node->getDoubleValue());
|
||||||
|
|
||||||
|
RangeFilter rangeFilter(aircraftPos );
|
||||||
|
CommStation* sta = CommStation::findByFreq(freqKhz, aircraftPos, &rangeFilter );
|
||||||
|
SetStation(sta);
|
||||||
|
if (sta && sta->airport())
|
||||||
|
{
|
||||||
|
SG_LOG(SG_ATC, SG_DEBUG, "FGATIS " << _name << ": " << sta->airport()->name());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SG_LOG(SG_ATC, SG_DEBUG, "FGATIS " << _name << ": no station.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -28,17 +28,29 @@
|
||||||
|
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
#include <simgear/timing/sg_time.hxx>
|
#include <simgear/timing/sg_time.hxx>
|
||||||
|
#include <simgear/props/props.hxx>
|
||||||
|
|
||||||
#include "ATC.hxx"
|
#include "ATC.hxx"
|
||||||
|
|
||||||
//DCL - a complete guess for now.
|
|
||||||
#define FG_ATIS_DEFAULT_RANGE 30
|
|
||||||
|
|
||||||
typedef std::map<std::string,std::string> MSS;
|
typedef std::map<std::string,std::string> MSS;
|
||||||
|
|
||||||
class FGATIS : public FGATC {
|
class FGATIS : public FGATC {
|
||||||
|
|
||||||
//atc_type type;
|
std::string _name;
|
||||||
|
int _num;
|
||||||
|
|
||||||
|
SGPropertyNode_ptr _root;
|
||||||
|
SGPropertyNode_ptr _volume;
|
||||||
|
SGPropertyNode_ptr _serviceable;
|
||||||
|
SGPropertyNode_ptr _operable;
|
||||||
|
SGPropertyNode_ptr _electrical;
|
||||||
|
SGPropertyNode_ptr _freq;
|
||||||
|
SGPropertyNode_ptr _atis;
|
||||||
|
|
||||||
|
// Pointers to current users position
|
||||||
|
SGPropertyNode_ptr _lon_node;
|
||||||
|
SGPropertyNode_ptr _lat_node;
|
||||||
|
SGPropertyNode_ptr _elev_node;
|
||||||
|
|
||||||
// The actual ATIS transmission
|
// The actual ATIS transmission
|
||||||
// This is generated from the prevailing conditions when required.
|
// This is generated from the prevailing conditions when required.
|
||||||
|
@ -60,26 +72,19 @@ class FGATIS : public FGATC {
|
||||||
bool _prev_display; // Previous value of _display flag
|
bool _prev_display; // Previous value of _display flag
|
||||||
MSS _remap; // abbreviations to be expanded
|
MSS _remap; // abbreviations to be expanded
|
||||||
|
|
||||||
std::string _commbase;
|
// internal periodic station search timer
|
||||||
|
double _time_before_search_sec;
|
||||||
// Aircraft position
|
int _last_frequency;
|
||||||
// ATIS is actually a special case in that unlike other ATC eg.tower it doesn't actually know about
|
|
||||||
// or the whereabouts of the aircraft it is transmitting to. However, to ensure consistancy of
|
|
||||||
// operation with the other ATC classes the ATIS class must calculate range to the aircraft in order
|
|
||||||
// to decide whether to render the transmission - hence the users plane details must be stored.
|
|
||||||
//SGPropertyNode_ptr airplane_lon_node;
|
|
||||||
//SGPropertyNode_ptr airplane_lat_node;
|
|
||||||
//SGPropertyNode_ptr airplane_elev_node;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FGATIS(const std::string& commbase);
|
FGATIS(const std::string& name, int num);
|
||||||
~FGATIS(void);
|
~FGATIS(void);
|
||||||
virtual void Init();
|
virtual void init();
|
||||||
void attend (int);
|
void attend (int);
|
||||||
|
|
||||||
//run the ATIS instance
|
//run the ATIS instance
|
||||||
void Update(double dt);
|
void update(double dt);
|
||||||
|
|
||||||
//inline void set_type(const atc_type tp) {type = tp;}
|
//inline void set_type(const atc_type tp) {type = tp;}
|
||||||
inline const std::string& get_trans_ident() { return trans_ident; }
|
inline const std::string& get_trans_ident() { return trans_ident; }
|
||||||
|
@ -96,6 +101,9 @@ private:
|
||||||
// (and in debug mode, print it on the console):
|
// (and in debug mode, print it on the console):
|
||||||
void TreeOut(int msgOK);
|
void TreeOut(int msgOK);
|
||||||
|
|
||||||
|
// Search the specified radio for stations on the same frequency and in range.
|
||||||
|
void search(void);
|
||||||
|
|
||||||
friend std::istream& operator>> ( std::istream&, FGATIS& );
|
friend std::istream& operator>> ( std::istream&, FGATIS& );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue