Fix rounding of 8.33 kHz spacing frequencies

Related to #186
This commit is contained in:
Lars Toenning
2023-02-03 00:14:30 +01:00
parent a85905532e
commit 92351fa8ee
2 changed files with 52 additions and 7 deletions

View File

@@ -129,18 +129,56 @@ namespace BlackMisc::Aviation
return isValidCivilAviationFrequency(f) || isValidMilitaryFrequency(f);
}
bool CComSystem::isValid8_33kHzChannel(int fKHz)
{
const int lastDigits = static_cast<int>(fKHz) % 100;
return fKHz % 5 == 0 && lastDigits != 20 && lastDigits != 45 && lastDigits != 70 && lastDigits != 95;
}
int CComSystem::round8_33kHzChannel(int fKHz)
{
if (!isValid8_33kHzChannel(fKHz))
{
const int diff = static_cast<int>(fKHz) % 5;
int lower = fKHz - diff;
if (!isValid8_33kHzChannel(lower)) { lower -= 5; }
Q_ASSERT_X(isValid8_33kHzChannel(lower), Q_FUNC_INFO, "Lower frequency not valid");
int upper = fKHz + (5 - diff);
if (!isValid8_33kHzChannel(upper)) { upper += 5; }
Q_ASSERT_X(isValid8_33kHzChannel(upper), Q_FUNC_INFO, "Upper frequency not valid");
const int lowerDiff = abs(fKHz - lower);
const int upperDiff = abs(fKHz - upper);
fKHz = lowerDiff < upperDiff ? lower : upper;
fKHz = std::clamp(fKHz, 118000, 136990);
}
return fKHz;
}
void CComSystem::roundToChannelSpacing(CFrequency &frequency, ChannelSpacing channelSpacing)
{
if (frequency.isNull()) { return; }
const double channelSpacingKHz = CComSystem::channelSpacingToFrequencyKHz(channelSpacing);
const double fKHz = frequency.valueRounded(CFrequencyUnit::kHz(), 0);
const int dDown = static_cast<int>(fKHz / channelSpacingKHz);
const double fDownKHz = dDown * channelSpacingKHz;
const double fUpKHz = (dDown + 1) * channelSpacingKHz;
const bool down = qAbs(fKHz - fDownKHz) < qAbs(fUpKHz - fKHz); // which is the closest value
const double fMHz(CMathUtils::round((down ? fDownKHz : fUpKHz) / 1000.0, 3));
frequency.switchUnit(CFrequencyUnit::MHz());
frequency.setCurrentUnitValue(fMHz);
if (channelSpacing == ChannelSpacing8_33KHz)
{
const int freqKHz = round8_33kHzChannel(fKHz);
frequency.switchUnit(CFrequencyUnit::kHz());
frequency.setCurrentUnitValue(freqKHz);
}
else
{
const int dDown = static_cast<int>(fKHz / channelSpacingKHz);
const double fDownKHz = dDown * channelSpacingKHz;
const double fUpKHz = (dDown + 1) * channelSpacingKHz;
const bool down = qAbs(fKHz - fDownKHz) < qAbs(fUpKHz - fKHz); // which is the closest value
const double fMHz(CMathUtils::round((down ? fDownKHz : fUpKHz) / 1000.0, 3));
frequency.switchUnit(CFrequencyUnit::MHz());
frequency.setCurrentUnitValue(fMHz);
}
}
bool CComSystem::isWithinChannelSpacing(const CFrequency &setFrequency, const CFrequency &compareFrequency, CComSystem::ChannelSpacing channelSpacing)

View File

@@ -141,6 +141,13 @@ namespace BlackMisc::Aviation
const PhysicalQuantities::CFrequency &compareFrequency,
ChannelSpacing channelSpacing);
//! Is passed frequency in kHz a valid 8.33 channel. This does not check if
//! the frequency is within the correct bounds.
static bool isValid8_33kHzChannel(int fKHz);
//! Round passed frequency in kHz to 8.33 frequency spacing
static int round8_33kHzChannel(int fKHz);
//! Parses almost any shitty string to a valid COM frequency
static PhysicalQuantities::CFrequency parseComFrequency(const QString &input, PhysicalQuantities::CPqString::SeparatorMode sep);