refs #386, further tests for interpolator

* calculate single vs. calculate all interpolations upfront
* added clear for interpolator
This commit is contained in:
Klaus Basan
2015-02-26 21:55:09 +01:00
parent 8d6be01c5d
commit f525e3bc2e
5 changed files with 118 additions and 32 deletions

View File

@@ -79,5 +79,12 @@ namespace BlackMisc
emit addedRemoteAircraftSituation(situation); emit addedRemoteAircraftSituation(situation);
} }
void CRemoteAircraftProviderDummy::clear()
{
m_situations.clear();
m_parts.clear();
m_aircraft.clear();
}
} // namespace } // namespace
} // namespace } // namespace

View File

@@ -65,6 +65,9 @@ namespace BlackMisc
//! For testing, add new situation and fire signals //! For testing, add new situation and fire signals
void insertNewSituation(const BlackMisc::Aviation::CAircraftSituation &situation); void insertNewSituation(const BlackMisc::Aviation::CAircraftSituation &situation);
// clear all data
void clear();
signals: signals:
//! \copydoc IRemoteAircraftProviderReadOnly::addedRemoteAircraftSituation //! \copydoc IRemoteAircraftProviderReadOnly::addedRemoteAircraftSituation
void addedRemoteAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation); void addedRemoteAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation);

View File

