diff --git a/src/blackcore/airspace_monitor.cpp b/src/blackcore/airspace_monitor.cpp index c22c6e9d8..c64157080 100644 --- a/src/blackcore/airspace_monitor.cpp +++ b/src/blackcore/airspace_monitor.cpp @@ -43,6 +43,7 @@ namespace BlackCore this->connect(this->m_network, &INetwork::pilotDisconnected, this, &CAirspaceMonitor::ps_pilotDisconnected); this->connect(this->m_network, &INetwork::atcDisconnected, this, &CAirspaceMonitor::ps_atcControllerDisconnected); this->connect(this->m_network, &INetwork::aircraftPositionUpdate, this, &CAirspaceMonitor::ps_aircraftUpdateReceived); + this->connect(this->m_network, &INetwork::aircraftInterimPositionUpdate, this, &CAirspaceMonitor::ps_aircraftInterimUpdateReceived); this->connect(this->m_network, &INetwork::frequencyReplyReceived, this, &CAirspaceMonitor::ps_frequencyReceived); this->connect(this->m_network, &INetwork::capabilitiesReplyReceived, this, &CAirspaceMonitor::ps_capabilitiesReplyReceived); this->connect(this->m_network, &INetwork::customFSinnPacketReceived, this, &CAirspaceMonitor::ps_customFSinnPacketReceived); @@ -843,6 +844,42 @@ namespace BlackCore emit this->changedAircraftInRange(); } + void CAirspaceMonitor::ps_aircraftInterimUpdateReceived(const CAircraftSituation &situation) + { + Q_ASSERT_X(BlackCore::isCurrentThreadCreatingThread(this), "ps_aircraftInterimUpdateReceived", "Called in different thread"); + if (!this->m_connected) { return; } + + CCallsign callsign(situation.getCallsign()); + Q_ASSERT_X(!callsign.isEmpty(), "ps_aircraftInterimUpdateReceived", "Empty callsign"); + + // todo: Check if the timestamp is copied here as well. + CAircraftSituation sitationCopy(situation); + + // Interim packets do not have groundspeed, hence set the last known value. + // If there is no full position available yet, throw this interim position away. + auto history = this->m_aircraftSituations.findByCallsign(callsign); + if (history.empty()) return; + sitationCopy.setGroundspeed(history.latestValue().getGroundSpeed()); + + // store situation history + this->m_aircraftSituations.push_front(situation); + this->m_aircraftSituations.removeOlderThanNowMinusOffset(AircraftSituationsRemovedOffsetMs); + emit this->addedRemoteAircraftSituation(situation); + + // update + CLength distance = ownAircraft().calculateGreatCircleDistance(situation.getPosition()); + distance.switchUnit(CLengthUnit::NM()); + CPropertyIndexVariantMap vm; + vm.addValue(CAircraft::IndexSituation, situation); + vm.addValue(CAircraft::IndexDistanceToOwnAircraft, distance); + + // here I expect always a changed value + this->m_aircraftInRange.applyIfCallsign(callsign, vm); + this->m_aircraftWatchdog.resetCallsign(callsign); + + emit this->changedAircraftInRange(); + } + void CAirspaceMonitor::ps_pilotDisconnected(const CCallsign &callsign) { Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this)); diff --git a/src/blackcore/airspace_monitor.h b/src/blackcore/airspace_monitor.h index 1a5360071..3e239cfbb 100644 --- a/src/blackcore/airspace_monitor.h +++ b/src/blackcore/airspace_monitor.h @@ -203,7 +203,7 @@ namespace BlackCore private slots: //! Create aircraft in range, this is the only place where a new aircraft should be added void ps_aircraftUpdateReceived(const BlackMisc::Aviation::CAircraftSituation &situation, const BlackMisc::Aviation::CTransponder &transponder); - + void ps_aircraftInterimUpdateReceived(const BlackMisc::Aviation::CAircraftSituation &situation); void ps_realNameReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &realname); void ps_capabilitiesReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, quint32 flags); void ps_customFSinnPacketReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &p1, const QString &aircraftDesignator, const QString &combinedAircraftType, const QString &model); diff --git a/src/blackcore/network.h b/src/blackcore/network.h index fbbd283e3..5ca7c306c 100644 --- a/src/blackcore/network.h +++ b/src/blackcore/network.h @@ -440,6 +440,12 @@ namespace BlackCore void aircraftPositionUpdate(const BlackMisc::Aviation::CAircraftSituation &situation, const BlackMisc::Aviation::CTransponder &transponder); + /*! + * We received a interim notification of the state of another aircraft on the network. + * Corresponding callsign in \sa CAircraftSituation::getCallsign . + */ + void aircraftInterimPositionUpdate(const BlackMisc::Aviation::CAircraftSituation &situation); + /*! * We received a reply to one of our queries. * \sa sendFrequencyQuery diff --git a/src/blackcore/network_vatlib.cpp b/src/blackcore/network_vatlib.cpp index 559eb6e2e..a7d20779f 100644 --- a/src/blackcore/network_vatlib.cpp +++ b/src/blackcore/network_vatlib.cpp @@ -754,9 +754,21 @@ namespace BlackCore emit cbvar_cast(cbvar)->aircraftConfigPacketReceived(cbvar_cast(cbvar)->fromFSD(callsign), config, isFull); } - void CNetworkVatlib::onInterimPilotPositionUpdate(VatSessionID, const char * /** callsign **/, const VatInterimPilotPosition * /** position **/, void * /** cbvar **/) + void CNetworkVatlib::onInterimPilotPositionUpdate(VatSessionID, const char *sender, const VatInterimPilotPosition *position, void *cbvar) { - //TODO + const CCallsign callsign(sender); + const CAircraftSituation situation( + callsign, + CCoordinateGeodetic(position->latitude, position->longitude, 0.0), + CAltitude(position->altitudeTrue, CAltitude::MeanSeaLevel, CLengthUnit::ft()), + CHeading(position->heading, CHeading::True, CAngleUnit::deg()), + CAngle(position->pitch, CAngleUnit::deg()), + CAngle(position->bank, CAngleUnit::deg()), + // There is no speed information in a interim packet + CSpeed(0.0, CSpeedUnit::kts()) + ); + + emit cbvar_cast(cbvar)->aircraftInterimPositionUpdate(situation); } void CNetworkVatlib::onAtcPositionUpdate(VatSessionID, const char *callsign, const VatAtcPosition *pos, void *cbvar) diff --git a/src/blackcore/network_vatlib.h b/src/blackcore/network_vatlib.h index 5217a114a..aaaaf4852 100644 --- a/src/blackcore/network_vatlib.h +++ b/src/blackcore/network_vatlib.h @@ -98,7 +98,7 @@ namespace BlackCore static void onTextMessageReceived(VatSessionID, const char *from, const char *to, const char *msg, void *cbvar); static void onRadioMessageReceived(VatSessionID, const char *from, int freqCount, int *freqList, const char *message, void *cbvar); static void onControllerDisconnected(VatSessionID, const char *callsign, void *cbvar); - static void onInterimPilotPositionUpdate(VatSessionID, const char *callsign, const VatInterimPilotPosition *position, void *cbvar); + static void onInterimPilotPositionUpdate(VatSessionID, const char *sender, const VatInterimPilotPosition *position, void *cbvar); static void onAtcPositionUpdate(VatSessionID, const char *callsign, const VatAtcPosition *pos, void *cbvar); static void onKicked(VatSessionID, const char *reason, void *cbvar); static void onPong(VatSessionID, const char *sender, double elapsedTime, void *cbvar);