406 lines
16 KiB
C++
Executable File
406 lines
16 KiB
C++
Executable File
/**
|
||
* Aes Handler for TetraRadioProxy
|
||
* $Id$
|
||
* $HeadURL$
|
||
* $Author$
|
||
* Created by Christian Ehrlicher, SLSE, 2016-07-12
|
||
*/
|
||
|
||
#pragma once
|
||
|
||
#include <QObject>
|
||
#include <QMap>
|
||
#include <QSet>
|
||
#include <QTimer>
|
||
#include <memory>
|
||
#include <unordered_map>
|
||
#include <AreaEffectSimulation/aes_dtc.h>
|
||
#include <ProjectDataManagement/pdm_dtc.h>
|
||
|
||
#include "pdm_handler.h"
|
||
#include "tab_db.h"
|
||
#include "logger.h"
|
||
#include "send_to_tab.h"
|
||
#include "training_area_telegrams.h"
|
||
|
||
namespace TrainingAreaBase
|
||
{
|
||
class DatabaseInterface;
|
||
class MainHandler;
|
||
class PositionHandler;
|
||
class SendCesHitRequest;
|
||
|
||
class AesStateHandler
|
||
{
|
||
public:
|
||
explicit AesStateHandler(MainHandler *mainHandler);
|
||
|
||
bool init();
|
||
|
||
int createAesTetraId(int aesDdsId, bool &alreadyExists);
|
||
int getAesTetraId(int aesDdsId) const
|
||
{
|
||
return m_ddsId2TetraId.value(aesDdsId);
|
||
}
|
||
int getAesDdsId(int aesTetraId) const
|
||
{
|
||
return m_tetraId2ddsId.value(aesTetraId);
|
||
}
|
||
// we assume, that aesDdsId and aesTetraId are correct
|
||
bool update(int aesDdsId, int aesTetraId, bool bSentToTetra);
|
||
bool isAlreadySentToTetra(int aesDdsId) const
|
||
{
|
||
return m_aesInTetraAvailable.contains(aesDdsId);
|
||
}
|
||
|
||
private:
|
||
// must be in sync ...
|
||
QMap<int, int> m_tetraId2ddsId;
|
||
QMap<int, int> m_ddsId2TetraId;
|
||
QSet<int> m_aesInTetraAvailable;
|
||
std::shared_ptr<DatabaseInterface> m_dbInterface;
|
||
int m_exerciseId;
|
||
LOGGER_T m_logger;
|
||
};
|
||
|
||
/**
|
||
* Listen on Aes Topics and create appropriate Tetra-Telegrams (current XDR-Telegrams)
|
||
* Make sure to assign a proper id and only publish aes which needs to go to tetra
|
||
*/
|
||
class RecvFromDdsAes : public QObject
|
||
{
|
||
Q_OBJECT
|
||
public:
|
||
RecvFromDdsAes(MainHandler *mainHandler,
|
||
const std::shared_ptr<SendToTab> &txCallback,
|
||
QObject *parent = nullptr);
|
||
~RecvFromDdsAes();
|
||
|
||
bool init();
|
||
std::shared_ptr<const AesStateHandler> aesStateHandler() const
|
||
{
|
||
return m_aesStateHandler;
|
||
}
|
||
|
||
int ddsIdFromTetraId(int aesTetraId) const
|
||
{
|
||
return m_aesStateHandler->getAesDdsId(aesTetraId);
|
||
}
|
||
int tetraIdFromDdsId(int aesId) const
|
||
{
|
||
return m_aesStateHandler->getAesTetraId(aesId);
|
||
}
|
||
int aesChargeId(int aesId) const;
|
||
TetraIcd::AreaEffectSimulationType aesTypeFromId(int aesId) const;
|
||
|
||
bool sendSingleFireSMArt(const SendCesHitRequest &request);
|
||
const QVector<TetraIcd::TrainingAreaTelegram*> sentAesTelegrams() const
|
||
{
|
||
return m_sentAesTelegrams;
|
||
}
|
||
|
||
void resetAllDusMines();
|
||
|
||
// [GUEZE-3469] Funktionsraum dekontaminiert faelschlicherweise:
|
||
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> dtcAes() const { return m_dtcAes;} ///< Pointer to DTC AreaEffectSimulation interface object
|
||
|
||
private:
|
||
|
||
template<typename T>
|
||
void handleEffectSimulation(const T &data, DataModification modType, TetraIcd::AreaEffectSimulationType aesType);
|
||
/*!
|
||
*\details Save all central area effect siumulations ´, dont send to tetra, needed for CesHitRequest
|
||
*/
|
||
template<typename T>
|
||
void fillCentralChangesTable(const T &data);
|
||
template <typename T>
|
||
void handleSendToTetra(const T &data, TetraIcd::AreaEffectSimulationType aesType);
|
||
|
||
void onAirSupportImpactChanged(const AreaEffectSimulation::AirSupportImpact &data, DataModification modType);
|
||
void onBcContaminationChanged(const AreaEffectSimulation::BCContamination &data, DataModification modType);
|
||
void onExplosionAreaChanged(const AreaEffectSimulation::ExplosionArea &data, DataModification modType);
|
||
void onExplosionSingleChanged(const AreaEffectSimulation::ExplosionSingle &data, DataModification modType);
|
||
void onMineAreaChanged(const AreaEffectSimulation::MineArea &data, DataModification modType);
|
||
void onNContaminationChanged(const AreaEffectSimulation::NContamination &data, DataModification modType);
|
||
void onFunctionalAreaChanged(const AreaEffectSimulation::FunctionalArea &data, DataModification modType);
|
||
void onTechnicalAreaChanged(const AreaEffectSimulation::TechnicalArea &data, DataModification modType);
|
||
void onTriggeredImpactsChanged(const AreaEffectSimulation::TriggeredImpacts &data, DataModification modType);
|
||
void onDusMineStateChanged(const AreaEffectSimulation::DusMineState &data, DataModification modType);
|
||
void onDusSingleMineChanged(const AreaEffectSimulation::DusSingleMine &data, DataModification modType);
|
||
void onGasPipeChanged(const AreaEffectSimulation::GasPipe &data, DataModification modType);
|
||
void onBoobyTrapChanged(const AreaEffectSimulation::BoobyTrap &data, DataModification modType);
|
||
void onOffRouteMineChanged(const AreaEffectSimulation::OffRouteMine &data, DataModification modType);
|
||
void onExplosionClusterChanged(const AreaEffectSimulation::ExplosionCluster &data, DataModification modType);
|
||
void onEffectsChanged(const AreaEffectSimulation::Effects &data, DataModification modType);
|
||
|
||
void sendCreateEffectSimulation(const AreaEffectSimulation::AirSupportImpact &aes, int aesTetraId);
|
||
void sendCreateEffectSimulation(const AreaEffectSimulation::BCContamination &aes, int aesTetraId);
|
||
void sendCreateEffectSimulation(const AreaEffectSimulation::ExplosionArea &aes, int aesTetraId);
|
||
void sendCreateEffectSimulation(const AreaEffectSimulation::ExplosionCluster &aes, int aesTetraId);
|
||
void sendCreateEffectSimulation(const AreaEffectSimulation::ExplosionSingle &aes, int aesTetraId, int equipmentNumber = 0);
|
||
void sendCreateEffectSimulation(const AreaEffectSimulation::MineArea &aes, int aesTetraId);
|
||
void sendCreateEffectSimulation(const AreaEffectSimulation::NContamination &aes, int aesTetraId);
|
||
void sendCreateEffectSimulation(const AreaEffectSimulation::FunctionalArea &aes, int aesTetraId);
|
||
void sendCreateEffectSimulation(const AreaEffectSimulation::TechnicalArea &aes, int aesTetraId);
|
||
void sendCreateEffectSimulation(const AreaEffectSimulation::DusSingleMine &aes, int aesTetraId);
|
||
void sendCreateEffectSimulation(const AreaEffectSimulation::GasPipe &aes, int aesTetraId);
|
||
void sendModifyEffectSimulationName(TetraIcd::AreaEffectSimulationType aesType, int aesTetraId, const std::string &name, int aesId);
|
||
void sendRemoveEffectSimulation(TetraIcd::AreaEffectSimulationType aesType, int aesDdsId);
|
||
void sendPauseEffectSimulation(int aesDdsId);
|
||
template<typename T>
|
||
void sendResumeEffectSimulation(const T &)
|
||
{
|
||
static_assert(std::is_base_of<AreaEffectSimulation::AesItem, T>::value, "Given type for sendResumeEffectSimulation is not an aes item!");
|
||
}
|
||
|
||
// If you to do anything special for type X in dataChanged, do it here
|
||
void doSpecialization(const AreaEffectSimulation::ExplosionArea &data, std::unordered_map<int, AreaEffectSimulation::ExplosionArea> &cont)
|
||
{
|
||
cont[data.id()].remainExplosionNumber(data.remainExplosionNumber());
|
||
}
|
||
template<typename T>
|
||
void doSpecialization(const T &data, std::unordered_map<int, T> &cont)
|
||
{
|
||
Q_UNUSED(data);
|
||
Q_UNUSED(cont);
|
||
}
|
||
template<typename T>
|
||
bool dataChanged(const T &data, std::unordered_map<int, T> &cont, bool &onlyNameChanged)
|
||
{
|
||
onlyNameChanged = false;
|
||
auto it = cont.find(data.id());
|
||
T dataTmp(data);
|
||
dataTmp.sampleTime(0);
|
||
|
||
if (it == cont.end())
|
||
{
|
||
cont.emplace(std::make_pair(data.id(), std::move(dataTmp)));
|
||
DEBUG_LOG(m_logger) << "new AES Item: " << data;
|
||
return true;
|
||
}
|
||
|
||
// do not check AES state, it is handled beforehand
|
||
it->second.effectStateId(data.effectStateId());
|
||
|
||
// for Explosion Area we have to always save the remainExplosionNumber value
|
||
doSpecialization(data, cont);
|
||
|
||
if (it->second == dataTmp)
|
||
{
|
||
DEBUG_LOG(m_logger) << "nothing changed for AES Item: " << data;
|
||
return false;
|
||
}
|
||
|
||
// check if only name changed
|
||
T tmp(it->second);
|
||
tmp.name(data.name());
|
||
tmp.sampleTime(data.sampleTime()); // sample time always 0 for objects in map
|
||
onlyNameChanged = (tmp == data);
|
||
|
||
std::swap(it->second, dataTmp); // with sampleTime = 0
|
||
|
||
DEBUG_LOG(m_logger) << "changed AES Item: " << data;
|
||
return true;
|
||
}
|
||
bool dataChanged(const AreaEffectSimulation::AirSupportImpact ¤t, bool &onlyNameChanged)
|
||
{
|
||
return dataChanged(current, m_currentAirSupportImpacts, onlyNameChanged);
|
||
}
|
||
bool dataChanged(const AreaEffectSimulation::BCContamination ¤t, bool &onlyNameChanged)
|
||
{
|
||
return dataChanged(current, m_currentBCContaminations, onlyNameChanged);
|
||
}
|
||
bool dataChanged(const AreaEffectSimulation::ExplosionArea ¤t, bool &onlyNameChanged)
|
||
{
|
||
AreaEffectSimulation::ExplosionArea copy(current);
|
||
// Todo: Something else to set?
|
||
copy.remainExplosionNumber(0);
|
||
return dataChanged(copy, m_currentExplosionArea, onlyNameChanged);
|
||
}
|
||
bool dataChanged(const AreaEffectSimulation::ExplosionCluster ¤t, bool &onlyNameChanged)
|
||
{
|
||
AreaEffectSimulation::ExplosionCluster copy(current);
|
||
// Todo: Something else to set?
|
||
copy.remainExplosionNumber(0);
|
||
return dataChanged(copy, m_currentExplosionCluster, onlyNameChanged);
|
||
}
|
||
|
||
bool dataChanged(const AreaEffectSimulation::ExplosionSingle ¤t, bool &onlyNameChanged)
|
||
{
|
||
return dataChanged(current, m_currentExplosionSingle, onlyNameChanged);
|
||
}
|
||
bool dataChanged(const AreaEffectSimulation::MineArea ¤t, bool &onlyNameChanged)
|
||
{
|
||
return dataChanged(current, m_currentMineArea, onlyNameChanged);
|
||
}
|
||
bool dataChanged(const AreaEffectSimulation::NContamination ¤t, bool &onlyNameChanged)
|
||
{
|
||
return dataChanged(current, m_currentNContamination, onlyNameChanged);
|
||
}
|
||
bool dataChanged(const AreaEffectSimulation::FunctionalArea ¤t, bool &onlyNameChanged)
|
||
{
|
||
return dataChanged(current, m_currentFunctionalArea, onlyNameChanged);
|
||
}
|
||
bool dataChanged(const AreaEffectSimulation::TechnicalArea ¤t, bool &onlyNameChanged)
|
||
{
|
||
return dataChanged(current, m_currentTechnicalArea, onlyNameChanged);
|
||
}
|
||
bool dataChanged(const AreaEffectSimulation::DusSingleMine ¤t, bool &onlyNameChanged)
|
||
{
|
||
return dataChanged(current, m_currentDusSingleMine, onlyNameChanged);
|
||
}
|
||
bool dataChanged(const AreaEffectSimulation::GasPipe ¤t, bool &onlyNameChanged)
|
||
{
|
||
return dataChanged(current, m_currentGasPipes, onlyNameChanged);
|
||
}
|
||
/*!
|
||
* \brief dataChanged
|
||
* \param current
|
||
* \details BoobyTrap is complete central, not going to tetra, the bool is just used as a placeholder
|
||
* \return
|
||
*/
|
||
bool dataChanged(const AreaEffectSimulation::BoobyTrap ¤t)
|
||
{
|
||
bool placeholder;
|
||
Q_UNUSED(placeholder);
|
||
return dataChanged(current, m_currentBoobyTraps, placeholder);
|
||
|
||
}
|
||
/*!
|
||
* \brief dataChanged
|
||
* \param current
|
||
* \details OffRouteMine is complete central, not going to tetra, the bool is just used as a placeholder
|
||
* \return
|
||
*/
|
||
bool dataChanged(const AreaEffectSimulation::OffRouteMine ¤t)
|
||
{
|
||
bool placeholder;
|
||
Q_UNUSED(placeholder);
|
||
return dataChanged(current, m_currentOffRouteMines, placeholder);
|
||
}
|
||
|
||
template <typename T>
|
||
void resetStartTime(int aesDdsId, T &cont)
|
||
{
|
||
auto it = cont.find(aesDdsId);
|
||
if (it == cont.end())
|
||
return;
|
||
it->second.effectStart(0);
|
||
}
|
||
|
||
void resetStartTime(const AreaEffectSimulation::AirSupportImpact ¤t)
|
||
{
|
||
resetStartTime(current.id(), m_currentBCContaminations);
|
||
}
|
||
void resetStartTime(const AreaEffectSimulation::BCContamination ¤t)
|
||
{
|
||
resetStartTime(current.id(), m_currentBCContaminations);
|
||
}
|
||
void resetStartTime(const AreaEffectSimulation::ExplosionArea ¤t)
|
||
{
|
||
resetStartTime(current.id(), m_currentExplosionArea);
|
||
}
|
||
void resetStartTime(const AreaEffectSimulation::ExplosionCluster ¤t)
|
||
{
|
||
resetStartTime(current.id(), m_currentExplosionCluster);
|
||
}
|
||
void resetStartTime(const AreaEffectSimulation::ExplosionSingle ¤t)
|
||
{
|
||
resetStartTime(current.id(), m_currentExplosionSingle);
|
||
}
|
||
void resetStartTime(const AreaEffectSimulation::MineArea ¤t)
|
||
{
|
||
resetStartTime(current.id(), m_currentMineArea);
|
||
}
|
||
void resetStartTime(const AreaEffectSimulation::NContamination ¤t)
|
||
{
|
||
resetStartTime(current.id(), m_currentNContamination);
|
||
}
|
||
void resetStartTime(const AreaEffectSimulation::FunctionalArea ¤t)
|
||
{
|
||
resetStartTime(current.id(), m_currentFunctionalArea);
|
||
}
|
||
void resetStartTime(const AreaEffectSimulation::TechnicalArea ¤t)
|
||
{
|
||
resetStartTime(current.id(), m_currentTechnicalArea);
|
||
}
|
||
void resetStartTime(const AreaEffectSimulation::DusSingleMine ¤t)
|
||
{
|
||
resetStartTime(current.id(), m_currentDusSingleMine);
|
||
}
|
||
void resetStartTime(const AreaEffectSimulation::GasPipe ¤t)
|
||
{
|
||
resetStartTime(current.id(), m_currentGasPipes);
|
||
}
|
||
void resetStartTime(const AreaEffectSimulation::BoobyTrap ¤t)
|
||
{
|
||
resetStartTime(current.id(), m_currentBoobyTraps);
|
||
}
|
||
void resetStartTime(const AreaEffectSimulation::OffRouteMine ¤t)
|
||
{
|
||
resetStartTime(current.id(), m_currentOffRouteMines);
|
||
}
|
||
|
||
std::shared_ptr<PdmHandler> pdm();
|
||
|
||
template<typename T>
|
||
void txData(const T &tele)
|
||
{
|
||
m_txCallback->txData(tele);
|
||
m_sentAesTelegrams.push_back(new T(tele));
|
||
m_sentAesTelegramsAesIds.push_back(tele.aesDdsId);
|
||
m_checkOutdatedTelegramsTimer->start();
|
||
DEBUG_LOG(m_logger) << "Appending " << tele.type()<< " to m_sentAesTelegrams";
|
||
}
|
||
|
||
void onCheckOutdatedTelegrams();
|
||
void onSendDusMineReactivationTimeout();
|
||
|
||
private:
|
||
std::unordered_map<int, AreaEffectSimulation::AirSupportImpact> m_currentAirSupportImpacts;
|
||
std::unordered_map<int, AreaEffectSimulation::BCContamination> m_currentBCContaminations;
|
||
std::unordered_map<int, AreaEffectSimulation::ExplosionArea> m_currentExplosionArea;
|
||
std::unordered_map<int, AreaEffectSimulation::ExplosionCluster> m_currentExplosionCluster;
|
||
std::unordered_map<int, AreaEffectSimulation::ExplosionSingle> m_currentExplosionSingle;
|
||
std::unordered_map<int, AreaEffectSimulation::MineArea> m_currentMineArea;
|
||
std::unordered_map<int, AreaEffectSimulation::TriggeredImpacts> m_temporarySingleMineState;
|
||
std::unordered_map<int, AreaEffectSimulation::NContamination> m_currentNContamination;
|
||
std::unordered_map<int, AreaEffectSimulation::FunctionalArea> m_currentFunctionalArea;
|
||
std::unordered_map<int, AreaEffectSimulation::TechnicalArea> m_currentTechnicalArea;
|
||
std::unordered_map<int, AreaEffectSimulation::DusSingleMine> m_currentDusSingleMine;
|
||
std::unordered_map<int, AreaEffectSimulation::GasPipe> m_currentGasPipes;
|
||
/*!
|
||
* \brief m_currentBoobyTraps (Verdeckte Ladung)
|
||
* \details Added for 3D Wirksim
|
||
* \author Niklas Schmidt
|
||
*/
|
||
std::unordered_map<int, AreaEffectSimulation::BoobyTrap> m_currentBoobyTraps;
|
||
/*!
|
||
* \brief m_currentOffRouteMines
|
||
* \details Added for 3D Wirksim
|
||
* \author Niklas Schmidt
|
||
*/
|
||
std::unordered_map<int, AreaEffectSimulation::OffRouteMine> m_currentOffRouteMines;
|
||
//std::unordered_map<int, AreaEffectSimulation::DangerZoneExplosion> m_currentDangerExplosionZones; //TODO: Not yet implemented in Aes (Gefahrenbereich Steilfeuer)
|
||
|
||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
|
||
std::shared_ptr<SendToTab> m_txCallback;
|
||
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> m_dtcAes;
|
||
std::shared_ptr<AesStateHandler> m_aesStateHandler;
|
||
|
||
QMap<int, AreaEffectSimulation::AesEffectState> m_currentEffectState;
|
||
QMap<int, AreaEffectSimulation::DusMine> m_allReactivatableDusMines; // united map of all DUS-mines independet of matched minearea/status
|
||
QVector<int> m_minesToSend;
|
||
std::shared_ptr<PositionHandler> m_posHandler;
|
||
MainHandler *m_mainHandler;
|
||
QTimer *m_checkOutdatedTelegramsTimer;
|
||
QTimer *m_sendDusMineReactivtionTimer;
|
||
|
||
QVector<TetraIcd::TrainingAreaTelegram*> m_sentAesTelegrams;
|
||
QVector<int> m_sentAesTelegramsAesIds;
|
||
|
||
LOGGER_T m_logger;
|
||
};
|
||
|
||
}
|