1
0
Fork 0

TACAN: Add support for setting TACAN by frequency

set instrumentation/tacan/selected-mhz to the required frequency and the channel will be correctly set based on frequency matching in the TACAN db.
This commit is contained in:
Richard Harrison 2018-09-02 13:39:52 +02:00
parent c923ae5b32
commit 8271bb0456
3 changed files with 60 additions and 19 deletions

View file

@ -101,6 +101,8 @@ void TACAN::init()
_electrical_node = fgGetNode("/systems/electrical/outputs/tacan", true);
// Add/trigger change listener after creating all nodes
_frequency_node->addChangeListener(this);
_channel_in0_node->addChangeListener(this);
_channel_in1_node->addChangeListener(this);
_channel_in2_node->addChangeListener(this);
@ -289,24 +291,43 @@ TACAN::valueChanged(SGPropertyNode *prop)
int index = prop->getIndex();
std::string channel = _channel;
if (index) { // channel digit or X/Y input
int c;
if (isdigit(c = _channel_in1_node->getStringValue()[0]))
channel[0] = c;
if (isdigit(c = _channel_in2_node->getStringValue()[0]))
channel[1] = c;
if (isdigit(c = _channel_in3_node->getStringValue()[0]))
channel[2] = c;
c = _channel_in4_node->getStringValue()[0];
if (c == 'X' || c == 'Y')
channel[3] = c;
if (std::string("selected-mhz") == prop->getName())
{
FGTACANRecord *rec= globals->get_channellist()->findByFrequency(prop->getDoubleValue()*1000);
if (rec != nullptr) {
channel = rec->get_channel();
_channel_in1_node->setStringValue(channel.substr(0, 1));
_channel_in2_node->setStringValue(channel.substr(1, 1));
_channel_in3_node->setStringValue(channel.substr(2, 1));
_channel_in4_node->setStringValue(channel.substr(3, 1));
index = 1;
}
else {
SG_LOG(SG_INSTR, SG_WARN, "Entered TACAN Frequency " << prop->getDoubleValue() << " does not map to a known TACAN channel");
}
}
else
{
if (index) { // channel digit or X/Y input
int c;
if (isdigit(c = _channel_in1_node->getStringValue()[0]))
channel[0] = c;
if (isdigit(c = _channel_in2_node->getStringValue()[0]))
channel[1] = c;
if (isdigit(c = _channel_in3_node->getStringValue()[0]))
channel[2] = c;
c = _channel_in4_node->getStringValue()[0];
if (c == 'X' || c == 'Y')
channel[3] = c;
} else { // channel number input
unsigned int f = prop->getIntValue();
if (f >= 1 && f <= 126) {
channel[0] = '0' + (f / 100) % 10;
channel[1] = '0' + (f / 10) % 10;
channel[2] = '0' + f % 10;
}
else { // channel number input
unsigned int f = prop->getIntValue();
if (f >= 1 && f <= 126) {
channel[0] = '0' + (f / 100) % 10;
channel[1] = '0' + (f / 10) % 10;
channel[2] = '0' + f % 10;
}
}
}

View file

@ -320,7 +320,24 @@ bool FGTACANList::add( FGTACANRecord *c )
return true;
}
/*
* ref: 070031b3c01f64a44433e8cce742373f4c76b7ac
* The ground reply frequencies are used to keep channels 1-16 and 60-69 out of the VOR frequency range as those channels
* don't have VORs associated with them.
* - this method will therefore only be able to locate channels 17 to 59.
*/
FGTACANRecord *FGTACANList::findByFrequency(int frequency_kHz)
{
//029Y 10925 (encoded) = 109.25 = 109250khz - so we divide the input by 10
int tfreq = frequency_kHz / 10;
for (tacan_ident_map_type::iterator it = ident_channels.begin(); it != ident_channels.end(); it++)
{
for (tacan_list_type::iterator lit = it->second.begin(); lit != it->second.end(); lit++)
if ((*lit)->get_freq() == tfreq)
return (*lit);
}
return nullptr;
}
// Given a TACAN Channel return the first matching frequency
FGTACANRecord *FGTACANList::findByChannel( const string& channel )
{

View file

@ -146,7 +146,10 @@ public:
bool add( FGTACANRecord *r );
// Given a TACAN Channel, return the appropriate frequency.
FGTACANRecord *findByChannel( const std::string& channel );
FGTACANRecord *findByChannel(const std::string& channel);
// Given a TACAN Channel, return the appropriate frequency.
FGTACANRecord *findByFrequency(int frequency_kHz);
};