From 7b50917410683ef140ba175a16fa749111f0f956 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Mon, 16 Oct 2017 09:14:28 +0200 Subject: [PATCH] Ref T171, fetch interpolator values in emulated driver. This allows to test and monitor the interpolator in the emulated driver. * UI allows to start/stop interpolator logging * Fetch data from interpolator --- .../simulator/emulated/simulatoremulated.cpp | 86 ++++++++++++- .../simulator/emulated/simulatoremulated.h | 35 +++++- .../simulatoremulatedmonitordialog.cpp | 89 ++++++++++++-- .../emulated/simulatoremulatedmonitordialog.h | 9 +- .../simulatoremulatedmonitordialog.ui | 113 +++++++++++++++--- 5 files changed, 300 insertions(+), 32 deletions(-) diff --git a/src/plugins/simulator/emulated/simulatoremulated.cpp b/src/plugins/simulator/emulated/simulatoremulated.cpp index a6365a591..a3e34cc6a 100644 --- a/src/plugins/simulator/emulated/simulatoremulated.cpp +++ b/src/plugins/simulator/emulated/simulatoremulated.cpp @@ -40,12 +40,14 @@ namespace BlackSimPlugin Q_ASSERT_X(sApp && sApp->getIContextSimulator(), Q_FUNC_INFO, "Need context"); CSimulatorEmulated::registerHelp(); + this->setObjectName(info.getSimulatorInfo()); m_myAircraft = this->getOwnAircraft(); // sync with provider - m_monitorWidget.reset(new CSimulatorEmulatedMonitorDialog(this, sGui->mainApplicationWindow())); - connect(qApp, &QApplication::aboutToQuit, this, &CSimulatorEmulated::closeMonitor); this->onSettingsChanged(); + connect(qApp, &QApplication::aboutToQuit, this, &CSimulatorEmulated::closeMonitor); + connect(&m_interpolatorFetchTimer, &QTimer::timeout, this, &CSimulatorEmulated::fetchFromInterpolator); + // connect own signals for monitoring this->connectOwnSignals(); } @@ -234,6 +236,24 @@ namespace BlackSimPlugin return this->updateOwnParts(parts); } + bool CSimulatorEmulated::setInterpolatorFetchTime(int timeMs) + { + if (timeMs < 1) + { + m_interpolatorFetchTimer.stop(); + } + else + { + m_interpolatorFetchTimer.start(timeMs); + } + return m_interpolatorFetchTimer.isActive(); + } + + bool CSimulatorEmulated::isInterpolatorFetching() const + { + return m_interpolatorFetchTimer.isActive(); + } + bool CSimulatorEmulated::isConnected() const { if (canLog()) m_monitorWidget->appendReceivingCall(Q_FUNC_INFO); @@ -257,8 +277,9 @@ namespace BlackSimPlugin if (canLog()) m_monitorWidget->appendReceivingCall(Q_FUNC_INFO, remoteAircraft.toQString()); CSimulatedAircraft aircraft(remoteAircraft); aircraft.setRendered(true); - m_renderedAircraft.push_back(aircraft); // my simulator list const CCallsign cs = aircraft.getCallsign(); + m_interpolators.insert(cs, CInterpolatorMultiWrapper(cs, &m_interpolationLogger, this)); + m_renderedAircraft.push_back(aircraft); // my simulator list this->updateAircraftRendered(cs, true); // in provider emit this->aircraftRenderingChanged(aircraft); return true; @@ -267,6 +288,7 @@ namespace BlackSimPlugin bool CSimulatorEmulated::physicallyRemoveRemoteAircraft(const CCallsign &callsign) { if (canLog()) m_monitorWidget->appendReceivingCall(Q_FUNC_INFO, callsign.toQString()); + m_interpolators.remove(callsign); const int c = m_renderedAircraft.removeByCallsign(callsign); return c > 0; } @@ -274,7 +296,9 @@ namespace BlackSimPlugin bool CSimulatorEmulated::setInterpolatorMode(CInterpolatorMulti::Mode mode, const CCallsign &callsign) { if (canLog()) m_monitorWidget->appendReceivingCall(Q_FUNC_INFO, CInterpolatorMulti::modeToString(mode), callsign.toQString()); - return false; + if (!m_interpolators.contains(callsign)) { return false; } + CInterpolatorMulti *im = m_interpolators[callsign]; + return im->setMode(mode); } int CSimulatorEmulated::physicallyRemoveAllRemoteAircraft() @@ -283,6 +307,23 @@ namespace BlackSimPlugin return CSimulatorCommon::physicallyRemoveAllRemoteAircraft(); } + void CSimulatorEmulated::onRemoteProviderAddedAircraftSituation(const CAircraftSituation &situation) + { + const CCallsign cs = situation.getCallsign(); + if (!m_interpolators.contains(cs)) { return; } + CInterpolatorMulti *im = m_interpolators[cs]; + Q_ASSERT_X(im, Q_FUNC_INFO, "no interpolator"); + im->addAircraftSituation(situation); + } + + void BlackSimPlugin::Emulated::CSimulatorEmulated::onRemoteProviderAddedAircraftParts(const CCallsign &callsign, const CAircraftParts &parts) + { + if (!m_interpolators.contains(callsign)) { return; } + CInterpolatorMulti *im = m_interpolators[callsign]; + Q_ASSERT_X(im, Q_FUNC_INFO, "no interpolator"); + im->addAircraftParts(parts); + } + bool CSimulatorEmulated::parseDetails(const CSimpleCommandParser &parser) { if (m_monitorWidget && parser.isKnownCommand()) @@ -293,6 +334,12 @@ namespace BlackSimPlugin return false; } + void CSimulatorEmulated::setObjectName(const CSimulatorInfo &info) + { + QObject::setObjectName("Emulated driver for " + info.getSimulator()); + m_interpolatorFetchTimer.setObjectName(this->objectName() + ":interpolatorFetchTimer"); + } + bool CSimulatorEmulated::canLog() const { return sApp && !sApp->isShuttingDown() && m_log && m_monitorWidget; @@ -311,8 +358,9 @@ namespace BlackSimPlugin const CSwiftPluginSettings settings(m_settings.get()); m_log = settings.isLoggingFunctionCalls(); + const CSimulatorInfo simulator = settings.getEmulatedSimulator(); const CSimulatorPluginInfoList plugins = sApp->getIContextSimulator()->getAvailableSimulatorPlugins(); - const CSimulatorPluginInfo plugin = plugins.findBySimulator(settings.getEmulatedSimulator()); + const CSimulatorPluginInfo plugin = plugins.findBySimulator(simulator); if (plugin.isValid()) { // ? restart driver, disconnect/reconnect @@ -325,6 +373,9 @@ namespace BlackSimPlugin // update provider this->updateOwnModel(settings.getOwnModel()); + + // own name + this->setObjectName(simulator); } void CSimulatorEmulated::connectOwnSignals() @@ -368,6 +419,31 @@ namespace BlackSimPlugin }, Qt::QueuedConnection)); } + void CSimulatorEmulated::fetchFromInterpolator() + { + const qint64 now = QDateTime::currentMSecsSinceEpoch(); + const CInterpolationAndRenderingSetup setup = this->getInterpolationAndRenderingSetup(); // threadsafe copy + for (const CSimulatedAircraft &aircraft : m_renderedAircraft) + { + const CCallsign cs = aircraft.getCallsign(); + if (!m_interpolators.contains(cs)) { continue; } + const bool log = setup.logCallsign(cs); + CInterpolatorMulti *im = m_interpolators[cs]; + CInterpolationStatus statusInterpolation; + CPartsStatus statusParts; + CInterpolationHints hints; + Q_ASSERT_X(im, Q_FUNC_INFO, "interpolator missing"); + if (m_hints.contains(cs)) { hints = m_hints[cs]; } + hints.setLoggingInterpolation(log); + const CAircraftSituation s = im->getInterpolatedSituation(now, setup, hints, statusInterpolation); + const CAircraftParts p = im->getInterpolatedParts(now, setup, statusParts, log); + m_countInterpolatedParts++; + m_countInterpolatedSituations++; + Q_UNUSED(s); + Q_UNUSED(p); + } + } + CSimulatorEmulatedListener::CSimulatorEmulatedListener(const CSimulatorPluginInfo &info) : ISimulatorListener(info) { } diff --git a/src/plugins/simulator/emulated/simulatoremulated.h b/src/plugins/simulator/emulated/simulatoremulated.h index 907e9ad89..770755bfe 100644 --- a/src/plugins/simulator/emulated/simulatoremulated.h +++ b/src/plugins/simulator/emulated/simulatoremulated.h @@ -13,12 +13,17 @@ #define BLACKSIMPLUGIN_EMULATED_SIMULATOREMULATED_H #include "blackcore/simulatorcommon.h" +#include "blackmisc/simulation/interpolatormulti.h" +#include "blackmisc/simulation/interpolationrenderingsetup.h" +#include "blackmisc/simulation/interpolationlogger.h" #include "blackmisc/simulation/simulatorplugininfo.h" #include "blackmisc/simulation/settings/swiftpluginsettings.h" #include "blackmisc/pq/time.h" #include "blackmisc/connectionguard.h" #include "simulatoremulatedmonitordialog.h" +#include +#include #include namespace BlackSimPlugin @@ -99,6 +104,12 @@ namespace BlackSimPlugin //! \remark normally used by corresponding BlackSimPlugin::Emulated::CSimulatorEmulatedMonitorDialog bool changeInternalParts(const BlackMisc::Aviation::CAircraftParts &parts); + //! Interpolator fetch time, <=0 stops + bool setInterpolatorFetchTime(int timeMs); + + //! Is fetching from interpolator + bool isInterpolatorFetching() const; + //! Register help static void registerHelp(); @@ -116,10 +127,19 @@ namespace BlackSimPlugin // just logged virtual int physicallyRemoveAllRemoteAircraft() override; + //! \name Remote aircraft provider overrides + //! @{ + virtual void onRemoteProviderAddedAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation) override; + virtual void onRemoteProviderAddedAircraftParts(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftParts &parts) override; + //! @} + //! \copydoc BlackCore::CSimulatorCommon::parseDetails virtual bool parseDetails(const BlackMisc::CSimpleCommandParser &parser) override; private: + //! Set object name + void setObjectName(const BlackMisc::Simulation::CSimulatorInfo &info); + //! Can append log messages? bool canLog() const; @@ -135,18 +155,25 @@ namespace BlackSimPlugin //! Connect own signals for monitoring void connectOwnSignals(); + //! Fetch data from interpolator + //! \remarks basically does the same as a real driver, obtains data from the interpolator + void fetchFromInterpolator(); + bool m_log = false; //!< from settings bool m_paused = false; bool m_connected = true; bool m_simulating = true; bool m_timeSyncronized = false; + int m_countInterpolatedSituations = 0; + int m_countInterpolatedParts = 0; + QTimer m_interpolatorFetchTimer { this }; //!< fetch data from interpolator BlackMisc::PhysicalQuantities::CTime m_offsetTime; - BlackMisc::Simulation::CSimulatedAircraft m_myAircraft; //!< represents own aircraft of simulator + BlackMisc::Simulation::CSimulatedAircraft m_myAircraft; //!< represents own aircraft of simulator BlackMisc::Simulation::CSimulatedAircraftList m_renderedAircraft; //!< represents remote aircraft in simulator - - QScopedPointer m_monitorWidget; //!< parent will be main window, so we need to destroy widget when destroyed + QScopedPointer m_monitorWidget; //!< parent will be main window, so we need to destroy widget when destroyed + BlackMisc::CConnectionGuard m_connectionGuard; //!< connected with provider BlackMisc::CSettingReadOnly m_settings { this, &CSimulatorEmulated::onSettingsChanged }; - BlackMisc::CConnectionGuard m_connectionGuard; + QMap m_interpolators; //!< interpolators per callsign }; //! Listener for swift diff --git a/src/plugins/simulator/emulated/simulatoremulatedmonitordialog.cpp b/src/plugins/simulator/emulated/simulatoremulatedmonitordialog.cpp index 6ea02a0e1..68797e391 100644 --- a/src/plugins/simulator/emulated/simulatoremulatedmonitordialog.cpp +++ b/src/plugins/simulator/emulated/simulatoremulatedmonitordialog.cpp @@ -10,6 +10,8 @@ #include "simulatoremulatedmonitordialog.h" #include "simulatoremulated.h" #include "ui_simulatoremulatedmonitordialog.h" +#include "blackmisc/logmessage.h" +#include using namespace BlackMisc; using namespace BlackMisc::Aviation; @@ -29,6 +31,7 @@ namespace BlackSimPlugin CSimulatorEmulatedMonitorDialog::CSimulatorEmulatedMonitorDialog(CSimulatorEmulated *simulator, QWidget *parent) : QDialog(parent), + CIdentifiable("Emulated driver dialog"), ui(new Ui::CSimulatorEmulatedMonitorDialog) { Q_ASSERT_X(simulator, Q_FUNC_INFO, "Need simulator"); @@ -41,9 +44,9 @@ namespace BlackSimPlugin m_simulator = simulator; m_uiUpdateTimer.setObjectName(this->objectName() + ":uiUpdateTimer"); m_uiUpdateTimer.start(2.5 * 1000); + connect(m_simulator, &CSimulatorEmulated::internalAircraftChanged, this, &CSimulatorEmulatedMonitorDialog::setInternalAircraftUiValues, Qt::QueuedConnection); connect(&m_uiUpdateTimer, &QTimer::timeout, this, &CSimulatorEmulatedMonitorDialog::timerBasedUiUpdates); - connect(ui->pb_ResetStatistics, &QPushButton::clicked, this, &CSimulatorEmulatedMonitorDialog::resetStatistics); connect(ui->cb_Connected, &QCheckBox::released, this, &CSimulatorEmulatedMonitorDialog::onSimulatorValuesChanged); connect(ui->cb_Paused, &QCheckBox::released, this, &CSimulatorEmulatedMonitorDialog::onSimulatorValuesChanged); @@ -54,11 +57,24 @@ namespace BlackSimPlugin connect(ui->editor_Com, &CCockpitComForm::changedCockpitValues, this, &CSimulatorEmulatedMonitorDialog::changeComFromUi); connect(ui->editor_Com, &CCockpitComForm::changedSelcal, this, &CSimulatorEmulatedMonitorDialog::changeSelcalFromUi); - ui->wi_LedReceiving->setToolTips("receiving", "idle"); - ui->wi_LedReceiving->setShape(CLedWidget::Rounded); - ui->wi_LedSending->setToolTips("sending", "idle"); - ui->wi_LedSending->setShape(CLedWidget::Rounded); + connect(ui->pb_ResetStatistics, &QPushButton::clicked, this, &CSimulatorEmulatedMonitorDialog::resetStatistics); + connect(ui->pb_InterpolatorStopLog, &QPushButton::clicked, this, &CSimulatorEmulatedMonitorDialog::interpolatorLogButton); + connect(ui->pb_InterpolatorWriteLog, &QPushButton::clicked, this, &CSimulatorEmulatedMonitorDialog::interpolatorLogButton); + connect(ui->pb_InterpolatorClearLog, &QPushButton::clicked, this, &CSimulatorEmulatedMonitorDialog::interpolatorLogButton); + connect(ui->pb_InterpolatorShowLogs, &QPushButton::clicked, this, &CSimulatorEmulatedMonitorDialog::interpolatorLogButton); + connect(ui->pb_InterpolatorStartLog, &QPushButton::clicked, this, &CSimulatorEmulatedMonitorDialog::interpolatorLogButton); + connect(ui->pb_InterpolatorFetch, &QPushButton::clicked, this, &CSimulatorEmulatedMonitorDialog::interpolatorLogButton); + ui->led_Receiving->setToolTips("receiving", "idle"); + ui->led_Receiving->setShape(CLedWidget::Rounded); + ui->led_Sending->setToolTips("sending", "idle"); + ui->led_Sending->setShape(CLedWidget::Rounded); + ui->led_Fetching->setToolTips("fetching interpolated", "not fetching interpolated"); + ui->led_Fetching->setShape(CLedWidget::Rounded); + + ui->le_InterpolatorTimeMs->setValidator(new QIntValidator(10, 20000, ui->le_InterpolatorTimeMs)); + + this->enableInterpolationLogButtons(false); this->setSimulatorUiValues(); this->setInternalAircraftUiValues(); } @@ -78,13 +94,13 @@ namespace BlackSimPlugin void CSimulatorEmulatedMonitorDialog::appendReceivingCall(const QString &function, const QString &p1, const QString &p2, const QString &p3) { - ui->wi_LedReceiving->blink(); + ui->led_Receiving->blink(); this->appendFunctionCall(function, p1, p2, p3); } void CSimulatorEmulatedMonitorDialog::appendSendingCall(const QString &function, const QString &p1, const QString &p2, const QString &p3) { - ui->wi_LedSending->blink(); + ui->led_Sending->blink(); this->appendFunctionCall(function, p1, p2, p3); } @@ -196,5 +212,64 @@ namespace BlackSimPlugin ui->le_SituationAdded->clear(); ui->le_PartsAdded->clear(); } + + void CSimulatorEmulatedMonitorDialog::interpolatorLogButton() + { + const QObject *sender = QObject::sender(); + bool ok = false; + if (sender == ui->pb_InterpolatorStopLog) + { + ok = m_simulator->parseCommandLine(".drv logint off", this->identifier()); + } + else if (sender == ui->pb_InterpolatorWriteLog) + { + ok = m_simulator->parseCommandLine(".drv logint write", this->identifier()); + } + else if (sender == ui->pb_InterpolatorClearLog) + { + ok = m_simulator->parseCommandLine(".drv logint clear", this->identifier()); + } + else if (sender == ui->pb_InterpolatorShowLogs) + { + ok = m_simulator->parseCommandLine(".drv logint show", this->identifier()); + } + else if (sender == ui->pb_InterpolatorStartLog) + { + const CCallsign cs = ui->comp_LogInterpolatorCallsign->getCallsign(); + if (cs.isValid()) + { + ok = m_simulator->parseCommandLine(".drv logint " + cs.asString(), this->identifier()); + } + else + { + CLogMessage(this).warning("Need a (valid) callsign to write a log"); + ok = true; // already a warning + } + } + else if (sender == ui->pb_InterpolatorFetch) + { + // toggle fetching + const int timeMs = m_simulator->isInterpolatorFetching() ? -1 : ui->le_InterpolatorTimeMs->text().toInt(); + const bool fetching = m_simulator->setInterpolatorFetchTime(timeMs); + ui->led_Fetching->setOn(fetching); + ui->pb_InterpolatorFetch->setText(fetching ? "Stop" : "Fetch"); + this->enableInterpolationLogButtons(fetching); + ok = true; + } + else + { + Q_ASSERT_X(false, Q_FUNC_INFO, "Unhandled button"); + } + if (!ok) { CLogMessage(this).warning("Cannot parse command for button: %1") << sender->objectName(); } + } + + void CSimulatorEmulatedMonitorDialog::enableInterpolationLogButtons(bool enable) + { + ui->pb_InterpolatorClearLog->setEnabled(enable); + ui->pb_InterpolatorShowLogs->setEnabled(enable); + ui->pb_InterpolatorStartLog->setEnabled(enable); + ui->pb_InterpolatorStopLog->setEnabled(enable); + ui->pb_InterpolatorWriteLog->setEnabled(enable); + } } // ns } // ns diff --git a/src/plugins/simulator/emulated/simulatoremulatedmonitordialog.h b/src/plugins/simulator/emulated/simulatoremulatedmonitordialog.h index 271fc8bb8..70b189ebf 100644 --- a/src/plugins/simulator/emulated/simulatoremulatedmonitordialog.h +++ b/src/plugins/simulator/emulated/simulatoremulatedmonitordialog.h @@ -15,6 +15,7 @@ #include "blackmisc/simulation/simulatedaircraft.h" #include "blackmisc/statusmessagelist.h" #include "blackmisc/logcategorylist.h" +#include "blackmisc/identifiable.h" #include #include @@ -30,7 +31,7 @@ namespace BlackSimPlugin /** * Monitor widget for the pseudo driver */ - class CSimulatorEmulatedMonitorDialog : public QDialog + class CSimulatorEmulatedMonitorDialog : public QDialog, public BlackMisc::CIdentifiable { Q_OBJECT @@ -95,6 +96,12 @@ namespace BlackSimPlugin //! Reset statistics void resetStatistics(); + //! Interpolator log button pressed + void interpolatorLogButton(); + + //! Enable/disable the interpolation log buttons + void enableInterpolationLogButtons(bool enable); + QScopedPointer ui; CSimulatorEmulated *m_simulator = nullptr; QTimer m_uiUpdateTimer { this }; diff --git a/src/plugins/simulator/emulated/simulatoremulatedmonitordialog.ui b/src/plugins/simulator/emulated/simulatoremulatedmonitordialog.ui index d83a112c7..060479b15 100644 --- a/src/plugins/simulator/emulated/simulatoremulatedmonitordialog.ui +++ b/src/plugins/simulator/emulated/simulatoremulatedmonitordialog.ui @@ -31,7 +31,7 @@ - + @@ -41,7 +41,7 @@ - + @@ -91,6 +91,19 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -385,6 +398,83 @@ + + + + Interpolator + + + + + + start log. + + + + + + + clear log + + + + + + + stop logging + + + + + + + write log.file + + + + + + + log.files + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + fetch + + + + + + + 40 + + + 10 + + + fetch time ms + + + + + + + + + @@ -426,19 +516,6 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - @@ -488,6 +565,12 @@
blackgui/led.h
1 + + BlackGui::Components::CCallsignCompleter + QFrame +
blackgui/components/callsigncompleter.h
+ 1 +