mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-30 22:29:13 +08:00
Ref T412, Ref T227, own aircraft positions and state detection
* keep history of own positions * detect moved aircraft * relay signals via proxy
This commit is contained in:
@@ -102,9 +102,18 @@ namespace BlackCore
|
|||||||
//! Own pilot (aka the swift user) changed
|
//! Own pilot (aka the swift user) changed
|
||||||
void changedPilot(const BlackMisc::Network::CUser &pilot);
|
void changedPilot(const BlackMisc::Network::CUser &pilot);
|
||||||
|
|
||||||
|
//! Changed aircraft model
|
||||||
|
void changedModel(const BlackMisc::Simulation::CAircraftModel &model);
|
||||||
|
|
||||||
//! Aircraft has been moved from one location to another (changed scenery)
|
//! Aircraft has been moved from one location to another (changed scenery)
|
||||||
void movedAircraft();
|
void movedAircraft();
|
||||||
|
|
||||||
|
//! Just airborne
|
||||||
|
void airborne();
|
||||||
|
|
||||||
|
//! Just landed
|
||||||
|
void touchdown();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
//! Get own aircraft
|
//! Get own aircraft
|
||||||
virtual BlackMisc::Simulation::CSimulatedAircraft getOwnAircraft() const = 0;
|
virtual BlackMisc::Simulation::CSimulatedAircraft getOwnAircraft() const = 0;
|
||||||
|
|||||||
@@ -7,31 +7,36 @@
|
|||||||
* contained in the LICENSE file.
|
* contained in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "blackcore/db/databaseutils.h"
|
#include "blackcore/context/contextownaircraftimpl.h"
|
||||||
|
|
||||||
|
// ----- cross context -----
|
||||||
#include "blackcore/context/contextapplication.h"
|
#include "blackcore/context/contextapplication.h"
|
||||||
#include "blackcore/context/contextaudio.h"
|
#include "blackcore/context/contextaudio.h"
|
||||||
#include "blackcore/context/contextnetwork.h"
|
#include "blackcore/context/contextnetwork.h"
|
||||||
#include "blackcore/context/contextownaircraftimpl.h"
|
#include "blackcore/context/contextsimulator.h"
|
||||||
|
// ----- cross context -----
|
||||||
|
|
||||||
#include "blackcore/application.h"
|
#include "blackcore/application.h"
|
||||||
#include "blackcore/webdataservices.h"
|
#include "blackcore/webdataservices.h"
|
||||||
#include "blackmisc/audio/voiceroom.h"
|
#include "blackmisc/audio/voiceroom.h"
|
||||||
#include "blackmisc/audio/voiceroomlist.h"
|
#include "blackmisc/audio/voiceroomlist.h"
|
||||||
|
#include "blackmisc/network/server.h"
|
||||||
#include "blackmisc/aviation/aircrafticaocode.h"
|
#include "blackmisc/aviation/aircrafticaocode.h"
|
||||||
#include "blackmisc/aviation/aircraftsituation.h"
|
#include "blackmisc/aviation/aircraftsituation.h"
|
||||||
#include "blackmisc/aviation/altitude.h"
|
#include "blackmisc/aviation/altitude.h"
|
||||||
#include "blackmisc/aviation/callsign.h"
|
#include "blackmisc/aviation/callsign.h"
|
||||||
#include "blackmisc/aviation/transponder.h"
|
#include "blackmisc/aviation/transponder.h"
|
||||||
#include "blackmisc/compare.h"
|
#include "blackcore/db/databaseutils.h"
|
||||||
#include "blackmisc/dbusserver.h"
|
#include "blackmisc/pq/physicalquantity.h"
|
||||||
#include "blackmisc/geo/latitude.h"
|
#include "blackmisc/geo/latitude.h"
|
||||||
#include "blackmisc/geo/longitude.h"
|
#include "blackmisc/geo/longitude.h"
|
||||||
|
#include "blackmisc/pq/units.h"
|
||||||
|
#include "blackmisc/simplecommandparser.h"
|
||||||
|
#include "blackmisc/compare.h"
|
||||||
|
#include "blackmisc/dbusserver.h"
|
||||||
#include "blackmisc/logcategory.h"
|
#include "blackmisc/logcategory.h"
|
||||||
#include "blackmisc/logmessage.h"
|
#include "blackmisc/logmessage.h"
|
||||||
#include "blackmisc/network/server.h"
|
|
||||||
#include "blackmisc/pq/physicalquantity.h"
|
|
||||||
#include "blackmisc/pq/units.h"
|
|
||||||
#include "blackmisc/sequence.h"
|
#include "blackmisc/sequence.h"
|
||||||
#include "blackmisc/simplecommandparser.h"
|
|
||||||
#include "blackmisc/statusmessage.h"
|
#include "blackmisc/statusmessage.h"
|
||||||
|
|
||||||
#include <QReadLocker>
|
#include <QReadLocker>
|
||||||
@@ -57,7 +62,13 @@ namespace BlackCore
|
|||||||
CIdentifiable(this)
|
CIdentifiable(this)
|
||||||
{
|
{
|
||||||
Q_ASSERT(this->getRuntime());
|
Q_ASSERT(this->getRuntime());
|
||||||
|
|
||||||
|
connect(&m_historyTimer, &QTimer::timeout, this, &CContextOwnAircraft::evaluateUpdateHistory);
|
||||||
this->setObjectName("CContextOwnAircraft");
|
this->setObjectName("CContextOwnAircraft");
|
||||||
|
m_historyTimer.setObjectName(this->objectName() + "::historyTimer");
|
||||||
|
m_historyTimer.start(2500);
|
||||||
|
m_situationHistory.setSortHint(CAircraftSituationList::TimestampLatestFirst);
|
||||||
|
|
||||||
CContextOwnAircraft::registerHelp();
|
CContextOwnAircraft::registerHelp();
|
||||||
|
|
||||||
if (sApp && sApp->getWebDataServices())
|
if (sApp && sApp->getWebDataServices())
|
||||||
@@ -175,6 +186,35 @@ namespace BlackCore
|
|||||||
emit this->getIContextApplication()->fakedSetComVoiceRoom(rooms);
|
emit this->getIContextApplication()->fakedSetComVoiceRoom(rooms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CContextOwnAircraft::evaluateUpdateHistory()
|
||||||
|
{
|
||||||
|
if (!m_history) { return; }
|
||||||
|
if (!this->getIContextSimulator()) { return; }
|
||||||
|
|
||||||
|
if (this->getIContextSimulator()->isSimulatorSimulating())
|
||||||
|
{
|
||||||
|
if (!m_situationHistory.isEmpty())
|
||||||
|
{
|
||||||
|
QReadLocker rl(&m_lockAircraft);
|
||||||
|
const CAircraftSituationList situations = m_situationHistory;
|
||||||
|
rl.unlock();
|
||||||
|
|
||||||
|
// using copy to minimize lock time
|
||||||
|
// 500km/h => 1sec: 0.1388 km
|
||||||
|
static const CLength maxDistance(25, CLengthUnit::km());
|
||||||
|
const bool jumpDetected = situations.containsObjectOutsideRange(situations.front(), maxDistance);
|
||||||
|
|
||||||
|
if (jumpDetected)
|
||||||
|
{
|
||||||
|
emit this->movedAircraft();
|
||||||
|
QWriteLocker wl(&m_lockAircraft);
|
||||||
|
m_situationHistory.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} // only if simulating
|
||||||
|
}
|
||||||
|
|
||||||
CAircraftModel CContextOwnAircraft::reverseLookupModel(const CAircraftModel &model)
|
CAircraftModel CContextOwnAircraft::reverseLookupModel(const CAircraftModel &model)
|
||||||
{
|
{
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
@@ -185,10 +225,15 @@ namespace BlackCore
|
|||||||
bool CContextOwnAircraft::updateOwnModel(const CAircraftModel &model)
|
bool CContextOwnAircraft::updateOwnModel(const CAircraftModel &model)
|
||||||
{
|
{
|
||||||
CAircraftModel updateModel(this->reverseLookupModel(model));
|
CAircraftModel updateModel(this->reverseLookupModel(model));
|
||||||
QWriteLocker l(&m_lockAircraft);
|
{
|
||||||
const bool changed = (m_ownAircraft.getModel() != updateModel);
|
QWriteLocker l(&m_lockAircraft);
|
||||||
if (!changed) { return false; }
|
const bool changed = (m_ownAircraft.getModel() != updateModel);
|
||||||
m_ownAircraft.setModel(updateModel);
|
if (!changed) { return false; }
|
||||||
|
m_ownAircraft.setModel(updateModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// changed model
|
||||||
|
emit this->changedModel(model);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,6 +242,12 @@ namespace BlackCore
|
|||||||
QWriteLocker l(&m_lockAircraft);
|
QWriteLocker l(&m_lockAircraft);
|
||||||
// there is intentionally no equal check
|
// there is intentionally no equal check
|
||||||
m_ownAircraft.setSituation(situation);
|
m_ownAircraft.setSituation(situation);
|
||||||
|
|
||||||
|
if (m_situationHistory.isEmpty() || qAbs(situation.getTimeDifferenceMs(m_situationHistory.front())) > MinHistoryDeltaMs)
|
||||||
|
{
|
||||||
|
m_situationHistory.push_frontKeepLatestAdjustedFirst(situation, true);
|
||||||
|
if (m_situationHistory.size() > MaxHistoryElements) { m_situationHistory.pop_back(); }
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,6 +388,21 @@ namespace BlackCore
|
|||||||
this->updateOwnModel(model);
|
this->updateOwnModel(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CContextOwnAircraft::xCtxChangedSimulatorStatus(int status)
|
||||||
|
{
|
||||||
|
const ISimulator::SimulatorStatus s = static_cast<ISimulator::SimulatorStatus>(status);
|
||||||
|
if (ISimulator::isAnyConnectedStatus(s))
|
||||||
|
{
|
||||||
|
// connected
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// disconnected
|
||||||
|
QWriteLocker l(&m_lockAircraft);
|
||||||
|
m_situationHistory.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CContextOwnAircraft::allSwiftWebDataRead()
|
void CContextOwnAircraft::allSwiftWebDataRead()
|
||||||
{
|
{
|
||||||
// we should already have received a reverse lookup model
|
// we should already have received a reverse lookup model
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "blackmisc/simulation/aircraftmodel.h"
|
#include "blackmisc/simulation/aircraftmodel.h"
|
||||||
#include "blackmisc/simulation/ownaircraftprovider.h"
|
#include "blackmisc/simulation/ownaircraftprovider.h"
|
||||||
#include "blackmisc/simulation/simulatedaircraft.h"
|
#include "blackmisc/simulation/simulatedaircraft.h"
|
||||||
|
#include "blackmisc/aviation/aircraftsituationlist.h"
|
||||||
#include "blackmisc/aviation/aircraftparts.h"
|
#include "blackmisc/aviation/aircraftparts.h"
|
||||||
#include "blackmisc/aviation/airlineicaocode.h"
|
#include "blackmisc/aviation/airlineicaocode.h"
|
||||||
#include "blackmisc/aviation/atcstation.h"
|
#include "blackmisc/aviation/atcstation.h"
|
||||||
@@ -37,6 +38,8 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QReadWriteLock>
|
#include <QReadWriteLock>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
namespace BlackMisc
|
namespace BlackMisc
|
||||||
{
|
{
|
||||||
@@ -180,10 +183,16 @@ namespace BlackCore
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
BlackMisc::Simulation::CSimulatedAircraft m_ownAircraft; //!< my aircraft
|
BlackMisc::Simulation::CSimulatedAircraft m_ownAircraft; //!< my aircraft
|
||||||
bool m_automaticVoiceRoomResolution = true; //!< automatic voice room resolution, or disable for override
|
bool m_automaticVoiceRoomResolution = true; //!< automatic voice room resolution, or disable for override
|
||||||
QString m_voiceRoom1UrlOverride; //!< overridden voice room url
|
QString m_voiceRoom1UrlOverride; //!< overridden voice room url
|
||||||
QString m_voiceRoom2UrlOverride; //!< overridden voice room url
|
QString m_voiceRoom2UrlOverride; //!< overridden voice room url
|
||||||
mutable QReadWriteLock m_lockAircraft; //!< lock aircraft
|
mutable QReadWriteLock m_lockAircraft; //!< lock aircraft
|
||||||
|
|
||||||
|
static constexpr qint64 MinHistoryDeltaMs = 1000;
|
||||||
|
static constexpr int MaxHistoryElements = 20;
|
||||||
|
QTimer m_historyTimer; //!< history timer
|
||||||
|
std::atomic_bool m_history { true }; //!< enable history
|
||||||
|
BlackMisc::Aviation::CAircraftSituationList m_situationHistory; //!< history, latest situation first
|
||||||
|
|
||||||
BlackMisc::CSetting<BlackMisc::Network::Settings::TCurrentTrafficServer> m_currentNetworkServer { this };
|
BlackMisc::CSetting<BlackMisc::Network::Settings::TCurrentTrafficServer> m_currentNetworkServer { this };
|
||||||
|
|
||||||
@@ -195,6 +204,10 @@ namespace BlackCore
|
|||||||
//! \ingroup crosscontextfunction
|
//! \ingroup crosscontextfunction
|
||||||
void xCtxChangedSimulatorModel(const BlackMisc::Simulation::CAircraftModel &model);
|
void xCtxChangedSimulatorModel(const BlackMisc::Simulation::CAircraftModel &model);
|
||||||
|
|
||||||
|
//! Simulator status changed
|
||||||
|
//! \ingroup crosscontextfunction
|
||||||
|
void xCtxChangedSimulatorStatus(int status);
|
||||||
|
|
||||||
//! Web data loaded
|
//! Web data loaded
|
||||||
void allSwiftWebDataRead();
|
void allSwiftWebDataRead();
|
||||||
|
|
||||||
@@ -204,6 +217,9 @@ namespace BlackCore
|
|||||||
//! Resolve voice rooms
|
//! Resolve voice rooms
|
||||||
void resolveVoiceRooms();
|
void resolveVoiceRooms();
|
||||||
|
|
||||||
|
//! Update position history
|
||||||
|
void evaluateUpdateHistory();
|
||||||
|
|
||||||
//! Reverse lookup of the model against DB data
|
//! Reverse lookup of the model against DB data
|
||||||
static BlackMisc::Simulation::CAircraftModel reverseLookupModel(const BlackMisc::Simulation::CAircraftModel &model);
|
static BlackMisc::Simulation::CAircraftModel reverseLookupModel(const BlackMisc::Simulation::CAircraftModel &model);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "blackcore/context/contextownaircraftproxy.h"
|
#include "blackcore/context/contextownaircraftproxy.h"
|
||||||
|
#include "blackmisc/simulation/aircraftmodel.h"
|
||||||
#include "blackmisc/dbus.h"
|
#include "blackmisc/dbus.h"
|
||||||
#include "blackmisc/dbusserver.h"
|
#include "blackmisc/dbusserver.h"
|
||||||
#include "blackmisc/genericdbusinterface.h"
|
#include "blackmisc/genericdbusinterface.h"
|
||||||
@@ -38,25 +39,30 @@ namespace BlackCore
|
|||||||
bool s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(),
|
bool s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(),
|
||||||
"changedAircraftCockpit", this, SIGNAL(changedAircraftCockpit(BlackMisc::Simulation::CSimulatedAircraft, BlackMisc::CIdentifier)));
|
"changedAircraftCockpit", this, SIGNAL(changedAircraftCockpit(BlackMisc::Simulation::CSimulatedAircraft, BlackMisc::CIdentifier)));
|
||||||
Q_ASSERT(s);
|
Q_ASSERT(s);
|
||||||
|
|
||||||
s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(),
|
s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(),
|
||||||
"changedSelcal", this, SIGNAL(changedSelcal(BlackMisc::Aviation::CSelcal, BlackMisc::CIdentifier)));
|
"changedSelcal", this, SIGNAL(changedSelcal(BlackMisc::Aviation::CSelcal, BlackMisc::CIdentifier)));
|
||||||
Q_ASSERT(s);
|
Q_ASSERT(s);
|
||||||
|
|
||||||
s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(),
|
s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(),
|
||||||
"changedCallsign", this, SIGNAL(changedCallsign(BlackMisc::Aviation::CCallsign)));
|
"changedCallsign", this, SIGNAL(changedCallsign(BlackMisc::Aviation::CCallsign)));
|
||||||
Q_ASSERT(s);
|
Q_ASSERT(s);
|
||||||
|
|
||||||
s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(),
|
s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(),
|
||||||
"changedAircraftIcaoCodes", this, SIGNAL(changedAircraftIcaoCodes(BlackMisc::Aviation::CAircraftIcaoCode, BlackMisc::Aviation::CAirlineIcaoCode)));
|
"changedAircraftIcaoCodes", this, SIGNAL(changedAircraftIcaoCodes(BlackMisc::Aviation::CAircraftIcaoCode, BlackMisc::Aviation::CAirlineIcaoCode)));
|
||||||
Q_ASSERT(s);
|
Q_ASSERT(s);
|
||||||
|
|
||||||
s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(),
|
s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(),
|
||||||
"changedPilot", this, SIGNAL(changedPilot(BlackMisc::Network::CUser)));
|
"changedPilot", this, SIGNAL(changedPilot(BlackMisc::Network::CUser)));
|
||||||
Q_ASSERT(s);
|
Q_ASSERT(s);
|
||||||
|
s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(),
|
||||||
|
"changedModel", this, SIGNAL(changedModel(BlackMisc::Simulation::CAircraftModel)));
|
||||||
|
Q_ASSERT(s);
|
||||||
s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(),
|
s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(),
|
||||||
"movedAircraft", this, SIGNAL(movedAircraft()));
|
"movedAircraft", this, SIGNAL(movedAircraft()));
|
||||||
Q_ASSERT(s);
|
Q_ASSERT(s);
|
||||||
|
s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(),
|
||||||
|
"airborne", this, SIGNAL(airborne()));
|
||||||
|
Q_ASSERT(s);
|
||||||
|
s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(),
|
||||||
|
"touchdown", this, SIGNAL(touchdown()));
|
||||||
|
Q_ASSERT(s);
|
||||||
|
|
||||||
this->relayBaseClassSignals(serviceName, connection, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName());
|
this->relayBaseClassSignals(serviceName, connection, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName());
|
||||||
Q_UNUSED(s);
|
Q_UNUSED(s);
|
||||||
|
|||||||
@@ -15,9 +15,10 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include "blackcore/blackcoreexport.h"
|
|
||||||
#include "blackcore/context/contextownaircraft.h"
|
#include "blackcore/context/contextownaircraft.h"
|
||||||
#include "blackcore/corefacadeconfig.h"
|
#include "blackcore/corefacadeconfig.h"
|
||||||
|
#include "blackcore/blackcoreexport.h"
|
||||||
|
#include "blackmisc/simulation/simulatedaircraft.h"
|
||||||
#include "blackmisc/aviation/airlineicaocode.h"
|
#include "blackmisc/aviation/airlineicaocode.h"
|
||||||
#include "blackmisc/aviation/comsystem.h"
|
#include "blackmisc/aviation/comsystem.h"
|
||||||
#include "blackmisc/aviation/selcal.h"
|
#include "blackmisc/aviation/selcal.h"
|
||||||
@@ -25,7 +26,6 @@
|
|||||||
#include "blackmisc/identifier.h"
|
#include "blackmisc/identifier.h"
|
||||||
#include "blackmisc/network/user.h"
|
#include "blackmisc/network/user.h"
|
||||||
#include "blackmisc/pq/frequency.h"
|
#include "blackmisc/pq/frequency.h"
|
||||||
#include "blackmisc/simulation/simulatedaircraft.h"
|
|
||||||
|
|
||||||
class QDBusConnection;
|
class QDBusConnection;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user