Files
qt5-legatus-legacy/Lts/Services/AreaEffectSimulation/ModuleTest_EffectCluster/effect_cluster_module_test.cpp
T
2026-08-13 18:33:10 +02:00

943 lines
34 KiB
C++
Executable File

/**
* @RDE_HEADER@
* ModuleTest
* $Id$
* $HeadURL$
* $Author$
*/
#include "effect_cluster_module_test.h"
#include <LtsCoordTrans/lts_coord_trans.h>
#include <nglapplication/nglcoreapplication.h>
// AES
#include <AreaEffectSimulation/Utils/polygons.h>
#include <AreaEffectSimulation/aes_dtc.h>
// PPM
#include "ParticipantManagement/ppm_ftc_types.h"
#include "TrainingAreaBase/tab.hpp"
#include <QDateTime>
#include <QDebug>
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QTimer>
#include <QVector>
#include <QXmlStreamReader>
#include <iostream>
using namespace AreaEffectSimulation;
using namespace LtsCoordTrans;
static QString s_REQUEST_SPL_FILE = QStringLiteral("EffectClusterModifyRequest_ESG.spl");
//
// some helper functions
//
template <typename T> dds::core::optional<T> toOptional(T inVal) { return inVal != T() ? dds::core::optional<T>(inVal) : dds::core::optional<T>(); }
template <typename T> dds::core::optional<T> optional() { return dds::core::optional<T>(); }
// mathematical positive north -> mathematical negativ, east = 0°, 0,01 degree in 1/100° -> factor 100
static inline int compassToMathAngleForSfm(double compassDegree)
{
int ret = qRound((90.0 - compassDegree) * 100.0);
while (ret < 0)
ret += 36000;
while (ret > 36000)
ret -= 36000;
return ret;
}
double distanceMeter(const LtsCoordTrans::UtmCoordinate &utmCoord1, const LtsCoordTrans::UtmCoordinate &utmCoord2)
{
double dist = LtsCoordTrans::distance(utmCoord1, utmCoord2);
return dist;
}
double distanceMeter(const Core::GeoPosition &geoPos, const LtsCoordTrans::UtmCoordinate &utmCoord)
{
const LtsCoordTrans::UtmCoordinate &utmPos = LtsCoordTrans::UtmCoordinate::fromGeographic(geoPos.lon(), geoPos.lat());
return distanceMeter(utmPos, utmCoord);
}
double distanceMeter(const Core::GeoPosition2D &geoPos2D, const LtsCoordTrans::UtmCoordinate &utmCoord)
{
const LtsCoordTrans::UtmCoordinate &utmPos = LtsCoordTrans::UtmCoordinate::fromGeographic(geoPos2D.lon(), geoPos2D.lat());
return distanceMeter(utmPos, utmCoord);
}
ModuleTestEffectCluster::ModuleTestEffectCluster(int domainId, int exerciseId)
: m_domainId(domainId)
, m_exerciseId(exerciseId)
, m_logger(getLogger("ModuleTestEffectCluster"))
{
m_timer = new QTimer(this);
m_timer->setSingleShot(true);
connect(m_timer,
&QTimer::timeout,
this,
[this]()
{
DEBUG_LOG(m_logger) << "Wirkfeldplanung";
doEffectClusterModifyRequest();
});
}
void ModuleTestEffectCluster::onEffectClusterModifyReply(const Core::FunctionReplyObject &replyObject)
{
m_replyError = replyObject.error();
DEBUG_LOG(m_logger) << " got reply - onEffectClusterModifyReply: " << m_replyError << ", aesItemId=" << replyObject.id();
m_aesItemId = replyObject.id();
if (!replyObject.str().empty())
ERROR_LOG(m_logger) << " got reply - onEffectClusterModifyReply: " << replyObject.translated();
}
void ModuleTestEffectCluster::onAcknowledgeExternalAesItemReply(const Core::FunctionReplyObject &replyObject)
{
m_replyError = replyObject.error();
DEBUG_LOG(m_logger) << " got reply - onAcknowledgeExternalAesItemReply: " << m_replyError;
sendTabExFire();
// AES::EffectState von ES_Received -> ES_Created
if (!replyObject.str().empty())
ERROR_LOG(m_logger) << " got reply - onAcknowledgeExternalAesItemReply: " << replyObject.translated();
}
void ModuleTestEffectCluster::onModifyPartyDataReply(const Core::FunctionReplyObject &replyObject)
{
m_replyError = replyObject.error();
DEBUG_LOG(m_logger) << " got reply - onModifyPartyDataReply: " << m_replyError << " " << replyObject.additionalInfo();
if (!replyObject.str().empty())
ERROR_LOG(m_logger) << " got reply - onModifyPartyDataReply: " << replyObject.translated();
if (!m_participantChangeRequestDone)
{
participantChangeRequest();
m_participantChangeRequestDone = true;
}
}
void ModuleTestEffectCluster::onModifyParticipantDataReply(const Core::FunctionReplyObject &replyObject)
{
m_replyError = replyObject.error();
DEBUG_LOG(m_logger) << " \n\ngot reply - onModifyParticipantDataReply error: " << m_replyError << ", additionalInfo: " << replyObject.additionalInfo();
if (!replyObject.str().empty())
ERROR_LOG(m_logger) << " got reply - onModifyParticipantDataReply: " << replyObject.translated();
DEBUG_LOG(m_logger) << "onModifyParticipantDataReply => Set Participant Pos";
QJsonArray jsonArray = QJsonDocument::fromJson(QByteArray::fromStdString(replyObject.additionalInfo())).object().value(QLatin1String("participants")).toArray();
DEBUG_LOG(m_logger) << "available_in_exercise jsonDocument.size()=" << jsonArray.size();
// ParticipantId aus dem Result bestimmen, keine Unit
// Dieser einfache Test arbeitet mit einem Participant
for (auto it = jsonArray.constBegin(); it != jsonArray.constEnd(); ++it)
{
int participantId = it->toInt();
DEBUG_LOG(m_logger) << "participantId=" << participantId;
ParticipantManagement::Participant participant = m_ppmDtc->participant(participantId);
if (m_ppmDtc->type(participant.typeId()).typeClass().underlying() != ParticipantManagement::TypeClass::Unit)
{
DEBUG_LOG(m_logger) << "m_participant1.id=" << participantId;
m_participant1.id(participantId); // wichtig zum loeschen
DEBUG_LOG(m_logger) << "m_participantId keine Unit=" << participantId;
setParticipantPos(participantId);
setEquipmentGearCharge(participantId);
// Wirkfeldplanung
if (!m_timer->isActive())
m_timer->start(500);
}
else
{
DEBUG_LOG(m_logger) << "m_participant0.id=" << participantId;
m_participant0.id(participantId); // wichtig zum loeschen
}
}
}
void ModuleTestEffectCluster::onAesItemViewChanged(const AesItemView &aesItemView, DataModification modType)
{
if (modType == DataModification::eRemoved)
return;
AreaEffectSimulation::AesType_def::type aesType = aesItemView.aesTypeId().underlying();
if (aesType != AreaEffectSimulation::AesType_def::AtEffectCluster)
return;
if (aesItemView.aesItemId() != m_aesItemId)
return;
DEBUG_LOG(m_logger) << " got onAesItemViewChanged: "
<< ", aesItemId=" << aesItemView.aesItemId() << ", aesType=" << aesType << ", effectStateId=" << aesItemView.effectStateId();
QCOMPARE(aesItemView.effectStateId(), m_effectStates[m_effectStateCounter]);
m_effectStateCounter++;
if (aesItemView.effectStateId() == AreaEffectSimulation::AesEffectState::EsReceived)
{
DEBUG_LOG(m_logger) << "sendAcknowledgeExternalAesItemRequest aesItemId=" << aesItemView.aesItemId();
sendAcknowledgeExternalAesItemRequest(aesItemView.aesItemId());
}
}
void ModuleTestEffectCluster::sendTabExFire()
{
DEBUG_LOG(m_logger) << "sendTabExFire";
TrainingAreaBase::EX_Fire exFire;
exFire.effectorId(m_effectorId); // Kenner z.B B1
exFire.identifier(m_identifier.toStdString()); // Verein z.B 451100
exFire.reference(m_reference.toStdString()); // UUID Feuerkampf
exFire.equipmentNumber(m_participant1.id() * -1);
exFire.sampleTime(QDateTime::currentMSecsSinceEpoch() + 500);
m_tabDts->publish(exFire);
}
void ModuleTestEffectCluster::onEffectsChanged(const Effects &effects, DataModification modType)
{
if (modType == DataModification::eRemoved)
return;
AreaEffectSimulation::AesType_def::type aesType = effects.aesTypeId().underlying();
DEBUG_LOG(m_logger) << " got onEffectsChanged - m_data: " << m_data.id() << ", aesType=" << aesType;
++m_counterDds.cntEffectClusterEffects;
m_effects = effects;
DEBUG_LOG(m_logger) << " got onEffectsChanged - m_effects: " << m_effects;
}
void ModuleTestEffectCluster::onChargeEffectChanged(const ChargeEffect &chargeEffect, DataModification modType)
{
DEBUG_LOG(m_logger) << "onChargeEffectChanged state=" << chargeEffect.state();
if (modType == DataModification::eRemoved)
return;
if (chargeEffect.state() == AreaEffectSimulation::AesEffectState::EsActivated)
{
// Compare Position
// mhpPosition.lon(0.201958);
// mhpPosition.lat(0.915263);
// mhpPosition.z(88.0);
double lon = qRound64(chargeEffect.position().lon() * 100000) / 100000.0; // Nur die ersten 5 Nachkommastellen beruecksichtigen
double lat = qRound64(chargeEffect.position().lat() * 100000) / 100000.0;
QCOMPARE(lon, 0.20196);
QCOMPARE(lat, 0.91526);
QCOMPARE(chargeEffect.position().z(), 88.0);
}
else if (chargeEffect.state() == AreaEffectSimulation::AesEffectState::EsExpired)
participantDeleteRequest();
DEBUG_LOG(m_logger) << " got onEffectsChanged - m_effects: " << m_effects;
}
void ModuleTestEffectCluster::onTrajectoryTimeAwareChanged(const TrajectoryTimeAware &data, DataModification modType)
{
Q_UNUSED(modType);
if (data.id() == -1)
return;
++m_counterDds.cntTrajectory;
DEBUG_LOG(m_logger) << " got TrajectoryTimeAwareChanged - data: " << data.id() << ", cntTrajectory=" << m_counterDds.cntTrajectory;
}
void ModuleTestEffectCluster::dumpCnt()
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " Counter: "
<< " cntEffectCluster = " << m_counterDds.cntEffectCluster << ", cntAtEffectCluster = " << m_counterDds.cntAtEffectCluster
<< ", cntGunToTargetLine = " << m_counterDds.cntAtEffectClusterGunToTargetLine << ", cntClusterEffects = " << m_counterDds.cntEffectClusterEffects
<< ", cntTrajectory = " << m_counterDds.cntTrajectory;
}
bool ModuleTestEffectCluster::waitForData(const std::function<bool()> &func, int retryCount)
{
// Maybe give QTRY_VERIFY2 or QTRY_VERIFY2_WITH_TIMEOUT a chance
// Or better QTRY_IMPL ??
// QTRY_IMPL(m_replyError == false, 1);
// wait for data
retryCount *= 10;
for (int i = 0; i < retryCount; ++i)
{
TRACE_LOG(m_logger) << " waitForData - i: " << i;
if (func())
return true;
QTest::qWait(1000);
}
return func();
}
EffectCluster ModuleTestEffectCluster::getEcForTneVerification(const QString &eaName, double rotation)
{
AreaEffectSimulation::EffectCluster eaData;
eaData.id(0);
eaData.effectStart((time(nullptr) + 30) * 1000); // msec
QString name(eaName);
name += QString::number(eaData.effectStart().get());
eaData.name(name.toStdString());
eaData.effectDuration(10000); // 10 seconds
// eaData.chargeStruct().chargeTypeId(s_ChargeTypeId1);
// eaData.chargeStruct().igniterTypeId(s_IgniterTypeProximity);
eaData.partyId(2);
eaData.participantId(7);
// SubStruct FlightCurve
FlightCurve fc;
fc.requestedRelativePeakHeight(100);
// siehe auch: GUEZE-2311 Verifikation des Algorithmus bzgl. MTPs zw. TNE und EXCON.
const double height = 100; // Y
const double width = 40; // X
const double rot = rotation;
// In Kontext GUEZE-2311 werden die MTPs unabhängig von eigentliche WirkfeldGeometrie an die TNE übermittelt.
// Um in der Zentrale den gewünschten MTP zu erhalten, muss das Wirkfeld entsprechend angelegt werden:
LtsCoordTrans::UtmCoordinate cp = LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U MD 97000 78000"));
QPointF bottomLeft(Polygons::centerPoint2BottomLeft(cp.geographic(), width, height, rot));
DEBUG_LOG(m_logger) << " bottomLeft" << bottomLeft;
eaData.area().cornerBottomLeft(Core::GeoPosition(bottomLeft.x(), bottomLeft.y(), 0.0));
eaData.area().height(height);
eaData.area().width(width);
eaData.area().rotation(rot);
eaData.explosionGeometry(AreaEffectSimulation::AesExplosionGeometry_def::EgArea);
eaData.tla(0); // aka zop
eaData.externalId(0);
return eaData;
}
std::vector<Core::RelativePositionRelativeTime> ModuleTestEffectCluster::parseTrajectory(const QString &filePath)
{
// EffectClusterModifyRequest
// AreaEffectSimulation::EffectorData
// std::vector< Core::GeoPositionRelativeTime >& trajectory
// GeoPositionRelativeTime ( lon, lat, z, relativeTime)
QFile file(filePath);
std::vector<Core::RelativePositionRelativeTime> points;
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return points;
QXmlStreamReader xml(&file);
while (!xml.atEnd() && !xml.hasError())
{
xml.readNext();
// Wir suchen nach Start-Elementen, die mit "trajectory." beginnen
if (xml.isStartElement() && xml.name().toString().startsWith(QStringLiteral("trajectory.")))
{
Core::RelativePositionRelativeTime p;
// Wir lesen die Unterelemente (lon, lat, z, relativeTime)
while (!(xml.isEndElement() && xml.name().toString().startsWith(QStringLiteral("trajectory."))))
{
xml.readNext();
if (xml.isStartElement())
{
QString name = xml.name().toString();
QString val = xml.readElementText();
if (name == QStringLiteral("lon"))
p.offsetX(val.toDouble());
else if (name == QStringLiteral("lat"))
p.offsetY(val.toDouble());
else if (name == QStringLiteral("z"))
p.offsetZ(val.toDouble());
else if (name == QStringLiteral("relativeTime"))
p.relativeTime(val.toDouble());
}
}
points.push_back(p);
DEBUG_LOG(m_logger) << "Punkt gelesen: offsetY" << p.offsetX() << ", offsetY" << p.offsetY() << ", offsetZ" << p.offsetZ() << ", time=" << p.relativeTime();
}
}
if (xml.hasError())
{
DEBUG_LOG(m_logger) << "XML Fehler:" << xml.errorString();
}
DEBUG_LOG(m_logger) << "file.close()";
file.close();
DEBUG_LOG(m_logger) << "return points";
return points;
}
int ModuleTestEffectCluster::sendAcknowledgeExternalAesItemRequest(int aesItemId)
{
DEBUG_LOG(m_logger) << "sendAcknowledgeExternalAesItemRequest aesItemId=" << aesItemId;
int ret = m_aesFtc->acknowledgeExternalAesItemRequest(AcknowledgeExternalAesItemRequest(aesItemId), this);
return ret;
}
int ModuleTestEffectCluster::doEffectClusterModifyRequest()
{
EffectCluster eaData;
QString dateTimeString = QDateTime::currentDateTime().toString(QStringLiteral("dd.MM.yyyy hh:mm"));
m_reference = dateTimeString;
if (eaData.effectStart().is_set())
INFO_LOG(m_logger) << " effectClusterModifyRequest with effectStart: " << QDateTime::fromMSecsSinceEpoch(eaData.effectStart().get()).toString();
else
INFO_LOG(m_logger) << " effectClusterModifyRequest with effectStart: not set ";
FlightCurve fc;
// if (eaData.flightCurve().is_set())
// fc = eaData.flightCurve().get();
QJsonObject obj;
obj[QStringLiteral("effectSource")] = 1;
obj[QStringLiteral("elemente")] = 1;
obj[QStringLiteral("feuerkampfReferenz")] = dateTimeString;
obj[QStringLiteral("firingType")] = 1;
obj[QStringLiteral("ladung")] = QStringLiteral("DM16");
obj[QStringLiteral("ladungsNummer")] = 3;
obj[QStringLiteral("partyId")] = 4;
obj[QStringLiteral("subTyp")] = 0;
obj[QStringLiteral("typ")] = 0;
obj[QStringLiteral("useReceived")] = true;
obj[QStringLiteral("effectSource")] = ProjectDataManagement::EffectSource::ES_ADLER;
QString propertiesStr = QString::fromStdString(QJsonDocument(obj).toJson(QJsonDocument::Compact).toStdString());
eaData.properties(propertiesStr.toStdString());
AreaEffectSimulation::ChargeStruct chargeStruct;
chargeStruct.chargeTypeId(367);
chargeStruct.igniterTypeId(1);
chargeStruct.igniterFunctionId(2);
Core::GeoPosition mhpPosition;
mhpPosition.lon(0.201958);
mhpPosition.lat(0.915263);
mhpPosition.z(88.0);
Core::GeoPosition2D cornerBottomLeft;
cornerBottomLeft.lon(0.201951);
cornerBottomLeft.lat(0.915259);
AreaEffectSimulation::Area area;
area.cornerBottomLeft(cornerBottomLeft);
area.width(50);
area.height(50);
area.rotation(0);
eaData.area(area);
eaData.explosionGeometry(AreaEffectSimulation::AesExplosionGeometry::EgPoint);
std::vector<Core::RelativePositionRelativeTime> trajectory = parseTrajectory(s_REQUEST_SPL_FILE);
AreaEffectSimulation::EffectorData effector;
effector.angleOfFall(0);
effector.participantId(m_participant1.id()); // Participant
DEBUG_LOG(m_logger) << "effector.participantId(m_participant1.id()=" << m_participant1.id();
effector.flightTime(39526.3);
effector.peakHeight(2002.0);
effector.interval(0);
effector.chargeStruct(chargeStruct);
effector.chargeAmount(1);
effector.mhpScatterLenght(3.08314e-316);
effector.mhpScatterWidth(8.76302e-315);
effector.mhpScatterLengthDetonationHeight(9.69057e-316);
effector.mhpScatterWidthDetonationHeight(8.76638e-315);
effector.mhpRotation(-45.4373);
effector.mhpPosition(mhpPosition);
effector.trajectoryRelative(trajectory);
DEBUG_LOG(m_logger) << "effector";
std::vector<AreaEffectSimulation::EffectorData> effectors;
effectors.push_back(effector);
DEBUG_LOG(m_logger) << "Nach effector";
eaData.id(0);
eaData.effectSourceId(ProjectDataManagement::EffectSource::ES_ADLER);
eaData.firePurposeId(2);
eaData.partyId(4);
eaData.participantId(m_participant0.id()); // Unit
DEBUG_LOG(m_logger) << "eaData.participantId(m_participant0.id()=" << m_participant0.id();
eaData.externalId(7);
eaData.effectMarkingInTa(1);
eaData.name(dateTimeString.toStdString());
eaData.element(dateTimeString.toStdString());
DEBUG_LOG(m_logger) << "Vor send effectClusterModifyRequest";
int ret = m_aesFtc->effectClusterModifyRequest(EffectClusterModifyRequest(eaData.id(),
eaData.name(),
eaData.element(),
eaData.effectStart(),
eaData.effectDuration(),
eaData.effectSourceId(),
eaData.area(),
eaData.explosionGeometry(), // AimPoint, Radial, Area, Line, Point
eaData.tla(), // ZielOrtungsGenauigkeit
effectors,
eaData.firePurposeId(), // FirePurpose: blenden, niederhalten, vernichten
eaData.partyId(),
eaData.participantId(),
{}, // esmParticipantIds
eaData.externalId(),
eaData.effectMarkingInTa(),
eaData.properties()),
this);
DEBUG_LOG(m_logger) << "send effectClusterModifyRequest ret=" << ret;
return ret;
}
void ModuleTestEffectCluster::waitForEffectStates(int lineNumber, int durPrep, int durAct, int durExp)
{
// expected condition:
if (!waitForData([this]() { return m_replyError == false; }, 1))
{
ERROR_LOG(m_logger) << "Error on request"
<< ", lineNumber = " << lineNumber;
return;
}
INFO_LOG(m_logger) << LOGFUNCTION << " waiting for EsPrepared...";
if (!waitForData([this]() { return m_data.effectStateId() == AreaEffectSimulation::AesEffectState_def::EsPrepared; }, durPrep))
{
ERROR_LOG(m_logger) << "Timeout waiting for EsPrepared of explosion cluster with id " << m_data.id() << ", lineNumber = " << lineNumber;
QVERIFY2(false, "ERROR, exit");
return;
}
INFO_LOG(m_logger) << LOGFUNCTION << " waiting for EsActivated...";
if (!waitForData([this]() { return m_data.effectStateId() == AreaEffectSimulation::AesEffectState_def::EsActivated; }, durAct))
{
ERROR_LOG(m_logger) << "Timeout waiting for EsActivated of explosion cluster with id " << m_data.id() << ", lineNumber = " << lineNumber;
QVERIFY2(false, "ERROR, exit");
return;
}
INFO_LOG(m_logger) << LOGFUNCTION << " waiting for EsExpired...";
if (!waitForData([this]() { return m_data.effectStateId() == AreaEffectSimulation::AesEffectState_def::EsExpired; }, durExp))
{
ERROR_LOG(m_logger) << "Timeout waiting for EsExpired of explosion cluster with id " << m_data.id() << ", lineNumber = " << lineNumber;
QVERIFY2(false, "ERROR, exit");
return;
}
}
void ModuleTestEffectCluster::disconnectFromParty()
{
DEBUG_LOG(m_logger) << "PPM::ModifyPartyDataRequest";
ParticipantManagement::Party party;
party.name("GREEN");
party.role(ParticipantManagement::Role::Neutral);
party.color(-16711936);
party.fadingColor(-6553701);
ModifyPartyDataRequest req;
req.id(m_partyId);
req.name(party.name());
req.color(party.color());
req.fadingColor(party.fadingColor());
req.role(party.role());
req.isUsedBy(true);
req.sampleTime(QDateTime::currentMSecsSinceEpoch());
const HlaForceIdentifierEnum hlaId = HlaForceIdentifierEnum::Neutral_1;
req.hlaForceIdentifier(hlaId);
QString properties = QStringLiteral("{\"Adler\": {\"wsId\": 3, \"SaaName\": \"UI Test\", \"assetId\": -1, \"saaName\": \"SAA1@GUEZ.DE\", \"szenarName\": \"UI Test\", "
"\"isSaaConnected\": 1, \"saaConnectedState\": 2}}");
req.properties(properties.toStdString());
if (!m_ppmFtc->modifyPartyDataRequest(req, this))
{
ERROR_LOG(m_logger) << "Error creating party data";
// failExit();
}
}
void ModuleTestEffectCluster::connectToParty()
{
DEBUG_LOG(m_logger) << "PPM::ModifyPartyDataRequest";
ParticipantManagement::Party party;
party.name("GREEN");
party.role(ParticipantManagement::Role::Neutral);
party.color(-16711936);
party.fadingColor(-6553701);
ModifyPartyDataRequest req;
req.id(m_partyId);
req.name(party.name());
req.color(party.color());
req.fadingColor(party.fadingColor());
req.role(party.role());
req.isUsedBy(true);
req.sampleTime(QDateTime::currentMSecsSinceEpoch());
const HlaForceIdentifierEnum hlaId = HlaForceIdentifierEnum::Neutral_1;
req.hlaForceIdentifier(hlaId);
QString properties = QStringLiteral("{\"Adler\": {\"wsId\": 3, \"SaaName\": \"UI Test\", \"assetId\": -1, \"saaName\": \"SAA1@GUEZ.DE\", \"szenarName\": \"UI Test\", "
"\"isSaaConnected\": 2, \"isVerbund\": true, \"saaConnectedState\": 4}}");
req.properties(properties.toStdString());
if (!m_ppmFtc->modifyPartyDataRequest(req, this))
{
ERROR_LOG(m_logger) << "Error creating party data";
// failExit();
}
}
void ModuleTestEffectCluster::participantChangeRequest()
{
DEBUG_LOG(m_logger) << "PPM::participantChangerequest";
m_participant0.id(0);
m_participant0.partyId(4);
m_participant0.hierarchyNumber(1);
m_participant0.typeId(182);
m_participant0.externalId(0);
m_participant0.symbol(QStringLiteral("AP6D|CMPL|10011000001308000000").toStdString());
m_participant0.name(QStringLiteral("451200").toStdString());
m_participant0.identification(QStringLiteral("").toStdString());
m_participant0.designator(QStringLiteral("451200").toStdString()), m_participant0.tacticalIdentifier(QStringLiteral("451200").toStdString());
m_participant0.info(QStringLiteral("").toStdString());
m_participant0.assignState(ParticipantManagement::ParticipantAssignState::NotAssigned);
m_participant0.isSimulated(false);
m_participant0.isDeleted(false);
m_participant0.properties(QStringLiteral("").toStdString());
m_participant0.modId(1138783559);
m_participant0.superiorModId(0);
m_participant1.id(0);
m_participant1.partyId(4);
m_participant1.hierarchyNumber(1);
m_participant1.typeId(188);
m_participant1.externalId(0);
m_participant1.symbol(QStringLiteral("AP6D|CMPL|10011500001114020000").toStdString());
m_participant1.name(QStringLiteral("C3").toStdString());
m_participant1.identification(QStringLiteral("").toStdString());
m_participant1.designator(QStringLiteral("C3").toStdString()), m_participant1.tacticalIdentifier(QStringLiteral("451200").toStdString());
m_participant1.info(QStringLiteral("").toStdString());
m_participant1.assignState(ParticipantManagement::ParticipantAssignState::NotAssigned);
m_participant1.isSimulated(false);
m_participant1.isDeleted(false);
m_participant1.properties(QStringLiteral("").toStdString());
m_participant1.modId(1390608527);
m_participant1.superiorModId(1138783559);
ModifyParticipantDataRequest req;
std::vector<ParticipantManagement::ParticipantData> data;
data.push_back(m_participant0);
data.push_back(m_participant1);
req.requestId(548288706);
req.data(data);
if (!m_ppmFtc->modifyParticipantDataRequest(req, this))
{
ERROR_LOG(m_logger) << "Error creating party data";
// failExit();
}
}
void ModuleTestEffectCluster::participantDeleteRequest()
{
DEBUG_LOG(m_logger) << "PPM::participantDeleteRequest";
m_participant0.isDeleted(true);
m_participant1.isDeleted(true);
ModifyParticipantDataRequest req;
std::vector<ParticipantManagement::ParticipantData> data;
data.push_back(m_participant0);
data.push_back(m_participant1);
req.requestId(548288707);
req.data(data);
if (!m_ppmFtc->modifyParticipantDataRequest(req, this))
{
ERROR_LOG(m_logger) << "Error creating party data";
// failExit();
}
}
void ModuleTestEffectCluster::setParticipantPos(int participantId)
{
DEBUG_LOG(m_logger) << "setupParticipants";
TrainingAreaBase::TabPosition position;
Core::GeoPosition geoPos;
TrainingAreaBase::EquipmentPosition pos;
geoPos.lon(0.20110363);
geoPos.lat(0.91579597);
geoPos.z(0.0);
DEBUG_LOG(m_logger) << " initTestCase_data1 ...";
pos.equipmentNumber(participantId * -1); // ParticipantId
pos.sampleTime(QDateTime::currentMSecsSinceEpoch());
position.reportingSource(Core::PositionReportingSource::SetByOperator);
position.position(geoPos);
pos.position(position);
m_tabDts->publish(pos);
}
void ModuleTestEffectCluster::setEquipmentGearCharge(int participantId)
{
DEBUG_LOG(m_logger) << "setupEquipmentGearCharge";
TrainingAreaBase::EquipmentGearChargeState egs;
TrainingAreaBase::GearCharge charge;
std::vector<TrainingAreaBase::GearCharge> charges;
egs.equipmentNumber(participantId * -1); // ParticipantId
egs.sampleTime(QDateTime::currentMSecsSinceEpoch());
charges.resize(7);
charge.gearId(138);
charge.gearTypeId(801);
charge.chargeTypeId(367);
charge.remain(50);
charges.push_back(charge); // 0
charge.chargeTypeId(366);
charges.push_back(charge); // 1
charge.chargeTypeId(361);
charges.push_back(charge); // 2
charge.chargeTypeId(362);
charges.push_back(charge); // 3
charge.chargeTypeId(363);
charges.push_back(charge); // 4
charge.chargeTypeId(364);
charges.push_back(charge); // 5
charge.chargeTypeId(365);
charges.push_back(charge); // 6
egs.charge(charges);
m_tabDts->publish(egs);
}
void ModuleTestEffectCluster::onPartyChanged(const ParticipantManagement::Party &data, DataModification modType)
{
DEBUG_LOG(m_logger) << "onPartyChanged:" << data;
// Remove Participant:
if (modType == DataModification::eRemoved)
{
return;
}
if (data.id() != m_partyId)
{
return;
}
DEBUG_LOG(m_logger) << "onPartyChanged id= " << data.id();
if (m_ppmDtc->saaConnectedState(data.id()) == ParticipantManagement::ConnectState::Connected)
{
DEBUG_LOG(m_logger) << "onPartyChanged saaConnectedState == connected";
}
else if (m_ppmDtc->saaConnectedState(data.id()) == ParticipantManagement::ConnectState::Disconnected)
{
DEBUG_LOG(m_logger) << "onPartyChanged saaConnectedState == disconnected => connectToParty";
connectToParty();
}
}
//
// context of textCases
//
void ModuleTestEffectCluster::initTestCase()
{
//
// DdsConnector
//
DEBUG_LOG(m_logger) << "DDSConnector: m_domainId " << m_domainId << ", m_exerciseId " << m_exerciseId;
QFile file(s_REQUEST_SPL_FILE);
const bool bFileExists = file.exists();
QVERIFY2(bFileExists, "ERROR, SPL file does not exists in current path");
// cmd
m_ddsConnector.reset(new DDSConnector::DdsConnector(m_domainId, IDL::PartitionType::Exercise, m_exerciseId));
bool bInit = m_ddsConnector->init();
QVERIFY2(bInit, "ERROR, ddsConnector.init failed!!");
if (!bInit)
{
ERROR_LOG(m_logger) << " ERROR, ddsConnector.init failed!!";
return;
}
INFO_LOG(m_logger) << " ddsConnector.init successfull";
// cmd
m_ddsConnector->initPublisherSubscriber();
INFO_LOG(m_logger) << " ddsConnector.initPublisherSubscriber done";
//
// Aes
//
// cmd
m_aesFtc = AreaEffectSimulation::Interface::Ftc::create(m_ddsConnector);
QVERIFY2(m_aesFtc, "ERROR, create m_aesFtc failed!!");
bool bRet = m_aesFtc->enableAll();
QVERIFY2(bRet, "ERROR, enableAll failed!!");
// cmd
m_aesDtc = AreaEffectSimulation::Interface::Dtc::create(m_ddsConnector);
QVERIFY2(m_aesDtc, "ERROR, create m_aesDtc failed!!");
bRet = bRet && m_aesDtc->enableAll();
QVERIFY2(bRet, "ERROR, enableAll failed!!");
m_aesFtc->enableAll();
m_aesDtc->enableAesItemView();
m_aesDtc->enableChargeEffect();
DEBUG_LOG(m_logger) << " waitForHistoricalDataAesItemView... ";
m_aesDtc->waitForHistoricalDataAesItemView(2000);
DEBUG_LOG(m_logger) << " waitForHistoricalDataAesItemView... Done";
QMap<qint32, AreaEffectSimulation::AesItemView> aesItemViewsCont = m_aesDtc->aesItemViews();
DEBUG_LOG(m_logger) << " aesItemViewsCont.size() " << aesItemViewsCont.size();
//
// PDM
//
m_pdmDtc = ProjectDataManagement::Interface::Dtc::create(m_ddsConnector);
QVERIFY2(m_pdmDtc, "ERROR, create m_pdmDtc failed!!");
//
// ISM
//
m_ismDtc = InfrastructureManagement::Interface::Dtc::create(m_ddsConnector);
QVERIFY2(m_ismDtc, "ERROR, create m_ismDtc failed!!");
bRet = bRet && m_ismDtc->enableAll();
QVERIFY2(bRet, "ERROR, enableAll failed!!");
//
// EXM ExerciseManagement
//
m_exmDtc = ExerciseManagement::Interface::Dtc::create(m_ddsConnector);
QVERIFY2(m_exmDtc, "ERROR, create m_exmDtc failed!!");
bRet = bRet && m_exmDtc->enableAll();
QVERIFY2(bRet, "ERROR, enableAll m_exmDtc failed!!");
m_exmDtc->waitForHistoricalDataExercise(2000);
DEBUG_LOG(m_logger) << " waitForHistoricalDataExercise... Done";
const ExerciseManagement::Exercise &exercise = m_exmDtc->exercise(m_exerciseId);
QVERIFY2(exercise.id() == m_exerciseId, "ERROR, exercise failed!!");
m_traingAreaId = exercise.trainingAreaId();
DEBUG_LOG(m_logger) << " ExerciseManagement"
<< ", m_traingAreaId = " << m_traingAreaId;
//
// PPM ParticipantManagement
//
//
m_ppmDtc = ParticipantManagement::Interface::Dtc::create(m_ddsConnector);
QVERIFY2(m_ppmDtc, "ERROR, create m_ppmDtc failed!!");
bRet = bRet && m_ppmDtc->enableAll();
QVERIFY2(bRet, "ERROR, enableAll m_ppmDtc failed!!");
m_ppmFtc = ParticipantManagement::Interface::Ftc::create(m_ddsConnector);
QVERIFY2(m_ppmFtc, "ERROR, create m_ppmFtc failed!!");
bRet = bRet && m_ppmFtc->enableAll();
m_ppmFtc->enableSetSimulatedPosition();
m_ppmFtc->enableModifyParticipantData();
QVERIFY2(bRet, "ERROR, m_ppmFtc enableAll failed!!");
m_tabDts = TrainingAreaBase::Interface::Dts::create(m_ddsConnector);
QVERIFY2(m_tabDts, "ERROR, create m_tabDts failed!!");
bRet = bRet && m_tabDts->enableAll();
QVERIFY2(bRet, "ERROR, m_tabDts enableAll failed!!");
DEBUG_LOG(m_logger) << "disconnectFromParty";
disconnectFromParty();
// connectToParty();
// connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::participantChanged,
// this, &ModuleTestEffectCluster::onParticipantChanged);
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::partyChanged, this, &ModuleTestEffectCluster::onPartyChanged);
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::aesItemViewChanged, this, &ModuleTestEffectCluster::onAesItemViewChanged, Qt::UniqueConnection);
connect(m_aesDtc.get(),
&AreaEffectSimulation::Interface::Dtc::trajectoryTimeAwareChanged,
this,
&ModuleTestEffectCluster::onTrajectoryTimeAwareChanged,
Qt::UniqueConnection);
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::effectsChanged, this, &ModuleTestEffectCluster::onEffectsChanged, Qt::UniqueConnection);
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::chargeEffectChanged, this, &ModuleTestEffectCluster::onChargeEffectChanged, Qt::UniqueConnection);
// spend some for the eventLoop to "consume" existing topics/samples:
for (int i = 0; i < 10; ++i)
QTest::qWait(1000);
}
void ModuleTestEffectCluster::init()
{
// init will be called before each test function is executed.
m_counterDds.reset();
}
void ModuleTestEffectCluster::cleanupTestCase()
{
// finish last (dds) calls:
waitForData([]() { return false; }, 10);
INFO_LOG(m_logger) << " ddsConnector destroy...";
m_ddsConnector.reset();
INFO_LOG(m_logger) << " ddsConnector destroy...DONE";
}
int main(int argc, char *argv[])
{
NGLCoreApplication app(argc, argv);
app.createLogger("ModuleTest_ExplosionCluster", "log4cxx_aes.props");
// aesModuleTestExplosionCluster -v2 test_long -e42 -d139
// ^^^ ^^^^ // no space!!!
// aesModuleTestExplosionCluster -v2 test_long -e42
// aesModuleTestExplosionCluster -v2 test_long -e42
// aesModuleTestExplosionCluster test_long -e42
// aesModuleTestExplosionCluster -e42
CmdLineParser options;
options.setUnitModuleTestMode(true);
std::cout << " consider 'aesModuleTestEffectCluster -e42' " << std::endl;
if (!options.init(true)) // showHelp , exitOnBadOption
return -1;
if (options.exerciseId() <= 0)
{
fprintf(stderr, "ExerciseId not set!\n");
return -2;
}
std::cout << " DomainId = " << options.domainId() << " - ExerciseId = " << options.exerciseId() << std::endl;
if (options.isSet(QStringLiteral("exerciseid")))
--argc;
if (options.isSet(QStringLiteral("domainid")))
--argc;
const QStringList &slPositionalArgs = options.positionalArguments();
for (const QString &item : qAsConst(slPositionalArgs))
std::cout << " item = " << item << std::endl;
ModuleTestEffectCluster tc(options.domainId(), options.exerciseId());
return QTest::qExec(&tc, argc, argv);
}