mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-07 11:05:33 +08:00
Reflecting discussed changes for interpolation performance refs #386
(based on FSX testing) * Only send changed situation to SIM * Split sending of parts / situations * Only send parts with a reduced frequency (means slower as positions) * Mark geodetic height as null for default values (the value is usually unavailable) * Fixed altitude to MSL for network data * Trace which aircrafts support aircraft parts via network * Renamed insert_fron push_front (as proposed by Roland) Status quo / lessons learnt * On slower PCs jitter is still noticed for interpolated aircraft. * Running interpolation in an independent process (aka core, not in GUI) reduced load dependencies => it seems to make sense to run driver in own thread * The onGround flag in parts seems clumsy as it required to retrieve parts for position updates * In interpolation performance really matters
This commit is contained in:
@@ -20,18 +20,31 @@ using namespace BlackMisc::Aviation;
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
CAircraftSituation CInterpolatorLinear::getCurrentInterpolatedSituation(const QHash<CCallsign, CAircraftSituationList> &allSituations, const CCallsign &callsign, qint64 currentTimeMsSinceEpoc, bool *ok) const
|
||||
CAircraftSituation CInterpolatorLinear::getInterpolatedSituation(const CCallsign &callsign, qint64 currentTimeMsSinceEpoc, InterpolationStatus &status, const CSituationsPerCallsign *situationsPerCallsign) const
|
||||
{
|
||||
const static CAircraftSituation empty;
|
||||
if (ok) { *ok = false; }
|
||||
if (!allSituations.contains(callsign)) { return empty; }
|
||||
if (allSituations[callsign].isEmpty()) { return empty; }
|
||||
|
||||
status.reset();
|
||||
QList<CAircraftSituationList> splitSituations;
|
||||
if (currentTimeMsSinceEpoc < 0) { currentTimeMsSinceEpoc = QDateTime::currentMSecsSinceEpoch(); }
|
||||
qint64 splitTimeMsSinceEpoch = currentTimeMsSinceEpoc - TimeOffsetMs;
|
||||
QList<CAircraftSituationList> splitSituations = allSituations[callsign].splitByTime(splitTimeMsSinceEpoch);
|
||||
CAircraftSituationList &situationsNewer = splitSituations[0]; // latest first
|
||||
CAircraftSituationList &situationsOlder = splitSituations[1]; // latest first
|
||||
|
||||
if (situationsPerCallsign)
|
||||
{
|
||||
if (!situationsPerCallsign->contains(callsign)) { return empty; }
|
||||
if ((*situationsPerCallsign)[callsign].isEmpty()) { return empty; }
|
||||
splitSituations = (*situationsPerCallsign)[callsign].splitByTime(splitTimeMsSinceEpoch);
|
||||
}
|
||||
else
|
||||
{
|
||||
// only part where it is locked
|
||||
QReadLocker lock(&m_lockSituations);
|
||||
if (!m_situationsByCallsign.contains(callsign)) { return empty; }
|
||||
if (m_situationsByCallsign[callsign].isEmpty()) { return empty; }
|
||||
splitSituations = m_situationsByCallsign[callsign].splitByTime(splitTimeMsSinceEpoch);
|
||||
}
|
||||
|
||||
CAircraftSituationList &situationsNewer = splitSituations[0]; // newer part
|
||||
CAircraftSituationList &situationsOlder = splitSituations[1]; // older part
|
||||
|
||||
// interpolation situations
|
||||
CAircraftSituation oldSituation;
|
||||
@@ -52,7 +65,6 @@ namespace BlackCore
|
||||
// We just place at he last position until we get before / after situations
|
||||
if (situationsOlderNo < 1 || situationsNewerNo < 1)
|
||||
{
|
||||
if (ok) { *ok = true; }
|
||||
// no after situations
|
||||
if (situationsOlderNo < 1) { return situationsNewer.back(); } // oldest newest
|
||||
|
||||
@@ -73,6 +85,7 @@ namespace BlackCore
|
||||
|
||||
CAircraftSituation currentSituation(oldSituation);
|
||||
CCoordinateGeodetic currentPosition;
|
||||
status.interpolationSucceeded = true;
|
||||
|
||||
// Time between start and end packet
|
||||
double deltaTime = oldSituation.absMsecsTo(newSituation);
|
||||
@@ -82,7 +95,7 @@ namespace BlackCore
|
||||
// 1) values > 1 mean extrapolation
|
||||
// 2) values > 2 mean no new situations coming in
|
||||
double simulationTimeFraction = 1 - ((newSituation.getMSecsSinceEpoch() - splitTimeMsSinceEpoch) / deltaTime);
|
||||
if (simulationTimeFraction > 1.5)
|
||||
if (simulationTimeFraction > 2.0)
|
||||
{
|
||||
if (this->m_withDebugMsg)
|
||||
{
|
||||
@@ -91,21 +104,34 @@ namespace BlackCore
|
||||
}
|
||||
|
||||
// Interpolate latitude: Lat = (LatB - LatA) * t + LatA
|
||||
currentPosition.setLatitude((newSituation.getPosition().latitude() - oldSituation.getPosition().latitude())
|
||||
const CLatitude oldLat(oldSituation.latitude());
|
||||
const CLatitude newLat(newSituation.latitude());
|
||||
const CLongitude oldLng(oldSituation.longitude());
|
||||
const CLongitude newLng(newSituation.longitude());
|
||||
|
||||
currentPosition.setLatitude((newLat - oldLat)
|
||||
* simulationTimeFraction
|
||||
+ oldSituation.getPosition().latitude());
|
||||
+ oldLat);
|
||||
|
||||
// Interpolate latitude: Lon = (LonB - LonA) * t + LonA
|
||||
currentPosition.setLongitude((newSituation.getPosition().longitude() - oldSituation.getPosition().longitude())
|
||||
currentPosition.setLongitude((newLng - oldLng)
|
||||
* simulationTimeFraction
|
||||
+ oldSituation.getPosition().longitude());
|
||||
+ oldLng);
|
||||
currentSituation.setPosition(currentPosition);
|
||||
|
||||
// Interpolate altitude: Alt = (AltB - AltA) * t + AltA
|
||||
currentSituation.setAltitude(CAltitude((newSituation.getAltitude() - oldSituation.getAltitude())
|
||||
const CAltitude oldAlt(oldSituation.getAltitude());
|
||||
const CAltitude newAlt(newSituation.getAltitude());
|
||||
Q_ASSERT(oldAlt.getReferenceDatum() == newAlt.getReferenceDatum()); // otherwise no calculation is possible
|
||||
currentSituation.setAltitude(CAltitude((newAlt - oldAlt)
|
||||
* simulationTimeFraction
|
||||
+ oldSituation.getAltitude(),
|
||||
oldSituation.getAltitude().getReferenceDatum()));
|
||||
+ oldAlt,
|
||||
oldAlt.getReferenceDatum()));
|
||||
|
||||
if (newLat == oldLat && newLng == oldLng && oldAlt == newAlt)
|
||||
{
|
||||
return currentSituation;
|
||||
}
|
||||
|
||||
// Interpolate heading: HDG = (HdgB - HdgA) * t + HdgA
|
||||
CHeading headingBegin = oldSituation.getHeading();
|
||||
@@ -143,13 +169,13 @@ namespace BlackCore
|
||||
|
||||
// TODO: According to the specification, banks to the right should be negative.
|
||||
// But somehow we get positive banks from the network.
|
||||
bank *= -1;
|
||||
bank *= -1.0;
|
||||
currentSituation.setBank(bank);
|
||||
|
||||
currentSituation.setGroundspeed((newSituation.getGroundSpeed() - oldSituation.getGroundSpeed())
|
||||
* simulationTimeFraction
|
||||
+ oldSituation.getGroundSpeed());
|
||||
if (ok) { *ok = true; }
|
||||
status.changedPosition = true;
|
||||
Q_ASSERT(currentSituation.getCallsign() == callsign);
|
||||
return currentSituation;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user