[xplane] Add monitoring of the number of minutes behind due to low FPS

This commit is contained in:
Mat Sutcliffe
2020-01-25 13:30:38 +00:00
parent 377b2f6a3e
commit e50bb6d5c7
10 changed files with 36 additions and 19 deletions

View File

@@ -262,6 +262,7 @@ namespace BlackCore
m_averageFps = -1.0; m_averageFps = -1.0;
m_simTimeRatio = 1.0; m_simTimeRatio = 1.0;
m_trackMilesShort = 0.0; m_trackMilesShort = 0.0;
m_minutesLate = 0.0;
} }
bool ISimulator::isUpdateAllRemoteAircraft(qint64 currentTimestamp) const bool ISimulator::isUpdateAllRemoteAircraft(qint64 currentTimestamp) const
@@ -1039,6 +1040,7 @@ namespace BlackCore
m_averageFps = -1.0; m_averageFps = -1.0;
m_simTimeRatio = 1.0; m_simTimeRatio = 1.0;
m_trackMilesShort = 0.0; m_trackMilesShort = 0.0;
m_minutesLate = 0.0;
return true; return true;
} }

View File

@@ -224,6 +224,9 @@ namespace BlackCore
//! Number of track miles over-reported, due to low FPS //! Number of track miles over-reported, due to low FPS
double getTrackMilesShort() const { return m_trackMilesShort; } double getTrackMilesShort() const { return m_trackMilesShort; }
//! Number of minutes behind scedule, due to low FPS
double getMinutesLate() const { return m_minutesLate; }
//! Send situation/parts for testing //! Send situation/parts for testing
virtual bool testSendSituationAndParts(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &situation, const BlackMisc::Aviation::CAircraftParts &parts) = 0; virtual bool testSendSituationAndParts(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &situation, const BlackMisc::Aviation::CAircraftParts &parts) = 0;
@@ -587,6 +590,7 @@ namespace BlackCore
double m_averageFps = -1.0; //!< FPS double m_averageFps = -1.0; //!< FPS
double m_simTimeRatio = 1.0; //!< ratio of simulation time to real time, due to low FPS (X-Plane) double m_simTimeRatio = 1.0; //!< ratio of simulation time to real time, due to low FPS (X-Plane)
double m_trackMilesShort = 0.0; //!< difference between real and reported groundspeed, multiplied by time double m_trackMilesShort = 0.0; //!< difference between real and reported groundspeed, multiplied by time
double m_minutesLate = 0.0; //!< difference between real and reported groundspeed, integrated over time
qint64 m_updateAllRemoteAircraftUntil = 0; //!< force an update of all remote aircraft, used when own aircraft is moved, paused to make sure all remote aircraft are updated qint64 m_updateAllRemoteAircraftUntil = 0; //!< force an update of all remote aircraft, used when own aircraft is moved, paused to make sure all remote aircraft are updated
qint64 m_statsUpdateAircraftTimeTotalMs = 0; //!< statistics total update time qint64 m_statsUpdateAircraftTimeTotalMs = 0; //!< statistics total update time
qint64 m_statsCurrentUpdateTimeMs = 0; //!< statistics current update time qint64 m_statsCurrentUpdateTimeMs = 0; //!< statistics current update time

View File

@@ -157,6 +157,9 @@ namespace BlackGui
const double miles = sGui->getISimulator()->getTrackMilesShort(); const double miles = sGui->getISimulator()->getTrackMilesShort();
this->addOrUpdateLiveDataByName(QStringLiteral("Miles Short"), QString::number(miles, 'f', 1), CIconList::allIcons().findByIndex(CIcons::ApplicationSimulator)); this->addOrUpdateLiveDataByName(QStringLiteral("Miles Short"), QString::number(miles, 'f', 1), CIconList::allIcons().findByIndex(CIcons::ApplicationSimulator));
const double minutes = sGui->getISimulator()->getMinutesLate();
this->addOrUpdateLiveDataByName(QStringLiteral("Minutes Late"), QString::number(minutes, 'f', 1), CIconList::allIcons().findByIndex(CIcons::ApplicationSimulator));
} }
} }

View File

@@ -369,7 +369,7 @@ namespace BlackSimPlugin
if ((m_slowTimerCalls % 5u) == 0u) if ((m_slowTimerCalls % 5u) == 0u)
{ {
// reading FPS resets average, so we only monitor over some time // reading FPS resets average, so we only monitor over some time
m_serviceProxy->getFrameStats(&m_averageFps, &m_simTimeRatio, &m_trackMilesShort); m_serviceProxy->getFrameStats(&m_averageFps, &m_simTimeRatio, &m_trackMilesShort, &m_minutesLate);
} }
} }
} }

View File

