- training_area_telegrams.cpp: Fixed QJsonObject initializer syntax (Qt6 requires {{}} not ({}))
- training_area_telegrams.cpp: Fixed fromJson() methods to access m_* members directly
- training_area_telegrams.cpp: Fixed brace mismatches in multiple toJson() methods
- training_area_telegrams.h: Changed Header struct to public members for consistency
- tx_mixin.cpp: Fixed getEquipmentNumber() template for direct member access
- lts_coordinate.cpp: Added missing #include <iomanip>
- MIGRATION_STATUS.md: Added migration progress tracking document
C++17 constraint enforced due to RTI Connext DDS 7.7.0 incompatibility with C++20+
Build status: BUILD_RTI=OFF successful (0 errors, warnings only)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
292 lines
9.2 KiB
C++
Executable File
292 lines
9.2 KiB
C++
Executable File
|
|
|
|
|
|
#include "handler_nasat_impact.h"
|
|
#include "initialization.h"
|
|
#include "dds_handler.h"
|
|
#include "handler_participant.h"
|
|
|
|
#include <QtCore/QDateTime>
|
|
#include <QtCore/QJsonDocument>
|
|
#include <QtCore/QJsonObject>
|
|
#include <ParticipantManagement/ppm.hpp>
|
|
#include <LtsCoordTrans/lts_coord_trans.h>
|
|
|
|
|
|
#ifdef TRIGGER_DUMMY_IMPACT
|
|
# include <QTimer>
|
|
#endif
|
|
|
|
namespace GuezNasat
|
|
{
|
|
HandlerNasatImpact::HandlerNasatImpact(Initialization *mainHandler)
|
|
: AreaEffectSimulation::Interface::Ftc::AirSupportImpactModifyReplyHandler()
|
|
, m_mainHandler(mainHandler)
|
|
{
|
|
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START";
|
|
auto pdmDtc = m_mainHandler->dds()->pdmDtc();
|
|
connect(pdmDtc.get(), &ProjectDataManagement::Interface::Dtc::chargeTypeChanged,
|
|
this, &HandlerNasatImpact::onChargeTypeChanged);
|
|
pdmDtc->chargeTypes([this](const ProjectDataManagement::ChargeType &ct) { onChargeTypeChanged(ct);});
|
|
|
|
#ifdef TRIGGER_DUMMY_IMPACT
|
|
FATAL_LOG(m_logger) << Q_FUNC_INFO << " prepare singleShot...";
|
|
|
|
QTimer *timer = new QTimer;
|
|
timer->setInterval(30000);
|
|
connect(timer, &QTimer::timeout, [this] () {
|
|
FATAL_LOG(m_logger) << Q_FUNC_INFO << " singleShot...";
|
|
|
|
NasatWeaponRelease wr;
|
|
wr.aircraftId = 1;
|
|
|
|
GeoPosition2D geoPos;
|
|
geoPos.lon = 11.56;
|
|
geoPos.lat = 52.46;
|
|
|
|
wr.impactPosition = geoPos;
|
|
wr.flightTime = 5;
|
|
wr.munition = Munition::MSL_AGM_114K;
|
|
|
|
wr.fuseType = FuseType::Instant;
|
|
wr.releaseMode = ReleaseMode::Undefined;
|
|
|
|
this->nasatWeaponRelease(wr);
|
|
|
|
FATAL_LOG(m_logger) << Q_FUNC_INFO << " singleShot...DONE";
|
|
});
|
|
timer->start();
|
|
|
|
#endif
|
|
|
|
TRACE_LOG(m_logger) << Q_FUNC_INFO << " END";
|
|
}
|
|
|
|
void HandlerNasatImpact::onAirSupportImpactModifyReply(const Core::FunctionReplyObject &reply)
|
|
{
|
|
if (reply.error())
|
|
WARNING_LOG(m_logger) << "Could not create single explosion for nasat impact: " << reply();
|
|
|
|
#ifdef NLDEVCTRL_844
|
|
testing.replyCounter++;
|
|
INFO_LOG(m_logger) << "Got create reply: " << reply() << "(id=" << reply.id() << ")"
|
|
<< ", this=" << this
|
|
<< " - replyCounter=" << testing.replyCounter;
|
|
#else
|
|
INFO_LOG(m_logger) << "Got create reply: " << reply() << "(id=" << reply.id() << ")"
|
|
<< ", this=" << this;
|
|
#endif
|
|
}
|
|
|
|
void HandlerNasatImpact::onExplosionClusterModifyReply(const Core::FunctionReplyObject &reply)
|
|
{
|
|
INFO_LOG(m_logger) << "Got create reply: " << reply() << "(id=" << reply.id() << ")"
|
|
<< ", this=" << this
|
|
<< ", reply.error()=" << reply.error();
|
|
if (reply.error())
|
|
ERROR_LOG(m_logger) << "onExplosionClusterModifyReply: Got reply: " << reply() << "(id=" << reply.id() << ")"
|
|
<< " '" << reply.translated() << "'";
|
|
}
|
|
|
|
void HandlerNasatImpact::nasatWeaponRelease(const GuezNasat::NasatWeaponRelease &weaponRelease)
|
|
{
|
|
const Core::GeoPosition geoPos(weaponRelease.impactPosition.lon * LtsCoordTrans::deg2rad(),
|
|
weaponRelease.impactPosition.lat * LtsCoordTrans::deg2rad(),
|
|
0);
|
|
|
|
double tsWeaponRelease = weaponRelease.timestamp < 0 ? QDateTime::currentSecsSinceEpoch() : weaponRelease.timestamp;
|
|
|
|
|
|
|
|
tsWeaponRelease += 5;
|
|
qint64 impactTimeMsec = qRound64((tsWeaponRelease + weaponRelease.flightTime) * 1000);
|
|
qint64 weaponReleaseMsec = qRound64(weaponRelease.flightTime * 1000);
|
|
nasatImpact(weaponRelease.aircraftId, geoPos, weaponReleaseMsec, impactTimeMsec, static_cast<int>(weaponRelease.munition), weaponRelease.fuseType);
|
|
}
|
|
|
|
void HandlerNasatImpact::nasatImpact(int nasatId, const Core::GeoPosition &pos, qint64 flightTimeMsec, qint64 impactTimeMsec, int munitionCode, FuseType fuseType)
|
|
{
|
|
#ifdef NLDEVCTRL_844
|
|
static bool bEnable = true;
|
|
|
|
if (!bEnable)
|
|
return;
|
|
#endif
|
|
|
|
DEBUG_LOG(m_logger) << Q_FUNC_INFO << " START, nasatId=" << nasatId
|
|
<< ", pos=" << pos
|
|
<< ", flightTimeMsec = " << flightTimeMsec
|
|
<< ", impactTimeMsec = " << impactTimeMsec;
|
|
|
|
const auto participants = m_mainHandler->handlerParticipant()->participantsForNasatId(nasatId);
|
|
if (participants.isEmpty())
|
|
{
|
|
WARNING_LOG(m_logger) << "Can not find a valid participant for nasat aircraft with id " << nasatId;
|
|
return;
|
|
}
|
|
|
|
const int chargeTypeIdVal = chargeTypeFromMunitionCode(munitionCode);
|
|
if (chargeTypeIdVal < 0)
|
|
return;
|
|
|
|
const QDateTime dtNow = QDateTime::currentDateTime();
|
|
const qint64 tNow = dtNow.toMSecsSinceEpoch() + 5000;
|
|
|
|
AreaEffectSimulation::ExplosionClusterSingleEffectOnlyRequest ecReq;
|
|
ecReq.id(0);
|
|
ecReq.effectStart(impactTimeMsec > tNow ? impactTimeMsec : tNow);
|
|
ecReq.name(QStringLiteral("NASAT_%1_%2_%3").arg(nasatId).arg(munitionCode).arg(dtNow.toString(QStringLiteral("dd hh:mm:ss"))).toStdString());
|
|
ecReq.element(ecReq.name());
|
|
ecReq.impactPosition(Core::GeoPosition2D(pos.lon(), pos.lat()));
|
|
ecReq.chargeTypeId(chargeTypeIdVal);
|
|
|
|
|
|
|
|
if (m_logger.isDebugEnabled())
|
|
{
|
|
const Core::GeoPosition &nasatPos = m_mainHandler->handlerParticipant()->nasatPosition(nasatId);
|
|
DEBUG_LOG(m_logger) << Q_FUNC_INFO << " START, nasatId=" << nasatId
|
|
<< ", pos=" << nasatPos
|
|
<< ", flightTimeMsec = " << flightTimeMsec
|
|
<< ", impactTimeMsec=" << impactTimeMsec;
|
|
}
|
|
|
|
|
|
AreaEffectSimulation::ExplosionClusterModifyRequest ecCommonModifyRequest;
|
|
ecCommonModifyRequest.id(0);
|
|
|
|
ecCommonModifyRequest.effectStart(impactTimeMsec > tNow ? impactTimeMsec : tNow);
|
|
ecCommonModifyRequest.effectDuration(1000);
|
|
ecCommonModifyRequest.effectSourceId(ProjectDataManagement::EffectSource::ES_Internal);
|
|
|
|
|
|
ecCommonModifyRequest.explosionGeometry(AreaEffectSimulation::AesExplosionGeometry_def::EgPoint);
|
|
|
|
|
|
ecCommonModifyRequest.chargeStruct().chargeTypeId(chargeTypeIdVal);
|
|
ecCommonModifyRequest.chargeStruct().igniterTypeId(fuseTypeToPdmIgniterType(fuseType));
|
|
|
|
ecCommonModifyRequest.area().cornerBottomLeft(Core::GeoPosition2D(pos.lon(), pos.lat()));
|
|
|
|
ecCommonModifyRequest.name(QStringLiteral("NASAT_%1_%2_%3").arg(nasatId).arg(munitionCode).arg(dtNow.toString(QStringLiteral("dd hh:mm:ss"))).toStdString());
|
|
ecCommonModifyRequest.element(ecReq.name());
|
|
|
|
ecCommonModifyRequest.mhpCount(1);
|
|
ecCommonModifyRequest.impactCount(1);
|
|
|
|
|
|
|
|
|
|
ecCommonModifyRequest.flightDuration(flightTimeMsec);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DEBUG_LOG(m_logger) << " Sending air support impact: number of participant= " << participants.size();
|
|
for (const NasatAircraftParticipantEx *nap : participants)
|
|
{
|
|
|
|
|
|
|
|
ecReq.partyId(nap->partyId());
|
|
|
|
ecCommonModifyRequest.partyId(nap->partyId());
|
|
ecCommonModifyRequest.participantId(nap->participantId());
|
|
|
|
|
|
int success = nap->publisher()->publish(ecCommonModifyRequest, this);
|
|
if (success)
|
|
DEBUG_LOG(m_logger) << "Sending air support impact create request: " << ecReq << " to exercise " << nap->exerciseId()
|
|
<< ", nap=" << nap->participant()
|
|
<< " -> success = " << success;
|
|
else
|
|
ERROR_LOG(m_logger) << "Error on Sending air support impact create request: " << ecReq << " to exercise " << nap->exerciseId()
|
|
<< ", nap=" << nap->participant()
|
|
<< " -> success = " << success;
|
|
|
|
#ifdef NLDEVCTRL_844
|
|
testing.requestCounter++;
|
|
INFO_LOG(m_logger) << " requestCounter = " << testing.requestCounter;
|
|
#endif
|
|
}
|
|
|
|
#ifdef NLDEVCTRL_844
|
|
bool bOk = (testing.requestCounter - testing.replyCounter) < 23;
|
|
|
|
FATAL_LOG(m_logger) << " bOk= " << bOk
|
|
<< ", requestCounter = " << testing.requestCounter
|
|
<< ", replyCounter = " << testing.replyCounter;
|
|
if (!bOk)
|
|
{
|
|
FATAL_LOG(m_logger) << " bOk= " << bOk
|
|
<< ", requestCounter = " << testing.requestCounter
|
|
<< " -> DISABLE";
|
|
bEnable = false;
|
|
abort();
|
|
}
|
|
if (testing.requestCounter > 70)
|
|
{
|
|
FATAL_LOG(m_logger) << " bOk= " << bOk
|
|
<< ", requestCounter = " << testing.requestCounter
|
|
<< " -> RESTART";
|
|
exit(42);
|
|
}
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
void HandlerNasatImpact::onChargeTypeChanged(const ProjectDataManagement::ChargeType &ct)
|
|
{
|
|
const QJsonDocument doc(QJsonDocument::fromJson(QByteArray::fromRawData(ct.properties().c_str(), ct.properties().size())));
|
|
const QJsonObject obj(doc.object());
|
|
if (!obj.contains(QLatin1String("nasatId")))
|
|
return;
|
|
int nasatId = obj.value(QLatin1String("nasatId")).toInt();
|
|
if (nasatId == 0)
|
|
{
|
|
WARNING_LOG(m_logger) << "Found charge with an invalid property 'nasatId', id: " << ct.id();
|
|
return;
|
|
}
|
|
m_chargeMapping.insert(nasatId, ct.id());
|
|
}
|
|
|
|
|
|
int HandlerNasatImpact::chargeTypeFromMunitionCode(int nasatChargeCode) const
|
|
{
|
|
auto it = m_chargeMapping.find(nasatChargeCode);
|
|
if (it != m_chargeMapping.end())
|
|
return it.value();
|
|
WARNING_LOG(m_logger) << "Got unmapped nasat charge code " << nasatChargeCode;
|
|
Q_ASSERT(false);
|
|
return -1;
|
|
}
|
|
|
|
int HandlerNasatImpact::fuseTypeToPdmIgniterType(FuseType fusetype) const
|
|
{
|
|
|
|
switch (fusetype) {
|
|
case FuseType::Instant:
|
|
return 102;
|
|
case FuseType::Delay:
|
|
return 103;
|
|
case GuezNasat::FuseType::AirBurst:
|
|
return 101;
|
|
|
|
default:
|
|
return 102;
|
|
}
|
|
}
|
|
|
|
|
|
}
|