/** * Convert internal gear and charge id to and from tas ids * $Id$ * $HeadURL$ * $Author$ * Created by Christian Ehrlicher, SLSE, 2016-04-14 */ #include "pdm_handler.h" #include "main_handler.h" #include namespace TrainingAreaBase { PdmHandler::PdmHandler(MainHandler *mainHandler) : m_initialized(false) , m_mainHandler(mainHandler) , m_logger(getLogger("PdmHandler")) {} bool PdmHandler::init() { m_dtcPdm = ProjectDataManagement::Interface::Dtc::create(m_mainHandler->ddsHandler()->ddsConnector()); if (!m_dtcPdm->enableIgniterType() || !m_dtcPdm->enableIgniterFunction() || !m_dtcPdm->enableLoadType() || !m_dtcPdm->enableChargeType() || !m_dtcPdm->enableGearType() || !m_dtcPdm->enableGearTypeChargeType() || !m_dtcPdm->enableChargeTypeIgniterTypeIgniterFunction() || !m_dtcPdm->enableChargeTypeLoadType() || !m_dtcPdm->enableTargetSubType() || !m_dtcPdm->enableTargetType() || !m_dtcPdm->enableTargetTypeTargetSubType() || !m_dtcPdm->enableRadioGroup() || !m_dtcPdm->enableBuildingChargeEffect() || !m_dtcPdm->enableVulnerabilityKind()) return false; return true; } bool PdmHandler::initializePdm() { //if (m_initialized == true) // return true; if (!m_dtcPdm->waitForHistoricalDataChargeType(20000) || !m_dtcPdm->waitForHistoricalDataGearType(20000) || !m_dtcPdm->waitForHistoricalDataGearTypeChargeType(20000) || !m_dtcPdm->waitForHistoricalDataIgniterType(20000) || !m_dtcPdm->waitForHistoricalDataIgniterFunction(20000) || !m_dtcPdm->waitForHistoricalDataLoadType(20000) || !m_dtcPdm->waitForHistoricalDataChargeTypeIgniterTypeIgniterFunction(20000) || !m_dtcPdm->waitForHistoricalDataChargeTypeLoadType(20000) || !m_dtcPdm->waitForHistoricalDataTargetType(20000) || !m_dtcPdm->waitForHistoricalDataTargetSubType(20000) || !m_dtcPdm->waitForHistoricalDataTargetTypeTargetSubType(20000) || !m_dtcPdm->waitForHistoricalDataRadioGroup(20000) || !m_dtcPdm->waitForHistoricalDataBuildingChargeEffect(20000) || !m_dtcPdm->waitForHistoricalDataVulnerabilityKind(20000)) // 20s { ERROR_LOG(m_logger) << "Can not read charge/gear types from PDM"; return false; } m_chargeTypes = m_dtcPdm->chargeTypes(); m_gearTypes = m_dtcPdm->gearTypes(); m_gearTypeChargeTypes = m_dtcPdm->gearTypeChargeTypes(); m_radioGroups = m_dtcPdm->radioGroups(); m_buildingChargeEffects = m_dtcPdm->buildingChargeEffects(); auto cbTasVulKind = [this](const ProjectDataManagement::VulnerabilityKind &k) { const int realTasKindId = k.taVulnerabilityKind() & 0x00FFFFFF; const int realTypeId = (k.taVulnerabilityKind() & 0x00FF0000) >> 16; const int fallbackTypeId = (k.taVulnerabilityKind() & 0xFF000000) >> 24; m_vulnerabilityKinds[realTasKindId] = k; TRACE_LOG(m_logger) << "realTasKindId: " << realTasKindId << ", realTypeId: " << realTypeId << ", fallbackTypeId: " << fallbackTypeId; if (fallbackTypeId) m_vulnerabilityKindFallback[realTypeId] = fallbackTypeId; }; m_dtcPdm->vulnerabilityKinds(cbTasVulKind); m_initialized = true; return true; } ProjectDataManagement::ChargeType PdmHandler::chargeTypeFromId(int chargeTypeId) { if (chargeTypeId <= 0) return ProjectDataManagement::ChargeType(); initializePdm(); int ctId = m_dtcPdm->getAvailableChargeTypeId(chargeTypeId); auto it = m_chargeTypes.constFind(ctId); if (it == m_chargeTypes.cend()) { WARNING_LOG(m_logger) << "Could not find charge type with id " << chargeTypeId; return ProjectDataManagement::ChargeType(); } return it.value(); } ProjectDataManagement::GearClass PdmHandler::gearClassFromChargeTypeId(int chargeTypeId) { if (chargeTypeId <= 0) return ProjectDataManagement::GearClass::Unknown; initializePdm(); for (const auto &gearType2ChargeType : qAsConst(m_gearTypeChargeTypes)) { if (gearType2ChargeType.chargeTypeId() == chargeTypeId) { const auto gearType = m_gearTypes.value(gearType2ChargeType.gearTypeId()); return gearType.gearClassId(); } } return ProjectDataManagement::GearClass::Unknown; } ProjectDataManagement::RadioGroup PdmHandler::radioGroup(int radioGroupId) { if (radioGroupId < 0) return ProjectDataManagement::RadioGroup(); initializePdm(); return m_radioGroups.value(radioGroupId); } ProjectDataManagement::BuildingChargeEffect PdmHandler::buildingChargeEffect(int chargeTypeId) { if (chargeTypeId < 0) return {}; initializePdm(); for (const auto &bce : qAsConst(m_buildingChargeEffects)) { if (bce.chargeTypeId() == chargeTypeId) return bce; } return {}; } int PdmHandler::vulnerabilityKindId(int tasVulnerabilityKindId, int equipmentNumber) { if (tasVulnerabilityKindId == 0 || m_vulnerabilityKinds.isEmpty()) return tasVulnerabilityKindId; initializePdm(); auto it = m_vulnerabilityKinds.constFind(tasVulnerabilityKindId); if (it == m_vulnerabilityKinds.constEnd()) { const int typeId = (tasVulnerabilityKindId & 0x00FF0000) >> 16; const int index = (tasVulnerabilityKindId & 0x0000FFFF); int fallBackTypeId = m_vulnerabilityKindFallback.value(typeId); TRACE_LOG(m_logger) << "Looking for fallback for typeId " << typeId << ": " << fallBackTypeId; if (!fallBackTypeId) { fallBackTypeId = m_vulnerabilityKindFallback.value(0); // fallback to default values TRACE_LOG(m_logger) << "None found - using default: " << fallBackTypeId; } tasVulnerabilityKindId = (fallBackTypeId << 16) | index; TRACE_LOG(m_logger) << "Searching for " << tasVulnerabilityKindId; it = m_vulnerabilityKinds.constFind(tasVulnerabilityKindId); if (it == m_vulnerabilityKinds.constEnd()) { WARNING_LOG(m_logger) << "Could not find vulnerability type with id " << typeId << " and index " << index << " for equipment " << equipmentNumber; return tasVulnerabilityKindId; } DEBUG_LOG(m_logger) << "vulnerability type with id " << typeId << " and index " << index << " is using fallback typeId " << fallBackTypeId; } return it.value().taVulnerabilityKind(); } QMap PdmHandler::radioGroups() { initializePdm(); return m_radioGroups; } //ProjectDataManagement::ChargeType PdmHandler::chargeTypeFromChargeTasCode(int chargeTasCode, bool directCharge) //{ // if (chargeTasCode <= 0) // return ProjectDataManagement::ChargeType(); // initializePdm(); // for (const auto &chargeType : qAsConst(m_chargeTypes)) // { // const int comp = (directCharge ? chargeType.tasCodeDirect() : chargeType.tasCodeIndirect()); // if (comp == chargeTasCode) // return chargeType; // } // WARNING_LOG(m_logger) << "Got unmapped training area charge type id " // << chargeTasCode << " - is direct charge: " // << directCharge; // return ProjectDataManagement::ChargeType(); //} static const int s_unknownMarker = 0x80000000; int PdmHandler::chargeTypeIdFromGearAndChargeTasCode(int gearTasCode, int chargeTasCode) { if (chargeTasCode < 0) return (s_unknownMarker | chargeTasCode); // set highest bit and use ta id for debugging purposes if (chargeTasCode == 0) return 0; // no charge given initializePdm(); if (gearTasCode > 0 && (gearTasCode & s_unknownMarker) == 0) { for (const auto &gearType2ChargeType : qAsConst(m_gearTypeChargeTypes)) { if (gearType2ChargeType.gearTypeId() == gearTasCode) { const auto chargeType = m_chargeTypes.value(gearType2ChargeType.chargeTypeId()); if (chargeType.id() == chargeTasCode) return chargeType.id(); } } } // not found - fallback for unmapped gears <-> charges - simply check chargeTasCode if (m_chargeTypes.contains(chargeTasCode)) return chargeTasCode; WARNING_LOG(m_logger) << "Got unmapped training area charge type id " << chargeTasCode << " for gear type " << gearTasCode; return (s_unknownMarker | chargeTasCode); // set highest bit and use ta id for debugging purposes } int PdmHandler::gearTypeIdFromTasGearTasCode(int gearTasCode) { if (gearTasCode < 0) return (s_unknownMarker | gearTasCode); // set highest bit and use ta id for debugging purposes if (gearTasCode == 0) return 0; // no gear given initializePdm(); for (const auto &gearType : qAsConst(m_gearTypes)) { if (gearType.tasCode() == gearTasCode) return gearType.id(); } WARNING_LOG(m_logger) << "Got unmapped training area gear type id " << gearTasCode; return (s_unknownMarker | gearTasCode); // set highest bit and use ta id for debugging purposes } int PdmHandler::legacyChargeTypeIgniterType(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return m_dtcPdm->getChargeTypeIgniterTypeIgniterFunction(chargeTypeId, igniterTypeId, igniterFunctionId).chargeLegacyId(); } double PdmHandler::impactRadius(const AreaEffectSimulation::ChargeStruct &chargeStruct) const { return m_dtcPdm->impactRadius(chargeStruct.chargeTypeId(), chargeStruct.igniterTypeId(), chargeStruct.igniterFunctionId()); } double PdmHandler::impactEdgeLength(const AreaEffectSimulation::ChargeStruct &chargeStruct) const { return m_dtcPdm->impactEdgeLength(chargeStruct.chargeTypeId(), chargeStruct.igniterTypeId(), chargeStruct.igniterFunctionId()); } bool PdmHandler::isSmartChargeType(const AreaEffectSimulation::ChargeStruct &chargeStruct) const { return m_dtcPdm->isSmart(chargeStruct.chargeTypeId(), chargeStruct.igniterTypeId(), chargeStruct.igniterFunctionId()); } bool PdmHandler::isIedChargeType(const AreaEffectSimulation::ChargeStruct &chargeStruct) const { return m_dtcPdm->isIed(chargeStruct.chargeTypeId(), chargeStruct.igniterTypeId(), chargeStruct.igniterFunctionId()); } bool PdmHandler::isReactivatableChargeType(const AreaEffectSimulation::ChargeStruct &chargeStruct) const { return m_dtcPdm->isReactivatable(chargeStruct.chargeTypeId(), chargeStruct.igniterTypeId(), chargeStruct.igniterFunctionId()); } bool PdmHandler::isIndirect(int chargeTypeId) const { return m_dtcPdm->isIndirect(chargeTypeId); } int PdmHandler::hazardDistance(const AreaEffectSimulation::ChargeStruct &chargeStruct) const { return m_dtcPdm->hazardDistance(chargeStruct.chargeTypeId(), chargeStruct.igniterTypeId(), chargeStruct.igniterFunctionId()); } bool PdmHandler::isLaserGuidable(const AreaEffectSimulation::ChargeStruct &chargeStruct) const { return m_dtcPdm->isLaserGuidable(chargeStruct.chargeTypeId(), chargeStruct.igniterTypeId(), chargeStruct.igniterFunctionId()); } bool PdmHandler::isUasDroppable(const AreaEffectSimulation::ChargeStruct &chargeStruct) const { return m_dtcPdm->isUasDroppable(chargeStruct.chargeTypeId(), chargeStruct.igniterTypeId(), chargeStruct.igniterFunctionId()); } } // namespace TrainingAreaBase