#include "ppm_handler.h" #include #include "ngs_handler.h" #include #include #include #include namespace HighLevelArchitecture { PpmHandler::PpmHandler(NgsHandler *ngsHandler) : m_ngsHandler(ngsHandler) , m_requestHelper(new LtsUtils::RequestHelper(this)) {} PpmHandler::~PpmHandler() { m_dtcPpm.reset(); m_ftcPpm.reset(); m_dtcPdm.reset(); m_dtsTab.reset(); m_ftcTab.reset(); m_dtcAes.reset(); } bool PpmHandler::init() { m_dtcPpm = ParticipantManagement::Interface::Dtc::create(m_ngsHandler->ddsHandler()->ddsConnector()); m_ftcPpm = ParticipantManagement::Interface::Ftc::create(m_ngsHandler->ddsHandler()->ddsConnector()); m_dtcPdm = ProjectDataManagement::Interface::Dtc::create(m_ngsHandler->ddsHandler()->ddsConnector()); m_dtsTab = TrainingAreaBase::Interface::Dts::create(m_ngsHandler->ddsHandler()->ddsConnector()); m_ftcTab = TrainingAreaBase::Interface::Ftc::create(m_ngsHandler->ddsHandler()->ddsConnector()); m_dtcAes = AreaEffectSimulation::Interface::Dtc::create(m_ngsHandler->ddsHandler()->ddsConnector()); connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::typeChanged, this, &PpmHandler::onTypeChanged); connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::dynamicParticipantDataChanged, this, &PpmHandler::onDynamicParticipantDataChanged); connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::participantChanged, this, &PpmHandler::onParticipantChanged); connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::participantPositionChanged, this, &PpmHandler::onParticipantPositionChanged); connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::partyChanged, this, &PpmHandler::onPartyChanged); m_dtcPpm->enableType(); m_dtcPpm->enableDynamicParticipantData(); m_dtcPpm->enableParticipant(); m_dtcPpm->enableParticipantPosition(); m_dtcPpm->enableParty(); m_dtcPpm->enableParticipantGearEvent(); m_dtcPdm->enableGearTypeChargeType(); m_dtcPpm->waitForHistoricalDataParticipant(); m_ftcPpm->enableModifyParticipantData(); connect(m_dtcPdm.get(), &ProjectDataManagement::Interface::Dtc::chargeTypeChanged, this, &PpmHandler::onChargeTypeChanged); m_dtcPdm->enableChargeType(); if (!(m_dtsTab->enableEquipmentPosition() && m_dtsTab->enableEquipmentGearEvent() && m_dtsTab->enableEquipmentState() && m_dtsTab->enableLaserDesignation() && m_dtsTab->enableSpecialSensorData() && m_dtsTab->enableGearCharge() && m_dtsTab->enableEquipmentGearChargeState() && m_dtsTab->enableEquipmentGearAssignment()) ) { ERROR_LOG(m_logger) << "Enabling TAB DTS Data-Topics failed."; return false; } m_ftcTab->enableDemandInit(); m_ftcTab->enableDemandVulnerabilityStateChange(); m_ftcTab->enableSendCesHitInformation(); NgsConnector *conn = m_ngsHandler->ngsConnector().get(); connect(conn, &NgsConnector::firstTickFinished, this, &PpmHandler::startPublishToNgs); connect(conn, &NgsConnector::spatialChanged, this, &PpmHandler::onSpatialChanged); connect(conn, &NgsConnector::markingChanged, this, &PpmHandler::onMarkingChanged); connect(conn, &NgsConnector::exconEngagement, this, &PpmHandler::onExconEngagement); connect(conn, &NgsConnector::weaponFire, this, &PpmHandler::onWeaponFire); connect(conn, &NgsConnector::gearChargeState, this, &PpmHandler::onGearChargeState); connect(conn, &NgsConnector::cesHitInformation, this, &PpmHandler::onParticipantCesHit); connect(conn, &NgsConnector::equipmentState, this, &PpmHandler::onEquipmentState); connect(conn, &NgsConnector::laserDesignation, this, &PpmHandler::onLaserDesignation); connect(conn, &NgsConnector::sensorChanged, this, &PpmHandler::onSensorDataChanged); return true; } ParticipantManagement::Role PpmHandler::roleForPartyId(int partyId) { if (partyId <= 0) return ParticipantManagement::Role::Unknown; auto it = m_partyData.constFind(partyId); if (it == m_partyData.constEnd()) { m_dtcPpm->waitForHistoricalDataParty(); m_partyData = m_dtcPpm->partys(); it = m_partyData.constFind(partyId); if (it == m_partyData.constEnd()) return ParticipantManagement::Role::Unknown; } return it.value().role(); } void PpmHandler::onTypeChanged(const ParticipantManagement::Type &data, DataModification modType) { switch (modType) { case DataModification::eAdded: case DataModification::eModified: m_types[data.id()] = data; break; case DataModification::eRemoved: m_types.remove(data.id()); break; } } int PpmHandler::getEquipmentNo(int participantId) const { if (!m_partData.contains(participantId)) return 0; const ParticipantManagement::Participant &p = m_partData[participantId]; if (!p.equipmentNumber().has_value()) return 0; return p.equipmentNumber().get(); } int PpmHandler::getParticipantIdByExternalId(int externalId) const { for(const auto &part : std::as_const(m_partData)) { if (part.externalId() == externalId) return part.id(); } return 0; } void PpmHandler::onDynamicParticipantDataChanged(const ParticipantManagement::DynamicParticipantData &data, DataModification modType) { int equipmentNo = getEquipmentNo(data.participantId()); if (equipmentNo == 0) { ERROR_LOG(m_logger) << "Could not find EquipmentNo for Participant " << data.participantId() << ". Cannot send Dynamic Participant Data Modification to HLA."; return; } switch (modType) { case DataModification::eAdded: case DataModification::eModified: { if (!m_ngsHandler->ngsConnector()->canPublishData()) break; std::shared_ptr conn = m_ngsHandler->ngsConnector(); const ParticipantManagement::StateInformation oldStateInfo = currentParticipantStateInformation(m_dynPartData.value(data.participantId())); const ParticipantManagement::StateInformation newStateInfo = currentParticipantStateInformation(data); if (oldStateInfo != newStateInfo) { m_dynPartData[data.participantId()] = data; if (newStateInfo.originatorType() == ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_AreaEffectSimulation) { conn->setParticipantHit(equipmentNo, newStateInfo, getParticipantPosition(data.participantId()), newStateInfo.originatorChargeTypeId(), newStateInfo.originatorType(), newStateInfo.originatorId()); } else if (newStateInfo.originatorType() == ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_Participant) { conn->setParticipantHit(equipmentNo, newStateInfo, getParticipantPosition(data.participantId()), newStateInfo.originatorChargeTypeId(), newStateInfo.originatorType(), getEquipmentNo(newStateInfo.originatorId())); } else { conn->setParticipantHit(equipmentNo, newStateInfo, getParticipantPosition(data.participantId()), newStateInfo.originatorChargeTypeId(), newStateInfo.originatorType(), newStateInfo.originatorId()); } } break; } case DataModification::eRemoved: m_dynPartData.remove(data.participantId()); break; } } void PpmHandler::onParticipantChanged(const ParticipantManagement::Participant &data, DataModification modType) { DEBUG_LOG(m_logger) << "onParticipantChanged: " << data; switch (modType) { case DataModification::eAdded: createParticipant(data); m_partData[data.id()] = data; break; case DataModification::eModified: { if (data.isDeleted() && !m_partData[data.id()].isDeleted()) { removeParticipant(m_partData[data.id()]); removeParticipant(data); m_partData[data.id()] = data; break; } if (!m_partData.contains(data.id())) { createParticipant(data); m_partData[data.id()] = data; break; } int oldEqNo = m_partData[data.id()].equipmentNumber().has_value() ? m_partData[data.id()].equipmentNumber().get() : 0; int newEqNo = data.equipmentNumber().has_value() ? data.equipmentNumber().get() : 0; if (oldEqNo != newEqNo) { removeParticipant(m_partData[data.id()]); createParticipant(data); } if (m_partData[data.id()].designator() != data.designator() && data.equipmentNumber().has_value()) m_ngsHandler->ngsConnector()->setParticipantName(data.equipmentNumber().get(), QString::fromStdString(data.designator())); m_partData[data.id()] = data; break; } case DataModification::eRemoved: removeParticipant(data); m_partData.remove(data.id()); break; } auto it = m_externalEquipmentNumbers.find(data.id()); if (it == m_externalEquipmentNumbers.end()) { if (modType == DataModification::eRemoved || !data.equipmentNumber().has_value() || data.externalId() <= 0) return; int equipNo = data.equipmentNumber().get(); m_externalEquipmentNumbers.insert(data.id(), equipNo); emit externalEquipmentNumberAdded(equipNo); } else { int oldEquipNo = it.value(); if (modType == DataModification::eRemoved || !data.equipmentNumber().has_value() || data.externalId() <= 0) { m_externalEquipmentNumbers.erase(it); emit externalEquipmentNumberRemoved(oldEquipNo); return; } if (oldEquipNo != data.equipmentNumber().get()) { emit externalEquipmentNumberRemoved(oldEquipNo); emit externalEquipmentNumberAdded(data.equipmentNumber().get()); it.value() = data.equipmentNumber().get(); } } } void PpmHandler::onParticipantPositionChanged(const ParticipantManagement::ParticipantPosition &data, DataModification modType) { DEBUG_LOG(m_logger) << "onParticipantPositionChanged: " << data; switch (modType) { case DataModification::eAdded: case DataModification::eModified: { if (m_ngsHandler->ngsConnector()->canPublishData()) { int eqNo = getEquipmentNo(data.participantId()); if (eqNo == 0) return; ParticipantPosition pos(data.pos(), data.sampleTime()); m_ngsHandler->ngsConnector()->setWorldLocation(eqNo, pos); } m_partPosData[data.participantId()] = data; break; } case DataModification::eRemoved: m_partPosData.remove(data.participantId()); break; } } void PpmHandler::onSpatialChanged(int eqId, const ParticipantPosition &pos, qint64 simTimeMSecs) { TrainingAreaBase::EquipmentPosition &position = m_observerPositions[eqId]; position.position().position() = pos.toGeoPosition(); position.equipmentNumber(eqId); position.sampleTime(simTimeMSecs); m_dtsTab->publish(position); } void PpmHandler::onSensorDataChanged(const TrainingAreaBase::SpecialSensorData &event) { m_dtsTab->publish(event); } bool PpmHandler::onMarkingChanged(int eqId, const QString &marking, qint64 simTimeMSecs) { Q_UNUSED(simTimeMSecs); ParticipantManagement::ParticipantData p = m_dtcPpm->convertParticipantToParticipantData(m_dtcPpm->participant(m_dtcPpm->participantIdByEquipmentNumber(eqId))); if (p.tacticalIdentifier() == marking.toStdString()) return true; p.tacticalIdentifier(marking.toStdString()); ParticipantManagement::ModifyParticipantDataRequest req; req.data().push_back(std::move(p)); return m_requestHelper->startSingleRequest([this, req]() { return m_ftcPpm->modifyParticipantDataRequest(req, this); }); } void PpmHandler::onPartyChanged(const ParticipantManagement::Party &data, DataModification modType) { switch (modType) { case DataModification::eAdded: case DataModification::eModified: m_partyData[data.id()] = data; break; case DataModification::eRemoved: m_partyData.remove(data.id()); break; } } void PpmHandler::onChargeTypeChanged(const ProjectDataManagement::ChargeType &data, DataModification modType) { switch (modType) { case DataModification::eAdded: case DataModification::eModified: m_chargeTypes[data.id()] = data; break; case DataModification::eRemoved: m_chargeTypes.remove(data.id()); break; } } void PpmHandler::startPublishToNgs() { INFO_LOG(m_logger) << "Recreating all players from scratch due to structure / exercise change"; m_createdParticipantIds.clear(); INFO_LOG(m_logger) << "(Re)Adding all players, size: " << m_partData.size(); for (const ParticipantManagement::Participant &participant : std::as_const(m_partData)) createParticipant(participant); } void PpmHandler::participantInitRequest(const TrainingAreaBase::TetraIcd::Init &request) { m_ngsHandler->ngsConnector()->sendParticipantInitRequest(request.header.equipmentNumber, request.resetManipulation, request.resetVulnerabilityState, request.restockCharges, request.header.timeStamp); } rpr2::DetonationResultCodeEnum8::ET PpmHandler::rpr2DetonationResultFromVulnerabilityState(TrainingAreaBase::TetraIcd::VulnerabilityState vulnerabilityState) { rpr2::DetonationResultCodeEnum8::ET status = rpr2::DetonationResultCodeEnum8::None; switch(vulnerabilityState) { case TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityState_CombatReady: status = rpr2::DetonationResultCodeEnum8::None; break; case TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityState_LightDamage: case TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityState_MediumDamage: case TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityState_HeavyDamage: case TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityState_MobilityKill: case TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityState_VisibleMobilityKill: case TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityState_WeaponSystemDamage: case TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityState_VisibleWeaponSystemDamage: status = rpr2::DetonationResultCodeEnum8::AirHit; break; case TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityState_CatastrophicKill: status = rpr2::DetonationResultCodeEnum8::EntityImpact; break; case TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityState_TemporarySeverance: case TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityState_NearMiss: case TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityState_HitWithNoEffect: status = rpr2::DetonationResultCodeEnum8::EntityProximateDetonation; break; case TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityState_VulnerabilityBitsChanged: case TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityState_Reserved: case TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityState_NContamination: case TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityState_BContamination: case TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityState_CContamination: status = rpr2::DetonationResultCodeEnum8::Other; break; } return status; } rpr2::DetonationResultCodeEnum8::ET PpmHandler::rpr2DetonationResultFromPercentage(int percentage) { rpr2::DetonationResultCodeEnum8::ET status = rpr2::DetonationResultCodeEnum8::EntityProximateDetonation; if (percentage > 0) status = rpr2::DetonationResultCodeEnum8::AirHit; if (percentage > 50) status = rpr2::DetonationResultCodeEnum8::EntityImpact; return status; } void PpmHandler::participantVulnerabilityStateRequest(const TrainingAreaBase::TetraIcd::DemandVulnerabilityStateChange &request) { DEBUG_LOG(m_logger) << "Participant Vulnerability State Request"; rpr2::DetonationResultCodeEnum8::ET resCode = rpr2DetonationResultFromVulnerabilityState(request.reqestedState); m_ngsHandler->ngsConnector()->sendMunitionDetonation(request.header.equipmentNumber, ProjectDataManagement::ChargeType(), 0, resCode, request.header.timeStamp); } void PpmHandler::participantCesHitInformationRequest(const TrainingAreaBase::TetraIcd::CesHitInformation &request) { rpr2::DetonationResultCodeEnum8::ET resCode = rpr2DetonationResultFromPercentage(request.effectPercent); ProjectDataManagement::ChargeType ct = chargeTypeFromTasCodeDirect(request.chargeTasCodeDirect); m_ngsHandler->ngsConnector()->sendMunitionDetonation(request.header.equipmentNumber, ct, request.originatorEquipmentNumber, resCode, request.header.timeStamp); } void PpmHandler::createParticipant(const ParticipantManagement::Participant &participant) { if (participant.externalId() > 0 || participant.equipmentNumber() == 0 || participant.isDeleted()) return; if (!m_ngsHandler->ngsConnector()->canPublishData()) { WARNING_LOG(m_logger) << "Can not publish data ... :("; return; } if (m_createdParticipantIds.contains(participant.id())) return; const ParticipantManagement::Type partType = getParticipantType(participant.typeId()); bool bCreated; switch (partType.typeClass()) { case ParticipantManagement::TypeClass::Human: bCreated = createHuman(participant); break; case ParticipantManagement::TypeClass::GroundVehicle: case ParticipantManagement::TypeClass::VehicleWithGear: case ParticipantManagement::TypeClass::WeaponSystem: bCreated = createGroundVehicle(participant); break; case ParticipantManagement::TypeClass::Aircraft: bCreated = createAircraft(participant); break; case ParticipantManagement::TypeClass::SupportEntity: case ParticipantManagement::TypeClass::Unit: case ParticipantManagement::TypeClass::Vessel: default: bCreated = false; } if (!bCreated) return; m_createdParticipantIds += participant.id(); } bool PpmHandler::removeParticipant(const ParticipantManagement::Participant &participant) { if (!participant.equipmentNumber().has_value() || participant.equipmentNumber().get() == 0) return false; return m_ngsHandler->ngsConnector()->removeBaseEntity(participant.equipmentNumber().get()); } bool PpmHandler::createHuman(const ParticipantManagement::Participant &participant) { const ParticipantInformation pi(participant, getTypestruct(participant.typeId()), getParticipantPosition(participant.id())); return m_ngsHandler->ngsConnector()->addHuman(pi, currentVulnerabilityState(participant.id())); } bool PpmHandler::createGroundVehicle(const ParticipantManagement::Participant &participant) { const ParticipantInformation pi(participant, getTypestruct(participant.typeId()), getParticipantPosition(participant.id())); return m_ngsHandler->ngsConnector()->addGroundVehicle(pi, currentVulnerabilityState(participant.id())); } bool PpmHandler::createAircraft(const ParticipantManagement::Participant &participant) { const ParticipantInformation pi(participant, getTypestruct(participant.typeId()), getParticipantPosition(participant.id())); return m_ngsHandler->ngsConnector()->addLongBowApache(pi, currentVulnerabilityState(participant.id())); } TypeStruct PpmHandler::getTypestruct(int typeId) { dds::core::vector disEntities = getParticipantType(typeId).disEntities(); if (disEntities.size()) return TypeStruct::fromDisInt(disEntities.at(0)); return TypeStruct(); } ParticipantManagement::Type PpmHandler::getParticipantType(int typeId) { auto it = m_types.constFind(typeId); if (it == m_types.constEnd()) { m_dtcPpm->waitForHistoricalDataType(); m_types = m_dtcPpm->types(); it = m_types.constFind(typeId); if (it == m_types.constEnd()) return ParticipantManagement::Type(); } return it.value(); } ProjectDataManagement::VulnerabilityState PpmHandler::currentVulnerabilityState(int participantId) const { ProjectDataManagement::VulnerabilityState ts; auto itPartData = m_dynPartData.find(participantId); if (itPartData != m_dynPartData.end()) { const auto &sh = itPartData.value().stateHistory(); if (sh.size() != 0) { size_t idxCurrent = 0; for (size_t i = 1; i < sh.size(); ++i) { if (sh.at(idxCurrent).stateTime() < sh.at(i).stateTime()) idxCurrent = i; } ts = sh.at(idxCurrent).vulnerabilityState(); return ts; } } ts = ProjectDataManagement::VulnerabilityState::VulnerabilityState_TemporarySeverance; return ts; } ParticipantManagement::StateInformation PpmHandler::currentParticipantStateInformation(int participantId) const { auto itPartData = m_dynPartData.find(participantId); if (itPartData != m_dynPartData.end()) return currentParticipantStateInformation(itPartData.value()); return ParticipantManagement::StateInformation(); } ParticipantManagement::StateInformation PpmHandler::currentParticipantStateInformation(const ParticipantManagement::DynamicParticipantData &data) { const auto &sh = data.stateHistory(); if (sh.size() == 0) return ParticipantManagement::StateInformation(); size_t idxCurrent = 0; for (size_t i = 1; i < sh.size(); ++i) { if (sh.at(idxCurrent).stateTime() < sh.at(i).stateTime()) idxCurrent = i; } return sh.at(idxCurrent); } dds::core::vector PpmHandler::currentParticipantGearInformation(int participantId) const { auto itPartData = m_dynPartData.find(participantId); if (itPartData != m_dynPartData.end()) return itPartData.value().gear(); return dds::core::vector(); } dds::core::vector PpmHandler::currentParticipantManipulationInformation(int participantId) const { auto itPartData = m_dynPartData.find(participantId); if (itPartData != m_dynPartData.end()) return itPartData.value().manipulation(); return dds::core::vector(); } ProjectDataManagement::ChargeType PpmHandler::chargeTypeFromId(int chargeTypeId) { auto it = m_chargeTypes.constFind(chargeTypeId); if (it == m_chargeTypes.constEnd() && m_dtcPdm) { m_dtcPdm->waitForHistoricalDataChargeType(); m_chargeTypes = m_dtcPdm->chargeTypes(); it = m_chargeTypes.constFind(chargeTypeId); } return (it == m_chargeTypes.constEnd()) ? ProjectDataManagement::ChargeType() : it.value(); } ProjectDataManagement::ChargeType PpmHandler::chargeTypeFromDisEntity(const std::string &disEntity) { if (m_chargeTypes.isEmpty() && m_dtcPdm) { m_dtcPdm->waitForHistoricalDataChargeType(); m_chargeTypes = m_dtcPdm->chargeTypes(); } for (const auto &item : std::as_const(m_chargeTypes)) { if (item.disEntity() == disEntity) return item; } return ProjectDataManagement::ChargeType(); } ProjectDataManagement::ChargeType PpmHandler::chargeTypeFromTasCodeDirect(int32_t tasCode) { if (m_chargeTypes.isEmpty() && m_dtcPdm) { m_dtcPdm->waitForHistoricalDataChargeType(); m_chargeTypes = m_dtcPdm->chargeTypes(); } for (const auto &item : std::as_const(m_chargeTypes)) { if (item.legacyId() == tasCode) return item; } return ProjectDataManagement::ChargeType(); } int PpmHandler::gearTypeIdFromChargeTypeId(int chargeTypeId) { if (m_gearTypeChargeTypes.isEmpty() && m_dtcPdm) { m_dtcPdm->waitForHistoricalDataGearTypeChargeType(); m_gearTypeChargeTypes = m_dtcPdm->gearTypeChargeTypes(); } int gearTypeId = 999999999; for (const auto &item : std::as_const(m_gearTypeChargeTypes)) { if (item.chargeTypeId() == chargeTypeId) if (item.gearTypeId() < gearTypeId) gearTypeId = item.gearTypeId(); } if (gearTypeId == 999999999) return 0; return gearTypeId; } rpr2::ForceIdentifierEnum8::ET PpmHandler::getRprForceIdentifierFromPpmForceIdentifier(const ParticipantManagement::HlaForceIdentifierEnum& ppmForceIdentifier) const { rpr2::ForceIdentifierEnum8::ET eqfi = rpr2::ForceIdentifierEnum8::Other; switch (ppmForceIdentifier) { case ParticipantManagement::HlaForceIdentifierEnum::Friendly_1: eqfi = rpr2::ForceIdentifierEnum8::Friendly; break; case ParticipantManagement::HlaForceIdentifierEnum::Friendly_2: eqfi = rpr2::ForceIdentifierEnum8::Friendly_2; break; case ParticipantManagement::HlaForceIdentifierEnum::Friendly_3: eqfi = rpr2::ForceIdentifierEnum8::Friendly_3; break; case ParticipantManagement::HlaForceIdentifierEnum::Friendly_4: eqfi = rpr2::ForceIdentifierEnum8::Friendly_4; break; case ParticipantManagement::HlaForceIdentifierEnum::Friendly_5: eqfi = rpr2::ForceIdentifierEnum8::Friendly_5; break; case ParticipantManagement::HlaForceIdentifierEnum::Friendly_6: eqfi = rpr2::ForceIdentifierEnum8::Friendly_6; break; case ParticipantManagement::HlaForceIdentifierEnum::Friendly_7: eqfi = rpr2::ForceIdentifierEnum8::Friendly_7; break; case ParticipantManagement::HlaForceIdentifierEnum::Friendly_8: eqfi = rpr2::ForceIdentifierEnum8::Friendly_8; break; case ParticipantManagement::HlaForceIdentifierEnum::Friendly_9: eqfi = rpr2::ForceIdentifierEnum8::Friendly_9; break; case ParticipantManagement::HlaForceIdentifierEnum::Friendly_10: eqfi = rpr2::ForceIdentifierEnum8::Friendly_10; break; case ParticipantManagement::HlaForceIdentifierEnum::Opposing_1: eqfi = rpr2::ForceIdentifierEnum8::Opposing; break; case ParticipantManagement::HlaForceIdentifierEnum::Opposing_2: eqfi = rpr2::ForceIdentifierEnum8::Opposing_2; break; case ParticipantManagement::HlaForceIdentifierEnum::Opposing_3: eqfi = rpr2::ForceIdentifierEnum8::Opposing_3; break; case ParticipantManagement::HlaForceIdentifierEnum::Opposing_4: eqfi = rpr2::ForceIdentifierEnum8::Opposing_4; break; case ParticipantManagement::HlaForceIdentifierEnum::Opposing_5: eqfi = rpr2::ForceIdentifierEnum8::Opposing_5; break; case ParticipantManagement::HlaForceIdentifierEnum::Opposing_6: eqfi = rpr2::ForceIdentifierEnum8::Opposing_6; break; case ParticipantManagement::HlaForceIdentifierEnum::Opposing_7: eqfi = rpr2::ForceIdentifierEnum8::Opposing_7; break; case ParticipantManagement::HlaForceIdentifierEnum::Opposing_8: eqfi = rpr2::ForceIdentifierEnum8::Opposing_8; break; case ParticipantManagement::HlaForceIdentifierEnum::Opposing_9: eqfi = rpr2::ForceIdentifierEnum8::Opposing_9; break; case ParticipantManagement::HlaForceIdentifierEnum::Opposing_10: eqfi = rpr2::ForceIdentifierEnum8::Opposing_10; break; case ParticipantManagement::HlaForceIdentifierEnum::Neutral_1: eqfi = rpr2::ForceIdentifierEnum8::Neutral; break; case ParticipantManagement::HlaForceIdentifierEnum::Neutral_2: eqfi = rpr2::ForceIdentifierEnum8::Neutral_2; break; case ParticipantManagement::HlaForceIdentifierEnum::Neutral_3: eqfi = rpr2::ForceIdentifierEnum8::Neutral_3; break; case ParticipantManagement::HlaForceIdentifierEnum::Neutral_4: eqfi = rpr2::ForceIdentifierEnum8::Neutral_4; break; case ParticipantManagement::HlaForceIdentifierEnum::Neutral_5: eqfi = rpr2::ForceIdentifierEnum8::Neutral_5; break; case ParticipantManagement::HlaForceIdentifierEnum::Neutral_6: eqfi = rpr2::ForceIdentifierEnum8::Neutral_6; break; case ParticipantManagement::HlaForceIdentifierEnum::Neutral_7: eqfi = rpr2::ForceIdentifierEnum8::Neutral_7; break; case ParticipantManagement::HlaForceIdentifierEnum::Neutral_8: eqfi = rpr2::ForceIdentifierEnum8::Neutral_8; break; case ParticipantManagement::HlaForceIdentifierEnum::Neutral_9: eqfi = rpr2::ForceIdentifierEnum8::Neutral_9; break; case ParticipantManagement::HlaForceIdentifierEnum::Neutral_10: eqfi = rpr2::ForceIdentifierEnum8::Neutral_10; break; case ParticipantManagement::HlaForceIdentifierEnum::Other: eqfi = rpr2::ForceIdentifierEnum8::Other; break; } return eqfi; } int PpmHandler::partyIdFromForceIdentifier(rpr2::ForceIdentifierEnum8::ET fi) { if (m_partyData.isEmpty() && m_dtcPpm) { m_dtcPpm->waitForHistoricalDataParty(); m_partyData = m_dtcPpm->partys(); } for (const ParticipantManagement::Party &item : std::as_const(m_partyData)) { if (fi == getRprForceIdentifierFromPpmForceIdentifier(item.hlaForceIdentifier())) return item.id(); } return -1; } rpr2::ForceIdentifierEnum8::ET PpmHandler::forceIdentifierFromPartyId(int partyId) { if (m_partyData.isEmpty() && m_dtcPpm) { m_dtcPpm->waitForHistoricalDataParty(); m_partyData = m_dtcPpm->partys(); } if (!m_partyData.contains(partyId)) return rpr2::ForceIdentifierEnum8::Other; return getRprForceIdentifierFromPpmForceIdentifier(m_partyData[partyId].hlaForceIdentifier()); } void PpmHandler::onModifyParticipantDataReply(const Core::FunctionReplyObject &replyObject) { m_requestHelper->requestReply(replyObject); } void PpmHandler::onDemandInitReply(const Core::FunctionReplyObject &reply) { m_requestHelper->requestReply(reply); } void PpmHandler::onDemandVulnerabilityStateChangeReply(const Core::FunctionReplyObject &reply) { m_requestHelper->requestReply(reply); } void PpmHandler::onSendCesHitInformationReply(const Core::FunctionReplyObject &reply) { m_requestHelper->requestReply(reply); } ParticipantPosition PpmHandler::getParticipantPosition(int participantId) const { auto itPartPos = m_partPosData.find(participantId); if (itPartPos == m_partPosData.end()) return ParticipantPosition(); ParticipantPosition pp(itPartPos.value().pos()); pp.msec = itPartPos.value().sampleTime(); return pp; } void PpmHandler::onParticipantHit(const GuezHitStruct &hitStruct) { const auto ct = chargeTypeFromDisEntity(hitStruct.originatorChargeTypeEtsString.toStdString()); TrainingAreaBase::TabPosition pos; pos.position(hitStruct.position); pos.reportingSource(Core::PositionReportingSource::External); TrainingAreaBase::EquipmentState es; es.equipmentNumber(hitStruct.targetId); es.originatorChargeTypeId(ct.id()); if (hitStruct.originatorType == ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_AreaEffectSimulation) { int aesItemId = 0; if (m_dtcAes->aesItemIdFromExternalId(hitStruct.originatorId, aesItemId) == AreaEffectSimulation::AesType::AtUnknown) es.originatorId(hitStruct.originatorId % 10); else es.originatorId(aesItemId); } else { es.originatorId(hitStruct.originatorId); } es.originatorType(hitStruct.originatorType); es.sampleTime(hitStruct.sampleTime); es.vulnerabilityBits(hitStruct.vulnerabilityBits); es.vulnerabilityKindId(hitStruct.vulnerabilityKind); es.vulnerabilityState(hitStruct.vulnerabilityState); if (!qIsNull(hitStruct.position.lat()) || !qIsNull(hitStruct.position.lon())) es.position(pos); m_dtsTab->publish(es); } void PpmHandler::onParticipantInit(int eqNo, bool resetManipulation, bool resupplyAmmo, bool resetVulnerabilityState) { TrainingAreaBase::DemandInitRequest dir; dir.equipmentNumbers().push_back(eqNo); dir.requestId(1); dir.resetManipulation(resetManipulation); dir.restockCharges(resupplyAmmo); dir.resetVulnerabilityState(resetVulnerabilityState); m_requestHelper->startSingleRequest([this, dir]() { return m_ftcTab->demandInitRequest(dir, this); }); } void PpmHandler::onParticipantCesHit(const TrainingAreaBase::SendCesHitInformation &request) { m_ftcTab->sendCesHitInformationRequest(request, this); } void PpmHandler::onLaserDesignation(const TrainingAreaBase::LaserDesignation &request) { m_dtsTab->publish(request); } void PpmHandler::onWeaponFire(const TrainingAreaBase::EquipmentGearEvent &event) { m_dtsTab->publish(event); } void PpmHandler::onGearChargeState(const TrainingAreaBase::EquipmentGearChargeState &event) { m_dtsTab->publish(event); } void PpmHandler::onGearAssignment(const TrainingAreaBase::EquipmentGearAssignment &event) { m_dtsTab->publish(event); } void PpmHandler::onEquipmentState(const TrainingAreaBase::EquipmentState &event) { m_dtsTab->publish(event); } bool PpmHandler::onExconEngagement(int eqNo, const ProjectDataManagement::VulnerabilityState &state) { if (state != ProjectDataManagement::VulnerabilityState::VulnerabilityState_CombatReady) { TrainingAreaBase::DemandVulnerabilityStateChangeRequest req; req.equipmentNumbers().push_back(eqNo); req.requestId(1); req.vulnerabilityState(state); return m_requestHelper->startSingleRequest([this, req]() { return m_ftcTab->demandVulnerabilityStateChangeRequest(req, this); }); } TrainingAreaBase::DemandInitRequest req; req.equipmentNumbers().push_back(eqNo); req.resetVulnerabilityState(true); return m_requestHelper->startSingleRequest([this, req]() { return m_ftcTab->demandInitRequest(req, this); }); } }