@@ -26,26 +26,15 @@ namespace BlackCoreTest
QScopedPointer<CRemoteAircraftProviderDummy> provider(new CRemoteAircraftProviderDummy()); QScopedPointer<CRemoteAircraftProviderDummy> provider(new CRemoteAircraftProviderDummy());
CInterpolatorLinear interpolator(provider.data()); CInterpolatorLinear interpolator(provider.data());
const CCallsign cs("SWIFT");
const qint64 ts = QDateTime::currentMSecsSinceEpoch(); const qint64 ts = QDateTime::currentMSecsSinceEpoch();
const qint64 deltaT = 5000; // ms const qint64 deltaT = 5000; // ms
CCallsign cs("SWIFT");
for (int i = 0; i < IInterpolator::MaxSituationsPerCallsign; i++) for (int i = 0; i < IInterpolator::MaxSituationsPerCallsign; i++)
{ {
CAltitude a(i, CAltitude::MeanSeaLevel, CLengthUnit::m()); CAircraftSituation s(getTestSituation(cs, i, ts, deltaT));
CLatitude lat(i, CAngleUnit::deg());
CLongitude lng(180.0 + i, CAngleUnit::deg());
CLength height(0, CLengthUnit::m());
CHeading heading(i * 10, CHeading::True, CAngleUnit::deg());
CAngle bank(i, CAngleUnit::deg());
CAngle pitch(i, CAngleUnit::deg());
CSpeed gs(i * 10, CSpeedUnit::km_h());
CCoordinateGeodetic c(lat, lng, height);
CAircraftSituation s(c, a, heading, pitch, bank, gs);
s.setMSecsSinceEpoch(ts - deltaT * i); // values in past
s.setCallsign(cs);
// check height above ground // check height above ground
CLength hag = (a - height); CLength hag = (s.getAltitude() - s.geodeticHeight());
QVERIFY2(s.getHeightAboveGround() == hag, "Wrong elevation"); QVERIFY2(s.getHeightAboveGround() == hag, "Wrong elevation");
provider->insertNewSituation(s); provider->insertNewSituation(s);
} }
@@ -57,7 +46,7 @@ namespace BlackCoreTest
QVERIFY2(interpolator.getSituationsForCallsign(cs).size() == IInterpolator::MaxSituationsPerCallsign, "Missing situations"); QVERIFY2(interpolator.getSituationsForCallsign(cs).size() == IInterpolator::MaxSituationsPerCallsign, "Missing situations");
// interpolation // interpolation
bool ok = false; IInterpolator::InterpolationStatus status;
double latOld = 360.0; double latOld = 360.0;
double lngOld = 360.0; double lngOld = 360.0;
for (qint64 currentTime = ts - 2 * deltaT; currentTime < ts; currentTime += 250) for (qint64 currentTime = ts - 2 * deltaT; currentTime < ts; currentTime += 250)
@@ -65,10 +54,11 @@ namespace BlackCoreTest
// This will use range // This will use range
// from: ts - 2* deltaT - IInterpolator::TimeOffsetMs // from: ts - 2* deltaT - IInterpolator::TimeOffsetMs
// to: ts - IInterpolator::TimeOffsetMs // to: ts - IInterpolator::TimeOffsetMs
CAircraftSituation currentSituation(interpolator.getCurrentInterpolatedSituation CAircraftSituation currentSituation(interpolator.getInterpolatedSituation
(interpolator.getSituationsByCallsign(), cs, currentTime, &ok) (cs, currentTime, status)
); );
QVERIFY2(ok, "OK was false"); QVERIFY2(status.interpolationSucceeded, "Interpolation was not succesful");
QVERIFY2(status.changedPosition, "Interpolation did not changed");
double latDeg = currentSituation.getPosition().latitude().valueRounded(CAngleUnit::deg(), 5); double latDeg = currentSituation.getPosition().latitude().valueRounded(CAngleUnit::deg(), 5);
double lngDeg = currentSituation.getPosition().longitude().valueRounded(CAngleUnit::deg(), 5); double lngDeg = currentSituation.getPosition().longitude().valueRounded(CAngleUnit::deg(), 5);
QVERIFY2(latDeg < latOld && lngDeg < lngOld, "Values shall decrease"); QVERIFY2(latDeg < latOld && lngDeg < lngOld, "Values shall decrease");
@@ -88,10 +78,10 @@ namespace BlackCoreTest
// This will use range // This will use range
// from: ts - 2* deltaT - IInterpolator::TimeOffsetMs // from: ts - 2* deltaT - IInterpolator::TimeOffsetMs
// to: ts - IInterpolator::TimeOffsetMs // to: ts - IInterpolator::TimeOffsetMs
CAircraftSituation currentSituation(interpolator.getCurrentInterpolatedSituation CAircraftSituation currentSituation(interpolator.getInterpolatedSituation
(interpolator.getSituationsByCallsign(), cs, currentTime, &ok) (cs, currentTime, status)
); );
QVERIFY2(ok, "OK was false"); QVERIFY2(status.allTrue(), "Failed interpolation");
QVERIFY2(currentSituation.getCallsign() == cs, "Wrong callsign"); QVERIFY2(currentSituation.getCallsign() == cs, "Wrong callsign");
double latDeg = currentSituation.getPosition().latitude().valueRounded(CAngleUnit::deg(), 5); double latDeg = currentSituation.getPosition().latitude().valueRounded(CAngleUnit::deg(), 5);
double lngDeg = currentSituation.getPosition().longitude().valueRounded(CAngleUnit::deg(), 5); double lngDeg = currentSituation.getPosition().longitude().valueRounded(CAngleUnit::deg(), 5);
@@ -102,20 +92,101 @@ namespace BlackCoreTest
} }
int timeMs = timer.elapsed(); int timeMs = timer.elapsed();
QVERIFY2(timeMs < interpolationNo, "Interpolation > 1ms"); QVERIFY2(timeMs < interpolationNo, "Interpolation > 1ms");
qDebug() << timeMs << "ms" << "for" << interpolationNo;
interpolator.syncRequestSituationsCalculationsForAllCallsigns(1, startTimeMsSinceEpoch); CAircraftSituationList interpolations(interpolator.getInterpolatedSituations(startTimeMsSinceEpoch));
CAircraftSituationList interpolationsSync(interpolator.getRequest(1)); QVERIFY(interpolations.size() == 1);
QVERIFY(interpolationsSync.size() == 1); QVERIFY(interpolations.containsCallsign(cs));
QVERIFY(interpolationsSync.containsCallsign(cs));
interpolator.asyncRequestSituationsCalculationsForAllCallsigns(2, startTimeMsSinceEpoch); //
QCoreApplication::processEvents(QEventLoop::AllEvents, 1000); // Single interpolation vs. all interpolations at once
CAircraftSituationList interpolationsAsync(interpolator.getRequest(1)); //
QVERIFY(interpolationsAsync.size() == 1);
QVERIFY(interpolationsAsync.containsCallsign(cs));
QVERIFY2(interpolationsAsync.front() == interpolationsSync.front(), "Calculated values should be equal"); // Create data in provider
provider->clear();
interpolator.clear();
QVERIFY(interpolator.getSituationsByCallsign().size() == 0);
const int callsignsInProvider = 20;
for (int callsignNo = 0; callsignNo < callsignsInProvider; callsignNo++)
{
cs = CCallsign("SWIFT" + QString::number(callsignNo));
int i = 0;
for (int t = 0; t < IInterpolator::MaxSituationsPerCallsign; t++)
{
qint64 currentTime = ts - t * deltaT;
CAircraftSituation s(getTestSituation(cs, i++, currentTime, 0));
provider->insertNewSituation(s);
}
}
QList<CCallsign> csKeys = interpolator.getSituationsByCallsign().keys();
CCallsignList callsigns(csKeys);
QVERIFY(callsigns.size() == callsignsInProvider);
QVERIFY(interpolator.getSituationsForCallsign("SWIFT0").size() == IInterpolator::MaxSituationsPerCallsign);
// interpolation for time, then for each callsign
int doneInterpolations = 0;
timer.start();
for (qint64 currentTime = ts - 2 * deltaT; currentTime < ts; currentTime += 250)
{
// This will use range
// from: ts - 2* deltaT - IInterpolator::TimeOffsetMs
// to: ts - IInterpolator::TimeOffsetMs
for (const CCallsign &cs : callsigns)
{
CAircraftSituation currentSituation(interpolator.getInterpolatedSituation
(cs, currentTime, status)
);
QVERIFY2(status.interpolationSucceeded, "Interpolation was not succesful");
QVERIFY2(status.changedPosition, "Interpolation did not changed");
double latDeg = currentSituation.getPosition().latitude().valueRounded(CAngleUnit::deg(), 5);
double lngDeg = currentSituation.getPosition().longitude().valueRounded(CAngleUnit::deg(), 5);
Q_UNUSED(latDeg);
Q_UNUSED(lngDeg);
doneInterpolations++;
}
}
timeMs = timer.elapsed();
qDebug() << "Per callsign" << doneInterpolations << "interpolations in" << timeMs << "ms";
doneInterpolations = 0;
timer.start();
for (qint64 currentTime = ts - 2 * deltaT; currentTime < ts; currentTime += 250)
{
// This will use range
// from: ts - 2* deltaT - IInterpolator::TimeOffsetMs
// to: ts - IInterpolator::TimeOffsetMs
CAircraftSituationList currentSituations(interpolator.getInterpolatedSituations(currentTime));
QVERIFY2(currentSituations.size() == callsignsInProvider, "Interpolation was not succesful");
for (const CAircraftSituation &currentSituation : currentSituations)
{
double latDeg = currentSituation.getPosition().latitude().valueRounded(CAngleUnit::deg(), 5);
double lngDeg = currentSituation.getPosition().longitude().valueRounded(CAngleUnit::deg(), 5);
doneInterpolations++;
Q_UNUSED(latDeg);
Q_UNUSED(lngDeg);
}
}
timeMs = timer.elapsed();
qDebug() << "All callsigns" << doneInterpolations << "interpolations in" << timeMs << "ms";
}
CAircraftSituation CTestInterpolator::getTestSituation(const CCallsign &callsign, int number, qint64 ts, qint64 deltaT)
{
CAltitude a(number, CAltitude::MeanSeaLevel, CLengthUnit::m());
CLatitude lat(number, CAngleUnit::deg());
CLongitude lng(180.0 + number, CAngleUnit::deg());
CLength height(0, CLengthUnit::m());
CHeading heading(number * 10, CHeading::True, CAngleUnit::deg());
CAngle bank(number, CAngleUnit::deg());
CAngle pitch(number, CAngleUnit::deg());
CSpeed gs(number * 10, CSpeedUnit::km_h());
CCoordinateGeodetic c(lat, lng, height);
CAircraftSituation s(callsign, c, a, heading, pitch, bank, gs);
s.setMSecsSinceEpoch(ts - deltaT * number); // values in past
return s;
} }
} // namespace } // namespace

