new_docker_build.sh gains Group 12 (212 GUI/Data plugins); fixes LtsUtilsGuiDds visibility (LTO-stripped exports), LtsProjectionWorkstation unity name shadow, 6 unity-off dirs (dup file-scope statics, ddsftc INTERFACE sources) and reconfigures BUILD_FILTERMANAGEMENT/BUILD_PLUGINS_SERVICEMONITOR=ON
1402 lines
49 KiB
C++
Executable File
1402 lines
49 KiB
C++
Executable File
|
|
|
|
|
|
#include "send_to_dds.h"
|
|
#include <utility>
|
|
#include "main_handler.h"
|
|
#include "settings.h"
|
|
#include <DDS/DTS/generic_dts.h>
|
|
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
|
|
#include <QtCore/QTimer>
|
|
|
|
namespace TrainingAreaBase
|
|
{
|
|
static constexpr const int s_PartyIdOffset = 1;
|
|
|
|
SendToDds::SendToDds(MainHandler *mainHandler)
|
|
: m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger())
|
|
, m_mainHandler(mainHandler)
|
|
, m_dtsTab(mainHandler->ddsHandler()->dtsTab())
|
|
, m_aesStateHandler(m_mainHandler->aesHandler() ? mainHandler->aesHandler()->aesStateHandler() : nullptr)
|
|
, m_aesHandler(m_mainHandler->aesHandler())
|
|
, m_posHandler(mainHandler->posHandler())
|
|
{}
|
|
|
|
template<typename S, typename T>
|
|
static inline void assignBase(const S &src, T &dest)
|
|
{
|
|
dest.equipmentNumber = src.header.equipmentNumber;
|
|
dest.sampleTime = src.header.timeStamp;
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::ManipulationReport &inData)
|
|
{
|
|
TrainingAreaBase::EquipmentOperationalState outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
outData.isManipulation = inData.isManipulation;
|
|
outData.equipmentFunctionId = inData.equipmentFunctionId;
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::EquipmentOperationalState &inData)
|
|
{
|
|
TrainingAreaBase::EquipmentOperationalState outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
outData.nbcProtectionActive = inData.nbcProtectionActive;
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::EquipmentConfigurationReport &inData)
|
|
{
|
|
TrainingAreaBase::EquipmentConfigurationReport outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
outData.equipmentNumber = inData.equipmentNumber;
|
|
outData.canStartupTime = inData.canStartUpTime;
|
|
outData.equipmentType = inData.equipmentType;
|
|
|
|
outData.loginWaittimeBitweenTrys = inData.loginWaittimeBitweenTrys;
|
|
outData.loginMaxRetryCount = inData.loginMaxRetryCnt;
|
|
outData.loginMasteringFlag = inData.loginMasteringFlag;
|
|
|
|
outData.canDeviceConfiguration = inData.canDeviceConfiguration;
|
|
|
|
outData.displayDeviceVoiceOutput = inData.displayDeviceVoiceOutput;
|
|
outData.displayDeviceLanguage = static_cast<ProjectDataManagement::LanguageConfiguration>(inData.displayDeviceLanguage);
|
|
|
|
outData.pyrotechnics = inData.pyrotechnics;
|
|
|
|
outData.mineHandgrenadeSensorMode = static_cast<TrainingAreaBase::MineHandgrenadeSensorMode>(inData.mhgrsMode);
|
|
outData.mineHandgrenadeSensorEnergySaving = inData.mhgrsEnergySaving;
|
|
|
|
outData.firMode = static_cast<TrainingAreaBase::FirMode>(inData.specialSensorFir);
|
|
outData.minelayerMode = static_cast<TrainingAreaBase::MinelayerMode>(inData.specialSensorMinelayer);
|
|
outData.specialSensorStandard = static_cast<TrainingAreaBase::SpecialSensorStandardMode>(inData.specialSensorStandard);
|
|
|
|
outData.agdusHwMode = static_cast<TrainingAreaBase::AgdusHwMode>(inData.agdusHwMode);
|
|
|
|
outData.positionUpdateIntervall = static_cast<TrainingAreaBase::PositionUpdateIntervall>(inData.positionUpdateInterval);
|
|
|
|
outData.displayTextMainGroup = inData.displayTextMainGroup;
|
|
outData.displayTextSubGroup = inData.displayTextSubGroup;
|
|
|
|
outData.vulnerabilityModelAgdus = inData.vulnerabilityModelAgdus;
|
|
outData.vulnerabilityModelMineIed = inData.vulnerabilityModelMineIed;
|
|
outData.vulnerabilityModelAreaFire = inData.vulnerabilityModelAreaFire;
|
|
outData.vulnerabilityModelOperatingResource = inData.vulnerabilityModelOperatingResource;
|
|
outData.vulnerabilityModelACWeaponry = inData.vulnerabilityModelAcWeaponry;
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
|
|
void SendToDds::rxData(const TetraIcd::CtaDataError &inData)
|
|
{
|
|
TrainingAreaBase::CtaDataError outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
outData.reason = static_cast<ProjectDataManagement::DataErrorReason>(inData.reason);
|
|
outData.originTelegramId = inData.originTelegramId;
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
template <typename S, typename T>
|
|
void setOptionalBuildingRoomId(S &in, const T &out)
|
|
{
|
|
if (out > 0)
|
|
in = out;
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::PositionReport &inData)
|
|
{
|
|
TrainingAreaBase::EquipmentPosition outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
if (!setPosition(outData, inData.geoPosition, inData.relPosition, inData.opsPosition, inData.header.timeStamp))
|
|
{
|
|
ctasErrorPosition(inData);
|
|
return;
|
|
}
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::PositionReportWithMountedEquipments &inData)
|
|
{
|
|
TrainingAreaBase::EquipmentPosition outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
if (!setPosition(outData, inData.geoPosition, inData.relPosition, inData.opsPosition, inData.header.timeStamp))
|
|
{
|
|
ctasErrorPosition(inData);
|
|
return;
|
|
}
|
|
|
|
|
|
outData.mountedParticipants = inData.mountedEquipments;
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::MineTriggered &inData)
|
|
{
|
|
TrainingAreaBase::MineTriggered outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
outData.mineAreaId = inData.mineAreaId;
|
|
outData.mineIndex = inData.mineIndex;
|
|
|
|
if (inData.chargeTypeId != 0)
|
|
outData.chargeTypeId = inData.chargeTypeId;
|
|
if (inData.relPositionValid)
|
|
{
|
|
if (!setPosition2d(outData, inData.relPosition))
|
|
{
|
|
ctasErrorPosition(inData);
|
|
return;
|
|
}
|
|
}
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
template<typename S, typename T>
|
|
static inline void assignIedBaseData(const S &inData, T &outData)
|
|
{
|
|
assignBase(inData, outData);
|
|
outData.iedId = inData.iedId;
|
|
outData.tacticalState = static_cast<int>(inData.tacticalState);
|
|
outData.statePyrotechnics = inData.statePyrotechnics;
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::DefinitionIed &inData)
|
|
{
|
|
TrainingAreaBase::DefinitionIed outData;
|
|
checkTimeStamp(inData);
|
|
assignIedBaseData(inData, outData);
|
|
if (!setPosition2d(outData, inData.relPosition))
|
|
{
|
|
ctasErrorPosition(inData);
|
|
return;
|
|
}
|
|
outData.type = static_cast<int>(inData.iedType);
|
|
outData.remoteTrigger = (inData.trigger & static_cast<int>(TetraIcd::DefinitionIed::TriggerTypes::Remote)) ? true : false;
|
|
outData.switchTrigger = (inData.trigger & static_cast<int>(TetraIcd::DefinitionIed::TriggerTypes::Switch)) ? true : false;
|
|
outData.lightBarrierTrigger = (inData.trigger & static_cast<int>(TetraIcd::DefinitionIed::TriggerTypes::LightBarrier)) ? true : false;
|
|
outData.tautWireTrigger = (inData.trigger & static_cast<int>(TetraIcd::DefinitionIed::TriggerTypes::TautWire)) ? true : false;
|
|
outData.explosiveForce = inData.explosiveForce;
|
|
outData.pairingState = static_cast<int>(inData.pairingState);
|
|
if (inData.pairingState != TrainingAreaBase::TetraIcd::IedPairingState::NotPaired)
|
|
outData.pairedId = inData.pairedId;
|
|
if (inData.partyId != 0)
|
|
outData.partyId = inData.partyId + s_PartyIdOffset;
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::StateIed &inData)
|
|
{
|
|
TrainingAreaBase::StateIed outData;
|
|
checkTimeStamp(inData);
|
|
assignIedBaseData(inData, outData);
|
|
outData.batteryWarnings = inData.batteryWarnings;
|
|
outData.errorStateElectronics = static_cast<int>(inData.errorStateElectronics);
|
|
outData.errorStatePyrotechnics1 = static_cast<int>(inData.errorStatePyrotechnics1);
|
|
outData.errorStatePyrotechnics2 = static_cast<int>(inData.errorStatePyrotechnics2);
|
|
outData.errorStatePyrotechnics3 = static_cast<int>(inData.errorStatePyrotechnics3);
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::DusSingleMineState &inData)
|
|
{
|
|
TrainingAreaBase::DusSingleMineState outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
outData.mineId = inData.mineId;
|
|
outData.effectStart = inData.effectStart;
|
|
setPosition2d(outData, inData.relPosition);
|
|
outData.chargeTypeId = inData.chargeTypeId;
|
|
outData.state = inData.state;
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::StateChangeDirect &inData)
|
|
{
|
|
|
|
|
|
if (Settings::laserRangeCode() == inData.chargeTypeId)
|
|
{
|
|
DEBUG_LOG(m_logger) << "laserRangeCode chargeTypeId=" << inData.chargeTypeId
|
|
<< "vulnerabilityState=" << static_cast<int>(inData.vulnerabilityState);
|
|
return;
|
|
}
|
|
|
|
TrainingAreaBase::EquipmentState outData;
|
|
|
|
checkTimeStamp(inData);
|
|
|
|
if (!assignStateChangeBase(inData, outData))
|
|
return;
|
|
|
|
const auto ct(pdm()->chargeTypeFromId(inData.chargeTypeId));
|
|
|
|
|
|
if (!pdm()->isIndirect(inData.chargeTypeId))
|
|
if (!setPosition(outData, inData.geoPosition, inData.relPosition, inData.opsPosition, inData.header.timeStamp))
|
|
ctasErrorPosition(inData);
|
|
|
|
|
|
const auto gearClass(pdm()->gearClassFromChargeTypeId(inData.chargeTypeId));
|
|
|
|
|
|
|
|
if (gearClass == ProjectDataManagement::GearClass::GearClass_MineSingle ||
|
|
gearClass == ProjectDataManagement::GearClass::GearClass_MineArea)
|
|
{
|
|
TetraIcd::MineTriggered mt;
|
|
mt.header.timeStamp = inData.header.timeStamp;
|
|
if (outData.position.has_value())
|
|
{
|
|
const TrainingAreaBase::TabPosition pos = outData.position.get();
|
|
mt.relPosition = m_posHandler->geographicToRelative(pos.position);
|
|
mt.relPositionValid = true;
|
|
mt.chargeTypeId = ct.id;
|
|
mt.mineIndex = inData.originatorId;
|
|
rxData(mt);
|
|
}
|
|
|
|
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_DusMine;
|
|
}
|
|
else
|
|
{
|
|
|
|
if (pdm()->isIedChargeType({ct.id,0,0,}))
|
|
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_ImprovisedExplosiveDevice;
|
|
else
|
|
{
|
|
if (m_mainHandler->ppmHandler()->getDtc()->participantIdByEquipmentNumber(inData.originatorId) <= 0)
|
|
{
|
|
if (m_mainHandler->ppmHandler()->getDtc()->party(inData.originatorId).id)
|
|
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_Party;
|
|
else
|
|
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_Participant;
|
|
}
|
|
else
|
|
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_Participant;
|
|
}
|
|
}
|
|
|
|
|
|
outData.originatorId = inData.originatorId;
|
|
|
|
outData.originatorChargeTypeId = inData.chargeTypeId;
|
|
|
|
if (outData.originatorType == ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_DusMine)
|
|
|
|
|
|
|
|
|
|
QTimer::singleShot(10, this, [this, outData]()
|
|
{
|
|
publish(outData);
|
|
});
|
|
else
|
|
publish(outData);
|
|
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::StateChangeIndirect &inData)
|
|
{
|
|
TrainingAreaBase::EquipmentState outData;
|
|
checkTimeStamp(inData);
|
|
|
|
if (!assignStateChangeBase(inData, outData))
|
|
return;
|
|
|
|
if (!setPosition(outData, inData.geoPosition, inData.relPosition, inData.opsPosition, inData.header.timeStamp))
|
|
ctasErrorPosition(inData);
|
|
|
|
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_AreaEffectSimulation;
|
|
|
|
outData.originatorId = inData.originatorId;
|
|
if (m_aesHandler)
|
|
{
|
|
|
|
|
|
|
|
int offsetIndirectHit = inData.isSecondaryEffect ? 500 : 0;
|
|
outData.originatorChargeTypeId = offsetIndirectHit + m_aesHandler->aesChargeId(outData.originatorId);
|
|
}
|
|
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::OperatorAction &inData)
|
|
{
|
|
TrainingAreaBase::OperatorAction outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
outData.operatorId = inData.operatorId;
|
|
outData.action = inData.action;
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::StateChange &inData)
|
|
{
|
|
TrainingAreaBase::EquipmentState outData;
|
|
checkTimeStamp(inData);
|
|
|
|
if (!assignStateChangeBase(inData, outData))
|
|
return;
|
|
|
|
switch (inData.originatorType)
|
|
{
|
|
case TrainingAreaBase::TetraIcd::OriginatorType::ObserverController:
|
|
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_ObserverController;
|
|
break;
|
|
case TrainingAreaBase::TetraIcd::OriginatorType::ExerciseControl:
|
|
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_ExerciseControl;
|
|
break;
|
|
case TrainingAreaBase::TetraIcd::OriginatorType::MedicTimeout:
|
|
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_MedicalTimeout;
|
|
break;
|
|
case TrainingAreaBase::TetraIcd::OriginatorType::Sanitation:
|
|
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_Sanitation;
|
|
break;
|
|
case TrainingAreaBase::TetraIcd::OriginatorType::MedicDecontamination:
|
|
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_WoundTreatmentDevice;
|
|
break;
|
|
case TrainingAreaBase::TetraIcd::OriginatorType::MaintainanceRepair:
|
|
case TrainingAreaBase::TetraIcd::OriginatorType::MaintainanceDecontamination:
|
|
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_MaintainanceDevice;
|
|
break;
|
|
case TrainingAreaBase::TetraIcd::OriginatorType::FunctionalArea:
|
|
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_FunctionalArea;
|
|
break;
|
|
case TrainingAreaBase::TetraIcd::OriginatorType::Initialisation:
|
|
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_Initialization;
|
|
break;
|
|
}
|
|
outData.originatorId = inData.originatorId;
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::FunctionalAreaEntry &inData)
|
|
{
|
|
TrainingAreaBase::FunctionalAreaEntry outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
if (!setPosition2d(outData, inData.relPosition))
|
|
ctasErrorPosition(inData);
|
|
|
|
outData.aesItemId = inData.aesDdsId;
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::SpecialSensorData &inData)
|
|
{
|
|
TrainingAreaBase::SpecialSensorData outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
if ((inData.relPosition.offsetX != 0 || inData.relPosition.offsetY != 0) && !setPosition2d(outData, inData.relPosition))
|
|
{
|
|
ctasErrorPosition(inData);
|
|
return;
|
|
}
|
|
int operationalState = inData.operationalState & 0xFF;
|
|
if (inData.airSensor)
|
|
operationalState |= 1 << 8;
|
|
if (inData.tireSensor)
|
|
operationalState |= 1 << 9;
|
|
if (inData.pointSensor)
|
|
operationalState |= 1 << 10;
|
|
if (inData.solidMatterSampleExtractor)
|
|
operationalState |= 1 << 11;
|
|
|
|
|
|
operationalState |= (inData.type & 0x0F) << 12;
|
|
operationalState |= (inData.nbcType & 0x03) << 16;
|
|
|
|
outData.operationalState = operationalState;
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
template<typename T>
|
|
static inline void assignMinelayerData(T &inData, TrainingAreaBase::MinelayerTrailerData &outData)
|
|
{
|
|
assignBase(inData, outData);
|
|
outData.barrierId = inData.barrierId;
|
|
outData.layingDensity = inData.layingDensity;
|
|
outData.effectStart = inData.effectStart;
|
|
outData.effectDuration = inData.effectDuration;
|
|
outData.mineCount = inData.mineCount;
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::MinelayerTrailerData &inData)
|
|
{
|
|
TrainingAreaBase::MinelayerTrailerData outData;
|
|
checkTimeStamp(inData);
|
|
assignMinelayerData(inData, outData);
|
|
outData.chargeTypeId = m_mainHandler->pdmHandler()->chargeTypeFromId(inData.indirectChargeTasCode).id;
|
|
if (!setPosition2d(outData, inData.relPosition))
|
|
{
|
|
ctasErrorPosition(inData);
|
|
return;
|
|
}
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::MinelayerThrowerData &inData)
|
|
{
|
|
TrainingAreaBase::MinelayerThrowerData outData;
|
|
checkTimeStamp(inData);
|
|
assignMinelayerData(inData, outData);
|
|
outData.chargeTypeId = m_mainHandler->pdmHandler()->chargeTypeFromId(inData.indirectChargeTasCode).id;
|
|
if (!setPosition2d(outData, inData.relPosition))
|
|
{
|
|
ctasErrorPosition(inData);
|
|
return;
|
|
}
|
|
outData.throwingType = static_cast<TrainingAreaBase::ThrowingType>(inData.throwingType);
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::MinelayerTrailerPosition &inData)
|
|
{
|
|
TrainingAreaBase::MinelayerTrailerPosition outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
outData.dusSerialNo = inData.dusSerialNo;
|
|
outData.chargeTypeId = m_mainHandler->pdmHandler()->chargeTypeFromId(inData.indirectChargeTasCode).id;
|
|
if (!setPosition2d(outData, inData.relPosition))
|
|
{
|
|
ctasErrorPosition(inData);
|
|
return;
|
|
}
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::BiteReport &inData)
|
|
{
|
|
TrainingAreaBase::EquipmentBite outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
outData.registerType = static_cast<int>(inData.loginType);
|
|
outData.biteState = inData.biteState;
|
|
outData.configState = inData.configState;
|
|
outData.batteryState = inData.batteryState;
|
|
outData.configError = inData.configError;
|
|
outData.biteErrors.resize(inData.biteErrors.size());
|
|
TrainingAreaBase::EquipmentBiteError ebe;
|
|
for (size_t i = 0; i < inData.biteErrors.size(); ++i)
|
|
{
|
|
const TetraIcd::BiteError &be = inData.biteErrors.at(i);
|
|
ebe.canDeviceNumber = be.canDeviceNumber;
|
|
ebe.errorNumber = be.errorNumber;
|
|
ebe.uniqueId = be.uniqueId;
|
|
ebe.subdeviceNumber = be.subdeviceNumber;
|
|
outData.biteErrors[i] = ebe;
|
|
}
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::EquipmentEvent &inData)
|
|
{
|
|
TrainingAreaBase::EquipmentEvent outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
if (!setPosition2d(outData, inData.relPosition))
|
|
ctasErrorPosition(inData);
|
|
|
|
TrainingAreaBase::Equipment src;
|
|
src.equipmentFunctionId = inData.equipmentFunctionId;
|
|
src.subDeviceId = inData.subDeviceId;
|
|
src.unqiueId = inData.uniqueId;
|
|
outData.source = src;
|
|
|
|
outData.code = inData.code;
|
|
outData.data = inData.payload;
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
|
|
void SendToDds::rxData(const TetraIcd::EquipmentGearAssignment &inData)
|
|
{
|
|
TrainingAreaBase::EquipmentGearAssignment outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
outData.gears.resize(inData.gears.size());
|
|
TrainingAreaBase::Gear tabGear;
|
|
for (size_t i = 0; i < inData.gears.size(); ++i)
|
|
{
|
|
const TetraIcd::Gear &gear = inData.gears.at(i);
|
|
tabGear.gearId = gear.gearSerialNumber;
|
|
tabGear.gearTypeId = pdm()->gearTypeIdFromTasGearTasCode(gear.gearTasCode);
|
|
tabGear.chargeCounting = gear.chargeCounting;
|
|
outData.gears[i] = tabGear;
|
|
}
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::EquipmentGearChargeState &inData)
|
|
{
|
|
TrainingAreaBase::EquipmentGearChargeState outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
outData.charge.resize(inData.charges.size());
|
|
TrainingAreaBase::GearCharge tabGr;
|
|
for (size_t i = 0; i < inData.charges.size(); ++i)
|
|
{
|
|
const TetraIcd::GearCharge &gr = inData.charges.at(i);
|
|
tabGr.gearId = gr.gearSerialNumber;
|
|
tabGr.gearTypeId = pdm()->gearTypeIdFromTasGearTasCode(gr.gearTasCode);
|
|
tabGr.remain = gr.remain;
|
|
tabGr.chargeTypeId = pdm()->chargeTypeIdFromGearAndChargeTasCode(tabGr.gearTypeId, gr.chargeTypeId);
|
|
|
|
|
|
if (gr.gearSerialNumber == 0 && gr.gearTasCode == 0)
|
|
tabGr.gearId = gr.location;
|
|
outData.charge[i] = tabGr;
|
|
}
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::EquipmentGearEvent &inData)
|
|
{
|
|
TrainingAreaBase::EquipmentGearEvent outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
outData.chargeAmount = inData.chargeAmount;
|
|
TrainingAreaBase::GearCharge tabGr;
|
|
tabGr.gearId = inData.charge.gearSerialNumber;
|
|
tabGr.gearTypeId = pdm()->gearTypeIdFromTasGearTasCode(inData.charge.gearTasCode);
|
|
tabGr.remain = inData.charge.remain;
|
|
tabGr.chargeTypeId = pdm()->chargeTypeIdFromGearAndChargeTasCode(tabGr.gearTypeId, inData.charge.chargeTypeId);
|
|
outData.charge = tabGr;
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::ParticipantSwVersions &inData)
|
|
{
|
|
TrainingAreaBase::ParticipantSwVersions outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
|
|
outData.equipments.resize(inData.equipments.size());
|
|
TrainingAreaBase::EquipmentSwVersion eqpmt;
|
|
for (size_t i = 0; i < inData.equipments.size(); ++i)
|
|
{
|
|
const TetraIcd::EquipmentSwVersion data = inData.equipments.at(i);
|
|
eqpmt.equipmentFunctionId = data.equipmentFunctionId;
|
|
eqpmt.subDeviceId = data.subDeviceId;
|
|
eqpmt.unqiueId = data.uniqueId;
|
|
eqpmt.swVersion = data.swVersion;
|
|
outData.equipments[i] = eqpmt;
|
|
}
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::EquipmentMessageOC &inData)
|
|
{
|
|
TrainingAreaBase::EquipmentMessage outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
outData.subject = inData.subject;
|
|
outData.text = inData.message;
|
|
outData.sender = inData.senderId;
|
|
outData.receiver = inData.receiverId;
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::OpaquePayloadDataIn &inData)
|
|
{
|
|
switch (inData.payloadType)
|
|
{
|
|
case TetraIcd::OpaquePayloadDataIn::Type::FireSmokeMarker:
|
|
{
|
|
TrainingAreaBase::FireSmokeMarkerData outData;
|
|
assignBase(inData, outData);
|
|
outData.payload = inData.payload;
|
|
publish(outData);
|
|
break;
|
|
}
|
|
case TetraIcd::OpaquePayloadDataIn::Type::Geopairing:
|
|
{
|
|
TrainingAreaBase::GeopairingData outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
if (!setPosition2d(outData, inData.relPosition))
|
|
{
|
|
ctasErrorPosition(inData);
|
|
return;
|
|
}
|
|
outData.payload = inData.payload;
|
|
publish(outData);
|
|
break;
|
|
}
|
|
case TetraIcd::OpaquePayloadDataIn::Type::Target:
|
|
{
|
|
TrainingAreaBase::TargetData outData;
|
|
assignBase(inData, outData);
|
|
outData.payload = inData.payload;
|
|
publish(outData);
|
|
break;
|
|
}
|
|
case TetraIcd::OpaquePayloadDataIn::Type::OC:
|
|
{
|
|
TrainingAreaBase::OcData outData;
|
|
assignBase(inData, outData);
|
|
outData.payload = inData.payload;
|
|
publish(outData);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::ParticipantModeReport &inData)
|
|
{
|
|
TrainingAreaBase::ParticipantModeReport outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
outData.language = static_cast<ProjectDataManagement::LanguageConfiguration>(inData.language);
|
|
outData.operationMode = static_cast<ProjectDataManagement::OperationMode>(inData.operationMode);
|
|
outData.reactivationDetoxication = inData.reactivationDetoxication;
|
|
outData.reactivationMaintenance = inData.reactivationMaintenance;
|
|
outData.reactivationMedic = inData.reactivationMedic;
|
|
outData.protectionModeVest = static_cast<ProjectDataManagement::WphMode>(inData.modeVest);
|
|
outData.protectionModeHelmet = static_cast<ProjectDataManagement::WphMode>(inData.modeHelmet);
|
|
outData.personellProtectionMode = static_cast<ProjectDataManagement::PersonalProtection>(inData.personellProtectionMode);
|
|
outData.protectionLevel = static_cast<ProjectDataManagement::ProtectionLevel>(inData.protectionLevel);
|
|
outData.handgrenadeSearchMode = static_cast<ProjectDataManagement::HandgrenadeSearchMode>(inData.handgrenadeSearchMode);
|
|
outData.internationalMode = static_cast<ProjectDataManagement::InternationalMode>(inData.internationalMode);
|
|
outData.abcProtectionMode = static_cast<ProjectDataManagement::ABCProtectionMode>(inData.abcProtectionMode);
|
|
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::ParticipantConfigurationReport &inData)
|
|
{
|
|
TrainingAreaBase::ParticipantConfigurationReport outData;
|
|
checkTimeStamp(inData);
|
|
assignBase(inData, outData);
|
|
outData.positionIntervallVehicle = inData.positionIntervallVehicle;
|
|
outData.positionIntervallPersonell = inData.positionIntervallPersonell;
|
|
outData.positionIntervallAircraft = inData.positionIntervallAircraft;
|
|
outData.positionTransmissionIntervall = inData.positionTransmissionIntervall;
|
|
outData.heightbarrier = inData.heightbarrier;
|
|
outData.faultPositionHandling = static_cast<TrainingAreaBase::FaultPositionHandling>(inData.faultPositionHandling);
|
|
outData.switchingPositionIntervall = static_cast<TrainingAreaBase::SwitichingPositionIntervall>(inData.switchingPositionIntervall);
|
|
outData.waittimeAdditionalBroadcastRequest = inData.waittimeAdditionalBroadcastDemand;
|
|
outData.factorWaittimeIncreaseHighload = inData.factorWaittimeIncreaseAtHighload;
|
|
outData.waittimeAutomaticVulnerbilityIncreaseLevel1 = inData.waittimeAutomaticVulnerabilityIncreaseLevel1;
|
|
outData.waittimeAutomaticVulnerbilityIncreaseLevel2 = inData.waittimeAutomaticVulnerabilityIncreaseLevel2;
|
|
outData.waittimeAutomaticVulnerbilityIncreaseLevel3 = inData.waittimeAutomaticVulnerabilityIncreaseLevel3;
|
|
outData.opticalCode = static_cast<TrainingAreaBase::OpticalCode>(inData.opticalCode);
|
|
outData.vulnerabilityModel = inData.vulnerabilityModel;
|
|
outData.validTimeOps = inData.validTimeOps;
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::EmergencyCall &inData)
|
|
{
|
|
TrainingAreaBase::EmergencyCall outData;
|
|
|
|
outData.equipmentNumber = inData.issi;
|
|
outData.sampleTime = inData.timeStamp;
|
|
const Core::GeoPosition2D pos(inData.absPosition.lon, inData.absPosition.lat);
|
|
outData.position = pos;
|
|
|
|
m_mainHandler->ddsHandler()->emergencyCall()->write(outData);
|
|
|
|
QTimer *t = m_emergencyCallTimer[inData.issi];
|
|
if (!t)
|
|
{
|
|
t = new QTimer(this);
|
|
t->setInterval(30 * 1000);
|
|
const int issi = inData.issi;
|
|
connect(t, &QTimer::timeout, this, [this, issi]() { onEmergencyCallTimerTimeout(issi); });
|
|
m_emergencyCallTimer[inData.issi] = t;
|
|
}
|
|
t->start();
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::SanitationRepair &inData)
|
|
{
|
|
TrainingAreaBase::ParticipantSanitationRepair sanRepair;
|
|
sanRepair.equipmentNumber = inData.header.equipmentNumber;
|
|
sanRepair.sampleTime = inData.header.timeStamp;
|
|
sanRepair.originatorType = static_cast<ProjectDataManagement::StateChangeOriginator>(inData.originatorType);
|
|
sanRepair.equipmentNumberOrigin = inData.equipmentNumberOrigin;
|
|
sanRepair.stateStart = static_cast<ProjectDataManagement::VulnerabilityState>(inData.stateStart);
|
|
sanRepair.typeOfTreatment = inData.typeOfTreatment;
|
|
sanRepair.triage = inData.triage;
|
|
sanRepair.tyeOfDamage = inData.tyeOfDamage;
|
|
sanRepair.stateResult = static_cast<ProjectDataManagement::VulnerabilityState>(inData.stateResult);
|
|
sanRepair.treatmentResult = static_cast<TrainingAreaBase::TreatmentResult>(inData.treatmentResult);
|
|
sanRepair.triagePriority = inData.triagePriority;
|
|
sanRepair.fullState = inData.fullState;
|
|
sanRepair.timeOfTreatment = inData.timeOfTreatment;
|
|
sanRepair.timeOfRecovery = inData.timeOfRecovery;
|
|
|
|
publish(sanRepair);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::SanitaryMaterialStockReport &inData)
|
|
{
|
|
TrainingAreaBase::ParticipantSanitaryMaterialStockReport sanReport;
|
|
sanReport.equipmentNumber = inData.header.equipmentNumber;
|
|
sanReport.sampleTime = inData.header.timeStamp;
|
|
sanReport.sanitaryMaterialCount = inData.sanitaryMaterialCount;
|
|
sanReport.sanitaryMaterialStock = inData.sanitaryMaterialStock;
|
|
sanReport.uniqueId = inData.uniqueId;
|
|
sanReport.originatorEquipmentNumber = inData.originatorEquipmentNumber;
|
|
sanReport.qualification = static_cast<TrainingAreaBase::Qualification>(inData.qualification);
|
|
|
|
publish(sanReport);
|
|
DEBUG_LOG(m_logger) << "SendToDds::rxData(const TetraIcd::SanitaryMaterialStockReport for " << sanReport.equipmentNumber;
|
|
|
|
if (sanReport.qualification == TrainingAreaBase::Qualification::NotDefined)
|
|
{
|
|
|
|
int oldEquipNo = m_uniqueId2EquipmentNumber.value(sanReport.uniqueId);
|
|
|
|
if (oldEquipNo > 0)
|
|
{
|
|
TrainingAreaBase::ParticipantSanitation sanitation;
|
|
sanitation.equipmentNumber = oldEquipNo;
|
|
sanitation.sampleTime = sanReport.sampleTime;
|
|
sanitation.proceduresTaken = 0;
|
|
sanitation.uniqueId = sanReport.uniqueId;
|
|
sanitation.originatorEquipmentNumber = 0;
|
|
sanitation.qualification = TrainingAreaBase::Qualification::NotDefined;
|
|
sanitation.sanitationResult = TrainingAreaBase::SanitationResult::NoEffect;
|
|
sanitation.sanitationEvaluation = TrainingAreaBase::SanitationEvaluation::NotApplicable;
|
|
publish(sanitation);
|
|
}
|
|
|
|
m_uniqueId2EquipmentNumber.remove(sanReport.uniqueId);
|
|
}
|
|
|
|
onPvSanUniqueIdMapping(sanReport.uniqueId, sanReport.equipmentNumber, sanReport.sampleTime);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::Sanitation &inData)
|
|
{
|
|
TrainingAreaBase::ParticipantSanitation sanitation;
|
|
sanitation.equipmentNumber = inData.header.equipmentNumber;
|
|
sanitation.sampleTime = inData.header.timeStamp;
|
|
sanitation.proceduresTaken = inData.proceduresTaken;
|
|
sanitation.uniqueId = inData.uniqeId;
|
|
sanitation.originatorEquipmentNumber = inData.originatorEquipmentNumber;
|
|
sanitation.qualification = static_cast<TrainingAreaBase::Qualification>(inData.qualification);
|
|
sanitation.sanitationResult = static_cast<TrainingAreaBase::SanitationResult>(inData.sanitationResult);
|
|
sanitation.sanitationEvaluation = static_cast<TrainingAreaBase::SanitationEvaluation>(inData.sanitationEvaluation);
|
|
publish(sanitation);
|
|
DEBUG_LOG(m_logger) << "SendToDds::rxData(const TetraIcd::Sanitation for " << sanitation.equipmentNumber;
|
|
|
|
if (sanitation.qualification == TrainingAreaBase::Qualification::NotDefined)
|
|
{
|
|
TrainingAreaBase::ParticipantSanitaryMaterialStockReport sanReport;
|
|
sanReport.equipmentNumber = sanitation.equipmentNumber;
|
|
sanReport.sampleTime = sanitation.sampleTime;
|
|
sanReport.sanitaryMaterialCount = 0;
|
|
sanReport.sanitaryMaterialStock = std::vector<int>();
|
|
sanReport.uniqueId = sanitation.uniqueId;
|
|
sanReport.originatorEquipmentNumber = 0;
|
|
sanReport.qualification = TrainingAreaBase::Qualification::NotDefined;
|
|
|
|
publish(sanReport);
|
|
|
|
m_uniqueId2EquipmentNumber.remove(sanitation.uniqueId);
|
|
}
|
|
else
|
|
onPvSanUniqueIdMapping(sanitation.uniqueId, sanitation.equipmentNumber, sanitation.sampleTime);
|
|
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::ApacheLaserDesignation &inData)
|
|
{
|
|
TrainingAreaBase::LaserDesignation laserDesignation;
|
|
laserDesignation.equipmentNumber = inData.header.equipmentNumber;
|
|
laserDesignation.sampleTime = inData.header.timeStamp;
|
|
laserDesignation.spotLocation = Core::GeoPosition2D(inData.spotLocation.lon, inData.spotLocation.lat);
|
|
laserDesignation.outputPower = inData.outputPower;
|
|
laserDesignation.code = inData.code;
|
|
laserDesignation.gearId = inData.gearId;
|
|
publish(laserDesignation);
|
|
}
|
|
|
|
template<typename S>
|
|
void SendToDds::ctasErrorPosition(const S &data)
|
|
{
|
|
TrainingAreaBase::CtaDataError error;
|
|
|
|
error.equipmentNumber = data.header.equipmentNumber;
|
|
error.sampleTime = data.header.timeStamp;
|
|
error.reason = ProjectDataManagement::DataErrorReason::DataErrorReason_InvalidPosition;
|
|
error.originTelegramId = data.id();
|
|
publish(error);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::BatteryInfo &inData)
|
|
{
|
|
TrainingAreaBase::BatteryInfo batteryInfo;
|
|
batteryInfo.equipmentNumber = inData.header.equipmentNumber;
|
|
batteryInfo.sampleTime = inData.header.timeStamp;
|
|
std::vector<TrainingAreaBase::BatteryState> batteryStates;
|
|
batteryStates.reserve(inData.batteryStates.size());
|
|
for(const TetraIcd::BatteryState &batState : std::as_const(inData.batteryStates))
|
|
{
|
|
TrainingAreaBase::BatteryState batStateOut;
|
|
batStateOut.batteryPort = batState.batteryPort();
|
|
batStateOut.batteryPercent = batState.batteryPercent();
|
|
batStateOut.current = batState.current();
|
|
batStateOut.frequency = batState.frequency();
|
|
batStateOut.generic = batState.generic();
|
|
batStateOut.serialNumber = batState.serialNumber().toStdString();
|
|
batStateOut.switchOrValue = batState.switchOrValue();
|
|
batStateOut.temperature = batState.temperature();
|
|
batStateOut.voltage = batState.voltage();
|
|
batteryStates.push_back(batStateOut);
|
|
}
|
|
batteryInfo.batteryStates = batteryStates;
|
|
|
|
publish(batteryInfo);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::BatteryAlarm &inData)
|
|
{
|
|
TrainingAreaBase::BatteryAlarm batAlarm;
|
|
batAlarm.acknowledge = inData.acknowledge();
|
|
batAlarm.alarmTime = inData.alarmTime();
|
|
batAlarm.condition = inData.condition();
|
|
batAlarm.description = inData.description().toStdString();
|
|
batAlarm.batteryPort = inData.id();
|
|
batAlarm.uniqueAlarmNumber = inData.uniqueAlarmNumber();
|
|
batAlarm.equipmentNumber = inData.header().equipmentNumber;
|
|
batAlarm.sampleTime = inData.header().timeStamp;
|
|
publish(batAlarm);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::ServiceControl &inData)
|
|
{
|
|
TrainingAreaBase::ServiceControl serviceControl;
|
|
serviceControl.equipmentNumber = inData.header.equipmentNumber;
|
|
serviceControl.sampleTime = inData.header.timeStamp;
|
|
serviceControl.serviceControlState = static_cast<TrainingAreaBase::ServiceControlEnum>(inData.serviceControlState);
|
|
publish(serviceControl);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::RestoreRadioReadiness &inData)
|
|
{
|
|
struct PositionStruct
|
|
{
|
|
int equipmentNumber;
|
|
Core::GeoPosition2D position;
|
|
};
|
|
|
|
RestoreRadioReadiness restoreRadioReadiness;
|
|
|
|
restoreRadioReadiness.equipmentNumber = inData.header.equipmentNumber;
|
|
restoreRadioReadiness.sampleTime = inData.header.timeStamp;
|
|
restoreRadioReadiness.readinessLossPosition = m_posHandler->relativeToGeographic(inData.readinessLossPosition);
|
|
restoreRadioReadiness.readinessLossTime = inData.readinessLossTime;
|
|
restoreRadioReadiness.readinessRestorePosition = m_posHandler->relativeToGeographic(inData.readinessRestorePosition);
|
|
restoreRadioReadiness.readinessRestoreTime = inData.readinessRestoreTime;
|
|
|
|
publish(restoreRadioReadiness);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::UAVRadioLinkConnectionStatus &inData)
|
|
{
|
|
TrainingAreaBase::UASRadioLinkConnectionState outData;
|
|
assignBase(inData, outData);
|
|
|
|
switch (inData.uavConnectionState)
|
|
{
|
|
case TetraIcd::UAVRadioLinkConnectionStatusType::Connected:
|
|
outData.connectionStatus = ProjectDataManagement::UasState::UasState_On;
|
|
break;
|
|
case TetraIcd::UAVRadioLinkConnectionStatusType::Disconnected:
|
|
outData.connectionStatus = ProjectDataManagement::UasState::UasState_Off;
|
|
break;
|
|
case TetraIcd::UAVRadioLinkConnectionStatusType::Connecting:
|
|
outData.connectionStatus = ProjectDataManagement::UasState::UasState_Init;
|
|
break;
|
|
case TetraIcd::UAVRadioLinkConnectionStatusType::Diconnecting:
|
|
outData.connectionStatus = ProjectDataManagement::UasState::UasState_Shutdown;
|
|
break;
|
|
case TetraIcd::UAVRadioLinkConnectionStatusType::Error:
|
|
outData.connectionStatus = ProjectDataManagement::UasState::UasState_Undefined;
|
|
break;
|
|
case TetraIcd::UAVRadioLinkConnectionStatusType::Undefined:
|
|
outData.connectionStatus = ProjectDataManagement::UasState::UasState_Undefined;
|
|
break;
|
|
}
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::UAVMissionStatus &inData)
|
|
{
|
|
TrainingAreaBase::UASMissionStatus outData;
|
|
assignBase(inData, outData);
|
|
|
|
switch (inData.currentAction)
|
|
{
|
|
case TetraIcd::UAVActionTask::Undefined: outData.currentTask = ProjectDataManagement::UasActionTask::Undefined; break;
|
|
case TetraIcd::UAVActionTask::Disarm: outData.currentTask = ProjectDataManagement::UasActionTask::Disarm; break;
|
|
case TetraIcd::UAVActionTask::Arm: outData.currentTask = ProjectDataManagement::UasActionTask::Arm; break;
|
|
case TetraIcd::UAVActionTask::Takeoff: outData.currentTask = ProjectDataManagement::UasActionTask::Takeoff; break;
|
|
case TetraIcd::UAVActionTask::Connect: outData.currentTask = ProjectDataManagement::UasActionTask::Connect; break;
|
|
case TetraIcd::UAVActionTask::Loiter: outData.currentTask = ProjectDataManagement::UasActionTask::Loiter; break;
|
|
case TetraIcd::UAVActionTask::Return: outData.currentTask = ProjectDataManagement::UasActionTask::Return; break;
|
|
case TetraIcd::UAVActionTask::Observe: outData.currentTask = ProjectDataManagement::UasActionTask::Observe; break;
|
|
}
|
|
|
|
outData.currentMissionName = inData.currentMissionName.toStdString();
|
|
outData.missionEnded = inData.missionEnded.toStdString();
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
void SendToDds::rxData(const TetraIcd::UAVStatus &inData)
|
|
{
|
|
TrainingAreaBase::UASStatus outData;
|
|
assignBase(inData, outData);
|
|
|
|
switch (inData.uavState)
|
|
{
|
|
case TetraIcd::UAVState::On:
|
|
outData.uasState = ProjectDataManagement::UasState::UasState_On;
|
|
break;
|
|
case TetraIcd::UAVState::Off:
|
|
outData.uasState = ProjectDataManagement::UasState::UasState_Off;
|
|
break;
|
|
case TetraIcd::UAVState::Init:
|
|
outData.uasState = ProjectDataManagement::UasState::UasState_Init;
|
|
break;
|
|
case TetraIcd::UAVState::Shutdown:
|
|
outData.uasState = ProjectDataManagement::UasState::UasState_Shutdown;
|
|
break;
|
|
case TetraIcd::UAVState::Calibrating:
|
|
outData.uasState = ProjectDataManagement::UasState::UasState_Calibrating;
|
|
break;
|
|
case TetraIcd::UAVState::Manual:
|
|
outData.uasState = ProjectDataManagement::UasState::UasState_Manual;
|
|
break;
|
|
case TetraIcd::UAVState::Maintenance:
|
|
outData.uasState = ProjectDataManagement::UasState::UasState_Maintenance;
|
|
break;
|
|
case TetraIcd::UAVState::Standby:
|
|
outData.uasState = ProjectDataManagement::UasState::UasState_Standby;
|
|
break;
|
|
case TetraIcd::UAVState::Normal:
|
|
outData.uasState = ProjectDataManagement::UasState::UasState_Normal;
|
|
break;
|
|
case TetraIcd::UAVState::Auto:
|
|
outData.uasState = ProjectDataManagement::UasState::UasState_Auto;
|
|
break;
|
|
case TetraIcd::UAVState::Undefined:
|
|
outData.uasState = ProjectDataManagement::UasState::UasState_Undefined;
|
|
break;
|
|
}
|
|
|
|
publish(outData);
|
|
}
|
|
|
|
template <typename T>
|
|
bool SendToDds::setPosition(T &data,
|
|
const TetraIcd::AbsolutePosition &geoPos,
|
|
const TetraIcd::RelativePosition &relPos,
|
|
const TetraIcd::OpsPosition &opsPos,
|
|
const qint64 timeStamp) const
|
|
{
|
|
bool bRet = true;
|
|
bool moutCheck = true;
|
|
TrainingAreaBase::TabPosition tabPos;
|
|
if (geoPos.isValid())
|
|
{
|
|
tabPos.position = Core::GeoPosition(geoPos.lon, geoPos.lat, geoPos.z);
|
|
setOptionalBuildingRoomId(tabPos.moutObjectId, opsPos.moutObjectId);
|
|
setOptionalBuildingRoomId(tabPos.moutRoomId, opsPos.moutRoomId);
|
|
|
|
|
|
|
|
|
|
const bool bWlsLocationLost = opsPos.moutObjectId == -2 &&
|
|
opsPos.moutRoomId == -2;
|
|
if (bWlsLocationLost)
|
|
{
|
|
TrainingAreaBase::TabPosition lastTabPos =
|
|
m_posHandler->lastPosition(data.equipmentNumber);
|
|
if (lastTabPos.reportingSource == Core::PositionReportingSource::Wls ||
|
|
std::isnan(lastTabPos.position.lon))
|
|
tabPos.reportingSource = Core::PositionReportingSource::Gps;
|
|
else
|
|
std::swap(tabPos, lastTabPos);
|
|
}
|
|
else
|
|
tabPos.reportingSource = Core::PositionReportingSource::Wls;
|
|
}
|
|
else if (opsPos.opsId == 0)
|
|
{
|
|
bool changeReportSource = true;
|
|
DEBUG_LOG(m_logger) << "ops == 0 so check for marked invalid to use last position!";
|
|
if (PositionHandler::isPositionMarkedInvalid(relPos))
|
|
{
|
|
|
|
|
|
tabPos = m_posHandler->lastPosition(data.equipmentNumber);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DEBUG_LOG(m_logger) << "ops == 0 got last Position its source is " << tabPos.reportingSource;
|
|
|
|
if (tabPos.reportingSource != Core::PositionReportingSource::Wls
|
|
&& tabPos.reportingSource != Core::PositionReportingSource::Ops
|
|
&& tabPos.reportingSource != Core::PositionReportingSource::OpsTunnel)
|
|
tabPos = TrainingAreaBase::TabPosition();
|
|
else if (tabPos.reportingSource == Core::PositionReportingSource::Ops
|
|
|| tabPos.reportingSource == Core::PositionReportingSource::OpsTunnel)
|
|
changeReportSource = false;
|
|
DEBUG_LOG(m_logger) << "ops == 0 changeSource is " << changeReportSource ;
|
|
}
|
|
else
|
|
{
|
|
|
|
if (!m_posHandler->isInTrainingArea(relPos))
|
|
{
|
|
DEBUG_LOG(m_logger) << "bret = false";
|
|
bRet = false;
|
|
}
|
|
tabPos.position = m_posHandler->relativeToGeographic(relPos);
|
|
setOptionalBuildingRoomId(tabPos.moutObjectId, opsPos.moutObjectId);
|
|
setOptionalBuildingRoomId(tabPos.moutRoomId, opsPos.moutRoomId);
|
|
|
|
|
|
TrainingAreaBase::TabPosition lastPosition = m_posHandler->lastPosition(data.equipmentNumber);
|
|
{
|
|
DEBUG_LOG(m_logger) << "lastPosition.reportingSource=" << lastPosition.reportingSource;
|
|
}
|
|
|
|
if (lastPosition.reportingSource == Core::PositionReportingSource::Ops &&
|
|
lastPosition.moutObjectId.has_value())
|
|
{
|
|
DEBUG_LOG(m_logger) << "Check leave Building equipmentNumber=" << data.equipmentNumber;
|
|
DEBUG_LOG(m_logger) << "relPos=" << relPos.offsetX << "/" << relPos.offsetY;
|
|
DEBUG_LOG(m_logger) << "posInExtendedBuildingFootprint";
|
|
const Core::GeoPosition &position = tabPos.position;
|
|
int moutObjectId = lastPosition.moutObjectId.get();
|
|
const int lastMountPointTypeId = m_posHandler->lastMountPointTypeId(data.equipmentNumber);
|
|
if (ism()->posInExtendedBuildingFootprint(moutObjectId, position, lastMountPointTypeId))
|
|
{
|
|
moutCheck = false;
|
|
bRet = false;
|
|
}
|
|
else
|
|
{
|
|
DEBUG_LOG(m_logger) << "lastMountPointTypeId =" << m_posHandler->lastMountPointTypeId(data.equipmentNumber);
|
|
|
|
if ( m_posHandler->lastMountPointTypeId(data.equipmentNumber) == static_cast<int>(InfrastructureManagement::MountingPointType::IndoorIPS))
|
|
{
|
|
|
|
double speed = m_posHandler->speed(relPos, data.equipmentNumber, timeStamp);
|
|
bool checkSpeed = !m_posHandler->isTimeToPerformSpeedCheckExceeded(data.equipmentNumber,
|
|
timeStamp,
|
|
Settings::maxSpeedCheckTimeout());
|
|
DEBUG_LOG(m_logger) << "Check Speed speed=" << speed
|
|
<< " MaxSoldierSpeed=" << Settings::maxSoldierSpeed()
|
|
<< " checkSpeed=" << checkSpeed;
|
|
if (checkSpeed && speed > Settings::maxSoldierSpeed())
|
|
{
|
|
DEBUG_LOG(m_logger) << "Check Speed bRet = false";
|
|
bRet = false;
|
|
moutCheck = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DEBUG_LOG(m_logger) << "Kein Speed check!";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (changeReportSource)
|
|
tabPos.reportingSource = Core::PositionReportingSource::Gps;
|
|
}
|
|
else
|
|
{
|
|
INFO_LOG(m_logger) << "Valid OpsData: " << opsPos.opsId;
|
|
|
|
IsmHandler::OpsData opsData;
|
|
if (ism())
|
|
{
|
|
opsData = ism()->dataFromOpsCode(opsPos.opsId);
|
|
|
|
|
|
DEBUG_LOG(m_logger) << "equipmentNumber=" << data.equipmentNumber
|
|
<< " AssetId=" << opsData.assetId
|
|
<< " opsData.structureElementId=" << opsData.structureElementId
|
|
<< " opsData.mseId=" << opsData.mainStructureElementId
|
|
<< " opsData.mptTypeId=" << opsData.mountingPointTypeId;
|
|
if ( opsData.structureElementId != 0)
|
|
m_posHandler->setLastMountPointTypeId(data.equipmentNumber, opsData.mountingPointTypeId);
|
|
}
|
|
|
|
if (opsData.opsCode != opsPos.opsId)
|
|
{
|
|
WARNING_LOG(m_logger) << "found no position data for ops id " << opsPos.opsId;
|
|
bRet = false;
|
|
}
|
|
else if (opsData.structureElementId == 0)
|
|
{
|
|
WARNING_LOG(m_logger) << "ops id " << opsPos.opsId << " is not mounted";
|
|
bRet = false;
|
|
}
|
|
else
|
|
{
|
|
DEBUG_LOG(m_logger) << "ops id " << opsPos.opsId;
|
|
tabPos.moutObjectId = opsData.mainStructureElementId;
|
|
tabPos.moutRoomId = opsData.roomId;
|
|
tabPos.position = opsData.position;
|
|
m_posHandler->setLastBuildingId(data.equipmentNumber, opsData.mainStructureElementId);
|
|
m_posHandler->setLastRoomId(data.equipmentNumber, opsData.roomId);
|
|
}
|
|
if (opsData.opsTunnel)
|
|
tabPos.reportingSource = Core::PositionReportingSource::OpsTunnel;
|
|
else
|
|
tabPos.reportingSource = Core::PositionReportingSource::Ops;
|
|
|
|
}
|
|
if (!bRet)
|
|
{
|
|
if ( moutCheck )
|
|
{
|
|
DEBUG_LOG(m_logger) << "POS = ungueltig";
|
|
tabPos.position.lon = nan("");
|
|
tabPos.position.lat = nan("");
|
|
}
|
|
else
|
|
{
|
|
DEBUG_LOG(m_logger) << "POS = ungueltig => alte Pos mit aktueller Zeit verschicken";
|
|
TrainingAreaBase::TabPosition lastPosition = m_posHandler->lastPosition(data.equipmentNumber);
|
|
tabPos.position.lon = lastPosition.position.lon;
|
|
tabPos.position.lat = lastPosition.position.lat;
|
|
tabPos.position.z = lastPosition.position.z;
|
|
tabPos.reportingSource = Core::PositionReportingSource::OpsBuilding;
|
|
tabPos.moutObjectId = m_posHandler->lastBuildingId(data.equipmentNumber);
|
|
tabPos.moutRoomId = m_posHandler->lastRoomId(data.equipmentNumber);
|
|
bRet = true;
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
DEBUG_LOG(m_logger) << "set last Position";
|
|
if (tabPos.reportingSource == Core::PositionReportingSource::Ops)
|
|
DEBUG_LOG(m_logger) << "ReportingSource=OPS";
|
|
else if (tabPos.reportingSource == Core::PositionReportingSource::Gps)
|
|
DEBUG_LOG(m_logger) << "ReportingSource=GPS";
|
|
DEBUG_LOG(m_logger) << "tabPos.reportingSource=" << tabPos.reportingSource
|
|
<< " timeStamp=" << timeStamp;
|
|
m_posHandler->setLastPosition(data.equipmentNumber, tabPos);
|
|
m_posHandler->setLastTime(data.equipmentNumber, timeStamp);
|
|
}
|
|
data.position = tabPos;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
template <typename T>
|
|
bool SendToDds::setPosition2d(T &data,
|
|
const TetraIcd::RelativePosition &relPos) const
|
|
{
|
|
TrainingAreaBase::TabPosition tabPos;
|
|
bool bRet = true;
|
|
|
|
if (PositionHandler::isPositionMarkedInvalid(relPos))
|
|
tabPos = m_posHandler->lastPosition(data.equipmentNumber);
|
|
else
|
|
{
|
|
|
|
if (!m_posHandler->isInTrainingArea(relPos))
|
|
bRet = false;
|
|
|
|
DEBUG_LOG(m_logger) << "tabPos.reportingSource=" << tabPos.reportingSource;
|
|
tabPos.position = m_posHandler->relativeToGeographic(relPos);
|
|
m_posHandler->setLastPosition(data.equipmentNumber, tabPos);
|
|
}
|
|
|
|
Core::GeoPosition2D pos2d;
|
|
pos2d.lat = tabPos.position.lat;
|
|
pos2d.lon = tabPos.position.lon;
|
|
data.position = pos2d;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
template<typename S, typename T>
|
|
bool SendToDds::assignStateChangeBase(const S &inData, T &outData)
|
|
{
|
|
assignBase(inData, outData);
|
|
|
|
if (inData.vulnerabilityState < TrainingAreaBase::TetraIcd::VulnerabilityState::CombatReady ||
|
|
inData.vulnerabilityState > TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityBitsChanged)
|
|
{
|
|
TrainingAreaBase::CtaDataError error;
|
|
assignBase(inData, error);
|
|
error.reason = ProjectDataManagement::DataErrorReason::DataErrorReason_InvalidTacticalState;
|
|
error.originTelegramId = inData.id();
|
|
publish(error);
|
|
return false;
|
|
}
|
|
|
|
outData.vulnerabilityState = static_cast<ProjectDataManagement::VulnerabilityState>(inData.vulnerabilityState);
|
|
outData.vulnerabilityKindId = pdm()->vulnerabilityKindId(inData.tasVulnerabilityKindId, inData.header.equipmentNumber);
|
|
outData.vitality = inData.tasVitality;
|
|
outData.vulnerabilityBits = inData.vulnerabilityBits;
|
|
return true;
|
|
}
|
|
|
|
template <typename S>
|
|
void SendToDds::checkTimeStamp(const S &data)
|
|
{
|
|
const auto partTime = m_mainHandler->ddsHandler()->partitionTime();
|
|
if (data.header.timeStamp > (partTime + Settings::timeDelayAhead()) ||
|
|
data.header.timeStamp < (partTime - Settings::timeDelayBack()))
|
|
{
|
|
TrainingAreaBase::CtaDataError error;
|
|
error.equipmentNumber = data.header.equipmentNumber;
|
|
error.sampleTime = data.header.timeStamp;
|
|
error.reason = ProjectDataManagement::DataErrorReason::DataErrorReason_InvalidTime;
|
|
error.originTelegramId = data.id();
|
|
publish(error);
|
|
}
|
|
}
|
|
|
|
std::shared_ptr<IsmHandler> SendToDds::ism() const
|
|
{
|
|
return m_mainHandler->ismHandler();
|
|
}
|
|
|
|
std::shared_ptr<PdmHandler> SendToDds::pdm() const
|
|
{
|
|
return m_mainHandler->pdmHandler();
|
|
}
|
|
|
|
template <typename T>
|
|
void SendToDds::publish(const T &data)
|
|
{
|
|
try
|
|
{
|
|
m_dtsTab->publish(data);
|
|
}
|
|
catch (const std::exception &ex)
|
|
{
|
|
WARNING_LOG(m_logger) << "Could not send telegram: " << ex.what();
|
|
}
|
|
}
|
|
|
|
void SendToDds::onEmergencyCallTimerTimeout(int issi)
|
|
{
|
|
auto it = m_emergencyCallTimer.find(issi);
|
|
if (it == m_emergencyCallTimer.end())
|
|
return;
|
|
delete it.value();
|
|
m_emergencyCallTimer.erase(it);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (m_mainHandler->ddsHandler()->emergencyCall())
|
|
{
|
|
TrainingAreaBase::EmergencyCall emergCallData;
|
|
emergCallData.equipmentNumber = issi;
|
|
if (!m_mainHandler->ddsHandler()->emergencyCall()->remove(emergCallData))
|
|
ERROR_LOG(m_logger) << Q_FUNC_INFO << " removing of TrainingAreaBase::EmergencyCall failed, issi = " << issi;
|
|
}
|
|
}
|
|
|
|
void SendToDds::onPvSanUniqueIdMapping(int uniqueId, int equipNo, qint64 sampleTime)
|
|
{
|
|
DEBUG_LOG(m_logger) << Q_FUNC_INFO << "start pvSan mapping " << equipNo << " uniqueId " << uniqueId;
|
|
|
|
|
|
if (m_uniqueId2EquipmentNumber.value(uniqueId) == equipNo)
|
|
return;
|
|
|
|
|
|
if (!m_uniqueId2EquipmentNumber.contains(uniqueId))
|
|
{
|
|
m_uniqueId2EquipmentNumber.insert(uniqueId, equipNo);
|
|
return;
|
|
}
|
|
|
|
|
|
int oldEquipNo = m_uniqueId2EquipmentNumber.value(uniqueId);
|
|
|
|
if (oldEquipNo > 0)
|
|
{
|
|
TrainingAreaBase::ParticipantSanitaryMaterialStockReport sanReport;
|
|
sanReport.equipmentNumber = oldEquipNo;
|
|
sanReport.sampleTime = sampleTime;
|
|
sanReport.sanitaryMaterialCount = 0;
|
|
sanReport.sanitaryMaterialStock = std::vector<int>();
|
|
sanReport.uniqueId = uniqueId;
|
|
sanReport.originatorEquipmentNumber = 0;
|
|
sanReport.qualification = TrainingAreaBase::Qualification::NotDefined;
|
|
|
|
publish(sanReport);
|
|
|
|
TrainingAreaBase::ParticipantSanitation sanitation;
|
|
sanitation.equipmentNumber = oldEquipNo;
|
|
sanitation.sampleTime = sampleTime;
|
|
sanitation.proceduresTaken = 0;
|
|
sanitation.uniqueId = uniqueId;
|
|
sanitation.originatorEquipmentNumber = 0;
|
|
sanitation.qualification = TrainingAreaBase::Qualification::NotDefined;
|
|
sanitation.sanitationResult = TrainingAreaBase::SanitationResult::NoEffect;
|
|
sanitation.sanitationEvaluation = TrainingAreaBase::SanitationEvaluation::NotApplicable;
|
|
publish(sanitation);
|
|
|
|
m_uniqueId2EquipmentNumber.insert(uniqueId, equipNo);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|