Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

@@ -0,0 +1,25 @@
#
# monitoring of the target areas
# $Id$
# $HeadURL$
# $Author$
#
SET(SRCS
handler_participant_gas_pipe.cpp
handler_participant_gas_pipe.h
plugin.cpp
plugin.h
)
NGL_ADD_LIBRARY(AAR SV cesPluginGasPipes MODULE ${SRCS})
NGL_TARGET_LINK_LIBRARIES(cesPluginGasPipes
Qt5::Network
Qt5::Widgets
cesPluginInterface
ngldb
svcCesDDSCommon
# ProjectConfig
)
NGL_INSTALL_TARGET(cesPluginGasPipes)
@@ -0,0 +1,408 @@
/**
* Handler for player data
* $Id$
* $HeadURL$
* $Author$
* Created by hjl, SLSE, 2017-02-20
*/
#include "handler_aes_data.h"
#include <CentralEffectSimulation/handler_participant.h>
//#include "main_handler.h"
#include "settings.h"
#include <QPainterPath>
#include <QPointF>
#include <QPolygonF>
#include <QTimer>
#include <QTransform>
#include <LtsUtilsCore/dds_bitarray.h>
#include <LtsUtilsCore/qpoint3d.h>
#include <LtsCoordTrans/lts_coord_trans.h>
namespace CentralEffectSimulationGasPipes
{
HandlerAesData::HandlerAesData(const std::shared_ptr<CentralEffectSimulation::DdsHandler> &ddsHandler,
QObject *parent)
: QObject(parent)
, m_ddsHandler(ddsHandler)
, m_handlerBuildingData(buildingDataHandler)
, m_logger(getLogger("HandlerAesData"))
{
} // end of ctor()
//-----------------------------------------------------------------------------
HandlerAesData::~HandlerAesData()
{
} // end of dtor()
//-----------------------------------------------------------------------------
bool HandlerAesData::init()
{
auto dtcAes = m_ddsHandler->dtcAes();
auto ftcTab = m_ddsHandler->ftcTab();
dtcAes->waitForHistoricalDataExplosionSingleCentral(20000);
ftcTab->enableSendCesHitInformation();
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::aesItemViewChanged,
this, &HandlerAesData::onAesItemViewChanged);
// Get 'static' data for all AesItemView
{
auto cb = [this](const AreaEffectSimulation::AesItemView & aiv)
{
onAesItemViewChanged(aiv, DataModification::eAdded);
};
if (!dtcAes->aesItemViews(cb))
return false;
}
return true;
} // end of init()
//-----------------------------------------------------------------------------
// ///////////////////////////////////
// A E S (AreaEffectSimulation)
// ///////////////////////////////////
void HandlerAesData::onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType)
{
if (modType != DataModification::eAdded &&
modType != DataModification::eModified)
return;
DEBUG_LOG(m_logger) << "Got AesItemView: " << data.effectStateId();
switch (data.effectStateId().underlying())
{
case AreaEffectSimulation::AesEffectState_def::EsUnknown:
case AreaEffectSimulation::AesEffectState_def::EsError:
case AreaEffectSimulation::AesEffectState_def::EsExpired:
case AreaEffectSimulation::AesEffectState_def::EsRemoved:
removeStates(data);
m_aesItemViews.remove(data.aesItemId());
break;
case AreaEffectSimulation::AesEffectState_def::EsPrepared:
case AreaEffectSimulation::AesEffectState_def::EsPaused:
case AreaEffectSimulation::AesEffectState_def::EsActivated:
m_aesItemViews.insert(data.aesItemId(), data);
break;
case AreaEffectSimulation::AesEffectState_def::EsCreated:
case AreaEffectSimulation::AesEffectState_def::EsReceived:
break;
}
}
void HandlerAesData::removeStates(const AreaEffectSimulation::AesItemView &data)
{
if (data.aesTypeId() != AreaEffectSimulation::AesType_def::AtExplosionArea)
return;
DEBUG_LOG(m_logger) << "Remove aesItemId=" << data.aesItemId();
} // end removeStates
void HandlerAesData::onExplosionSingleChanged(const AreaEffectSimulation::ExplosionSingle &data, DataModification modType)
{
bool handleExplosion = false;
if (modType != DataModification::eAdded &&
modType != DataModification::eModified)
{
m_explosionSingleState.remove(data.id());
return;
}
if (data.effectStateId() == AreaEffectSimulation::AesEffectState_def::EsRemoved)
{
DEBUG_LOG(m_logger) << "Remove SingleExplosion";
m_explosionSingleState.remove(data.id());
return;
}
// Only handle transitions from prepared to activated
if (m_explosionSingleState.value(data.id()) == AreaEffectSimulation::AesEffectState_def::EsPrepared
&& data.effectStateId() == AreaEffectSimulation::AesEffectState_def::EsActivated)
{
DEBUG_LOG(m_logger) << "Handle SingleExplosion";
handleExplosion = true;
}
m_explosionSingleState.insert(data.id(), data.effectStateId());
DEBUG_LOG(m_logger) << "Got ExplosionSingle";
if (handleExplosion)
{
const double impactRadius = m_ddsHandler->chargeTypeRadius(data.chargeTypeId());
DEBUG_LOG(m_logger) << "Handle ExplosionSingle (EsActivated)";
// Bounding-Box-Check
// QMap<int, Footprint> m_footprints;
for (const Footprint &footprint : qAsConst(m_footprints))
{
const QPointF impactPos(CentralEffectSimulation::geographic2Utm(data.impactPosition(), footprint.zone));
const QPolygonF polyBldgRadius({QPointF(footprint.boundingBoxPolyUtm.bottomLeft().rx() - impactRadius,
footprint.boundingBoxPolyUtm.bottomLeft().ry() + impactRadius),
QPointF(footprint.boundingBoxPolyUtm.topRight().rx() + impactRadius,
footprint.boundingBoxPolyUtm.bottomLeft().ry() + impactRadius),
QPointF(footprint.boundingBoxPolyUtm.topRight().rx() + impactRadius,
footprint.boundingBoxPolyUtm.topRight().ry() - impactRadius),
QPointF(footprint.boundingBoxPolyUtm.bottomLeft().rx() - impactRadius,
footprint.boundingBoxPolyUtm.topRight().ry() - impactRadius)});
if (polyBldgRadius.containsPoint(impactPos, Qt::OddEvenFill))
{
//calculateImpacts(data, footprint.mseId);
// check, if impact-pos + munition-radius touch the building
// get radius of munition
const Core::GeoPosition2D impactPosition(data.impactPosition().lon(), data.impactPosition().lat());
if (inFootprint(impactPosition, impactRadius, footprint))
{
DEBUG_LOG(m_logger) << "ftc sendCESHitOnBuilding mseId = " << footprint.mseId
<< " chargeTypeId = " << data.chargeTypeId()
<< " id = " << data.id()
<< " currentPartitionTime = " << m_ddsHandler->currentPartitionTime()
<< " impactPosition.lon = " << impactPosition.lon()
<< " impactPosition.lat = " << impactPosition.lat();
Buildings::SendCesHitOnBuildingRequest requestBld(
footprint.mseId,
data.chargeTypeId(),
data.id(),
m_ddsHandler->currentPartitionTime(),
Core::GeoPosition(impactPosition.lon(), impactPosition.lat(), 0.0));
m_ddsHandler->ftcBld()->sendCesHitOnBuildingRequest(requestBld, this);
}
else
DEBUG_LOG(m_logger) << "Not sendCESHitOnBuilding mseId = " << footprint.mseId;
DEBUG_LOG(m_logger) << "boundingBoxImpact.contains(footprint)";
}
} // for
}
} // onExplosionSingleChanged
void HandlerAesData::onAirSupportImpactChanged(const AreaEffectSimulation::AirSupportImpact &data, DataModification modType)
{
DEBUG_LOG(m_logger) << "Got onAirSupportImpactChanged()";
AreaEffectSimulation::ExplosionSingle esData;
esData.id(data.id());
esData.chargeTypeId(data.chargeTypeId());
esData.impactPosition(data.impactPosition());
esData.effectStateId(data.effectStateId());
onExplosionSingleChanged(esData, modType);
} // onExplosionSingleChanged
void HandlerAesData::onTriggeredImpactsChanged(const AreaEffectSimulation::TriggeredImpacts &data, DataModification modType)
{
if (modType != DataModification::eAdded &&
modType != DataModification::eModified)
return;
DEBUG_LOG(m_logger) << "Got TriggeredImpacts";
preCalculateImpacts(data);
}
// ///////////////////////////////////
// I S M (InfrastructureManagement)
// ///////////////////////////////////
void HandlerAesData::onMainFootprintChanged(const InfrastructureManagement::MainFootprint &data, DataModification modType)
{
switch (modType)
{
case DataModification::eAdded:
case DataModification::eModified:
DEBUG_LOG(m_logger) << "Got MainFootprint (Building)";
calculateFootprint(data);
break;
case DataModification::eRemoved:
m_footprints.remove(data.id());
break;
}
}
// ///////////////////////////////////
// Calculations:
// ///////////////////////////////////
void HandlerAesData::calculateFootprint(const InfrastructureManagement::MainFootprint &mainFootprint)
{
DEBUG_LOG(m_logger) << "Footprint: " << mainFootprint.id() << ": " << mainFootprint;
DEBUG_LOG(m_logger) << "Footprint: " << " mainFootprint.elements().size()=" << mainFootprint.elements().size();
// If poly is Empty continue with next Footprint
if (mainFootprint.elements().size() <= 0)
return;
const InfrastructureManagement::MainStructureElement mse
= m_handlerBuildingData->mainStructureElement(mainFootprint.id());
if (mse.id() != mainFootprint.id())
{
// not (yet) there
QTimer::singleShot(1000, this, [this, mainFootprint]() { calculateFootprint(mainFootprint); });
return;
}
// insert all Points to poly
QPolygonF poly;
poly.reserve(mainFootprint.elements().size());
for (const InfrastructureManagement::FootprintElement &element : mainFootprint.elements())
{
const auto &relPos = element.relPosition();
poly.push_back(QPointF(relPos.offsetX(), relPos.offsetY()));
}
// rotate poly
QTransform trans;
trans.rotate(mse.angle());
poly = trans.map(poly);
Footprint footprint;
footprint.mseId = mainFootprint.id();
footprint.geoPosition = mse.geoPosition();
const QPointF utmFpPosition = CentralEffectSimulation::geographic2Utm(footprint.geoPosition, &footprint.zone);
footprint.polyUtm.reserve(poly.size());
for (const QPointF &point : qAsConst(poly))
footprint.polyUtm.push_back(utmFpPosition + point);
footprint.boundingBoxPolyUtm = footprint.polyUtm.boundingRect();
m_footprints.insert(footprint.mseId, footprint);
}
bool HandlerAesData::inFootprint(const Core::GeoPosition2D &geoPosition, const double radius, const Footprint &footPrint) const
{
const QPointF impact(CentralEffectSimulation::geographic2Utm(geoPosition, footPrint.zone));
if (m_logger.isDebugEnabled())
{
const QPointF utmBuilding(CentralEffectSimulation::geographic2Utm(footPrint.geoPosition, footPrint.zone));
DEBUG_LOG(m_logger) << "Impact (x/y)=" << CentralEffectSimulation::debug(impact - utmBuilding);
for (int i = 0; i < footPrint.polyUtm.length(); i++)
DEBUG_LOG(m_logger) << " poly (x/y)=" << CentralEffectSimulation::debug(footPrint.polyUtm[i] - utmBuilding);
}
// Check, if hit direct on building
if (footPrint.polyUtm.containsPoint(impact, Qt::OddEvenFill))
return true;
// Check, if hit in munition-radius
QPainterPath ppFp;
ppFp.addPolygon(footPrint.polyUtm);
QPainterPath ppCircle;
ppCircle.addEllipse(impact, radius, radius);
return ppFp.intersects(ppCircle);
}
void HandlerAesData::preCalculateImpacts(const AreaEffectSimulation::TriggeredImpacts &data)
{
if (data.id() <= 0)
return;
DEBUG_LOG(m_logger) << "preCalculateImpacts";
// Find AES ItemView and set Bounding-Box of Aes-Field
// Search corresponding itemView and get boundingBox data in UTM
const bool bFound = m_aesItemViews.contains(data.aesItemId());
if (!bFound)
{
WARNING_LOG(m_logger) << "Could not find item view for aes with id " << data.aesItemId();
return;
}
// Bounding-Box-Check
// QMap<int, Footprint> m_footprints;
for (const Footprint &footprint : qAsConst(m_footprints))
{
//if (boundingBoxImpact.contains(footprint.boundingBoxPolyUtm))
calculateImpacts(data, footprint);
} // for
}
void HandlerAesData::onSendCesHitOnBuildingReply(const Core::FunctionReplyObject &replyObject)
{
if (replyObject.error())
WARNING_LOG(m_logger) << "Can not send hit on building to building service: " << replyObject();
else
DEBUG_LOG(m_logger) << "onSendCesHitOnBuildingReply for id " << replyObject.id() << " success\n"
<< " replyObject.str() = " << replyObject.str();
}
void HandlerAesData::onSendCesHitInformationReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
WARNING_LOG(m_logger) << "onSendCesHitInformationReply for id " << reply.id() << " failed: " << reply.str();
else
DEBUG_LOG(m_logger) << "onSendCesHitInformationReply for id " << reply.id() << " successful";
}
// calculate impacts for one building
void HandlerAesData::calculateImpacts(const AreaEffectSimulation::TriggeredImpacts &data, const Footprint &footprint)
{
// check for correct AES type artillery only
switch (data.aesTypeId().underlying())
{
case AreaEffectSimulation::AesType_def::AtExplosionArea:
case AreaEffectSimulation::AesType_def::AtExplosionSingle:
case AreaEffectSimulation::AesType_def::AtExplosionAreaSingleExplosions:
DEBUG_LOG(m_logger) << "Calculate";
break;
default:
DEBUG_LOG(m_logger) << "No Calculation";
return;
}
DEBUG_LOG(m_logger) << "calculateImpacts mseId=" << footprint.mseId << " data.aesItemId() " << data.aesItemId();
// get position(s) of impact(s):
// Search corresponding itemView. If not available no impact to participant.
auto it = m_aesItemViews.constFind(data.aesItemId());
if (it == m_aesItemViews.constEnd())
{
WARNING_LOG(m_logger) << "TriggeredExplosions.aesItemId=" << data.aesItemId() << " No aesItemView available";
return;
}
BitfieldStates &bitfieldStates = m_bitfieldStatesBld[footprint.mseId];
QSet<int> &bitfieldState = bitfieldStates[data.aesItemId()];
for (int i : qAsConst(bitfieldState))
DEBUG_LOG(m_logger) << "bitfieldState for " << data.aesItemId() << ": " << i;
const AreaEffectSimulation::AesItemView &aesItemView = *it;
for (int32_t bitFieldIdx = 0; bitFieldIdx < data.impactCount(); ++bitFieldIdx)
{
// no break, because every bit can be a hit
if (LtsUtils::BitArray::testBit(data.bitfield(), bitFieldIdx))
continue;
// get position of impact to corresponding bit
if (aesItemView.form().size() <= size_t(bitFieldIdx))
continue;
const Core::GeoPosition2D &impactPosition = aesItemView.form()[bitFieldIdx];
DEBUG_LOG(m_logger) << LOGFUNCTION
<< " impactPosition: lat/lon" << impactPosition.lat() << "/" << impactPosition.lon()
<< " UTM=" << CentralEffectSimulation::debug(CentralEffectSimulation::geographic2Utm(impactPosition));
// check, if impact-pos + munition-radius touch the building
// get radius of munition
const double impactRadius = m_ddsHandler->chargeTypeRadius(aesItemView.chargeTypeId());
if (inFootprint(impactPosition, impactRadius, footprint))
{
DEBUG_LOG(m_logger) << "In Footprint mseId = " << footprint.mseId;
if (!bitfieldState.contains(bitFieldIdx))
{
bitfieldState.insert(bitFieldIdx);
DEBUG_LOG(m_logger) << "m_bitfieldStates.insert(data.aesItemId()=" << data.aesItemId() << ", bitfieldState)" << " bitFieldIdx=" << bitFieldIdx;
DEBUG_LOG(m_logger) << "ftc sendCESHitOnBuilding mseId = " << footprint.mseId << " bitFieldIdx= " << bitFieldIdx ;
Buildings::SendCesHitOnBuildingRequest requestBld(
footprint.mseId,
aesItemView.chargeTypeId(),
aesItemView.aesItemId(),
m_ddsHandler->currentPartitionTime(),
Core::GeoPosition(impactPosition.lon(), impactPosition.lat(), 0.0));
m_ddsHandler->ftcBld()->sendCesHitOnBuildingRequest(requestBld, this);
}
}
} // foreach Impact
}
} // namespace CentralEffectSimulationGasPipes
@@ -0,0 +1,112 @@
/**
* Handler for player data
* $Id$
* $HeadURL$
* $Author$
* Created by gr, SLSE, 2017-02-20
*/
#pragma once
#include <CentralEffectSimulation/dds_handler.h>
#include "logger.h"
#include <AreaEffectSimulation/aes_dtc.h>
#include <ProjectDataManagement/pdm_dtc.h>
#include <TrainingAreaBase/tab_ftc.h>
#include <QtCore/QObject>
#include <QtCore/QMap>
#include <QtCore/QHash>
#include <QtCore/QVector>
#include <QPolygonF>
namespace LtsUtils
{
class QPoint3D;
}
// AES-Handling for gas pipes
namespace CentralEffectSimulationGasPipes
{
class HandlerAesData : public QObject
, protected TrainingAreaBase::Interface::Ftc::SendCesHitInformationReplyHandler
{
Q_OBJECT
public:
explicit HandlerAesData(const std::shared_ptr<CentralEffectSimulation::DdsHandler> &ddsHandler,
QObject *parent = nullptr);
~HandlerAesData();
/**
* Initialize the handler to manage information from player management
*/
bool init();
AreaEffectSimulation::AesItemView itemView(const int &aesId) const { return m_aesItemViews.value(aesId); }
protected:
void onSendCesHitInformationReply(const Core::FunctionReplyObject &reply) override final;
private slots:
/**
* Handle the signals from 'AES'
*/
void onExplosionSingleChanged(const AreaEffectSimulation::ExplosionSingle &data, DataModification modType);
void onAirSupportImpactChanged(const AreaEffectSimulation::AirSupportImpact &data, DataModification modType);
void onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType);
void onTriggeredImpactsChanged(const AreaEffectSimulation::TriggeredImpacts &data, DataModification modType);
/**
* Handle MainFootprint from 'ISM'
*/
void onMainFootprintChanged(const InfrastructureManagement::MainFootprint &data, DataModification modType);
void removeStates(const AreaEffectSimulation::AesItemView &data);
private: // structs
struct Footprint
{
int mseId = -1;
int zone = -1;
Core::GeoPosition geoPosition;
QPolygonF polyUtm;
QRectF boundingBoxPolyUtm;
bool isValid() const { return mseId > 0; }
};
typedef QHash<int, QSet<int>> BitfieldStates;
private: // methoden
void handleExplosionSingleCentral(const AreaEffectSimulation::AesItemView &itemView);
void calculateFootprint(const InfrastructureManagement::MainFootprint &mainFootprint);
bool inFootprint(const Core::GeoPosition2D &geoPosition, const double radius, const Footprint &footPrint) const;
void preCalculateImpacts(const AreaEffectSimulation::TriggeredImpacts &data);
void calculateImpacts(const AreaEffectSimulation::TriggeredImpacts &data, const Footprint &footprint);
double getRadiusOfMunition(const int32_t chargeTypeId) const;
private: // attributes
std::shared_ptr<CentralEffectSimulation::DdsHandler> m_ddsHandler; ///< Pointer to VOM DDS handler
QHash<int, Footprint> m_footprints; // key = footprint.mseId
// AES-Values
QHash<int, AreaEffectSimulation::AesItemView> m_aesItemViews; // key = aesItemId
QHash<int, AreaEffectSimulation::AesEffectState> m_explosionSingleState; // key = id value = state
NGL::INGLLogger &m_logger; ///< Interface to the Logging-Facility
};
} // namespace CentralEffectSimulationGasPipes
@@ -0,0 +1,327 @@
/**
* Handler for player data
* $Id$
* $HeadURL$
* $Author$
* Created by gr, SLSE, 2017-02-20
*/
#include "handler_participant_gas_pipe.h"
#include <QLineF>
#include <QTimer>
#include <LtsCoordTrans/lts_coord_trans.h>
namespace CentralEffectSimulationGasPipes
{
HandlerParticipantGasPipe::HandlerParticipantGasPipe(const std::shared_ptr<CentralEffectSimulation::DdsHandler> &ddsHandler,
const std::shared_ptr<CentralEffectSimulation::HandlerParticipant> &participantHandler,
QObject *parent)
: QObject(parent)
, m_ddsHandler(ddsHandler)
, m_handlerParticipant(participantHandler)
// , m_handlerAesData(aesDataHandler)
, m_gasPipes()
, m_requestMap()
, m_timer(new QTimer(this))
, m_logger(CentralEffectSimulation::getLogger("Plugin.VirtualMines.HandlerParticipantGasPipe"))
{
m_timer->setSingleShot(true);
connect(m_timer, &QTimer::timeout, this, &HandlerParticipantGasPipe::sendFtcCesHitRequestTimeout);
} // end of ctor()
//-----------------------------------------------------------------------------
HandlerParticipantGasPipe::~HandlerParticipantGasPipe()
{
} // end of dtor()
//-----------------------------------------------------------------------------
bool HandlerParticipantGasPipe::init()
{
INFO_LOG(m_logger) << "HandlerParticipantGasPipe::init";
auto dtcAes = m_ddsHandler->dtcAes();
dtcAes->waitForHistoricalDataGasPipe(2000);
dtcAes->enableAesItemView();
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::aesItemViewChanged,
this, &HandlerParticipantGasPipe::onAesItemViewChanged);
dtcAes->enableGasPipe();
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::gasPipeChanged,
this, &HandlerParticipantGasPipe::onGasPipeChanged);
//connect(m_handlerParticipant.get(), &HandlerParticipant::newIndoorPosition,
// this, &HandlerParticipantGasPipe::onParticipantPositionChanged);
//connect(m_handlerParticipant.get(), &HandlerParticipant::newOutdoorPosition,
// this, &HandlerParticipantGasPipe::onParticipantPositionChanged);
// Get 'static' data for all onAesItemView
{
auto cb = [this](const AreaEffectSimulation::AesItemView & aiv)
{
onAesItemViewChanged(aiv, DataModification::eAdded);
};
if (!dtcAes->aesItemViews(cb))
return false;
}
INFO_LOG(m_logger) << "HandlerParticipantGasPipe::init() finished. ";
return true;
} // end of init()
//-----------------------------------------------------------------------------
// ///////////////////////////////////
// A E S (AreaEffectSimulation)
// ///////////////////////////////////
void HandlerParticipantGasPipe::onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType)
{
INFO_LOG(m_logger) << "HandlerParticipantGasPipe::onAesItemViewChanged";
//
if (data.aesTypeId() != AreaEffectSimulation::AesType_def::AtGasPipe)
return;
const int aesItemId = data.aesItemId();
DEBUG_LOG(m_logger) << "Got AesItemView id: " << aesItemId
<< ", type: " << data.aesTypeId()
<< ", effectState: " << data.effectStateId()
<< ", modType: " << modType;
if (modType == DataModification::eRemoved)
{
m_gasPipes.remove(aesItemId);
return;
}
if (modType == DataModification::eAdded
|| modType == DataModification::eModified)
{
const AreaEffectSimulation::AesEffectState &effectState = data.effectStateId();
switch (effectState.underlying())
{
case AreaEffectSimulation::AesEffectState_def::EsActivated:
{
CentralEffectSimulation::AesItemViewUtm prevData;
const double impactRadius = 0;
prevData.aesItemId = 0;
const CentralEffectSimulation::AesItemViewUtm gasPipeUtm = CentralEffectSimulation::AesItemViewUtm::create(data, prevData, impactRadius);
m_gasPipes.insert(data.aesItemId(), gasPipeUtm);
DEBUG_LOG(m_logger) << "Check each participant";
// Check each participant
const auto partPosMap = m_handlerParticipant->positions();
for (const auto &participantPos : partPosMap)
{
if (m_handlerParticipant->isOutdated(participantPos))
{
DEBUG_LOG(m_logger) << "isOutdated participantId=" << participantPos.participantId();
continue;
}
const CentralEffectSimulation::AesItemViewUtm gasPipe = m_gasPipes.value(data.aesItemId());
calculateGasPipeParticipant(gasPipe, participantPos);
}
break;
}
default:
{
DEBUG_LOG(m_logger) << "remove GasPipe";
m_gasPipes.remove(aesItemId);
}
}
return;
}
} // onAesItemViewChanged
void HandlerParticipantGasPipe::onGasPipeChanged(const AreaEffectSimulation::GasPipe &data, DataModification modType)
{
INFO_LOG(m_logger) << "HandlerParticipantGasPipe::onGasPipeChanged id=" << data.id();
if (modType == DataModification::eRemoved)
{
return;
}
}
bool HandlerParticipantGasPipe::insideGasPipeArea(const QPolygonF &polygonf, const QPointF &participantPos) const
{
DEBUG_LOG(m_logger) << "pos to check: " << CentralEffectSimulation::debug(participantPos) ;
return polygonf.containsPoint(participantPos, Qt::OddEvenFill);
}
void HandlerParticipantGasPipe::calculateGasPipeParticipant(const CentralEffectSimulation::AesItemViewUtm &gasPipe,
const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPosition)
{
//const AesItemViewUtm gasPipe = m_gasPipes.value(itemView.aesItemId());
const QPointF partPosGeo = CentralEffectSimulation::geographic2Utm(participantPosition.pos(), gasPipe.zone);
DEBUG_LOG(m_logger) << "calculateGasPipeParticipant itemView.id=" << gasPipe.aesItemId
<< " participantId=" << participantPosition.participantId();
DEBUG_LOG(m_logger) << "gasPipe id = " << gasPipe.aesItemId
<< ", Box bottomLeft = " << CentralEffectSimulation::debug(gasPipe.boundingBoxBottomLeft)
<< ", topRight = " << CentralEffectSimulation::debug(gasPipe.boundingBoxTopRight);
const QPolygonF boundingBoxGasPipe({QPointF(gasPipe.boundingBoxBottomLeft.x(),
gasPipe.boundingBoxBottomLeft.y()),
QPointF(gasPipe.boundingBoxTopRight.x(),
gasPipe.boundingBoxBottomLeft.y()),
QPointF(gasPipe.boundingBoxTopRight.x(),
gasPipe.boundingBoxTopRight.y()),
QPointF(gasPipe.boundingBoxBottomLeft.x(),
gasPipe.boundingBoxTopRight.y())
});
if (!boundingBoxGasPipe.containsPoint(partPosGeo, Qt::OddEvenFill))
{
DEBUG_LOG(m_logger) << "not in boundingBox";
return;
}
const bool result = insideGasPipeArea(gasPipe.form, partPosGeo);
DEBUG_LOG(m_logger) << "result gasPipe Explosion = " << result;
if (result)
{
DEBUG_LOG(m_logger) << "sendParticipantEvent";
sendParticipantEvent(gasPipe, participantPosition, ProjectDataManagement::EventType_def::HitGasPipe);
DEBUG_LOG(m_logger) << "sendParticipantHit";
sendParticipantHit(gasPipe, participantPosition, ProjectDataManagement::EventType_def::HitGasPipe);
}
}
void HandlerParticipantGasPipe::onParticipantPositionChanged(const CentralEffectSimulation::HandlerParticipant::CesParticipantData &partPos)
{
bool result = false;
// Bounding Box von der Linie
DEBUG_LOG(m_logger) << "ParicipantPos "
<< " participantId=" << partPos.participantId()
<< " participantTypeId=" << partPos.participantTypeId()
<< " participantPos: lat=" << partPos.pos().lat()
<< " lon=" << partPos.pos().lon()
<< " Anzahl GasPipes=" << m_gasPipes.size();
for (const CentralEffectSimulation::AesItemViewUtm &gasPipe : qAsConst(m_gasPipes))
{
calculateGasPipeParticipant(gasPipe, partPos);
const QPointF partPosGeo = CentralEffectSimulation::geographic2Utm(partPos.pos(), gasPipe.zone);
DEBUG_LOG(m_logger) << "gasPipe id = " << gasPipe.aesItemId
<< ", Box bottomLeft = " << CentralEffectSimulation::debug(gasPipe.boundingBoxBottomLeft)
<< ", topRight = " << CentralEffectSimulation::debug(gasPipe.boundingBoxTopRight);
// if (!m_gasPipes.value(gasPipe.aesItemId).containsPoint(partPosGeo, Qt::OddEvenFill))
// continue;
result = insideGasPipeArea(gasPipe.form, partPosGeo);
DEBUG_LOG(m_logger) << "result gasPipe Explosion = " << result<< gasPipe.aesItemId;
if (result)
sendParticipantEvent(gasPipe, partPos, ProjectDataManagement::EventType_def::HitGasPipe);
}
} // end of onParticipantPositionChanged()
//-----------------------------------------------------------------------------
// ///////////////////////////////////
// P D M (ProjectDataManagement)
// ///////////////////////////////////
// Search for corresponding aesItemView
// Check for all participants wheter he is in the explosion area
void HandlerParticipantGasPipe::sendParticipantEvent(const CentralEffectSimulation::AesItemViewUtm &gasPipe,
const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPosition,
const ProjectDataManagement::EventType eventType)
{
ParticipantManagement::TypeClass typeClass = m_handlerParticipant->typeClassFromTypeId(participantPosition.participantTypeId());
if (typeClass == ParticipantManagement::TypeClass_def::Unit ||
typeClass == ParticipantManagement::TypeClass_def::SupportUnit ||
typeClass == ParticipantManagement::TypeClass_def::SupportEntity ||
typeClass == ParticipantManagement::TypeClass_def::Unknown)
return;
int equipmentNumber = m_ddsHandler->participantId2EquipNo(participantPosition.participantId());
if (equipmentNumber <= 0)
return;
const AreaEffectSimulation::GasPipe &gp = m_ddsHandler->dtcAes()->gasPipe(gasPipe.aesItemId);
CentralEffectSimulation::ParticipantEvent pe;
DEBUG_LOG(m_logger) << "sendParticipantEvent participantId=" << participantPosition.participantId()
<< " lat= " << participantPosition.pos().lat()
<< " lon= " << participantPosition.pos().lon()
<< " equipmentNumber=" << equipmentNumber
<< " eventType=" << eventType;
pe.id(m_ddsHandler->getParticipantEventId());
pe.eventTypeId(eventType);
pe.participantId(participantPosition.participantId());
pe.eventTime(participantPosition.sampleTime());
pe.aesItemId(gasPipe.aesItemId);
pe.partyId(participantPosition.partyId());
pe.aesName(gp.name());
pe.equipmentNumber(equipmentNumber);
pe.position(participantPosition.pos());
m_ddsHandler->dtsCes()->publish(pe);
qint64 id = pe.id();
QTimer::singleShot(1 * 60 * 1000, this, [id, this]() { m_ddsHandler->dtsCes()->removeParticipantEventByKey(id); });
}
void HandlerParticipantGasPipe::sendParticipantHit(const CentralEffectSimulation::AesItemViewUtm &gasPipe,
const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPosition,
const ProjectDataManagement::EventType eventType)
{
const int equipNo = m_ddsHandler->participantId2EquipNo(participantPosition.participantId());
const int participantId = participantPosition.participantId();
const int originatorEquipNo = 0;
DEBUG_LOG(m_logger) << "sendParticipantHit participantId=" << participantId
<< " equipmentNumber=" << equipNo;
Core::GeoPosition position;
position.lat(participantPosition.pos().lat());
position.lon(participantPosition.pos().lon());
const TrainingAreaBase::TabPosition pos(position, participantPosition.reportingSource(), 0, 0);
//pos.position(position);
//pos.reportingSource(participantPosition.reportingSource());
TrainingAreaBase::SendCesHitRequest requestTab(
equipNo, // equipmentNumber
participantId, // participantId
gasPipe.chargeTypeId, // chargeTypeId
gasPipe.aesItemId, // aesId
originatorEquipNo, // originatorEquipmentNumber
100, // IED heavy
pos,
gasPipe.effectStart, // effectTime
eventType,
gasPipe.partyId, // originPartyId
0
);
m_requestMap.insert(equipNo, requestTab);
if (!m_timer->isActive() && !m_requestMap.isEmpty())
m_timer->start(1000);
}
void HandlerParticipantGasPipe::onSendCesHitReply(const Core::FunctionReplyObject &replyObject)
{
//if (replyObject.error())
// WARNING_LOG(m_logger) << "Can not send hit on participant to training area: " << replyObject();
//else
DEBUG_LOG(m_logger) << "onSendCesHitReply for id " << replyObject.id() << " success";
}
void HandlerParticipantGasPipe::sendFtcCesHitRequestTimeout()
{
auto ftcTab = m_ddsHandler->ftcTab();
for (const TrainingAreaBase::SendCesHitRequest &hr : qAsConst(m_requestMap))
{
DEBUG_LOG(m_logger) << "sendFtcCesHitRequestTimeout: " << hr;
ftcTab->sendCesHitRequest(hr, this);
}
m_requestMap.clear();
}
} // namespace CentralEffectSimulationGasPipes
@@ -0,0 +1,95 @@
/**
* Handler for player data
* $Id$
* $HeadURL$
* $Author$
* Created by gr, SLSE, 2017-02-20
*/
#pragma once
#include <QObject>
#include <QHash>
#include <QRectF>
#include <QPolygonF>
#include <CentralEffectSimulation/dds_handler.h>
#include <handler_aes_data.h>
#include <CentralEffectSimulation/aes_item_view_utm.h>
#include <AreaEffectSimulation/aes_dtc.h>
#include <CentralEffectSimulation/handler_participant.h>
#include <QTimer>
// AES-Handling for participants
namespace CentralEffectSimulationGasPipes
{
class HandlerParticipantGasPipe final : public QObject
, protected TrainingAreaBase::Interface::Ftc::SendCesHitReplyHandler
{
Q_OBJECT
public:
HandlerParticipantGasPipe(const std::shared_ptr<CentralEffectSimulation::DdsHandler> &ddsHandler,
const std::shared_ptr<CentralEffectSimulation::HandlerParticipant> &participantHandler,
QObject *parent = nullptr);
~HandlerParticipantGasPipe();
/**
* Initialize the handler to manage information from player management
*/
bool init();
protected:
void onSendCesHitReply(const Core::FunctionReplyObject &replyObject) override final;
private Q_SLOTS:
/**
* Handle the signals from 'ParticipantHandler'
*/
void onParticipantPositionChanged(const CentralEffectSimulation::HandlerParticipant::CesParticipantData &partPos);
/**
* Handle the signals from 'AES'
*/
void onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType);
void onGasPipeChanged(const AreaEffectSimulation::GasPipe &data, DataModification modType);
/**
* Send Hit to participant
*/
void sendFtcCesHitRequestTimeout();
private: // methoden
void sendParticipantEvent(const CentralEffectSimulation::AesItemViewUtm &gasPipe,
const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPosition,
const ProjectDataManagement::EventType eventType);
void sendParticipantHit(const CentralEffectSimulation::AesItemViewUtm &gasPipe,
const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPosition,
const ProjectDataManagement::EventType eventType);
bool insideGasPipeArea(const QPolygonF &polygonf, const QPointF &participantPos) const;
void calculateGasPipeParticipant(const CentralEffectSimulation::AesItemViewUtm &gasPipe,
const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPosition);
private: // attributes
std::shared_ptr<CentralEffectSimulation::DdsHandler> m_ddsHandler; ///< Pointer to VOM DDS handler
std::shared_ptr<CentralEffectSimulation::HandlerParticipant> m_handlerParticipant;
// std::shared_ptr<HandlerAesData> m_handlerAesData;
// AES-Values
QHash<int, CentralEffectSimulation::AesItemViewUtm> m_gasPipes; // key = aesItemId
QHash<int, TrainingAreaBase::SendCesHitRequest> m_requestMap; // Key = equipmentNumber
QTimer *m_timer;
CentralEffectSimulation::LOGGER_T &m_logger; ///< Interface to the Logging-Facility};
};
} // namespace CentralEffectSimulationGasPipes
@@ -0,0 +1,93 @@
/**
* Plugin Ces Virtual Mines
* $Id$
* $HeadURL$
* $Author$
* Created by Gerlinde Rudolphus, SLTE, 2016-04-14
*/
#include "plugin.h"
#include <ngldb/db_service_handler.h>
namespace CesGasPipes
{
std::shared_ptr<CentralEffectSimulation::Plugin::Interface> CesGasPipesPlugin::createInterface(CentralEffectSimulation::Plugin::DataProvider *pdp,
const std::shared_ptr<DDSConnector::DdsConnector> &dDSConnector,
NGL::Settings *settings,
CentralEffectSimulation::MainHandler *mainHandler)
{
return std::make_shared<CesGasPipesInterfaceImpl>(pdp, dDSConnector, settings, mainHandler);
}
CesGasPipesInterfaceImpl::CesGasPipesInterfaceImpl(CentralEffectSimulation::Plugin::DataProvider *pdp,
const std::shared_ptr<DDSConnector::DdsConnector> &dDSConnector,
NGL::Settings *settings,
CentralEffectSimulation::MainHandler *mainHandler)
: m_pdp(pdp)
, m_ddsConnector(dDSConnector)
, m_mainHandler(mainHandler)
, m_ddsHandler(m_mainHandler->dds())
, m_db(m_mainHandler->db())
, m_handlerParticipant(m_mainHandler->handlerParticipant())
, m_logger(CentralEffectSimulation::getLogger("Plugin.GasPipes.CesMinesInterfaceImpl"))
{
Q_UNUSED(settings)
}
CesGasPipesInterfaceImpl::~CesGasPipesInterfaceImpl()
{
// m_handlerParticipantBoobyTrap.reset();
// m_handlerParticipantOffRouteMine.reset();
}
bool CesGasPipesInterfaceImpl::init(int domainId, int exerciseId)
{
m_domainId = domainId;
m_exerciseId = exerciseId;
INFO_LOG(m_logger) << "CesGasPipesInterfaceImpl::init()"
<< " m_domainId=" << m_domainId
<< " m_exerciseId=" << m_exerciseId;
// // initialize handlerBoobyTrap
// m_handlerParticipantBoobyTrap = std::make_shared<HandlerParticipantBoobyTrap>(m_ddsHandler,
// m_handlerParticipant,
// this);
// if (!m_handlerParticipantBoobyTrap->init())
// {
// ERROR_LOG(m_logger) << "Initialisation m_handlerParticipantBoobyTrap failed.";
// return false;
// }
// // initialize offRouteMine
// m_handlerParticipantOffRouteMine = std::make_shared<HandlerParticipantOffRouteMine>(m_ddsHandler,
// m_handlerParticipant,
// this);
// if (!m_handlerParticipantOffRouteMine->init())
// {
// ERROR_LOG(m_logger) << "Initialisation m_handlerParticipantOffRouteMine failed.";
// return false;
// }
return true;
}
QString CesGasPipesInterfaceImpl::echo(const QString &message)
{
QString ret(QStringLiteral("<<<< %1 >>>> CesGasPipesInterfaceImpl::echo").arg(message));
INFO_LOG(m_logger) << "CesGasPipesInterfaceImpl::echo return:" << ret;
DEBUG_LOG(m_logger) << "DEBUG: CesGasPipesInterfaceImpl::echo return:" << ret;
return ret;
}
} //namespace CesGasPipes
@@ -0,0 +1,74 @@
/**
* Plugin Ces Virtual Mines
* $Id$
* $HeadURL$
* $Author$
* Created by Gerlinde Rudolphus, SLTE, 2016-04-14
*/
#pragma once
#include <CentralEffectSimulation/logger.h>
#include <CentralEffectSimulation/ces_plugin_interface.h>
#include <CentralEffectSimulation/main_handler.h>
#include <CentralEffectSimulation/dds_handler.h>
#include <DDS/DDSConnector/dds_connector.h>
#include <QObject>
namespace CesGasPipes
{
class CesGasPipesPlugin : public QObject, public CentralEffectSimulation::Plugin::Plugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "special:3:ces.CesGasPipesPlugin")
Q_INTERFACES(CentralEffectSimulation::Plugin::Plugin)
public:
CesGasPipesPlugin() = default;
~CesGasPipesPlugin() = default;
std::shared_ptr<CentralEffectSimulation::Plugin::Interface> createInterface(CentralEffectSimulation::Plugin::DataProvider *pdp,
const std::shared_ptr<DDSConnector::DdsConnector> &dDSConnector,
NGL::Settings *settings,
CentralEffectSimulation::MainHandler *mainHandler) override;
};
class CesGasPipesInterfaceImpl final : public CentralEffectSimulation::Plugin::Interface
{
Q_OBJECT
public:
CesGasPipesInterfaceImpl(CentralEffectSimulation::Plugin::DataProvider *pdp,
const std::shared_ptr<DDSConnector::DdsConnector> &dDSConnector,
NGL::Settings *settings,
CentralEffectSimulation::MainHandler *mainHandler);
~CesGasPipesInterfaceImpl();
//bool init();
const char *name() const override { return "CentralEffectGasPipes"; }
QString echo(const QString &message) override;
private Q_SLOTS:
bool init(int domainId, int exerciseId) override;
private:
private:
CentralEffectSimulation::Plugin::DataProvider *m_pdp;
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
CentralEffectSimulation::MainHandler *m_mainHandler{nullptr};
std::shared_ptr<CentralEffectSimulation::DdsHandler> m_ddsHandler;
std::shared_ptr<CentralEffectSimulation::DatabaseInterface> m_db;
std::shared_ptr<CentralEffectSimulation::HandlerParticipant> m_handlerParticipant; ///< Pointer to handler for all participants
// std::shared_ptr<HandlerParticipantBoobyTrap> m_handlerParticipantBoobyTrap; ///< Pointer to handler for BoobyTrap
// std::shared_ptr<HandlerParticipantOffRouteMine> m_handlerParticipantOffRouteMine; ///< Pointer to handler for OffRouteMine
CentralEffectSimulation::LOGGER_T &m_logger; ///< Interface to the Logging-Facility
int m_domainId = 0;
int m_exerciseId = 0;
};
} // namespace CesGasPipes