Ref T231, Ref T236, Ref T238 improvements based on Unit test

* check for a correct callsign (assert)
* set callsign if missing (fallback)
* resetLastInterpolation - null last inperpolation
This commit is contained in:
Klaus Basan
2018-01-28 20:06:56 +01:00
parent 0a06ad223f
commit 69e2ed6efe
5 changed files with 69 additions and 15 deletions

View File

@@ -29,6 +29,10 @@ namespace BlackMisc
CAircraftSituation::CAircraftSituation() CAircraftSituation::CAircraftSituation()
: m_groundElevation( { 0, nullptr }, CAltitude::MeanSeaLevel) {} : m_groundElevation( { 0, nullptr }, CAltitude::MeanSeaLevel) {}
CAircraftSituation::CAircraftSituation(const CCallsign &correspondingCallsign)
: m_correspondingCallsign(correspondingCallsign), m_groundElevation( { 0, nullptr }, CAltitude::MeanSeaLevel)
{}
CAircraftSituation::CAircraftSituation(const CCoordinateGeodetic &position, const CHeading &heading, const CAngle &pitch, const CAngle &bank, const CSpeed &gs, const CAltitude &groundElevation) CAircraftSituation::CAircraftSituation(const CCoordinateGeodetic &position, const CHeading &heading, const CAngle &pitch, const CAngle &bank, const CSpeed &gs, const CAltitude &groundElevation)
: m_position(position), m_heading(heading), m_pitch(pitch), : m_position(position), m_heading(heading), m_pitch(pitch),
m_bank(bank), m_groundSpeed(gs), m_groundElevation(groundElevation) m_bank(bank), m_groundSpeed(gs), m_groundElevation(groundElevation)
@@ -167,6 +171,23 @@ namespace BlackMisc
return 0; return 0;
} }
bool CAircraftSituation::isNull() const
{
return this->isPositionNull();
}
void CAircraftSituation::setNull()
{
m_position.setNull();
m_pressureAltitude.setNull();
m_heading.setNull();
m_pitch.setNull();
m_bank.setNull();
m_groundElevation.setNull();
m_groundSpeed.setNull();
m_onGroundReliability = CAircraftSituation::OnGroundReliabilityNoSet;
}
const QString &CAircraftSituation::isOnGroundAsString() const const QString &CAircraftSituation::isOnGroundAsString() const
{ {
return CAircraftSituation::isOnGroundToString(this->isOnGround()); return CAircraftSituation::isOnGroundToString(this->isOnGround());

View File

@@ -85,6 +85,9 @@ namespace BlackMisc
//! Default constructor. //! Default constructor.
CAircraftSituation(); CAircraftSituation();
//! Constructor with callsign
CAircraftSituation(const CCallsign &correspondingCallsign);
//! Comprehensive constructor //! Comprehensive constructor
CAircraftSituation(const Geo::CCoordinateGeodetic &position, CAircraftSituation(const Geo::CCoordinateGeodetic &position,
const CHeading &heading = {}, const CHeading &heading = {},
@@ -117,6 +120,12 @@ namespace BlackMisc
//! Position null? //! Position null?
bool isPositionNull() const { return m_position.isNull(); } bool isPositionNull() const { return m_position.isNull(); }
//! Null situation
virtual bool isNull() const override;
//! Set to null
void setNull();
//! Set position //! Set position
void setPosition(const Geo::CCoordinateGeodetic &position) { m_position = position; } void setPosition(const Geo::CCoordinateGeodetic &position) { m_position = position; }

View File

@@ -57,13 +57,20 @@ namespace BlackMisc
const CInterpolationAndRenderingSetup &setup, const CInterpolationHints &hints, const CInterpolationAndRenderingSetup &setup, const CInterpolationHints &hints,
CInterpolationStatus &status) CInterpolationStatus &status)
{ {
Q_ASSERT_X(!m_callsign.isEmpty(), Q_FUNC_INFO, "Missing callsign");
// this code is used by linear and spline interpolator // this code is used by linear and spline interpolator
status.reset(); status.reset();
CInterpolationLogger::SituationLog log; CInterpolationLogger::SituationLog log;
// any data at all? // any data at all?
if (m_aircraftSituations.isEmpty()) { return {}; } if (m_aircraftSituations.isEmpty()) { return CAircraftSituation(m_callsign); }
CAircraftSituation currentSituation = m_lastInterpolation.isNull() ? m_aircraftSituations.front() : m_lastInterpolation; CAircraftSituation currentSituation = m_lastInterpolation.isNull() ? m_aircraftSituations.front() : m_lastInterpolation;
if (currentSituation.getCallsign() != m_callsign)
{
BLACK_VERIFY_X(false, Q_FUNC_INFO, "Wrong callsign");
currentSituation.setCallsign(m_callsign);
}
// Update current position by hints' elevation // Update current position by hints' elevation
// * for XP provided by hints.getElevationProvider at current position // * for XP provided by hints.getElevationProvider at current position
@@ -296,8 +303,12 @@ namespace BlackMisc
template <typename Derived> template <typename Derived>
void CInterpolator<Derived>::addAircraftSituation(const CAircraftSituation &situation) void CInterpolator<Derived>::addAircraftSituation(const CAircraftSituation &situation)
{ {
Q_ASSERT_X(!m_callsign.isEmpty(), Q_FUNC_INFO, "Empty callsign");
Q_ASSERT_X(situation.getCallsign() == m_callsign, Q_FUNC_INFO, "Wrong callsign");
if (m_aircraftSituations.isEmpty()) if (m_aircraftSituations.isEmpty())
{ {
this->resetLastInterpolation(); // delete any leftover
// make sure we have enough situations to do start interpolating immediately without waiting for more updates // make sure we have enough situations to do start interpolating immediately without waiting for more updates
m_aircraftSituations = { situation, situation }; m_aircraftSituations = { situation, situation };
m_aircraftSituations.back().addMsecs(-10000); // number here does m_aircraftSituations.back().addMsecs(-10000); // number here does
@@ -337,6 +348,12 @@ namespace BlackMisc
boolToYesNo(m_lastInterpolation.isNull()); boolToYesNo(m_lastInterpolation.isNull());
} }
template<typename Derived>
void CInterpolator<Derived>::resetLastInterpolation()
{
m_lastInterpolation.setNull();
}
template <typename Derived> template <typename Derived>
void CInterpolator<Derived>::setGroundElevationFromHint(const CInterpolationHints &hints, CAircraftSituation &situation, bool override) void CInterpolator<Derived>::setGroundElevationFromHint(const CInterpolationHints &hints, CAircraftSituation &situation, bool override)
{ {

View File

@@ -82,6 +82,10 @@ namespace BlackMisc
//! Get an interpolator info string (for debug info) //! Get an interpolator info string (for debug info)
QString getInterpolatorInfo() const; QString getInterpolatorInfo() const;
//! Reset last interpolation to null
//! \remark mainly needed in UNIT tests
void resetLastInterpolation();
protected: protected:
Aviation::CAircraftSituationList m_aircraftSituations; //!< recent situations for one aircraft Aviation::CAircraftSituationList m_aircraftSituations; //!< recent situations for one aircraft
Aviation::CAircraftPartsList m_aircraftParts; //!< recent parts for one aircraft Aviation::CAircraftPartsList m_aircraftParts; //!< recent parts for one aircraft

View File

@@ -99,7 +99,7 @@ namespace BlackMiscTest
QVERIFY2(status.isInterpolated(), "Value was not interpolated"); QVERIFY2(status.isInterpolated(), "Value was not interpolated");
const double latDeg = currentSituation.getPosition().latitude().valueRounded(CAngleUnit::deg(), 5); const double latDeg = currentSituation.getPosition().latitude().valueRounded(CAngleUnit::deg(), 5);
const double lngDeg = currentSituation.getPosition().longitude().valueRounded(CAngleUnit::deg(), 5); const double lngDeg = currentSituation.getPosition().longitude().valueRounded(CAngleUnit::deg(), 5);
QVERIFY2(latDeg < latOld && lngDeg < lngOld, "Values shall decrease"); QVERIFY2(latDeg < latOld && lngDeg < lngOld, QString("Values shall decrease: %1/%2 %3/%4").arg(latDeg).arg(latOld).arg(lngDeg).arg(lngOld).toLatin1());
QVERIFY2(latDeg >= 0 && latDeg <= IRemoteAircraftProvider::MaxSituationsPerCallsign, "Values shall be in range"); QVERIFY2(latDeg >= 0 && latDeg <= IRemoteAircraftProvider::MaxSituationsPerCallsign, "Values shall be in range");
latOld = latDeg; latOld = latDeg;
lngOld = lngDeg; lngOld = lngDeg;
@@ -108,13 +108,14 @@ namespace BlackMiscTest
QTime timer; QTime timer;
timer.start(); timer.start();
int interpolationNo = 0; int interpolationNo = 0;
qint64 startTimeMsSinceEpoch = ts - 2 * deltaT; const qint64 startTimeMsSinceEpoch = ts - 2 * deltaT;
// Pseudo performance test: // Pseudo performance test:
// Those make not completely sense, as the performance depends on the implementation of // Those make not completely sense, as the performance depends on the implementation of
// the dummy provider, which is different from the real provider // the dummy provider, which is different from the real provider
// With one callsign in the lists (of dummy provider) it is somehow expected to be roughly the same performance // With one callsign in the lists (of dummy provider) it is somehow expected to be roughly the same performance
interpolator.resetLastInterpolation();
for (int loops = 0; loops < 20; loops++) for (int loops = 0; loops < 20; loops++)
{ {
for (qint64 currentTime = startTimeMsSinceEpoch + offset; currentTime < ts + offset; currentTime += (deltaT / 20)) for (qint64 currentTime = startTimeMsSinceEpoch + offset; currentTime < ts + offset; currentTime += (deltaT / 20))
@@ -126,9 +127,10 @@ namespace BlackMiscTest
(currentTime, setup, hints, status) (currentTime, setup, hints, status)
); );
QVERIFY2(status.isInterpolated(), "Not interpolated"); QVERIFY2(status.isInterpolated(), "Not interpolated");
QVERIFY2(!currentSituation.getCallsign().isEmpty(), "Empty callsign");
QVERIFY2(currentSituation.getCallsign() == cs, "Wrong callsign"); QVERIFY2(currentSituation.getCallsign() == cs, "Wrong callsign");
double latDeg = currentSituation.getPosition().latitude().valueRounded(CAngleUnit::deg(), 5); const double latDeg = currentSituation.getPosition().latitude().valueRounded(CAngleUnit::deg(), 5);
double lngDeg = currentSituation.getPosition().longitude().valueRounded(CAngleUnit::deg(), 5); const double lngDeg = currentSituation.getPosition().longitude().valueRounded(CAngleUnit::deg(), 5);
Q_UNUSED(latDeg); Q_UNUSED(latDeg);
Q_UNUSED(lngDeg); Q_UNUSED(lngDeg);
interpolationNo++; interpolationNo++;
@@ -143,7 +145,8 @@ namespace BlackMiscTest
for (qint64 currentTime = ts - 2 * deltaT; currentTime < ts; currentTime += 250) for (qint64 currentTime = ts - 2 * deltaT; currentTime < ts; currentTime += 250)
{ {
CPartsStatus partsStatus; CPartsStatus partsStatus;
CAircraftParts pl(interpolator.getInterpolatedParts(ts, setup, partsStatus)); const CAircraftParts pl(interpolator.getInterpolatedParts(ts, setup, partsStatus));
Q_UNUSED(pl);
fetchedParts++; fetchedParts++;
QVERIFY2(partsStatus.isSupportingParts(), "Parts not supported"); QVERIFY2(partsStatus.isSupportingParts(), "Parts not supported");
} }
@@ -153,15 +156,15 @@ namespace BlackMiscTest
CAircraftSituation CTestInterpolator::getTestSituation(const CCallsign &callsign, int number, qint64 ts, qint64 deltaT, qint64 offset) CAircraftSituation CTestInterpolator::getTestSituation(const CCallsign &callsign, int number, qint64 ts, qint64 deltaT, qint64 offset)
{ {
CAltitude alt(number, CAltitude::MeanSeaLevel, CLengthUnit::m()); const CAltitude alt(number, CAltitude::MeanSeaLevel, CLengthUnit::m());
CLatitude lat(number, CAngleUnit::deg()); const CLatitude lat(number, CAngleUnit::deg());
CLongitude lng(180.0 + number, CAngleUnit::deg()); const CLongitude lng(180.0 + number, CAngleUnit::deg());
CHeading heading(number * 10, CHeading::True, CAngleUnit::deg()); const CHeading heading(number * 10, CHeading::True, CAngleUnit::deg());
CAngle bank(number, CAngleUnit::deg()); const CAngle bank(number, CAngleUnit::deg());
CAngle pitch(number, CAngleUnit::deg()); const CAngle pitch(number, CAngleUnit::deg());
CSpeed gs(number * 10, CSpeedUnit::km_h()); const CSpeed gs(number * 10, CSpeedUnit::km_h());
CAltitude gndElev({ 0, CLengthUnit::m() }, CAltitude::MeanSeaLevel); const CAltitude gndElev({ 0, CLengthUnit::m() }, CAltitude::MeanSeaLevel);
CCoordinateGeodetic c(lat, lng, alt); const CCoordinateGeodetic c(lat, lng, alt);
CAircraftSituation s(callsign, c, heading, pitch, bank, gs, gndElev); CAircraftSituation s(callsign, c, heading, pitch, bank, gs, gndElev);
s.setMSecsSinceEpoch(ts - deltaT * number); // values in past s.setMSecsSinceEpoch(ts - deltaT * number); // values in past
s.setTimeOffsetMs(offset); s.setTimeOffsetMs(offset);