mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-14 16:55:36 +08:00
refs #386, further improvements on interpolation
* extended unit tests for interpolator / parts testing * allow to skip sorting when splitting by time * update ot aircraft to FSX in own member function * Skip time sync parts (FSX) when disabled
This commit is contained in:
@@ -66,7 +66,7 @@ namespace BlackCore
|
||||
return m_situationsByCallsign;
|
||||
}
|
||||
|
||||
CAircraftPartsList IInterpolator::getAndRemovePartsBeforeOffset(const CCallsign &callsign, qint64 cutoffTime, BlackCore::IInterpolator::PartsStatus &partsStatus)
|
||||
CAircraftPartsList IInterpolator::getAndRemovePartsBeforeTime(const CCallsign &callsign, qint64 cutoffTime, BlackCore::IInterpolator::PartsStatus &partsStatus)
|
||||
{
|
||||
static const CAircraftPartsList empty;
|
||||
partsStatus.reset();
|
||||
@@ -78,6 +78,7 @@ namespace BlackCore
|
||||
}
|
||||
else
|
||||
{
|
||||
// did we ever have parts for this callsign
|
||||
partsStatus.supportsParts = m_aircraftSupportingParts.contains(callsign);
|
||||
return empty;
|
||||
}
|
||||
@@ -99,6 +100,19 @@ namespace BlackCore
|
||||
return m_situationsByCallsign[callsign];
|
||||
}
|
||||
|
||||
CAircraftPartsList IInterpolator::getPartsForCallsign(const CCallsign &callsign) const
|
||||
{
|
||||
QReadLocker l(&m_lockParts);
|
||||
static const CAircraftPartsList empty;
|
||||
if (!m_partsByCallsign.contains(callsign)) { return empty; }
|
||||
return m_partsByCallsign[callsign];
|
||||
}
|
||||
|
||||
void IInterpolator::forceSorting(bool sort)
|
||||
{
|
||||
this->m_forceSortWhenAddingValues = sort;
|
||||
}
|
||||
|
||||
void IInterpolator::ps_onAddedAircraftSituation(const CAircraftSituation &situation)
|
||||
{
|
||||
QWriteLocker lock(&m_lockSituations);
|
||||
@@ -110,6 +124,10 @@ namespace BlackCore
|
||||
// list from new to old
|
||||
CAircraftSituationList &l = this->m_situationsByCallsign[callsign];
|
||||
l.push_frontMaxElements(situation, MaxSituationsPerCallsign);
|
||||
if (this->m_forceSortWhenAddingValues) { l.sortLatestFirst(); }
|
||||
|
||||
// check sort order
|
||||
Q_ASSERT(l.size() < 2 || l[0].getMSecsSinceEpoch() >= l[1].getMSecsSinceEpoch());
|
||||
}
|
||||
|
||||
void IInterpolator::ps_onAddedAircraftParts(const CAircraftParts &parts)
|
||||
@@ -123,9 +141,14 @@ namespace BlackCore
|
||||
// list sorted from new to old
|
||||
CAircraftPartsList &l = this->m_partsByCallsign[callsign];
|
||||
l.push_frontMaxElements(parts, MaxPartsPerCallsign);
|
||||
if (this->m_forceSortWhenAddingValues) { l.sortLatestFirst(); }
|
||||
|
||||
if (m_aircraftSupportingParts.contains(callsign)) { return; }
|
||||
m_aircraftSupportingParts.push_back(callsign);
|
||||
m_aircraftSupportingParts.push_back(callsign); // mark as callsign which supports parts
|
||||
|
||||
// check sort order
|
||||
Q_ASSERT(l.size() < 2 || l[0].getMSecsSinceEpoch() >= l[1].getMSecsSinceEpoch());
|
||||
|
||||
}
|
||||
|
||||
void IInterpolator::ps_onRemovedAircraft(const CCallsign &callsign)
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace BlackCore
|
||||
|
||||
//! Parts before given offset time (aka pending parts)
|
||||
//! \threadsafe
|
||||
virtual BlackMisc::Aviation::CAircraftPartsList getAndRemovePartsBeforeOffset(const BlackMisc::Aviation::CCallsign &callsign, qint64 timeOffset, PartsStatus &partsStatus);
|
||||
virtual BlackMisc::Aviation::CAircraftPartsList getAndRemovePartsBeforeTime(const BlackMisc::Aviation::CCallsign &callsign, qint64 timeOffset, PartsStatus &partsStatus);
|
||||
|
||||
//! Clear all data
|
||||
//! \threadsafe
|
||||
@@ -95,9 +95,16 @@ namespace BlackCore
|
||||
//! \threadsafe
|
||||
BlackMisc::Aviation::CAircraftSituationList getSituationsForCallsign(const BlackMisc::Aviation::CCallsign &callsign) const;
|
||||
|
||||
//! Parts for given callsign
|
||||
//! \threadsafe
|
||||
BlackMisc::Aviation::CAircraftPartsList getPartsForCallsign(const BlackMisc::Aviation::CCallsign &callsign) const;
|
||||
|
||||
//! Enable debug messages
|
||||
void enableDebugMessages(bool enabled);
|
||||
|
||||
//! Force sorting (latest first), not required if order can be guaranteed
|
||||
void forceSorting(bool sort);
|
||||
|
||||
static const qint64 TimeOffsetMs = 6000; //!< offset for interpolation
|
||||
static const int MaxSituationsPerCallsign = 6; //!< How many situations per callsign
|
||||
static const int MaxPartsPerCallsign = 3; //!< How many parts per callsign
|
||||
@@ -120,7 +127,8 @@ namespace BlackCore
|
||||
//! Constructor
|
||||
IInterpolator(BlackMisc::Simulation::IRemoteAircraftProviderReadOnly *provider, const QString &workerName, QObject *parent = nullptr);
|
||||
|
||||
bool m_withDebugMsg = false; //!< allows to disable debug messages
|
||||
bool m_withDebugMsg = false; //!< allows to disable debug messages
|
||||
bool m_forceSortWhenAddingValues = false; //!< force sorting (latest first) when adding values
|
||||
BlackMisc::Aviation::CCallsignList m_aircraftSupportingParts; //!< aircraft supporting parts
|
||||
|
||||
// hashs, because not sorted by key but keeping order
|
||||
|
||||
@@ -30,8 +30,9 @@ namespace BlackCore
|
||||
|
||||
if (situationsPerCallsign)
|
||||
{
|
||||
if (!situationsPerCallsign->contains(callsign)) { return empty; }
|
||||
if ((*situationsPerCallsign)[callsign].isEmpty()) { return empty; }
|
||||
// lock free, expected that situationsPerCallsign is a copy
|
||||
if (!situationsPerCallsign->contains(callsign)) { return empty; }
|
||||
if ((*situationsPerCallsign)[callsign].isEmpty()) { return empty; }
|
||||
splitSituations = (*situationsPerCallsign)[callsign].splitByTime(splitTimeMsSinceEpoch);
|
||||
}
|
||||
else
|
||||
@@ -40,7 +41,7 @@ namespace BlackCore
|
||||
QReadLocker lock(&m_lockSituations);
|
||||
if (!m_situationsByCallsign.contains(callsign)) { return empty; }
|
||||
if (m_situationsByCallsign[callsign].isEmpty()) { return empty; }
|
||||
splitSituations = m_situationsByCallsign[callsign].splitByTime(splitTimeMsSinceEpoch);
|
||||
splitSituations = m_situationsByCallsign[callsign].splitByTime(splitTimeMsSinceEpoch, true);
|
||||
}
|
||||
|
||||
CAircraftSituationList &situationsNewer = splitSituations[0]; // newer part
|
||||
@@ -78,8 +79,8 @@ namespace BlackCore
|
||||
}
|
||||
else
|
||||
{
|
||||
oldSituation = situationsOlder.front(); // first oldest
|
||||
newSituation = situationsNewer.back(); // latest newest
|
||||
oldSituation = situationsOlder.front(); // first oldest (aka newest oldest)
|
||||
newSituation = situationsNewer.back(); // latest newest (aka oldest of newer block)
|
||||
Q_ASSERT(oldSituation.getMSecsSinceEpoch() < newSituation.getMSecsSinceEpoch());
|
||||
}
|
||||
|
||||
@@ -103,12 +104,12 @@ namespace BlackCore
|
||||
}
|
||||
}
|
||||
|
||||
// Interpolate latitude: Lat = (LatB - LatA) * t + LatA
|
||||
const CLatitude oldLat(oldSituation.latitude());
|
||||
const CLatitude newLat(newSituation.latitude());
|
||||
const CLongitude oldLng(oldSituation.longitude());
|
||||
const CLongitude newLng(newSituation.longitude());
|
||||
|
||||
// Interpolate latitude: Lat = (LatB - LatA) * t + LatA
|
||||
currentPosition.setLatitude((newLat - oldLat)
|
||||
* simulationTimeFraction
|
||||
+ oldLat);
|
||||
@@ -130,6 +131,8 @@ namespace BlackCore
|
||||
|
||||
if (newLat == oldLat && newLng == oldLng && oldAlt == newAlt)
|
||||
{
|
||||
// stop interpolation here
|
||||
//! \todo Does not work for VTOL aircraft. We need a flag for VTOL aircraft
|
||||
return currentSituation;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user