Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Proxies/TrainingAreaBaseOC/handler_aes_data.cpp
T

802 lines
26 KiB
C++
Executable File

#include <QtCore/QCoreApplication>
#include <QtCore/QRegularExpression>
#include <utility>
#include <QtCore/QPointF>
#include <LtsUtilsCore/qbytearray_byteaccess.h>
#include <NGLLogger/NGLLoggerBootstrap.h>
#include "handler_aes_data.h"
#include "settings.h"
namespace TrainingAreaBaseOC
{
static inline int compassToMathAngleForSfm(double compassDegree)
{
int ret = qRound((90.0 - compassDegree / 100.0));
while (ret < 0)
ret += 360;
while (ret > 360)
ret -= 360;
return ret;
}
HandlerAesData::HandlerAesData(const std::shared_ptr<DdsHandler> &dds,
const std::shared_ptr<AreaEffectSimulation::Interface::Dtc> &aesDtc,
const std::shared_ptr<AreaEffectSimulation::Interface::Ftc> &aesFtc,
const std::shared_ptr<ProjectDataManagement::Interface::Dtc> &pdmDtc)
: m_dds(dds)
, m_aesDtc(aesDtc)
, m_aesFtc(aesFtc)
, m_pdmDtc(pdmDtc)
, m_utmCoord(LtsCoordTrans::UtmCoordinate::fromMgrs(Settings::baseCoord()))
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger())
{
}
bool HandlerAesData::init()
{
if (!m_aesDtc->enableBCContamination() || !m_aesDtc->enableExplosionArea() || !m_aesDtc->enableExplosionSingle() || !m_aesDtc->enableFunctionalArea()
|| !m_aesDtc->enableNContamination() || !m_aesDtc->enableMineArea() || !m_aesDtc->enableExplosionCluster())
{
ERROR_LOG(m_logger) << "Error enabling AES Data-Topics.";
return false;
}
if (!m_aesFtc->enableBCContaminationModify() || !m_aesFtc->enableExplosionAreaModify() || !m_aesFtc->enableExplosionSingleModify()
|| !m_aesFtc->enableFunctionalAreaModify() || !m_aesFtc->enableNContaminationModify() || !m_aesFtc->enableExplosionClusterOcModify()
|| !m_aesFtc->enableMineAreaModifyFromCtaData() || !m_aesFtc->enableBCContaminationRemove() || !m_aesFtc->enableExplosionAreaRemove()
|| !m_aesFtc->enableExplosionSingleRemove() || !m_aesFtc->enableFunctionalAreaRemove() || !m_aesFtc->enableNContaminationRemove()
|| !m_aesFtc->enableMineAreaRemove() || !m_aesFtc->enableExplosionClusterRemove() || !m_aesFtc->enableExplosionAreaPauseResume()
|| !m_aesFtc->enableMineAreaReferenceModify())
{
ERROR_LOG(m_logger) << "Error enabling AES Function-Topics.";
return false;
}
if (!m_pdmDtc->enableChargeType() || !m_pdmDtc->enableGearTypeChargeType() || !m_pdmDtc->enableGearType())
{
ERROR_LOG(m_logger) << "Error enabling PDM Data-Topic.";
return false;
}
if (!m_aesDtc->waitForHistoricalDataBCContamination(10000) || !m_aesDtc->waitForHistoricalDataExplosionArea(10000)
|| !m_aesDtc->waitForHistoricalDataExplosionSingle(10000) || !m_aesDtc->waitForHistoricalDataFunctionalArea(10000)
|| !m_aesDtc->waitForHistoricalDataNContamination(10000) || !m_aesDtc->waitForHistoricalDataMineArea(10000)
|| !m_aesDtc->waitForHistoricalDataExplosionCluster(10000))
{
ERROR_LOG(m_logger) << "Error waiting for historical data AES.";
return false;
}
DEBUG_LOG(m_logger) << "Initialisation successful";
return true;
}
void HandlerAesData::process(const QByteArray &data, int multiplexer)
{
if (data.isEmpty())
return;
switch (multiplexer)
{
case MineArea:
{
mineAreas(data);
break;
}
case ExplosionArea:
{
explosionAreas(data);
break;
}
case ExplosionSingle:
{
explosionSingles(data);
break;
}
case NContamination:
{
nContaminations(data);
break;
}
case BcContamination:
{
bcContaminations(data);
break;
}
case FunctionalArea:
{
functionalAreas(data);
break;
}
case ExplosionAreaStop:
{
explosionAreasPause(data);
break;
}
case ExplosionAreaContinue:
{
explosionAreasResume(data);
break;
}
default:
WARNING_LOG(m_logger) << "Got unknown multiplexer.";
}
}
void HandlerAesData::specificsExercise(const OcTelegrams::SpecificsExercise &data)
{
m_utmCoord = LtsCoordTrans::UtmCoordinate::fromMgrs(QString::number(data.zone) + QLatin1Char(data.band) + QString::fromLatin1(data.square)
+ QString::number(data.northing).rightJustified(7, QLatin1Char('0'))
+ QString::number(data.easting).rightJustified(7, QLatin1Char('0')));
}
void HandlerAesData::onMineAreaModifyFromCtaDataReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
ERROR_LOG(m_logger) << "Mine area modify failed: " << reply.translated();
else
DEBUG_LOG(m_logger) << "Mine area modify successfull. Id: " << reply.id();
}
void HandlerAesData::onNContaminationModifyReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
ERROR_LOG(m_logger) << "N contamination modify failed: " << reply.translated();
else
DEBUG_LOG(m_logger) << "N contamination modify successfull. Id: " << reply.id();
}
void HandlerAesData::onFunctionalAreaModifyReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
ERROR_LOG(m_logger) << "Functional area modify failed: " << reply.translated();
else
DEBUG_LOG(m_logger) << "Functional area modify successfull. Id: " << reply.id();
}
void HandlerAesData::onExplosionSingleModifyReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
ERROR_LOG(m_logger) << "Explosion single modify failed: " << reply.translated();
else
DEBUG_LOG(m_logger) << "Explosion single modify successfull. Id: " << reply.id();
}
void HandlerAesData::onExplosionAreaModifyReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
ERROR_LOG(m_logger) << "Explosion area modify failed: " << reply.translated();
else
DEBUG_LOG(m_logger) << "Explosion area modify successfull. Id: " << reply.id();
}
void HandlerAesData::onBCContaminationModifyReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
ERROR_LOG(m_logger) << "BC contamination modify failed: " << reply.translated();
else
DEBUG_LOG(m_logger) << "BC contamination modify successfull. Id: " << reply.id();
}
void HandlerAesData::onExplosionClusterOcModifyReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
ERROR_LOG(m_logger) << "ExplosionCluster modify failed: " << reply.translated();
else
DEBUG_LOG(m_logger) << "ExplosionCluster successfull. Id: " << reply.id();
}
void HandlerAesData::onMineAreaRemoveReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
ERROR_LOG(m_logger) << "Mine area remove failed: " << reply.translated();
else
DEBUG_LOG(m_logger) << "Mine area remove successfull. Id: " << reply.id();
}
void HandlerAesData::onNContaminationRemoveReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
ERROR_LOG(m_logger) << "N contamination remove failed: " << reply.translated();
else
DEBUG_LOG(m_logger) << "N contamination remove successfull. Id: " << reply.id();
}
void HandlerAesData::onFunctionalAreaRemoveReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
ERROR_LOG(m_logger) << "Functional area remove failed: " << reply.translated();
else
DEBUG_LOG(m_logger) << "Functional area remove successfull. Id: " << reply.id();
}
void HandlerAesData::onExplosionSingleRemoveReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
ERROR_LOG(m_logger) << "Explosion single remove failed: " << reply.translated();
else
DEBUG_LOG(m_logger) << "Explosion single remove successfull. Id: " << reply.id();
}
void HandlerAesData::onExplosionAreaRemoveReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
ERROR_LOG(m_logger) << "Explosion area remove failed: " << reply.translated();
else
DEBUG_LOG(m_logger) << "Explosion area remove successfull. Id: " << reply.id();
}
void HandlerAesData::onBCContaminationRemoveReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
ERROR_LOG(m_logger) << "BC contamination remove failed: " << reply.translated();
else
DEBUG_LOG(m_logger) << "BC contamination remove successfull. Id: " << reply.id();
}
void HandlerAesData::onExplosionClusterRemoveReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
ERROR_LOG(m_logger) << "ExplosionCluster remove failed: " << reply.translated();
else
DEBUG_LOG(m_logger) << "ExplosionCluster remove successfull. Id: " << reply.id();
}
void HandlerAesData::onExplosionAreaPauseResumeReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
ERROR_LOG(m_logger) << "Explosion area pause/resume failed: " << reply.translated();
else
DEBUG_LOG(m_logger) << "Explosion area pause/resume successfull. Id: " << reply.id();
}
template <typename T> static inline void getBasicData(const QByteArray &data, size_t &pos, T &req, bool withoutEffectStart = false)
{
uint64_t tmp;
LtsUtils::get2Byte(data, pos, tmp);
req.id = tmp;
req.name = data.mid(pos, 8).toStdString();
QString name = QString::fromStdString(req.name);
name = name.replace(QRegularExpression(QStringLiteral("[^ -~]")), QLatin1String(""));
name = name.trimmed();
if (!name.isEmpty())
req.name = name.toStdString();
pos += 8;
LtsUtils::get1Byte(data, pos, tmp);
if (tmp != 0)
req.partyId = dds::core::optional<int32_t>(tmp);
else
req.partyId = dds::core::optional<int32_t>();
if (!withoutEffectStart)
{
LtsUtils::get4Byte(data, pos, tmp);
if (tmp != 0)
req.effectStart = dds::core::optional<rti::core::int64>(tmp * 1000);
else
req.effectStart = dds::core::optional<rti::core::int64>();
}
}
static inline double mathToCompassAngle(int mathDegree)
{
int ret = 9000 - mathDegree;
while (ret < 0)
ret += 36000;
while (ret > 36000)
ret -= 36000;
return ret / 100.0;
}
void HandlerAesData::bcContaminations(const QByteArray &data)
{
INFO_LOG(m_logger) << "Got new BC contamination data";
DEBUG_LOG(m_logger) << "Binary data: " << data.toHex(' ');
QList<int> aesToBeDeleted = m_aesDtc->bCContaminations().keys();
size_t pos = 0;
int cnt;
LtsUtils::get1Byte(data, pos, cnt);
AreaEffectSimulation::BCContaminationModifyRequest req;
req.weatherSource = AreaEffectSimulation::AesWeatherSource::AwsNoUpdate;
uint64_t tmp;
int x = 0, y = 0;
for (int i = 0; i < cnt; ++i)
{
getBasicData(data, pos, req);
LtsUtils::get1Byte(data, pos, tmp);
req.effectDuration = tmp * 60 * 1000;
LtsUtils::get3Byte(data, pos, y);
LtsUtils::get3Byte(data, pos, x);
req.impactPosition = relativeToGeoPosition(x, y);
LtsUtils::get2Byte(data, pos, tmp);
req.impactRadius = tmp;
LtsUtils::get1Byte(data, pos, tmp);
LtsUtils::get2Byte(data, pos, tmp);
req.propagationDirection = dds::core::optional<double>(compassToMathAngleForSfm(tmp));
LtsUtils::get1Byte(data, pos, tmp);
req.windSpeed = dds::core::optional<double>(tmp);
LtsUtils::get4Byte(data, pos, tmp);
req.weatherTimestamp = dds::core::optional<rti::core::int64>(tmp * 1000);
LtsUtils::get3Byte(data, pos, y);
LtsUtils::get3Byte(data, pos, x);
req.weatherPosition = dds::core::optional<Core::GeoPosition2D>(relativeToGeoPosition(x, y));
LtsUtils::get1Byte(data, pos, tmp);
req.chargeTypeId = chargeTypeIdFromChargeTasCode(ProjectDataManagement::GearClass::GearClass_Chemical, tmp);
if (req.chargeTypeId == 0)
req.chargeTypeId = chargeTypeIdFromChargeTasCode(ProjectDataManagement::GearClass::GearClass_Biological, tmp);
LtsUtils::get1Byte(data, pos, tmp);
DEBUG_LOG(m_logger) << (aesToBeDeleted.contains(req.id) ? "Modifying " : "Creating ") << "BC contamination: " << req;
aesToBeDeleted.removeAll(req.id);
req.id = req.id * -1;
m_aesFtc->bCContaminationModifyRequest(req, this);
}
for (int id : std::as_const(aesToBeDeleted))
{
if (m_aesDtc->bCContamination(id).isCentral)
continue;
if (m_aesDtc->bCContamination(id).effectStateId > AreaEffectSimulation::AesEffectState::EsRemoved)
{
DEBUG_LOG(m_logger) << "Removing BC contamination id: " << id;
m_aesFtc->bCContaminationRemoveRequest(Core::RemoveElementRequest(id), this);
}
}
}
void HandlerAesData::explosionAreas(const QByteArray &data)
{
INFO_LOG(m_logger) << "Got new explosion cluster data";
DEBUG_LOG(m_logger) << "Binary data: " << data.toHex(' ');
QList<int> aesToBeDeleted = m_aesDtc->explosionClusters().keys();
size_t pos = 0;
int cnt;
LtsUtils::get1Byte(data, pos, cnt);
AreaEffectSimulation::ExplosionClusterOcModifyRequest req;
uint64_t tmp;
int x = 0, y = 0;
for (int i = 0; i < cnt; ++i)
{
LtsUtils::get2Byte(data, pos, tmp);
req.id = tmp;
req.name = data.mid(pos, 8).toStdString();
QString name = QString::fromStdString(req.name);
name = name.replace(QRegularExpression(QStringLiteral("[^ -~]")), QLatin1String(""));
name = name.trimmed();
if (!name.isEmpty())
req.name = name.toStdString();
pos += 8;
LtsUtils::get1Byte(data, pos, tmp);
req.partyId = tmp;
LtsUtils::get4Byte(data, pos, tmp);
req.effectStart = tmp * 1000;
LtsUtils::get2Byte(data, pos, tmp);
req.effectDuration = tmp * 1000;
AreaEffectSimulation::Area area;
LtsUtils::get3Byte(data, pos, y);
LtsUtils::get3Byte(data, pos, x);
area.cornerBottomLeft = relativeToGeoPosition(x, y);
LtsUtils::get1Byte(data, pos, tmp);
area.width = tmp * 5;
LtsUtils::get1Byte(data, pos, tmp);
area.height = tmp * 5;
LtsUtils::get2Byte(data, pos, tmp);
area.rotation = mathToCompassAngle(tmp + 9000);
req.area = area;
LtsUtils::get2Byte(data, pos, tmp);
LtsUtils::get2Byte(data, pos, tmp);
req.mhpRotation = mathToCompassAngle(tmp + 9000);
LtsUtils::get2Byte(data, pos, tmp);
req.impactCount = tmp;
LtsUtils::get2Byte(data, pos, tmp);
LtsUtils::get1Byte(data, pos, tmp);
req.chargeStruct.chargeTypeId = chargeTypeIdFromChargeTasCode(ProjectDataManagement::GearClass::GearClass_Artillery, tmp);
if (req.chargeStruct.chargeTypeId == 0)
req.chargeStruct.chargeTypeId = chargeTypeIdFromChargeTasCode(ProjectDataManagement::GearClass::GearClass_Mortar, tmp);
if (req.chargeStruct.chargeTypeId == 0)
req.chargeStruct.chargeTypeId = chargeTypeIdFromChargeTasCode(ProjectDataManagement::GearClass::GearClass_AirSupport, tmp);
LtsUtils::get2Byte(data, pos, tmp);
LtsUtils::get1Byte(data, pos, tmp);
req.mhpCount = tmp;
for (int32_t mhpCounter = 0; mhpCounter < req.mhpCount; ++mhpCounter)
{
LtsUtils::get3Byte(data, pos, tmp);
LtsUtils::get3Byte(data, pos, tmp);
}
DEBUG_LOG(m_logger) << "New ExplosionClusterOcModifyRequest: "
<< "\nid:" << req.id << "\nname:" << req.name << "\neffectStart:" << req.effectStart << "\neffectDuration:" << req.effectDuration
<< "\narea:" << req.area << "\nmhpCount:" << req.mhpCount << "\nmhpRotation:" << req.mhpRotation << "\nimpactCount:" << req.impactCount
<< "\nchargeTypeId:" << req.chargeStruct.chargeTypeId << "\npartyId:" << req.partyId;
DEBUG_LOG(m_logger) << (aesToBeDeleted.contains(req.id) ? "Modifying " : "Creating ") << "explosion cluster: " << req;
aesToBeDeleted.removeOne(req.id);
req.id = req.id * -1;
m_aesFtc->explosionClusterOcModifyRequest(req, this);
}
for (int id : std::as_const(aesToBeDeleted))
{
const AreaEffectSimulation::ExplosionCluster &exp = m_aesDtc->explosionCluster(id);
if (exp.isCentral)
continue;
if ((exp.effectStateId >= AreaEffectSimulation::AesEffectState::EsPrepared)
|| ((exp.effectStateId >= AreaEffectSimulation::AesEffectState::EsActivated)
&& (((exp.effectStart.is_set() && ((exp.effectStart.get() + exp.effectDuration)) < (m_dds->currentPartitionTime() - 5000)))
||
(exp.effectStateId == AreaEffectSimulation::AesEffectState::EsPaused))))
{
DEBUG_LOG(m_logger) << "Removing explosion cluster with id: " << id;
m_aesFtc->explosionClusterRemoveRequest(Core::RemoveElementRequest(id), this);
}
}
}
void HandlerAesData::explosionSingles(const QByteArray &data)
{
INFO_LOG(m_logger) << "Got new explosion single data";
DEBUG_LOG(m_logger) << "Binary data: " << data.toHex(' ');
QList<int> aesToBeDeleted = m_aesDtc->explosionSingles().keys();
size_t pos = 0;
int cnt;
LtsUtils::get1Byte(data, pos, cnt);
AreaEffectSimulation::ExplosionSingleModifyRequest req;
uint64_t tmp;
int x = 0, y = 0;
for (int i = 0; i < cnt; ++i)
{
getBasicData(data, pos, req);
LtsUtils::get3Byte(data, pos, y);
LtsUtils::get3Byte(data, pos, x);
req.impactPosition = relativeToGeoPosition(x, y);
if (m_use2BytesForSingleFireDiameter)
LtsUtils::get2Byte(data, pos, tmp);
else
LtsUtils::get1Byte(data, pos, tmp);
LtsUtils::get1Byte(data, pos, tmp);
req.chargeTypeId = chargeTypeIdFromChargeTasCode(ProjectDataManagement::GearClass::GearClass_Artillery, tmp);
if (req.chargeTypeId == 0)
req.chargeTypeId = chargeTypeIdFromChargeTasCode(ProjectDataManagement::GearClass::GearClass_Mortar, tmp);
DEBUG_LOG(m_logger) << (aesToBeDeleted.contains(req.id) ? "Modifying " : "Creating ") << "explosion single: " << req;
aesToBeDeleted.removeAll(req.id);
req.id = req.id * -1;
m_aesFtc->explosionSingleModifyRequest(req, this);
}
for (int id : std::as_const(aesToBeDeleted))
{
const AreaEffectSimulation::ExplosionSingle &exp = m_aesDtc->explosionSingle(id);
if (exp.isCentral)
continue;
if ((exp.effectStateId > AreaEffectSimulation::AesEffectState::EsRemoved)
&& (exp.effectStart.is_set() && (exp.effectStart.get() > (m_dds->currentPartitionTime() + 5000))))
{
DEBUG_LOG(m_logger) << "Removing explosion single id: " << id;
m_aesFtc->explosionSingleRemoveRequest(Core::RemoveElementRequest(id), this);
}
}
}
void HandlerAesData::functionalAreas(const QByteArray &data)
{
INFO_LOG(m_logger) << "Got functional area data";
DEBUG_LOG(m_logger) << "Binary data: " << data.toHex(' ');
QList<int> aesToBeDeleted = m_aesDtc->functionalAreas().keys();
size_t pos = 0;
int cnt;
LtsUtils::get1Byte(data, pos, cnt);
AreaEffectSimulation::FunctionalAreaModifyRequest req;
uint64_t tmp;
int x = 0, y = 0;
for (int i = 0; i < cnt; ++i)
{
getBasicData(data, pos, req, true);
if (!aesToBeDeleted.contains(req.id))
req.effectStart = dds::core::optional<rti::core::int64>(m_dds->currentPartitionTime() + 100);
AreaEffectSimulation::Area area;
LtsUtils::get3Byte(data, pos, y);
LtsUtils::get3Byte(data, pos, x);
area.cornerBottomLeft = relativeToGeoPosition(x, y);
LtsUtils::get1Byte(data, pos, tmp);
area.width = tmp * 5;
LtsUtils::get1Byte(data, pos, tmp);
area.height = tmp * 5;
area.rotation = 0;
req.area = area;
LtsUtils::get1Byte(data, pos, tmp);
req.deconMode = static_cast<AreaEffectSimulation::AesOperatingMode>(tmp);
LtsUtils::get1Byte(data, pos, tmp);
req.deconTime = tmp * 10 * 60 * 1000;
LtsUtils::get1Byte(data, pos, tmp);
req.maintMode = static_cast<AreaEffectSimulation::AesOperatingMode>(tmp);
LtsUtils::get1Byte(data, pos, tmp);
req.maintTime = tmp * 10 * 60 * 1000;
LtsUtils::get1Byte(data, pos, tmp);
req.medicMode = static_cast<AreaEffectSimulation::AesOperatingMode>(tmp);
LtsUtils::get1Byte(data, pos, tmp);
req.medicTime = tmp * 10 * 60 * 1000;
req.chargeTypeId = 411;
DEBUG_LOG(m_logger) << (aesToBeDeleted.contains(req.id) ? "Modifying " : "Creating ") << "functional area: " << req;
aesToBeDeleted.removeAll(req.id);
req.id = req.id * -1;
m_aesFtc->functionalAreaModifyRequest(req, this);
}
for (int id : std::as_const(aesToBeDeleted))
{
if (m_aesDtc->functionalArea(id).isCentral)
continue;
if (m_aesDtc->functionalArea(id).effectStateId > AreaEffectSimulation::AesEffectState::EsRemoved)
{
DEBUG_LOG(m_logger) << "Removing functional area id: " << id;
m_aesFtc->functionalAreaRemoveRequest(Core::RemoveElementRequest(id), this);
}
}
}
void HandlerAesData::nContaminations(const QByteArray &data)
{
INFO_LOG(m_logger) << "Got new N contamination data";
DEBUG_LOG(m_logger) << "Binary data: " << data.toHex(' ');
QList<int> aesToBeDeleted = m_aesDtc->nContaminations().keys();
size_t pos = 0;
int cnt;
LtsUtils::get1Byte(data, pos, cnt);
AreaEffectSimulation::NContaminationModifyRequest req;
uint64_t tmp;
int x = 0, y = 0;
for (int i = 0; i < cnt; ++i)
{
getBasicData(data, pos, req);
LtsUtils::get2Byte(data, pos, tmp);
req.effectDuration = tmp * 6 * 60 * 1000;
LtsUtils::get3Byte(data, pos, y);
LtsUtils::get3Byte(data, pos, x);
req.impactPosition = relativeToGeoPosition(x, y);
LtsUtils::get2Byte(data, pos, tmp);
req.impactRadius = tmp;
LtsUtils::get2Byte(data, pos, tmp);
req.borderLengthInner = tmp;
LtsUtils::get2Byte(data, pos, tmp);
req.borderLengthOuter = tmp;
LtsUtils::get2Byte(data, pos, tmp);
req.spanAngle = tmp / 100.0;
LtsUtils::get2Byte(data, pos, tmp);
req.rotationAngle = mathToCompassAngle(tmp);
req.chargeTypeId = chargeTypeIdFromChargeTasCode(ProjectDataManagement::GearClass::GearClass_Nuclear, 1);
DEBUG_LOG(m_logger) << (aesToBeDeleted.contains(req.id) ? "Modifying " : "Creating ") << "N contamination: " << req;
aesToBeDeleted.removeAll(req.id);
req.id = req.id * -1;
m_aesFtc->nContaminationModifyRequest(req, this);
}
for (int id : std::as_const(aesToBeDeleted))
{
if (m_aesDtc->nContamination(id).isCentral)
continue;
if (m_aesDtc->nContamination(id).effectStateId > AreaEffectSimulation::AesEffectState::EsRemoved)
{
DEBUG_LOG(m_logger) << "Removing N contamination id: " << id;
m_aesFtc->nContaminationRemoveRequest(Core::RemoveElementRequest(id), this);
}
}
}
void HandlerAesData::mineAreas(const QByteArray &data)
{
INFO_LOG(m_logger) << "Got new mine area data";
DEBUG_LOG(m_logger) << "Binary data: " << data.toHex(' ');
QList<int> aesToBeDeleted = m_aesDtc->mineAreas().keys();
size_t pos = 0;
int cnt;
LtsUtils::get1Byte(data, pos, cnt);
AreaEffectSimulation::MineArea req;
uint64_t tmp;
int x = 0, y = 0;
for (int i = 0; i < cnt; ++i)
{
getBasicData(data, pos, req);
LtsUtils::get1Byte(data, pos, tmp);
req.effectDuration = tmp * 60 * 60 * 1000;
LtsUtils::get1Byte(data, pos, tmp);
req.width = tmp;
LtsUtils::get1Byte(data, pos, tmp);
req.density = tmp / 100.0;
LtsUtils::get1Byte(data, pos, tmp);
if (217 > tmp && 210 < tmp)
req.chargeStruct.chargeTypeId = chargeTypeIdFromChargeTasCode(ProjectDataManagement::GearClass::GearClass_MineArea, tmp);
else
req.chargeStruct.chargeTypeId = tmp;
LtsUtils::get2Byte(data, pos, tmp);
int segmentCnt = 0;
LtsUtils::get1Byte(data, pos, segmentCnt);
req.segments.resize(segmentCnt);
for (int j = 0; j < segmentCnt; ++j)
{
AreaEffectSimulation::MineSegment &segment = req.segments.at(j);
LtsUtils::get3Byte(data, pos, y);
LtsUtils::get3Byte(data, pos, x);
segment.positionStart = relativeToGeoPosition(x, y);
LtsUtils::get3Byte(data, pos, y);
LtsUtils::get3Byte(data, pos, x);
segment.positionEnd = relativeToGeoPosition(x, y);
}
req.isCenterLine = true;
DEBUG_LOG(m_logger) << (aesToBeDeleted.contains(req.id) ? "Modifying " : "Creating ") << "mine area: " << req;
aesToBeDeleted.removeAll(req.id);
req.id = req.id * -1;
req.setMineSorted = false;
m_aesFtc->mineAreaModifyFromCtaDataRequest(req, this);
}
for (int id : std::as_const(aesToBeDeleted))
{
if (m_aesDtc->mineArea(id).isCentral)
continue;
if (m_aesDtc->mineArea(id).effectStateId > AreaEffectSimulation::AesEffectState::EsRemoved)
{
DEBUG_LOG(m_logger) << "Removing mine area id: " << id;
m_aesFtc->mineAreaRemoveRequest(Core::RemoveElementRequest(id), this);
}
}
}
void HandlerAesData::explosionAreasPause(const QByteArray &data)
{
INFO_LOG(m_logger) << "Got new explosion area pause data";
DEBUG_LOG(m_logger) << "Binary data: " << data.toHex(' ');
size_t pos = 0;
int cnt;
LtsUtils::get1Byte(data, pos, cnt);
uint64_t id;
for (int i = 0; i < cnt; ++i)
{
LtsUtils::get2Byte(data, pos, id);
DEBUG_LOG(m_logger) << "Pausing ID: " << id;
m_aesFtc->explosionAreaPauseResumeRequest(AreaEffectSimulation::ExplosionAreaPauseResumeRequest(id,
false,
dds::core::optional<rti::core::int64>(),
dds::core::optional<int32_t>(),
dds::core::optional<int32_t>()),
this);
}
}
void HandlerAesData::explosionAreasResume(const QByteArray &data)
{
INFO_LOG(m_logger) << "Got new explosion area resume data";
DEBUG_LOG(m_logger) << "Binary data: " << data.toHex(' ');
size_t pos = 0;
int cnt;
LtsUtils::get1Byte(data, pos, cnt);
uint64_t tmp;
AreaEffectSimulation::ExplosionAreaPauseResumeRequest req;
req.resumeExecution = true;
for (int i = 0; i < cnt; ++i)
{
LtsUtils::get2Byte(data, pos, tmp);
req.id = tmp;
LtsUtils::get2Byte(data, pos, tmp);
req.resumeSeed = dds::core::optional<int32_t>(tmp);
LtsUtils::get2Byte(data, pos, tmp);
LtsUtils::get4Byte(data, pos, tmp);
req.timeToResume = dds::core::optional<rti::core::int64>(tmp * 1000);
LtsUtils::get2Byte(data, pos, tmp);
req.remainingDuration = dds::core::optional<int32_t>(tmp);
DEBUG_LOG(m_logger) << "Resuming: " << req;
m_aesFtc->explosionAreaPauseResumeRequest(req, this);
}
}
int HandlerAesData::chargeTypeIdFromChargeTasCode(ProjectDataManagement::GearClass gearClass, int chargeTasCodeIndirect)
{
static bool initialized = false;
if (!initialized)
{
if (!m_pdmDtc->waitForHistoricalDataChargeType(20000))
{
ERROR_LOG(m_logger) << "Can not read charge types from PDM";
QCoreApplication::exit(-1);
return -1;
}
initialized = true;
}
return m_pdmDtc->chargeTypeIdFromLegacyId(gearClass, chargeTasCodeIndirect);
}
Core::GeoPosition2D HandlerAesData::relativeToGeoPosition(int x, int y) const
{
const QPointF point(m_utmCoord.geographic(x, y));
return Core::GeoPosition2D(point.x(), point.y());
}
}