@@ -319,32 +319,34 @@ namespace BlackSimPlugin
m_dbusInterface->callDBusAsync(QLatin1String("isUsingRealTime"), setterCallback(o_isRealTime)); m_dbusInterface->callDBusAsync(QLatin1String("isUsingRealTime"), setterCallback(o_isRealTime));
} }
void CXSwiftBusServiceProxy::getFrameStats(double *o_averageFps, double *o_simTimeRatio, double *o_trackMilesLost) const void CXSwiftBusServiceProxy::getFrameStats(double *o_averageFps, double *o_simTimeRatio, double *o_trackMilesShort, double *o_minutesLate) const
{ {
std::function<void(QDBusPendingCallWatcher *)> callback = [ = ](QDBusPendingCallWatcher * watcher) std::function<void(QDBusPendingCallWatcher *)> callback = [ = ](QDBusPendingCallWatcher * watcher)
{ {
QDBusPendingReply<double, double, double> reply = *watcher; QDBusPendingReply<double, double, double, double> reply = *watcher;
if (!reply.isError()) if (!reply.isError())
{ {
*o_averageFps = reply.argumentAt<0>(); *o_averageFps = reply.argumentAt<0>();
*o_simTimeRatio = reply.argumentAt<1>(); *o_simTimeRatio = reply.argumentAt<1>();
*o_trackMilesLost = reply.argumentAt<2>(); *o_trackMilesShort = reply.argumentAt<2>();
*o_minutesLate = reply.argumentAt<3>();
} }
watcher->deleteLater(); watcher->deleteLater();
}; };
m_dbusInterface->callDBusAsync(QLatin1String("getFrameStats"), callback)->waitForFinished(); m_dbusInterface->callDBusAsync(QLatin1String("getFrameStats"), callback)->waitForFinished();
} }
void CXSwiftBusServiceProxy::getFrameStatsAsync(double *o_averageFps, double *o_simTimeRatio, double *o_trackMilesLost) void CXSwiftBusServiceProxy::getFrameStatsAsync(double *o_averageFps, double *o_simTimeRatio, double *o_trackMilesShort, double *o_minutesLate)
{ {
std::function<void(QDBusPendingCallWatcher *)> callback = [ = ](QDBusPendingCallWatcher * watcher) std::function<void(QDBusPendingCallWatcher *)> callback = [ = ](QDBusPendingCallWatcher * watcher)
{ {
QDBusPendingReply<double, double, double> reply = *watcher; QDBusPendingReply<double, double, double, double> reply = *watcher;
if (!reply.isError()) if (!reply.isError())
{ {
*o_averageFps = reply.argumentAt<0>(); *o_averageFps = reply.argumentAt<0>();
*o_simTimeRatio = reply.argumentAt<1>(); *o_simTimeRatio = reply.argumentAt<1>();
*o_trackMilesLost = reply.argumentAt<2>(); *o_trackMilesShort = reply.argumentAt<2>();
*o_minutesLate = reply.argumentAt<3>();
} }
watcher->deleteLater(); watcher->deleteLater();
}; };

View File

@@ -210,8 +210,8 @@ namespace BlackSimPlugin
//! \copydoc XSwiftBus::CService::getFrameStats //! \copydoc XSwiftBus::CService::getFrameStats
//! @{ //! @{
void getFrameStats(double *o_averageFps, double *o_simTimeRatio, double *o_trackMilesLost) const; void getFrameStats(double *o_averageFps, double *o_simTimeRatio, double *o_trackMilesShort, double *o_minutesLate) const;
void getFrameStatsAsync(double *o_averageFps, double *o_simTimeRatio, double *o_trackMilesLost); void getFrameStatsAsync(double *o_averageFps, double *o_simTimeRatio, double *o_trackMilesShort, double *o_minutesLate);
//! @} //! @}
//! \copydoc XSwiftBus::CService::getLatitudeDeg //! \copydoc XSwiftBus::CService::getLatitudeDeg

View File

@@ -67,6 +67,7 @@ R"XML(<node>
<arg name="averageFps" type="d" direction="out"/> <arg name="averageFps" type="d" direction="out"/>
<arg name="simTimeRatio" type="d" direction="out"/> <arg name="simTimeRatio" type="d" direction="out"/>
<arg name="trackMilesShort" type="d" direction="out"/> <arg name="trackMilesShort" type="d" direction="out"/>
<arg name="minutesLate" type="d" direction="out"/>
</method> </method>
<method name="getLatitudeDeg"> <method name="getLatitudeDeg">
<arg type="d" direction="out"/> <arg type="d" direction="out"/>

View File

@@ -161,7 +161,7 @@ namespace XSwiftBus
if (m_service) if (m_service)
{ {
m_service->onAircraftModelChanged(); m_service->onAircraftModelChanged();
m_service->resetMilesLost(); m_service->resetFrameTotals();
} }
} }
@@ -170,7 +170,7 @@ namespace XSwiftBus
if (m_service) if (m_service)
{ {
m_service->updateAirportsInRange(); m_service->updateAirportsInRange();
m_service->resetMilesLost(); m_service->resetFrameTotals();
} }
} }

