/** * Connect to ngs / hla and provide the basic interface * $Id$ * $HeadURL$ * $Author$ * Created by Christian Ehrlicher, SLSE, 2017-04-07 */ #pragma once #include "ws_telegrams.h" #include #include #include #include #include #include #include #include #include namespace ngs { class ISimulatedWorldAdmin; class IFederationMaster; class IObserverObjectInstance; } namespace rpr2 { class ArrayOfWorldLocationStructDynamicHLAlengthlessVarArray; class ArrayOfHLAoctetN_slsh_AperfectalwaysN_slsh_ADynamicHLApaddingTo32Array; class IPlayerSOM; class EntityTypeStruct; class MarkingStruct; class ClockTimeStruct; class TacticalStatusStruct; class IPlayerPhysicalEntityObjInstance; class IPlayerEnvironmentObjectObjInstance; class IPlayerBaseEntityObjInstance; class OMT13string; class EventIdentifierStruct; class EntityIdentifierStruct; class IsPartOfStruct; class IObserverBaseEntityObjInstance; class IObserverMunitionDetonationIntInstance; class IObserverWeaponFireIntInstance; class IObserverGuezHitIntInstance; class IObserverGuezInitIntInstance; class IObserverGuezBiteReportIntInstance; class IObserverGuezRequestBiteReportIntInstance; class IObserverEnvironmentObjectObjInstance; class IObserverGuezMineFieldObjInstance; class IObserverGuezMineFieldBreachObjInstance; } namespace NGL { class INGLLogger; } namespace TrainingAreaBase { class EquipmentGearEvent; class EquipmentBite; class DemandBiteRequest; } namespace ParticipantManagement { class ParticipantGearEvent; class StateInformation; } namespace AreaEffectSimulation { class ExplosionSingle; class ExplosionArea; class MineArea; class MineAreaModifyRequest; class MineSegment; class MineCorridor; class MineCorridorModifyRequest; class ExplosionSingleModifyRequest; class NContamination; class BCContamination; } namespace LtsCoordTrans { struct UtmCoordinate; } class ObserverGuezHumanCBNotifier; class ObserverGuezObserverControllerCBNotifier; class ObserverGuezGroundVehicleCBNotifier; class ObserverObjectCB; class ObserverBaseEntityObjectCB; class ObserverPhysicalEntityObjectCB; class ObserverPlatformObjectCB; class ObserverGroundVehicleObjectCB; class ObserverGuezGroundVehicleObjectCB; class ObserverLifeformObjectCB; class ObserverHumanObjectCB; class ObserverGuezHumanObjectCB; class ObserverGuezObserverControllerObjectCB; class ObserverGuezMineFieldCBNotifier; class ObserverGuezMineFieldBreachCBNotifier; class ObserverEnvironmentObjectObjectCB; class ObserverArealObjectObjectCB; class ObserverPointObjectObjectCB; class ObserverOtherArealObjectObjectCB; class ObserverOtherPointObjectObjectCB; class ObserverGuezMineFieldObjectCB; class ObserverGuezMineFieldBreachObjectCB; class ObserverMunitionDetonationCBNotifier; class ObserverWeaponFireCBNotifier; class ObserverGuezHitCBNotifier; class ObserverGuezInitCBNotifier; class ObserverGuezBiteReportCBNotifier; class ObserverGuezRequestBiteReportCBNotifier; class QTimer; struct GuezHitStruct { qint32 targetId = 0; qint64 sampleTime = 0; ProjectDataManagement::VulnerabilityState vulnerabilityState = ProjectDataManagement::VulnerabilityState_def::get_default(); qint32 vulnerabilityKind = 0; qint32 vulnerabilityBits = 0; Core::GeoPosition position = Core::GeoPosition(0, 0, 0); qint64 originatorId = 0; // So EIS fits completely! ProjectDataManagement::StateChangeOriginator originatorType = ProjectDataManagement::StateChangeOriginator_def::get_default(); QString originatorChargeTypeEtsString; }; namespace HighLevelArchitecture { class NgsHandler; class PlayerCallback; class DamageModel; class IdentifierStruct; class TypeStruct; struct ParticipantInformation; class NgsConnector : public QObject { Q_OBJECT void connectObserverObjectSignals(ObserverObjectCB *entity); void connectObserverBaseEntityObjectSignals(ObserverBaseEntityObjectCB *entity); void connectObserverPhysicalEntityObjectSignals(ObserverPhysicalEntityObjectCB *entity); void connectObserverPlatformObjectSignals(ObserverPlatformObjectCB *entity); void connectObserverGroundVehicleObjectSignals(ObserverGroundVehicleObjectCB *entity); void connectObserverGuezGroundVehicleObjectSignals(ObserverGuezGroundVehicleObjectCB *entity); void connectObserverLifeformObjectSignals(ObserverLifeformObjectCB *entity); void connectObserverHumanObjectSignals(ObserverHumanObjectCB *entity); void connectObserverGuezHumanObjectSignals(ObserverGuezHumanObjectCB *entity); void connectObserverGuezObserverControllerObjectSignals(ObserverGuezObserverControllerObjectCB *entity); void connectObserverEnvironmentObjectObjectSignals(ObserverEnvironmentObjectObjectCB *entity); void connectObserverArealObjectObjectSignals(ObserverArealObjectObjectCB *entity); void connectObserverPointObjectObjectSignals(ObserverPointObjectObjectCB *entity); void connectObserverOtherArealObjectObjectSignals(ObserverOtherArealObjectObjectCB *entity); void connectObserverOtherPointObjectObjectSignals(ObserverOtherPointObjectObjectCB *entity); void connectObserverGuezMineFieldObjectSignals(ObserverGuezMineFieldObjectCB *entity); void connectObserverGuezMineFieldBreachObjectSignals(ObserverGuezMineFieldBreachObjectCB *entity); void addObserverObjectInstance(const ngs::IObserverObjectInstance &obj); void removeObserverObjectInstance(const ngs::IObserverObjectInstance &obj); void ensureDamageModelExists(const IdentifierStruct &is); bool addBaseEntity(rpr2::IPlayerBaseEntityObjInstance *playerInstance, const ParticipantInformation &participantData); bool addPhysicalEntity(rpr2::IPlayerPhysicalEntityObjInstance *playerInstance, const ParticipantInformation &playerData); static rpr2::MarkingStruct toMarkingStruct(const QString &designator); static rpr2::ClockTimeStruct getClockTimeStruct(qint64 msecsSinceEpoch); static qint64 getMSecsSinceEpoch(const rpr2::ClockTimeStruct &cts); // rpr2::EntityTypeStruct getEtsCharge(int chargeType) const; template static rpr2::ArrayOfWorldLocationStructDynamicHLAlengthlessVarArray positionArray(const T &data); static inline QTransform fromRotation(double rot) { return QTransform().rotate(rot); } // static QPolygonF explosionArea(const AreaEffectSimulation::ExplosionArea &ea); // static QPolygonF mineAreaSegment(const AreaEffectSimulation::MineSegment &segment, double width, double density, bool bIsCenterline); // static QPolygonF mineCorridorSegment(const Core::GeoPosition2D &start, const Core::GeoPosition2D &end, double width); // static QPolygonF nContamination(const AreaEffectSimulation::NContamination &awf); // static std::vector bcReduction(const std::vector &form); static QPolygonF utmToGeogrphic(const QPolygonF &polyUtm, const LtsCoordTrans::UtmCoordinate &base); static rpr2::ArrayOfHLAoctetN_slsh_AperfectalwaysN_slsh_ADynamicHLApaddingTo32Array triggeredImpactsArray(const std::vector &data); static rpr2::HitResultEnum16::ET getHitResultEnum(const ProjectDataManagement::VulnerabilityState &ts); static ProjectDataManagement::VulnerabilityState getTacticalStatusEnum(const rpr2::HitResultEnum16::ET &hr); rpr2::EventIdentifierStruct getEventIdentifierStruct(); bool setVulnerabilityState(int eqNo, const ParticipantManagement::StateInformation &state); static rpr2::TacticalStatusStruct getTacticalStatusFromState(const ParticipantManagement::StateInformation &state); bool addMinefield(const rpr2::IObserverGuezMineFieldObjInstance *minefield); bool addMinefieldBreach(const rpr2::IObserverGuezMineFieldBreachObjInstance *minefieldBreach); int getEquipmentNoByRTIObjectId(const std::string &sender) const; static ngs::SimTime getSimTime(qint64 msecsSinceEpoch = 0); static ngs::SimTime getSimTime(const QDateTime &dateTime); IdentifierStruct getIdentifierStructbyEquipmentNo(const int eqId) const; public: NgsConnector(const QString &fedName, NgsHandler *ngsHandler); ~NgsConnector(); bool initialize(ngs::IObserver::ProtocolType protocol, const QString &playerName, const QString &appDirPath); void uninitialize(); bool canPublishData() const { return m_bCanPublishData; } bool addHuman(const ParticipantInformation &participantData, const rpr2::TacticalStatusStruct &state); bool addGroundVehicle(const ParticipantInformation &participantData, const rpr2::TacticalStatusStruct &state); bool addObserverController(const ParticipantInformation &participantData); bool removeBaseEntity(int eqNo); bool setParticipantName(int eqNo, const QString &designator); bool setParticipantForce(int eqNo, const rpr2::ForceIdentifierEnum8::ET forceIdentifier); // bool setParticipantHit(int eqNo, const ParticipantManagement::StateInformation &state, // const ParticipantPosition &partPos, int chargeType, // ProjectDataManagement::StateChangeOriginator originatorType, int originatorEqNo = 0); // bool setWeaponFire(int eqNo, const ParticipantManagement::ParticipantGearEvent &data); // bool setEquipmentBite(int eqNo, const TrainingAreaBase::EquipmentBite &data); // AES: bool removeAesItem(int objId); bool guezMineField(const WsTelegramMineFieldObject &data); // bool setItemForm(int aesItemId, int aesTypeId = 0, const std::vector &form = std::vector()); // bool setWorldLocation(int eqNo, const ParticipantPosition &pos, int eqNoHost = -1); // void sendMunitionDetonation(const ParticipantPosition &pos, int chargeTypeId, rpr2::ForceIdentifierEnum8::ET forceId); void sendParticipantBiteRequest(const int eqId, bool withSelfTest, qint64 simTimeMsecs); void sendParticipantInitRequest(const int eqId, bool resetManipulation, bool resetVulnerabilityState, bool restockCharges, qint64 simTimeMSecs); protected slots: void go(); void onFirstTickFinished(); signals: void spatialChanged(int eqId, const ParticipantPosition &pos, qint64 simTimeMSecs); void markingChanged(int eqId, const QString &marking, qint64 simTimeMSecs); void participantReceivedInit(int eqId, qint64 simTimeMSecs); void virtualParticipantDeleted(int eqId); void firstTickFinished(); void aesNameChanged(qint64 identifierInt, const std::string &name); void aesActivationTimeChanged(qint64 identifierInt, qint64 msecsSinceEpoch); void aesForceIdentifierChanged(qint64 identifierInt, int partyId); void aesDurationChanged(qint64 identifierInt, quint32 msecs); void aesChargeChanged(qint64 identifierInt, int chargeTypeId); void aesRoundsChanged(qint64 identifierInt, quint32 rounds); void aesDetonationLocationChanged(qint64 identifierInt, const ParticipantPosition &pos); void aesPointsDataChanged(quint64 eqId, const std::vector &form, qint64 simTimeMSecs); void aesRemoveItem(qint64 identifierInt); void munitionDetonation(AreaEffectSimulation::ExplosionSingleModifyRequest &explosion); void weaponFire(const TrainingAreaBase::EquipmentGearEvent &event); void guezHit(const GuezHitStruct &hitStruct); void guezInit(int eqNo, bool resetManipulation, bool resupplyAmmo, bool resetVulnerabilityState); void playerManipulationChanged(int eqNo, bool playerIsManipulated, qint64 simTimeMSecs); void isPartOfChanged(int eqNo, int eqNoHost, qint64 simTimeMSecs); // Host is null, if player unmounted void eventCountOverflow(); void biteReport(const TrainingAreaBase::EquipmentBite &report); void biteRequest(const TrainingAreaBase::DemandBiteRequest &request); void newMinefield(AreaEffectSimulation::MineAreaModifyRequest &ma); void newMinefieldBreach(AreaEffectSimulation::MineCorridorModifyRequest &mc); protected: void subscribeAtNgs(); void unsubscribeFromNgs(); int m_enitityNumberCounter; int m_eventCount; NgsHandler *m_ngsHandler; const QString m_fedName; ngs::ISimulatedWorldAdmin *m_swadmin; ngs::IFederationMaster *m_master; rpr2::IPlayerSOM *m_somPlayer; PlayerCallback *m_playerCallback; // Callbacks: ObserverGuezHumanCBNotifier *m_humanCallback; ObserverGuezObserverControllerCBNotifier *m_observerControllerCallback; ObserverGuezGroundVehicleCBNotifier *m_groundVehicleCallback; ObserverGuezMineFieldCBNotifier *m_minefieldCallback; ObserverGuezMineFieldBreachCBNotifier *m_minefieldBreachCallback; ObserverMunitionDetonationCBNotifier *m_munitionDetonationCallback; ObserverWeaponFireCBNotifier *m_weaponfireCallback; ObserverGuezHitCBNotifier *m_hitCallback; ObserverGuezInitCBNotifier *m_initCallback; ObserverGuezBiteReportCBNotifier *m_biteReportCallback; ObserverGuezRequestBiteReportCBNotifier *m_requestBiteReportCallback; QMap m_playerMap; // Key: EqNo // All Players, WE handle QMap m_observerPlayerInstances; // Key: EqNo // All of THEIR Players on the bus. QMap m_observerPositions; // Key: EqNo QMap m_damageModelMap; // Key: EqNo QSet m_newObjectsWithoutParticipantIdSet; QSet m_guezHitActive; QMap m_environmentObjects; // Key: AesId // All EOs, WE handle QMap m_observerEnvironmentObjects; // Key: AesId // All of THEIR EOs on the bus. QSet m_nonpublishedEnvironmentObjects; // AesId QMap > m_arealObjectSingleItems; // Key: AesId QMap > m_arealObjectForms; // Key: AesId QMap > m_arealObjectTriggeredImpacts; // Key: AesId bool m_bInitialized; bool m_bCanPublishData; QTimer *m_timer; // Todo: Start with 1 ms occurs! Needed? NGL::INGLLogger &m_logger; static quint16 s_ownSiteId; static quint16 s_ownApplicationId; static const int STATUS_WAIT_INTERVAL = 500; // Wartezeit auf Statusänderung static const int ACTIVATION_LEAD_TIME = 5000; // Vorlaufzeit beim Aktivieren von Wirkfeldern. private slots: void onEntityIdentifierChanged(const rpr2::EntityIdentifierStruct &eis, const rpr2::IObserverBaseEntityObjInstance *obj); bool onSpatialChanged(const rpr2::EntityIdentifierStruct &eis, const rpr2::WorldLocationStruct &wl, qint64 simTimeMSecs); void onEntityTypeChanged(const rpr2::EntityIdentifierStruct &eis, const rpr2::EntityTypeStruct &ets, qint64 simTimeMSecs); void onIsPartOfChanged(const rpr2::EntityIdentifierStruct &eis, const rpr2::IsPartOfStruct &ipos, qint64 simTimeMSecs); bool onMarkingChanged(const rpr2::EntityIdentifierStruct &eis, const rpr2::MarkingStruct &marking, qint64 simTimeMSecs); bool onPointsDataChanged(const rpr2::EntityIdentifierStruct &eis, const rpr2::ArrayOfWorldLocationStructDynamicHLAlengthlessVarArray &points, qint64 simTimeMSecs); bool onForceIdentifierChanged(const rpr2::EntityIdentifierStruct &eis, rpr2::ForceIdentifierEnum8::ET identifier, qint64 simTimeMSecs); bool onForceIdentifierChangedEO(const rpr2::EntityIdentifierStruct &eis, rpr2::ForceIdentifierEnum8::ET identifier, qint64 simTimeMSecs); bool onTacticalStatusChanged(const rpr2::EntityIdentifierStruct &eis, const rpr2::TacticalStatusStruct &rprStatus, qint64 simTimeMSecs); bool onDeactivatedChanged(const rpr2::EntityIdentifierStruct &eis, bool state, qint64 simTimeMSecs); bool onPercentCompleteChanged(const rpr2::EntityIdentifierStruct &eis, ngs::UINT32 state, qint64 simTimeMSecs); bool onObjectIdentifierChanged(const rpr2::EntityIdentifierStruct &eis, const rpr2::IObserverEnvironmentObjectObjInstance *obj); void onAreaEffectSimulationNameChanged(const rpr2::EntityIdentifierStruct &eis, const rpr2::OMT13string &value, qint64 simTimeMSecs); void onActivationTimeChanged(const rpr2::EntityIdentifierStruct &eis, const rpr2::ClockTimeStruct &value, qint64 simTimeMSecs); void onDurationChanged(const rpr2::EntityIdentifierStruct &eis, ngs::UINT32 value, qint64 simTimeMSecs); void onMineTypeChanged(const rpr2::EntityIdentifierStruct &eis, const rpr2::EntityTypeStruct &ets, qint64 simTimeMSecs); void onNewMunitionDetonation(const rpr2::IObserverMunitionDetonationIntInstance &interaction); void onNewWeaponFire(const rpr2::IObserverWeaponFireIntInstance &interaction); void onNewGuezHit(const rpr2::IObserverGuezHitIntInstance &interaction); void onNewGuezInit(const rpr2::IObserverGuezInitIntInstance &interaction); void onNewGuezBiteReport(const rpr2::IObserverGuezBiteReportIntInstance &interaction); void onNewGuezRequestBiteReport(const rpr2::IObserverGuezRequestBiteReportIntInstance &interaction); }; } // namespace