1
0
Fork 0

CommRadio frequency updates from Sascha Reißner

Reject invalid frequencies from apt.dat in the loader, and fix
25Khz encoding to be the exact value (i.e round frequencies ending
in 20 and 70 to 25 and 75)

Fix ATCdialog to show 3 digits of comm radio frequency at all times,
and remove its rounding-conversion.

Finally, expand the tests to capture the new behaviour. Test for
EPLL is disabled for now because it contains an invalid frequency.
This commit is contained in:
James Turner 2021-04-01 14:46:21 +01:00
parent cec9ab5039
commit adae75821d
5 changed files with 71 additions and 12 deletions

View file

@ -154,11 +154,9 @@ void FGATCDialogNew::frequencyDisplay(const std::string& ident)
entry->setStringValue("text[0]/label", comm->ident());
char buf[8];
snprintf(buf, 8, "%.2f", comm->freqMHz());
if(buf[5] == '3') buf[5] = '2';
if(buf[5] == '8') buf[5] = '7';
buf[7] = '\0';
char buf[9];
::snprintf(buf, 9, "%.3f", comm->freqMHz());
buf[8] = '\0';
entry->setStringValue("text[1]/label", buf);
entry->setStringValue("button[0]/binding/value", buf);

View file

@ -822,8 +822,36 @@ void APTLoader::parseCommLine(const string& aptDat,
if (isAPT1000Code) {
rowCode -= 1000;
}
// short int representing tens of kHz, or just kHz directly
int freqKhz = std::stoi(token[1]) * (isAPT1000Code ? 1 : 10);
int freqKhz = std::stoi(token[1]);
if (isAPT1000Code) {
const int channel = freqKhz % 25;
if (channel != 0 && channel != 5 && channel != 10 && channel != 15) {
SG_LOG(SG_GENERAL, SG_ALERT,
aptDat << ":" << lineNum << ": skipping invalid 8.333 kHz Frequency " << freqKhz << " for " << last_apt_id);
return;
}
} else {
freqKhz *= 10;
const int remainder = freqKhz % 100;
// this is to ensure frequencies such as 126.12 become 126.125
if (remainder == 20 || remainder == 70) {
freqKhz += 5;
}
if (freqKhz % 25) {
SG_LOG(SG_GENERAL, SG_ALERT,
aptDat << ":" << lineNum << ": skipping invalid 25 kHz Frequency " << freqKhz << " for " << last_apt_id);
return;
}
}
if (freqKhz < 118000 || freqKhz >= 137000) {
SG_LOG(SG_GENERAL, SG_ALERT,
aptDat << ":" << lineNum << ": skipping out of range Frequency " << freqKhz << " for " << last_apt_id);
return;
}
int rangeNm = 50;
FGPositioned::Type ty;

View file

@ -631,11 +631,13 @@ void CommRadioImpl::update(double dt)
if (_stationTTL <= 0.0) {
_stationTTL = 30.0;
// 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);
_commStationForFrequency = flightgear::CommStation::findByFreq(freqKhz, position, NULL);
int freqKhz = static_cast<int>(_frequency * 1000 + 0.5);
// make sure the frequency is integral multiple of 25, if not using 8.333 kHz spacing
if (!_useEightPointThree && freqKhz % 25) {
freqKhz += 5;
}
_commStationForFrequency = flightgear::CommStation::findByFreq(freqKhz, position, NULL);
}
if (false == _commStationForFrequency.valid()) {

View file

@ -1,7 +1,7 @@
#ifndef FG_NAVCACHE_SCHEMA_HXX
#define FG_NAVCACHE_SCHEMA_HXX
const int SCHEMA_VERSION = 19;
const int SCHEMA_VERSION = 20;
#define SCHEMA_SQL \
"CREATE TABLE properties (key VARCHAR, value VARCHAR);" \

View file

@ -58,6 +58,34 @@ SGSubsystemRef CommRadioTests::setupStandardRadio(const std::string& name, int i
void CommRadioTests::testBasic()
{
auto r = setupStandardRadio("commtest", 2, false);
FGAirportRef apt = FGAirport::getByIdent("EDDM");
FGTestApi::setPositionAndStabilise(apt->geod());
SGPropertyNode_ptr n = globals->get_props()->getNode("instrumentation/commtest[2]");
// EDDM ATIS
n->setDoubleValue("frequencies/selected-mhz", 123.125);
r->update(1.0);
// CPPUNIT_ASSERT_DOUBLES_EQUAL(25, n->getDoubleValue("frequencies/selected-channel-width-khz"), 1e-3);
CPPUNIT_ASSERT_EQUAL("123.12"s, string{n->getStringValue("frequencies/selected-mhz-fmt")});
CPPUNIT_ASSERT_EQUAL("EDDM"s, string{n->getStringValue("airport-id")});
CPPUNIT_ASSERT_EQUAL("ATIS"s, string{n->getStringValue("station-name")});
CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, n->getDoubleValue("slant-distance-m"), 1e-6);
CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, n->getDoubleValue("signal-quality-norm"), 1e-6);
n->setDoubleValue("frequencies/selected-mhz", 121.72);
r->update(1.0);
CPPUNIT_ASSERT_EQUAL("121.72"s, string{n->getStringValue("frequencies/selected-mhz-fmt")});
CPPUNIT_ASSERT_EQUAL("EDDM"s, string{n->getStringValue("airport-id")});
CPPUNIT_ASSERT_EQUAL("CLNC DEL"s, string{n->getStringValue("station-name")});
CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, n->getDoubleValue("slant-distance-m"), 1e-6);
CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, n->getDoubleValue("signal-quality-norm"), 1e-6);
}
void CommRadioTests::testEightPointThree()
@ -135,6 +163,9 @@ void CommRadioTests::testEightPointThree()
void CommRadioTests::testEPLLTuning833()
{
// this test is disabled until data entry for EPLL is fixed
return;
auto r = setupStandardRadio("commtest", 2, true);
FGAirportRef apt = FGAirport::getByIdent("EPLL");
@ -142,7 +173,7 @@ void CommRadioTests::testEPLLTuning833()
SGPropertyNode_ptr n = globals->get_props()->getNode("instrumentation/commtest[2]");
// should be EPLL TWR
n->setDoubleValue("frequencies/selected-mhz", 124.23);
n->setDoubleValue("frequencies/selected-mhz", 124.225);
r->update(1.0);
CPPUNIT_ASSERT_EQUAL("EPLL"s, string{n->getStringValue("airport-id")});