Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
Executable
+146
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* PositionsCnr
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Fröbel, NLE, 2019-08-05
|
||||
*/
|
||||
|
||||
#include "positions_cnr.h"
|
||||
#include "exercise_manager.h"
|
||||
#include "helper.h"
|
||||
#include <AudioVideoManagement/avm_dtc.h>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <LtsUtilsCore/outdated_position.h>
|
||||
#include <QtGlobal>
|
||||
#include <QDateTime>
|
||||
#include <QSet>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
QSet<int> participantIdsFromParty(const QMap<int32_t, ParticipantManagement::Participant> &participants, int partyId, bool isGlobal)
|
||||
{
|
||||
QSet<int> ret;
|
||||
if (isGlobal)
|
||||
{
|
||||
ret.reserve(participants.size());
|
||||
for (const auto &p : participants)
|
||||
ret += p.id();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto &participant : participants)
|
||||
if (participant.partyId() == partyId)
|
||||
ret += participant.id();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
namespace CombatNetRadio
|
||||
{
|
||||
|
||||
PositionsCnr::PositionsCnr(int exerciseId, ExerciseManager *exerciseManager, ParticipantManagement::Interface::Dtc *ppmDtc, AudioVideoManagement::Interface::Dtc *avmDtc)
|
||||
: m_exerciseId(exerciseId)
|
||||
, m_exerciseManager(exerciseManager)
|
||||
, m_ppmDtc(ppmDtc)
|
||||
, m_avmDtc(avmDtc)
|
||||
{
|
||||
Q_ASSERT(exerciseId > 0);
|
||||
Q_ASSERT(exerciseManager);
|
||||
Q_ASSERT(ppmDtc);
|
||||
Q_ASSERT(avmDtc);
|
||||
}
|
||||
|
||||
WebSocketInterface::Messages::PositionsCnrMessage::PositionsCnrMessageData PositionsCnr::data() const
|
||||
{
|
||||
WebSocketInterface::Messages::PositionsCnrMessage::PositionsCnrMessageData positionsData;
|
||||
|
||||
positionsData.time = QDateTime::currentDateTime().toString(Qt::ISODate);
|
||||
|
||||
boost::optional<AudioVideoManagement::FrequencyPlanning> plan = activePlan();
|
||||
if (!plan)
|
||||
return positionsData;
|
||||
|
||||
for (const auto &entry : plan->data())
|
||||
{
|
||||
AudioVideoManagement::CnrConfig cnrConfig = m_avmDtc->cnrConfig(entry.cnrConfigId());
|
||||
AudioVideoManagement::CnrChannel cnrChannel = m_avmDtc->cnrChannel(cnrConfig.cnrChannelId());
|
||||
|
||||
positionsData.radioCircuit.push_back({toRcIdString(cnrChannel), positionsFor(cnrConfig)});
|
||||
}
|
||||
|
||||
return positionsData;
|
||||
}
|
||||
|
||||
QVector<WebSocketInterface::Messages::ReplyMessage::LonLatPoint> PositionsCnr::positionsForGlobal(const AudioVideoManagement::CnrConfig &config) const
|
||||
{
|
||||
bool isGlobal = !config.exerciseId().is_set();
|
||||
Q_ASSERT(isGlobal);
|
||||
return positionsForLocal(config);
|
||||
}
|
||||
|
||||
QVector<WebSocketInterface::Messages::ReplyMessage::LonLatPoint> PositionsCnr::positionsFor(const AudioVideoManagement::CnrConfig &config) const
|
||||
{
|
||||
bool isLocal = config.exerciseId().is_set();
|
||||
if (isLocal)
|
||||
return positionsForLocal(config);
|
||||
else
|
||||
return m_exerciseManager->positionsForGlobal(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be called for a global config, too. But then only positions for Participants of this Exercise will be returned.
|
||||
*/
|
||||
QVector<WebSocketInterface::Messages::ReplyMessage::LonLatPoint> PositionsCnr::positionsForLocal(const AudioVideoManagement::CnrConfig &config) const
|
||||
{
|
||||
auto allParticipants = m_ppmDtc->participants();
|
||||
|
||||
QSet<int> participantIdsInUnit;
|
||||
if (config.unitId().is_set())
|
||||
m_ppmDtc->participantIdsByUnit(config.unitId().get(), allParticipants, participantIdsInUnit);
|
||||
else
|
||||
{
|
||||
bool isGlobal = !config.exerciseId().is_set();
|
||||
participantIdsInUnit = participantIdsFromParty(allParticipants, config.partyId(), isGlobal);
|
||||
}
|
||||
|
||||
const qint64 now = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
QVector<WebSocketInterface::Messages::ReplyMessage::LonLatPoint> positions;
|
||||
for (int participantId : qAsConst(participantIdsInUnit))
|
||||
{
|
||||
const ParticipantManagement::Participant &participant = allParticipants.value(participantId);
|
||||
if (!participant.equipmentNumber().is_set())
|
||||
continue;
|
||||
|
||||
const ParticipantManagement::Type &type = m_ppmDtc->type(participant.typeId());
|
||||
if (type.radioCount() < 1)
|
||||
continue; // participant has no radio equipped
|
||||
|
||||
const auto &pos = m_ppmDtc->participantPosition(participantId);
|
||||
if (pos.participantId() != participantId)
|
||||
continue; // participant has no position
|
||||
|
||||
if (LtsUtils::isPositionTimeOutdated(now, pos.sampleTime()))
|
||||
continue; // position invalid
|
||||
|
||||
positions.push_back({toDeg(pos.pos().lon()), toDeg(pos.pos().lat())});
|
||||
}
|
||||
|
||||
return positions;
|
||||
}
|
||||
|
||||
boost::optional<AudioVideoManagement::FrequencyPlanning> PositionsCnr::activePlan() const
|
||||
{
|
||||
AudioVideoManagement::ActiveFrequencyPlanning activePlanning = m_avmDtc->activeFrequencyPlanning(m_exerciseId);
|
||||
if (activePlanning.exerciseId() != m_exerciseId)
|
||||
return boost::none;
|
||||
return m_avmDtc->frequencyPlanning(activePlanning.frequencyPlanningId());
|
||||
}
|
||||
|
||||
} // namespace CombatNetRadio
|
||||
Reference in new issue
Block a user