943 lines
34 KiB
C++
Executable File
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);
|
|
}
|