View File

@@ -12,6 +12,7 @@
#ifndef BLACKCORETEST_TESTAVIATIONBASE_H #ifndef BLACKCORETEST_TESTAVIATIONBASE_H
#define BLACKCORETEST_TESTAVIATIONBASE_H #define BLACKCORETEST_TESTAVIATIONBASE_H
#include "blackmisc/avaircraftsituation.h"
#include <QtTest/QtTest> #include <QtTest/QtTest>
namespace BlackCoreTest namespace BlackCoreTest
@@ -29,6 +30,10 @@ namespace BlackCoreTest
private slots: private slots:
//! Basic unit tests for interpolator //! Basic unit tests for interpolator
void linearInterpolator(); void linearInterpolator();
private:
//! Test situation for testing
static BlackMisc::Aviation::CAircraftSituation getTestSituation(const BlackMisc::Aviation::CCallsign &callsign, int number, qint64 ts, qint64 deltaT);
}; };
} // namespace } // namespace

View File

@@ -266,7 +266,7 @@ namespace BlackMiscTest
CAircraftSituation s; CAircraftSituation s;
s.setCallsign("CS" + QString::number(i)); s.setCallsign("CS" + QString::number(i));
s.setMSecsSinceEpoch(cTs); s.setMSecsSinceEpoch(cTs);
situations.insertTimestampObject(s, maxElements); situations.push_frontMaxElements(s, maxElements);
if (i > maxElements - 1) if (i > maxElements - 1)
{ {
QVERIFY2(situations.size() == maxElements, "Situations must only contain max.elements"); QVERIFY2(situations.size() == maxElements, "Situations must only contain max.elements");