View File

@@ -35,23 +35,25 @@ namespace XSwiftBus
float m_total = 0; float m_total = 0;
float m_totalOverBudget = 0; float m_totalOverBudget = 0;
float m_totalMetersShort = 0; float m_totalMetersShort = 0;
float m_totalSecondsLate = 0;
size_t m_lastSampleIndex = 0; size_t m_lastSampleIndex = 0;
static constexpr size_t c_maxSampleCount = 500; static constexpr size_t c_maxSampleCount = 500;
static constexpr float c_framePeriodBudget = 0.05f; static constexpr float c_framePeriodBudget = 0.05f;
FramePeriodSampler() : CDrawable(xplm_Phase_LastCockpit, false) {} FramePeriodSampler() : CDrawable(xplm_Phase_LastCockpit, false) {}
std::tuple<float, float, float> getFrameStats() std::tuple<float, float, float, float> getFrameStats()
{ {
if (m_total == 0) { return {}; } if (m_total == 0) { return {}; }
const float fps = m_samples.size() / m_total; const float fps = m_samples.size() / m_total;
const float ratio = 1 - m_totalOverBudget / m_total; const float ratio = 1 - m_totalOverBudget / m_total;
const float miles = m_totalMetersShort / 1852.0f; const float miles = m_totalMetersShort / 1852.0f;
const float minutes = m_totalSecondsLate / 60.0f;
m_total = 0; m_total = 0;
m_totalOverBudget = 0; m_totalOverBudget = 0;
m_samples.clear(); m_samples.clear();
m_lastSampleIndex = 0; m_lastSampleIndex = 0;
return std::make_tuple(fps, ratio, miles); return std::make_tuple(fps, ratio, miles, minutes);
} }
protected: protected:
@@ -80,6 +82,7 @@ namespace XSwiftBus
const float metersShort = m_groundSpeed.get() * std::max(0.0f, current - c_framePeriodBudget); const float metersShort = m_groundSpeed.get() * std::max(0.0f, current - c_framePeriodBudget);
m_totalMetersShort += metersShort; m_totalMetersShort += metersShort;
if (m_groundSpeed.get() > 1.0f) { m_totalSecondsLate += std::max(0.0f, current - c_framePeriodBudget); }
} }
}; };
@@ -118,14 +121,14 @@ namespace XSwiftBus
return XSWIFTBUS_COMMIT; return XSWIFTBUS_COMMIT;
} }
std::tuple<double, double, double> CService::getFrameStats() std::tuple<double, double, double, double> CService::getFrameStats()
{ {
if (!m_framePeriodSampler) { return {}; } if (!m_framePeriodSampler) { return {}; }
const auto result = m_framePeriodSampler->getFrameStats(); const auto result = m_framePeriodSampler->getFrameStats();
return std::make_tuple(static_cast<double>(std::get<0>(result)), static_cast<double>(std::get<1>(result)), static_cast<double>(std::get<2>(result))); return std::make_tuple(static_cast<double>(std::get<0>(result)), static_cast<double>(std::get<1>(result)), static_cast<double>(std::get<2>(result)), static_cast<double>(std::get<3>(result)));
} }
void CService::resetMilesLost() void CService::resetFrameTotals()
{ {
if (m_framePeriodSampler) if (m_framePeriodSampler)
{ {
@@ -590,6 +593,7 @@ namespace XSwiftBus
reply.appendArgument(std::get<0>(stats)); reply.appendArgument(std::get<0>(stats));
reply.appendArgument(std::get<1>(stats)); reply.appendArgument(std::get<1>(stats));
reply.appendArgument(std::get<2>(stats)); reply.appendArgument(std::get<2>(stats));
reply.appendArgument(std::get<3>(stats));
sendDBusMessage(reply); sendDBusMessage(reply);
}); });
} }

View File

@@ -114,11 +114,12 @@ namespace XSwiftBus
//! or since this function was last called, whichever is later. //! or since this function was last called, whichever is later.
//! Second part is the average simulation time ratio during the same period. //! Second part is the average simulation time ratio during the same period.
//! Third part is the total track miles over-reported during the same period. //! Third part is the total track miles over-reported during the same period.
//! Fourth part is the total minutes behind scedule during the same period.
//! \return Zero if no samples were collected since this function was last called. //! \return Zero if no samples were collected since this function was last called.
std::tuple<double, double, double> getFrameStats(); std::tuple<double, double, double, double> getFrameStats();
//! Reset the monitoring of total track miles lost due to low frame rate. //! Reset the monitoring of total miles and minutes lost due to low frame rate.
void resetMilesLost(); void resetFrameTotals();
//! Get aircraft latitude in degrees //! Get aircraft latitude in degrees
double getLatitudeDeg() const { return m_latitude.get(); } double getLatitudeDeg() const { return m_latitude.get(); }