1099 lines
41 KiB
C++
Executable File
1099 lines
41 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* PpmHandler for AdlerJson Plugin
|
|
* $Id: ppm_handler.cpp 62899 2024-05-29 11:08:50Z ewert_j $
|
|
* $HeadURL: svn://slssvn/TDS/branches/product/features/ufom/Lts/Proxies/TrainingAreaBase/Plugins/AdlerJson/ppm_handler.cpp $
|
|
* $Author: ewert_j $
|
|
* Created by Julius Ewert, ESIM, 2024-03-20
|
|
*/
|
|
|
|
#include "ppm_handler.h"
|
|
#include "Core/core.hpp"
|
|
|
|
#include <QJsonDocument>
|
|
|
|
#include "json_dispatcher.h"
|
|
#include <QRandomGenerator>
|
|
#include <LtsUtilsCore/dds_vector.h>
|
|
#include <ParticipantManagement/ppm.hpp>
|
|
|
|
namespace AdlerJson
|
|
{
|
|
// See PPM::SpecialSensorStatus
|
|
static const int ADLER_OPERATIONAL = 125;
|
|
// static const int ADLER_CONDITIONALLY_OPERATIONAL = 126;
|
|
static const int ADLER_NOT_OPERATIONAL = 127;
|
|
|
|
PpmHandler::PpmHandler(QObject *parent)
|
|
: QObject(parent)
|
|
, m_logger(getLogger("PpmHandler"))
|
|
, m_sendParticipantDataTimer(new QTimer(this))
|
|
{
|
|
}
|
|
|
|
bool PpmHandler::init(MainDispatcher *mainDispatcher)
|
|
{
|
|
|
|
m_mainDispatcher = mainDispatcher;
|
|
m_ftcPpm = ParticipantManagement::Interface::Ftc::create(m_mainDispatcher->ddsHandler()->ddsConnector());
|
|
m_ftcPpm->enableModifyParticipantData();
|
|
m_ftcPpm->enableModifyPartyData();
|
|
m_ftcPpm->enableSetSimulatedPosition();
|
|
|
|
m_dtcPpm = ParticipantManagement::Interface::Dtc::create(m_mainDispatcher->ddsHandler()->ddsConnector());
|
|
|
|
DEBUG_LOG(m_logger) << "-------------<><><>------" << m_mainDispatcher->exerciseId();
|
|
if (!m_dtcPpm->enableParticipant() || !m_dtcPpm->enableDynamicParticipantData() || !m_dtcPpm->enableParticipantPosition())
|
|
{
|
|
ERROR_LOG(m_logger) << "Can not read data from Ppm";
|
|
return false;
|
|
}
|
|
|
|
m_dtcPpm->enableType();
|
|
m_dtcPpm->waitForHistoricalDataParticipant(2000);
|
|
m_dtcPpm->waitForHistoricalDataDynamicParticipantData(1000);
|
|
m_dtcPpm->waitForHistoricalDataParticipantPosition(1000);
|
|
|
|
m_sendParticipantDataTimer->setInterval(2 * 1000);
|
|
connect(m_sendParticipantDataTimer, &QTimer::timeout, this, &PpmHandler::onSendParticipantDataTimeout);
|
|
|
|
connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::partyChanged, this, &PpmHandler::onPartyChanged);
|
|
|
|
connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::participantChanged, this, &PpmHandler::onParticipantChanged);
|
|
|
|
connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::participantPositionChanged, this, &PpmHandler::onParticipantPositionChanged);
|
|
|
|
connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::dynamicParticipantDataChanged, this, &PpmHandler::onDynamicParticipantDataChanged);
|
|
|
|
return true;
|
|
}
|
|
|
|
void PpmHandler::modifyPartyAdlerProperties(const int wsId,
|
|
const int assetId,
|
|
const int partyId,
|
|
const QString &saaName,
|
|
const QString &szenarName,
|
|
const ParticipantManagement::ConnectState &connectState,
|
|
const bool isVerbund)
|
|
{
|
|
DEBUG_LOG(m_logger) << "modifyParty"
|
|
<< " assetId=" << assetId << " partyId=" << partyId << " saaName=" << saaName << " szenarName=" << szenarName << " connectState=" << connectState
|
|
<< " isVerbund=" << isVerbund;
|
|
|
|
ParticipantManagement::Party requestParty;
|
|
requestParty = m_dtcPpm->party(partyId);
|
|
// Get old properties and then update them
|
|
QJsonObject origObj = QJsonDocument::fromJson(requestParty.properties().c_str()).object();
|
|
// This might be empty after creation, but it's okay
|
|
QJsonObject adlerPropertiesObj = origObj[QStringLiteral("Adler")].toObject();
|
|
adlerPropertiesObj[QStringLiteral("saaConnectedState")] = connectState.underlying();
|
|
adlerPropertiesObj[QStringLiteral("szenarName")] = szenarName;
|
|
adlerPropertiesObj[QStringLiteral("saaName")] = saaName;
|
|
adlerPropertiesObj[QStringLiteral("wsId")] = wsId;
|
|
adlerPropertiesObj[QStringLiteral("assetId")] = ((connectState == ParticipantManagement::ConnectState::Connected) ? assetId : -1); // sicherung
|
|
adlerPropertiesObj[QStringLiteral("isVerbund")] = isVerbund;
|
|
|
|
const QByteArray &propertiesBa = requestParty.properties().c_str();
|
|
QJsonParseError parserError;
|
|
QJsonDocument doc(QJsonDocument::fromJson(propertiesBa, &parserError));
|
|
|
|
if (parserError.error != QJsonParseError::NoError)
|
|
{
|
|
ERROR_LOG(m_logger) << "Error parsing json document: " << parserError.errorString() << " '" << propertiesBa << "'";
|
|
doc = QJsonDocument();
|
|
}
|
|
|
|
DEBUG_LOG(m_logger) << "json to parse: " << doc.toJson();
|
|
|
|
QJsonObject obj(doc.object());
|
|
obj[QStringLiteral("Adler")] = adlerPropertiesObj;
|
|
|
|
const QByteArray propertiesStr = QJsonDocument(obj).toJson(QJsonDocument::Compact);
|
|
requestParty.properties() = propertiesStr.data();
|
|
|
|
m_ftcPpm->modifyPartyDataRequest(requestParty);
|
|
}
|
|
|
|
void PpmHandler::parseSQFS(const Feuerstellungsdaten &exSQFS, const int wsId)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Start parse SQFS";
|
|
auto saa = m_mainDispatcher->jsonDispatcher()->getSAAByWs(wsId);
|
|
if (!saa)
|
|
{
|
|
ERROR_LOG(m_logger) << "SQ WS from SAA but SAA with id " << wsId << " not found";
|
|
return;
|
|
}
|
|
const QString &verein = exSQFS.feuereinheit.verein;
|
|
const ProjectDataManagement::L26_EffectingSystemType &internalType = exSQFS.typ;
|
|
|
|
// The random number helps us identifying this message and its content inside the temp maps
|
|
int rndNmbr = QRandomGenerator::global()->generate();
|
|
ParticipantManagement::ParticipantData pUdata = findParticipantDataByInternalName(rndNmbr, verein, saa->getIsVerbund());
|
|
|
|
// Here we Need to save the charges
|
|
auto chargeMap = m_tempChargesMap.value(rndNmbr);
|
|
chargeMap.insert(verein, QVector<Geschoss>(exSQFS.geschosse));
|
|
m_tempChargesMap.insert(rndNmbr, chargeMap);
|
|
|
|
QMap<QString, ProjectDataManagement::L28_Status> readyMap;
|
|
readyMap.insert(verein, exSQFS.status);
|
|
m_tempReadyMessage.insert(rndNmbr, readyMap);
|
|
|
|
// we will use the mid point coordinate for the unit position
|
|
auto posdMap = m_tempPositionMap.value(rndNmbr);
|
|
AdlerJson::KoordinateMitHoehe middle;
|
|
middle.koordinate.longitude = exSQFS.mittelpunkt.koordinate.longitude;
|
|
middle.koordinate.latitude = exSQFS.mittelpunkt.koordinate.latitude;
|
|
posdMap.insert(verein, middle);
|
|
m_tempPositionMap.insert(rndNmbr, posdMap);
|
|
|
|
// add custom function to get participant for own party!
|
|
int superiorModId = 1000000007;
|
|
ParticipantManagement::Participant pUnit = findParticipantByInternalName(verein, saa->getPartyId(), saa->getIsVerbund());
|
|
// We already had a "fake" Unit, we just need the tempmaps
|
|
if (pUdata.modId() > 0)
|
|
{
|
|
m_sendParticipantDataTimer->start();
|
|
return;
|
|
}
|
|
// We have either an existing unit or not even a fake unit: then we will update or create one
|
|
if (pUnit.id() > 0)
|
|
{
|
|
// Update UnitPos //what about others?
|
|
// Nothing to do as we dont Update Unit Symbols by itself.
|
|
// But Update Charges
|
|
// It still applies, that units never publsh their positions..
|
|
// see Lts/Services/ParticipantManagement/ParticipantHandling/participant.cpp:37
|
|
sendChargesFromTempMap(rndNmbr, saa->getPartyId(), saa->getIsVerbund());
|
|
sendReadyMessageFromTempMap(rndNmbr, saa->getPartyId(), saa->getIsVerbund());
|
|
sendPositionFromTempMap(rndNmbr, saa->getPartyId(), saa->getIsVerbund());
|
|
// then remove again here
|
|
m_tempChargesMap.remove(rndNmbr);
|
|
m_tempPositionMap.remove(rndNmbr);
|
|
m_tempinternalNameMap.remove(rndNmbr);
|
|
m_tempReadyMessage.remove(rndNmbr);
|
|
}
|
|
else
|
|
{
|
|
std::vector<ParticipantManagement::ParticipantData> list;
|
|
// Get UnitType
|
|
const ParticipantManagement::Type unitType = m_dtcPpm->getTypeFromAdlerType(waffensystemtypMap.key(internalType.underlying()), true, saa->getIsVerbund());
|
|
|
|
// find parent First
|
|
// modId will be 0 if not found and set if found
|
|
// append root if set
|
|
const auto root = findRootUnit(saa->getPartyId());
|
|
if (root.id() > 0)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Append FS Unit to root Unit";
|
|
list.push_back(root);
|
|
}
|
|
|
|
ParticipantManagement::ParticipantData data = findParticipantDataByInternalName(rndNmbr, verein, saa->getIsVerbund()); // update
|
|
data.id(0);
|
|
data.partyId(saa->getPartyId());
|
|
data.externalId(0);
|
|
data.hierarchyNumber(1);
|
|
data.name(verein.toStdString());
|
|
data.designator(verein.toStdString());
|
|
data.symbol(unitType.symbol());
|
|
data.tacticalIdentifier(verein.toStdString());
|
|
data.typeId(unitType.id());
|
|
data.modId(superiorModId);
|
|
data.isDeleted(false);
|
|
data.isSimulated(false);
|
|
data.superiorModId(root.modId());
|
|
|
|
list.push_back(data);
|
|
|
|
ParticipantManagement::ModifyParticipantDataRequest newRequest;
|
|
newRequest.requestId(rndNmbr); // we store the random number here to adress later for the postion
|
|
newRequest.data(list);
|
|
|
|
// add to m_tempPartDataList
|
|
m_tempPartDataList.insert(rndNmbr, list);
|
|
|
|
// Send Request
|
|
m_ftcPpm->modifyParticipantDataRequest(newRequest, this);
|
|
}
|
|
}
|
|
|
|
void PpmHandler::parseSQWS(const Waffensystemdaten &exSQWS, const int wsId)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Start parse SQWS";
|
|
auto saa = m_mainDispatcher->jsonDispatcher()->getSAAByWs(wsId);
|
|
if (!saa)
|
|
{
|
|
ERROR_LOG(m_logger) << "SQ WS from SAA but SAA with id " << wsId << " not found";
|
|
return;
|
|
}
|
|
const ProjectDataManagement::L27_EffectorId &internalName = exSQWS.kenner;
|
|
const ProjectDataManagement::L26_EffectingSystemType &internalType = exSQWS.typ;
|
|
const auto &charges = exSQWS.geschosse;
|
|
const QString &verein = exSQWS.einheit.verein;
|
|
|
|
// The random number helps us identifying this message and its content inside the temp maps
|
|
int currentRandomNumber = QRandomGenerator::global()->generate();
|
|
// overrides currentRandomNumber if the verin is already inside
|
|
ParticipantManagement::ParticipantData pUdata = findParticipantDataByInternalName(currentRandomNumber, verein, saa->getIsVerbund());
|
|
|
|
// Save Name for later
|
|
auto nameVec = m_tempinternalNameMap.value(currentRandomNumber);
|
|
nameVec.append(waffensystemkennerMap.key(internalName));
|
|
m_tempinternalNameMap.insert(currentRandomNumber, nameVec);
|
|
|
|
QMap<QString, QVector<Geschoss>> map = m_tempChargesMap.value(currentRandomNumber);
|
|
map.insert(waffensystemkennerMap.key(internalName), charges);
|
|
|
|
m_tempChargesMap.insert(currentRandomNumber, map);
|
|
|
|
// add custom function to get participant for own party!
|
|
ParticipantManagement::Participant pp = findParticipantByInternalName(waffensystemkennerMap.key(internalName), saa->getPartyId(), saa->getIsVerbund());
|
|
|
|
// Save Position and internal name in temp Maps:
|
|
auto posMap = m_tempPositionMap.value(currentRandomNumber);
|
|
posMap.insert(waffensystemkennerMap.key(internalName), exSQWS.koordinate);
|
|
|
|
m_tempPositionMap.insert(currentRandomNumber, posMap);
|
|
|
|
if (pp.id() > 0)
|
|
{
|
|
// Update
|
|
DEBUG_LOG(m_logger) << "Found Participant only update pos";
|
|
sendPositionFromTempMap(currentRandomNumber, saa->getPartyId(), saa->getIsVerbund());
|
|
sendChargesFromTempMap(currentRandomNumber, saa->getPartyId(), saa->getIsVerbund());
|
|
// then remove again here
|
|
m_tempChargesMap.remove(currentRandomNumber);
|
|
m_tempPositionMap.remove(currentRandomNumber);
|
|
m_tempinternalNameMap.remove(currentRandomNumber);
|
|
m_randomNumbers.removeAll(currentRandomNumber);
|
|
}
|
|
else
|
|
{
|
|
|
|
// need to map those inside the ppmdtc
|
|
const ParticipantManagement::Type type = m_dtcPpm->getTypeFromAdlerType(waffensystemtypMap.key(internalType.underlying()), false, saa->getIsVerbund());
|
|
DEBUG_LOG(m_logger) << "found type with id: " << type.id() << " for name: " << waffensystemtypMap.key(internalType);
|
|
if (type.id() <= 0)
|
|
{
|
|
ERROR_LOG(m_logger) << "NO Type Found";
|
|
return;
|
|
}
|
|
|
|
std::vector<ParticipantManagement::ParticipantData> list = m_tempPartDataList.value(currentRandomNumber);
|
|
|
|
// Find Unit first)
|
|
uint superiorModId = QRandomGenerator::global()->generate() / 2;
|
|
|
|
ParticipantManagement::Participant pUnit = findParticipantByInternalName(verein, saa->getPartyId(), saa->getIsVerbund());
|
|
DEBUG_LOG(m_logger) << "Looking for Verein: " << verein << " found Unit: " << pUnit.id() << " foundData: " << pUdata.modId();
|
|
|
|
if (pUdata.modId() > 0)
|
|
{
|
|
superiorModId = pUdata.modId();
|
|
DEBUG_LOG(m_logger) << "FOUND UNIT in list use their modId " << superiorModId << " RND: " << currentRandomNumber;
|
|
}
|
|
else if (pUnit.id() > 0)
|
|
{
|
|
// Mod Unit
|
|
ParticipantManagement::ParticipantData pUData = m_dtcPpm->convertParticipantToParticipantData(pUnit);
|
|
pUData.modId(superiorModId);
|
|
pUData.hierarchyNumber(1);
|
|
|
|
list.push_back(pUData);
|
|
m_tempPartDataList.insert(currentRandomNumber, list);
|
|
DEBUG_LOG(m_logger) << "CREATE Uit from ppm " << superiorModId << " RND: " << currentRandomNumber;
|
|
ParticipantManagement::Participant tmp = pUnit;
|
|
while (tmp.superiorId() > 0)
|
|
{
|
|
tmp = m_dtcPpm->participant(tmp.superiorId());
|
|
pUData = m_dtcPpm->convertParticipantToParticipantData(tmp);
|
|
list.push_back(pUData);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// create new
|
|
// find parent First
|
|
// modId will be 0 if not found and set if found
|
|
// append root if set
|
|
const auto root = findRootUnit(saa->getPartyId());
|
|
if (root.id() > 0)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Append to Unit" << superiorModId << " RND: " << currentRandomNumber;
|
|
list.push_back(root);
|
|
}
|
|
const ParticipantManagement::Type unitType = m_dtcPpm->getTypeFromAdlerType(waffensystemtypMap.key(internalType), true, saa->getIsVerbund());
|
|
DEBUG_LOG(m_logger) << "CREATE NEW Unit use supId" << superiorModId << " RND: " << currentRandomNumber;
|
|
ParticipantManagement::ParticipantData data;
|
|
data.id(0);
|
|
data.partyId(saa->getPartyId());
|
|
data.externalId(0);
|
|
data.hierarchyNumber(1);
|
|
data.name(verein.toStdString());
|
|
data.designator(verein.toStdString());
|
|
data.symbol(unitType.symbol());
|
|
data.tacticalIdentifier(verein.toStdString());
|
|
data.typeId(unitType.id()); // use korrect type
|
|
data.modId(superiorModId);
|
|
data.isDeleted(false);
|
|
data.isSimulated(false);
|
|
data.superiorModId(root.modId());
|
|
// Add to request List
|
|
list.push_back(data);
|
|
}
|
|
// Create
|
|
DEBUG_LOG(m_logger) << "Create new Participant"
|
|
<< " RND: " << currentRandomNumber;
|
|
|
|
ParticipantManagement::ParticipantData data;
|
|
|
|
data.id(0);
|
|
data.partyId(saa->getPartyId());
|
|
data.externalId(0);
|
|
data.hierarchyNumber(list.size());
|
|
data.name(waffensystemkennerMap.key(internalName).toStdString());
|
|
data.designator(waffensystemkennerMap.key(internalName).toStdString());
|
|
data.symbol(type.symbol());
|
|
data.tacticalIdentifier(verein.toStdString());
|
|
data.typeId(type.id()); // use korrect type
|
|
data.modId(QRandomGenerator::global()->generate() / 2);
|
|
data.isDeleted(false);
|
|
data.isSimulated(false);
|
|
data.superiorModId(superiorModId);
|
|
// ParticipantManagement::ModifyParticipantDataRequest *newRequest = new ParticipantManagement::ModifyParticipantDataRequest();
|
|
// newRequest->requestId(rndNmbr); //we store the random number here to adress later for the postion
|
|
list.push_back(data);
|
|
m_tempPartDataList.insert(currentRandomNumber, list);
|
|
m_randomNumbers.append(currentRandomNumber);
|
|
m_sendParticipantDataTimer->start();
|
|
}
|
|
}
|
|
|
|
void PpmHandler::parseSQLP(const Ladeplatzdaten &exSQLP, const int wsId)
|
|
{
|
|
DEBUG_LOG(m_logger) << "START parse SQLP";
|
|
auto saa = m_mainDispatcher->jsonDispatcher()->getSAAByWs(wsId);
|
|
if (!saa)
|
|
{
|
|
ERROR_LOG(m_logger) << "SQ LP from SAA but SAA with id " << wsId << " not found";
|
|
return;
|
|
}
|
|
const QString &verein = exSQLP.einheit.verein;
|
|
// lets assume that there is no "unit for that and can be added manualy
|
|
int rndNmbr = QRandomGenerator::global()->generate();
|
|
// Save Position and internal name in temp Maps:
|
|
auto posdMap = m_tempPositionMap.value(rndNmbr);
|
|
posdMap.insert(verein, exSQLP.koordinate);
|
|
m_tempPositionMap.insert(rndNmbr, posdMap);
|
|
|
|
QMap<QString, QVector<Geschoss>> map;
|
|
map.insert(verein, QVector<Geschoss>(exSQLP.geschosse));
|
|
m_tempChargesMap.insert(rndNmbr, map);
|
|
|
|
auto nameVec = m_tempinternalNameMap.value(rndNmbr);
|
|
nameVec.append(verein);
|
|
m_tempinternalNameMap.insert(rndNmbr, nameVec);
|
|
|
|
// add custom function to get participant for own party!
|
|
ParticipantManagement::Participant pp = findParticipantByInternalName(verein, saa->getPartyId(), saa->getIsVerbund());
|
|
const ParticipantManagement::Type type = m_dtcPpm->getTypeFromAdlerType(QStringLiteral("LP"), false, saa->getIsVerbund());
|
|
if (pp.id() > 0)
|
|
{
|
|
// Update pos
|
|
sendPositionFromTempMap(rndNmbr, saa->getPartyId(), saa->getIsVerbund());
|
|
// update charge
|
|
sendChargesFromTempMap(rndNmbr, saa->getPartyId(), saa->getIsVerbund());
|
|
|
|
// then remove again here
|
|
m_tempChargesMap.remove(rndNmbr);
|
|
m_tempPositionMap.remove(rndNmbr);
|
|
m_tempinternalNameMap.remove(rndNmbr);
|
|
}
|
|
else
|
|
{
|
|
// Create new Participant
|
|
|
|
// Create
|
|
DEBUG_LOG(m_logger) << "Create new Participant LP";
|
|
std::vector<ParticipantManagement::ParticipantData> list;
|
|
|
|
// find parent First
|
|
// modId will be 0 if not found and set if found
|
|
// append root if set
|
|
const auto root = findRootUnit(saa->getPartyId());
|
|
if (root.id() > 0)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Append LP to Unit";
|
|
list.push_back(root);
|
|
}
|
|
|
|
ParticipantManagement::ParticipantData data;
|
|
|
|
data.id(0);
|
|
data.partyId(saa->getPartyId());
|
|
data.externalId(0);
|
|
data.hierarchyNumber(1);
|
|
data.name(verein.toStdString());
|
|
data.designator(verein.toStdString());
|
|
data.symbol(type.symbol());
|
|
data.tacticalIdentifier(verein.toStdString());
|
|
data.typeId(type.id()); // use korrect type
|
|
data.modId(1000000001);
|
|
data.isDeleted(false);
|
|
data.isSimulated(false);
|
|
data.superiorModId(root.modId());
|
|
ParticipantManagement::ModifyParticipantDataRequest *newRequest = new ParticipantManagement::ModifyParticipantDataRequest();
|
|
newRequest->requestId(rndNmbr); // we store the random number here to adress later for the postion
|
|
list.push_back(data);
|
|
newRequest->data(list);
|
|
|
|
// add to m_tempPartDataList
|
|
m_tempPartDataList.insert(rndNmbr, list);
|
|
|
|
m_ftcPpm->modifyParticipantDataRequest(*newRequest, this);
|
|
}
|
|
}
|
|
|
|
void PpmHandler::removeAllSAAParticipants(const int partyId)
|
|
{
|
|
// find all participants frpom this SAA
|
|
const auto &participants = findAllSAAParticipants(partyId);
|
|
if (participants.isEmpty())
|
|
return;
|
|
ParticipantManagement::ModifyParticipantDataRequest req;
|
|
std::vector<ParticipantManagement::ParticipantData> list;
|
|
for (const auto &part : qAsConst(participants))
|
|
{
|
|
const ParticipantManagement::Type &participantType = m_dtcPpm->type(part.typeId());
|
|
bool isUnitType
|
|
= (participantType.typeClass() == ParticipantManagement::TypeClass::Unit) || (participantType.typeClass() == ParticipantManagement::TypeClass::SupportUnit);
|
|
if (isUnitType)
|
|
continue;
|
|
|
|
ParticipantManagement::ParticipantData pToDel;
|
|
pToDel.id() = part.id();
|
|
pToDel.isDeleted() = true;
|
|
list.push_back(pToDel);
|
|
}
|
|
req.data(list);
|
|
DEBUG_LOG(m_logger) << "Remove all participants (without Units): " << list.size();
|
|
m_ftcPpm->modifyParticipantDataRequest(req, this);
|
|
}
|
|
|
|
// void PpmHandler::onPartyChanged(const ParticipantManagement::Party &data, DataModification modType)
|
|
// {
|
|
|
|
// }
|
|
|
|
void PpmHandler::onCreateParticipant()
|
|
{
|
|
ParticipantManagement::ParticipantData data;
|
|
|
|
data.id(0);
|
|
data.partyId(3);
|
|
data.externalId(0);
|
|
data.hierarchyNumber(1);
|
|
data.name("Noah Thiering");
|
|
data.designator("Hund");
|
|
data.symbol("AP6D|CMPL|10011000001308000000");
|
|
data.tacticalIdentifier("14");
|
|
data.typeId(177);
|
|
data.modId(1000000001);
|
|
data.isDeleted(false);
|
|
data.isSimulated(false);
|
|
data.superiorModId(0);
|
|
ParticipantManagement::ModifyParticipantDataRequest *newRequest = new ParticipantManagement::ModifyParticipantDataRequest();
|
|
newRequest->requestId(2);
|
|
std::vector<ParticipantManagement::ParticipantData> liste;
|
|
liste.push_back(data);
|
|
newRequest->data(liste);
|
|
// ParticipantManagement::ParticipantData data;
|
|
// int32_t id,
|
|
// int32_t partyId,
|
|
// int32_t hierarchyNumber,
|
|
// const ::dds::core::optional< int32_t >& equipmentNumber,
|
|
// int32_t typeId,
|
|
// ::rti::core::int64 externalId,
|
|
// const std::string& symbol,
|
|
// const std::string& name,
|
|
// const std::string& identification,
|
|
// const std::string& designator,
|
|
// const std::string& tacticalIdentifier,
|
|
// const std::string& info,
|
|
// const ParticipantManagement::ParticipantAssignState& assignState,
|
|
// bool isSimulated,
|
|
// bool isDeleted,
|
|
// const std::string& properties,
|
|
// int32_t modId,
|
|
// int32_t superiorModId);
|
|
// data.id(0);
|
|
// data.partyId(1);
|
|
// data.typeId(5);
|
|
// ParticipantManagement::ModifyParticipantDataRequest *newRequest = new ParticipantManagement::ModifyParticipantDataRequest();
|
|
// newRequest->requestId(9999);
|
|
// std::vector<ParticipantManagement::ParticipantData> liste;
|
|
// liste.push_back(data);
|
|
// newRequest->data(liste);
|
|
|
|
// m_ftcPpm->modifyParticipantDataRequest(*newRequest);
|
|
|
|
m_ftcPpm->modifyParticipantDataRequest(*newRequest);
|
|
}
|
|
|
|
void PpmHandler::getParticipants()
|
|
{
|
|
|
|
if (!m_dtcPpm)
|
|
return;
|
|
|
|
for (const auto &participant : m_dtcPpm->participants())
|
|
{
|
|
onParticipantChanged(participant, DataModification::eAdded);
|
|
}
|
|
}
|
|
|
|
bool PpmHandler::isEqNumberInExercise(const int equipmentNumber) const
|
|
{
|
|
bool result = m_dtcPpm->participantIdByEquipmentNumber(equipmentNumber) > 0;
|
|
|
|
return result;
|
|
}
|
|
|
|
void PpmHandler::onParticipantChanged(const ParticipantManagement::Participant &participant, DataModification modType)
|
|
{
|
|
if (!participant.equipmentNumber().is_set())
|
|
{
|
|
for (auto it = m_participantIdsByEqNo.begin(); it != m_participantIdsByEqNo.end(); ++it)
|
|
if (it.value() == participant.id())
|
|
{
|
|
m_participantIdsByEqNo.remove(it.key());
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
if (participant.externalId() > 0)
|
|
return;
|
|
|
|
QJsonObject headerJson;
|
|
headerJson[QStringLiteral("equipmentNumber")] = participant.equipmentNumber().get();
|
|
headerJson[QStringLiteral("timeStamp")] = m_mainDispatcher->ddsHandler()->partitionTime();
|
|
|
|
if (modType == DataModification::eRemoved)
|
|
{
|
|
m_participantIdsByEqNo.remove(participant.equipmentNumber().get());
|
|
QJsonObject telegram;
|
|
QJsonObject data;
|
|
data[QStringLiteral("header")] = headerJson;
|
|
|
|
telegram[QStringLiteral("data")] = data;
|
|
telegram[QStringLiteral("type")] = QStringLiteral("UFomHlaRemoveParticipant");
|
|
// telegram[QStringLiteral("typeId")] = TrainingAreaBase::TetraIcd::TelegramId::UFOMHLA_REMOVE_PARTICIPANT;
|
|
emit participantChanged(telegram);
|
|
|
|
return;
|
|
}
|
|
if (m_participantIdsByEqNo.contains(participant.equipmentNumber().get()))
|
|
{
|
|
if (m_participantIdsByEqNo[participant.equipmentNumber().get()] != participant.id())
|
|
{
|
|
for (auto it = m_participantIdsByEqNo.begin(); it != m_participantIdsByEqNo.end(); ++it)
|
|
if (it.value() == participant.id())
|
|
{
|
|
m_participantIdsByEqNo.remove(it.key());
|
|
break;
|
|
}
|
|
m_participantIdsByEqNo[participant.equipmentNumber().get()] = participant.id();
|
|
}
|
|
}
|
|
else
|
|
m_participantIdsByEqNo[participant.equipmentNumber().get()] = participant.id();
|
|
|
|
ParticipantManagement::DynamicParticipantData dynamicData = m_dtcPpm->dynamicParticipantData(participant.id());
|
|
ParticipantManagement::Party party = m_dtcPpm->party(participant.partyId());
|
|
ParticipantManagement::Type type = m_dtcPpm->type(participant.typeId());
|
|
ParticipantManagement::ParticipantPosition partPos = m_dtcPpm->participantPosition(participant.id());
|
|
|
|
QJsonObject telegram;
|
|
|
|
QJsonObject geoPositionObj;
|
|
geoPositionObj[QStringLiteral("lon")] = partPos.pos().lon();
|
|
geoPositionObj[QStringLiteral("lat")] = partPos.pos().lat();
|
|
geoPositionObj[QStringLiteral("z")] = partPos.pos().z();
|
|
|
|
QJsonObject data;
|
|
data[QStringLiteral("header")] = headerJson;
|
|
|
|
data[QStringLiteral("status")] = static_cast<int>(m_dtcPpm->youngestStateInformation(dynamicData.stateHistory()).vulnerabilityState().underlying());
|
|
data[QStringLiteral("forceIdentifier")] = static_cast<int>(party.hlaForceIdentifier().underlying());
|
|
|
|
data[QStringLiteral("geoPosition")] = geoPositionObj;
|
|
telegram[QStringLiteral("data")] = data;
|
|
telegram[QStringLiteral("type")] = QStringLiteral("UFomHlaAddParticipant");
|
|
// telegram[QStringLiteral("typeId")] = TrainingAreaBase::TetraIcd::TelegramId::UFOMHLA_ADD_PARTICIPANT;
|
|
emit participantChanged(telegram);
|
|
}
|
|
|
|
void PpmHandler::onParticipantPositionChanged(const ParticipantManagement::ParticipantPosition &position, DataModification modType)
|
|
{
|
|
if (modType == DataModification::eRemoved)
|
|
return;
|
|
|
|
const bool participantIsExternal = m_dtcPpm->participant(position.participantId()).externalId() > 0;
|
|
|
|
if (participantIsExternal)
|
|
{
|
|
handleParticipantPositionChangedExternal(position);
|
|
}
|
|
else
|
|
{
|
|
handleParticipantPositionChangedInternal(position);
|
|
}
|
|
}
|
|
|
|
void PpmHandler::onDynamicParticipantDataChanged(const ParticipantManagement::DynamicParticipantData &dynPartData, DataModification modType)
|
|
{
|
|
if (modType == DataModification::eRemoved)
|
|
return;
|
|
|
|
ParticipantManagement::Participant part = m_dtcPpm->participant(dynPartData.participantId());
|
|
|
|
if (part.externalId() > 0 || !part.equipmentNumber().is_set())
|
|
return;
|
|
|
|
QJsonObject telegram;
|
|
// telegram[QStringLiteral("typeId")] = TrainingAreaBase::TetraIcd::TelegramId::UFOMHLA_VULNERABILITY_STATE_CHANGED;
|
|
telegram[QStringLiteral("type")] = QStringLiteral("UFomHlaVulnerabilityStateChanged");
|
|
|
|
QJsonObject headerJson;
|
|
headerJson[QStringLiteral("equipmentNumber")] = part.equipmentNumber().get();
|
|
headerJson[QStringLiteral("timeStamp")] = m_mainDispatcher->ddsHandler()->partitionTime();
|
|
|
|
QJsonObject data;
|
|
data[QStringLiteral("header")] = headerJson;
|
|
|
|
data[QStringLiteral("status")] = static_cast<int>(m_dtcPpm->youngestStateInformation(dynPartData.stateHistory()).vulnerabilityState().underlying());
|
|
telegram[QStringLiteral("data")] = data;
|
|
|
|
emit participantChanged(telegram);
|
|
}
|
|
|
|
void PpmHandler::onSendParticipantDataTimeout()
|
|
{
|
|
m_sendParticipantDataTimer->stop();
|
|
if (m_randomNumbers.empty())
|
|
ERROR_LOG(m_logger) << "Cant Send ParticipantData RandomNumbers is empty";
|
|
ParticipantManagement::ModifyParticipantDataRequest *newRequest = new ParticipantManagement::ModifyParticipantDataRequest();
|
|
int currentRandomNumber = m_randomNumbers.first();
|
|
newRequest->requestId(currentRandomNumber); // we store the random number here to adress later for the postion
|
|
newRequest->data(m_tempPartDataList.value(currentRandomNumber));
|
|
|
|
m_ftcPpm->modifyParticipantDataRequest(*newRequest, this);
|
|
}
|
|
|
|
void PpmHandler::handleParticipantPositionChangedExternal(const ParticipantManagement::ParticipantPosition &position)
|
|
{
|
|
ParticipantManagement::Participant part = m_dtcPpm->participant(position.participantId());
|
|
|
|
const bool participantPreviouslyMounted = m_mountedParticipants.contains(part.equipmentNumber().get());
|
|
if (!participantPreviouslyMounted)
|
|
return;
|
|
const bool mountedOnOtherParticipant = position.mountedOn().is_set();
|
|
if (!mountedOnOtherParticipant)
|
|
{
|
|
sendParticipantUnmount(part);
|
|
return;
|
|
}
|
|
const bool newMountedParticipantIsExternal = m_dtcPpm->participant(position.mountedOn().get()).externalId() != 0;
|
|
if (newMountedParticipantIsExternal)
|
|
{ // If the new mounted participant is internal the entry in the Hashmap is still used. So dont remove it!
|
|
m_mountedParticipants.remove(part.equipmentNumber().get());
|
|
}
|
|
}
|
|
|
|
void PpmHandler::handleParticipantPositionChangedInternal(const ParticipantManagement::ParticipantPosition &position)
|
|
{
|
|
DEBUG_LOG(m_logger) << "handleParticipantPositionChangedInternal";
|
|
ParticipantManagement::Participant part = m_dtcPpm->participant(position.participantId());
|
|
|
|
const bool hasMountedParticipants = position.mountedParticipants().is_set() && position.mountedParticipants().get().size() > 0;
|
|
if (hasMountedParticipants)
|
|
{
|
|
const QVector<int32_t> mountedParticipantIds(position.mountedParticipants().get().begin(), position.mountedParticipants().get().end());
|
|
|
|
for (int mountedParticipantId : qAsConst(mountedParticipantIds))
|
|
{
|
|
ParticipantManagement::Participant mountedParticipant = m_dtcPpm->participant(mountedParticipantId);
|
|
const bool isExternal = mountedParticipant.externalId() > 0;
|
|
const bool wasMountedOnThisPart = m_mountedParticipants.contains(mountedParticipant.equipmentNumber().get())
|
|
&& m_mountedParticipants[mountedParticipant.equipmentNumber().get()] == part.equipmentNumber().get();
|
|
if (!isExternal || wasMountedOnThisPart)
|
|
continue;
|
|
|
|
if (!part.equipmentNumber().is_set())
|
|
continue;
|
|
sendParticipantMount(mountedParticipant, part);
|
|
}
|
|
|
|
if (part.equipmentNumber().is_set())
|
|
{
|
|
sendParticipantPositionChanged(position);
|
|
}
|
|
}
|
|
}
|
|
|
|
void PpmHandler::sendParticipantMount(const ParticipantManagement::Participant &part, const ParticipantManagement::Participant &partToBeMounted) // Passanger, Vehicle
|
|
{
|
|
m_mountedParticipants.insert(part.equipmentNumber().get(), partToBeMounted.equipmentNumber().get());
|
|
ERROR_LOG(m_logger) << "Mount Participant";
|
|
QJsonObject telegram;
|
|
// telegram[QStringLiteral("typeId")] = TrainingAreaBase::TetraIcd::TelegramId::UFOMHLA_PARTICIPANT_MOUNT;
|
|
telegram[QStringLiteral("type")] = QStringLiteral("UFomHlaParticipantMount");
|
|
|
|
QJsonObject headerJson;
|
|
headerJson[QStringLiteral("equipmentNumber")] = part.equipmentNumber().get();
|
|
headerJson[QStringLiteral("timeStamp")] = m_mainDispatcher->ddsHandler()->partitionTime();
|
|
|
|
QJsonObject data;
|
|
data[QStringLiteral("header")] = headerJson;
|
|
data[QStringLiteral("mountedOn")] = QJsonValue(partToBeMounted.equipmentNumber().get());
|
|
|
|
telegram[QStringLiteral("data")] = data;
|
|
emit participantMount(telegram);
|
|
}
|
|
|
|
void PpmHandler::sendParticipantUnmount(const ParticipantManagement::Participant &participant)
|
|
{
|
|
m_mountedParticipants.remove(participant.equipmentNumber().get());
|
|
DEBUG_LOG(m_logger) << "Unmount Participant";
|
|
QJsonObject telegram;
|
|
// telegram[QStringLiteral("typeId")] = TrainingAreaBase::TetraIcd::TelegramId::UFOMHLA_PARTICIPANT_UNMOUNT;
|
|
telegram[QStringLiteral("type")] = QStringLiteral("UFomHlaParticipantUnmount");
|
|
|
|
QJsonObject headerJson;
|
|
headerJson[QStringLiteral("equipmentNumber")] = participant.equipmentNumber().get();
|
|
headerJson[QStringLiteral("timeStamp")] = m_mainDispatcher->ddsHandler()->partitionTime();
|
|
|
|
QJsonObject data;
|
|
data[QStringLiteral("header")] = headerJson;
|
|
|
|
telegram[QStringLiteral("data")] = data;
|
|
emit participantUnmount(telegram);
|
|
}
|
|
void PpmHandler::sendParticipantPositionChanged(const ParticipantManagement::ParticipantPosition &position)
|
|
{
|
|
|
|
ParticipantManagement::Participant part = m_dtcPpm->participant(position.participantId());
|
|
|
|
QJsonObject telegram;
|
|
// telegram[QStringLiteral("typeId")] = TrainingAreaBase::TetraIcd::TelegramId::UFOMHLA_POSITION_CHANGED;
|
|
telegram[QStringLiteral("type")] = QStringLiteral("UFomHlaPositionChanged");
|
|
|
|
QJsonObject headerJson;
|
|
headerJson[QStringLiteral("equipmentNumber")] = part.equipmentNumber().get();
|
|
headerJson[QStringLiteral("timeStamp")] = m_mainDispatcher->ddsHandler()->partitionTime();
|
|
|
|
QJsonObject data;
|
|
data[QStringLiteral("header")] = headerJson;
|
|
data[QStringLiteral("lon")] = position.pos().lon();
|
|
data[QStringLiteral("lat")] = position.pos().lat();
|
|
data[QStringLiteral("z")] = position.pos().z();
|
|
|
|
telegram[QStringLiteral("data")] = data;
|
|
|
|
emit participantChanged(telegram);
|
|
}
|
|
|
|
void PpmHandler::onModifyParticipantDataReply(const Core::FunctionReplyObject &reply)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Got Function Reply " << reply.str();
|
|
|
|
if (!reply.error())
|
|
{
|
|
|
|
if (!m_tempPartDataList.contains(reply.id()))
|
|
return;
|
|
|
|
const int partyId = m_tempPartDataList.value(reply.id()).data()->partyId();
|
|
|
|
if (!m_mainDispatcher->jsonDispatcher()->getSAAByParty(partyId))
|
|
return;
|
|
|
|
const bool isVerbund = m_mainDispatcher->jsonDispatcher()->getSAAByParty(partyId)->getIsVerbund();
|
|
|
|
DEBUG_LOG(m_logger) << "Got ModifyParticipant Reply SEND from temp Maps (partyId: " << partyId << " , isVerbund: " << isVerbund << ")";
|
|
|
|
if (m_tempPositionMap.contains(reply.id()))
|
|
sendPositionFromTempMap(reply.id(), partyId, isVerbund);
|
|
|
|
if (m_tempChargesMap.contains(reply.id()))
|
|
sendChargesFromTempMap(reply.id(), partyId, isVerbund);
|
|
|
|
if (m_tempReadyMessage.contains(reply.id()))
|
|
sendReadyMessageFromTempMap(reply.id(), partyId, isVerbund);
|
|
}
|
|
else
|
|
{
|
|
ERROR_LOG(m_logger) << "GOT ModifyParticipant Replay with error " << reply.translated();
|
|
}
|
|
|
|
// then remove any entries from Map
|
|
m_tempChargesMap.remove(reply.id());
|
|
m_tempPositionMap.remove(reply.id());
|
|
m_tempinternalNameMap.remove(reply.id());
|
|
m_tempReadyMessage.remove(reply.id());
|
|
if (m_randomNumbers.contains(reply.id()))
|
|
{
|
|
m_randomNumbers.removeAll(reply.id());
|
|
if (!m_randomNumbers.isEmpty() && !m_sendParticipantDataTimer->isActive())
|
|
m_sendParticipantDataTimer->start();
|
|
}
|
|
m_tempPartDataList.remove(reply.id());
|
|
}
|
|
|
|
void PpmHandler::onModifyPartyDataReply(const Core::FunctionReplyObject &reply) { DEBUG_LOG(m_logger) << "Got Function Reply " << reply.str(); }
|
|
|
|
QList<ParticipantManagement::Participant> PpmHandler::findAllSAAParticipants(const int partyId)
|
|
{
|
|
QList<ParticipantManagement::Participant> ret;
|
|
const auto &list = m_dtcPpm->participants();
|
|
for (const auto &part : qAsConst(list))
|
|
{
|
|
if (part.partyId() != partyId || part.isDeleted())
|
|
continue;
|
|
if (!m_dtcPpm->isArtilleryType(part.typeId()))
|
|
continue;
|
|
if (part.name().empty())
|
|
continue;
|
|
ret.append(part);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
ParticipantManagement::ParticipantData PpmHandler::findParticipantDataByInternalName(int &randomNumberInOut, const QString &internalName, const bool isVerbund)
|
|
{
|
|
ParticipantManagement::ParticipantData ret;
|
|
|
|
for (const auto &randomNumber : m_tempPartDataList.keys())
|
|
{
|
|
for (const auto &part : m_tempPartDataList.value(randomNumber))
|
|
{
|
|
if (part.name() != internalName.toStdString())
|
|
continue;
|
|
|
|
if (m_dtcPpm->isAdlerVerbund(part.typeId()) != isVerbund)
|
|
continue;
|
|
|
|
randomNumberInOut = randomNumber;
|
|
return part;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
ParticipantManagement::ParticipantData PpmHandler::findRootUnit(const int partyId)
|
|
{
|
|
ParticipantManagement::ParticipantData ret;
|
|
const auto &list = m_dtcPpm->participants();
|
|
for (const auto &part : qAsConst(list))
|
|
{
|
|
if (part.partyId() != partyId || part.isDeleted())
|
|
continue;
|
|
if (m_dtcPpm->type(part.typeId()).typeClass() != ParticipantManagement::TypeClass::Unit)
|
|
continue;
|
|
if (m_dtcPpm->isArtilleryType(part.typeId()))
|
|
continue;
|
|
if (part.superiorId() > 0)
|
|
continue;
|
|
ret = m_dtcPpm->convertParticipantToParticipantData(part);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
ParticipantManagement::Participant PpmHandler::findParticipantByInternalName(const QString &internalName, const int partyId, const bool isVerbund)
|
|
{
|
|
ParticipantManagement::Participant pp;
|
|
DEBUG_LOG(m_logger) << "START find participant: " << internalName;
|
|
auto participantMap = m_dtcPpm->participants();
|
|
for (const auto &part : qAsConst(participantMap))
|
|
{
|
|
if (part.partyId() != partyId || part.isDeleted())
|
|
continue;
|
|
|
|
if (!m_dtcPpm->isArtilleryType(part.typeId()))
|
|
continue;
|
|
if (m_dtcPpm->isAdlerVerbund(part.typeId()) != isVerbund)
|
|
continue;
|
|
|
|
if (part.name() != internalName.toStdString())
|
|
continue;
|
|
|
|
pp = part;
|
|
}
|
|
|
|
return pp;
|
|
}
|
|
|
|
void PpmHandler::onPartyChanged(const ParticipantManagement::Party &data, DataModification modType)
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << ", modType: " << modType;
|
|
|
|
if (modType == DataModification::eRemoved)
|
|
return;
|
|
|
|
const ParticipantManagement::ConnectState connectState = m_dtcPpm->saaConnectedState(data.id());
|
|
DEBUG_LOG(m_logger) << "++++ connectState: " << connectState;
|
|
|
|
// only in connect state disconnecting: delete all ADLER objects and force the disconnection
|
|
if (connectState != ParticipantManagement::ConnectState::Disconnecting)
|
|
return;
|
|
|
|
auto saa = m_mainDispatcher->jsonDispatcher()->getSAAByParty(data.id());
|
|
if (!saa)
|
|
return;
|
|
|
|
DEBUG_LOG(m_logger) << "++++ szenarName: " << saa->getSzenarName() << ", wsId: " << saa->getWsId();
|
|
|
|
EXStatus status;
|
|
status.status = Szenarstatus::Gestoppt;
|
|
m_mainDispatcher->jsonDispatcher()->onSAAStatus(saa->getWsId(), status);
|
|
m_mainDispatcher->jsonDispatcher()->onSAADeregistration(saa->getWsId(), data.id());
|
|
}
|
|
|
|
void PpmHandler::sendPositionFromTempMap(int rndNmbr, const int partyId, const bool isVerbund)
|
|
{
|
|
const QMap<QString, KoordinateMitHoehe> posMap = m_tempPositionMap.value(rndNmbr);
|
|
const QList<QString> partList;
|
|
|
|
// we need the participant Id now
|
|
const auto &nameVec = m_tempinternalNameMap.value(rndNmbr);
|
|
QMapIterator<QString, KoordinateMitHoehe> it(posMap);
|
|
while (it.hasNext())
|
|
{
|
|
it.next();
|
|
ParticipantManagement::Participant pp = findParticipantByInternalName(it.key(), partyId, isVerbund);
|
|
if (pp.id() <= 0)
|
|
return;
|
|
|
|
TrainingAreaBase::EquipmentPosition equipPosReq;
|
|
Core::GeoPosition tlnPos;
|
|
TrainingAreaBase::TabPosition tabPos;
|
|
tlnPos.lat(it.value().koordinate.latitude * (M_PI / 180.0));
|
|
tlnPos.lon(it.value().koordinate.longitude * (M_PI / 180.0));
|
|
// Ignore Adler Z Value due to different elevation maps
|
|
// tlnPos.z(it.value().hoehe);
|
|
tabPos.position(tlnPos);
|
|
tabPos.reportingSource(Core::PositionReportingSource::SetByOperator);
|
|
|
|
equipPosReq.sampleTime(m_mainDispatcher->ddsHandler()->partitionTime());
|
|
equipPosReq.position(tabPos);
|
|
equipPosReq.equipmentNumber(-1 * pp.id());
|
|
// equipPosReq.mountedParticipants();
|
|
// equipPosReq.orientation();
|
|
m_mainDispatcher->ddsHandler()->dtsTab()->publish(equipPosReq);
|
|
}
|
|
}
|
|
|
|
void PpmHandler::sendChargesFromTempMap(const int rndNmbr, const int partyId, const bool isVerbund)
|
|
{
|
|
// No ammunition supply is displayed in ADLER standalone mode
|
|
if (!isVerbund)
|
|
return;
|
|
|
|
const auto &charges = m_tempChargesMap.value(rndNmbr);
|
|
const ParticipantManagement::Type type = m_dtcPpm->getTypeFromAdlerType(QStringLiteral("LP"), false, isVerbund);
|
|
|
|
for (const auto &charge : charges.toStdMap())
|
|
{
|
|
TrainingAreaBase::EquipmentGearChargeState gearChargeState;
|
|
TrainingAreaBase::GearCharge gc;
|
|
ParticipantManagement::Participant participant = findParticipantByInternalName(charge.first, partyId, isVerbund);
|
|
|
|
const QVector<Geschoss> geschosse = sumUpAnzahlForSameGeschoss(charge.second);
|
|
|
|
for (auto c : geschosse)
|
|
{
|
|
int chargeTypeId = m_mainDispatcher->pdmHandler()->getDtc()->getChargeTypeIdFromAdlerCharges(c.geschosssorte);
|
|
|
|
// if geschosssorte is null, we cannot get a valid chargeTypeId for it
|
|
// this happens when the SAA is sending "Ladung" without a valid geschosssorte)
|
|
if (chargeTypeId <= 0)
|
|
continue;
|
|
|
|
DEBUG_LOG(m_logger) << "---- participant.id:" << participant.id() << (participant.typeId() == type.id() ? " (Ladeplatz)" : "");
|
|
|
|
QVector<int> gearTypesIds = m_mainDispatcher->pdmHandler()->getDtc()->gearTypeIdFromChargeTypeId(chargeTypeId);
|
|
// Here only one gearType should be found
|
|
gc.gearTypeId() = !gearTypesIds.isEmpty() ? gearTypesIds.first() : 0;
|
|
gc.gearId(participant.id());
|
|
gc.chargeTypeId(chargeTypeId);
|
|
gc.remain() = c.anzahl;
|
|
gearChargeState.charge().push_back(gc);
|
|
}
|
|
gearChargeState.sampleTime(m_mainDispatcher->ddsHandler()->partitionTime());
|
|
gearChargeState.equipmentNumber(-1 * participant.id());
|
|
m_mainDispatcher->ddsHandler()->dtsTab()->publish(gearChargeState);
|
|
}
|
|
m_tempChargesMap.remove(rndNmbr);
|
|
}
|
|
|
|
void PpmHandler::sendReadyMessageFromTempMap(int rndNmbr, const int partyId, const bool isVerbund)
|
|
{
|
|
const auto &readyMap = m_tempReadyMessage.value(rndNmbr);
|
|
|
|
for (const auto &readyMsg : readyMap.toStdMap())
|
|
{
|
|
ParticipantManagement::Participant participant = findParticipantByInternalName(readyMsg.first, partyId, isVerbund);
|
|
TrainingAreaBase::SpecialSensorData ssData;
|
|
ssData.sampleTime(m_mainDispatcher->ddsHandler()->partitionTime());
|
|
ssData.operationalState(convertStatus_L28(readyMsg.second));
|
|
ssData.equipmentNumber(-1 * participant.id());
|
|
m_mainDispatcher->ddsHandler()->dtsTab()->publish(ssData);
|
|
}
|
|
|
|
m_tempReadyMessage.remove(rndNmbr);
|
|
}
|
|
|
|
int PpmHandler::convertStatus_L28(const ProjectDataManagement::L28_Status &status)
|
|
{
|
|
switch (status.underlying())
|
|
{
|
|
case ProjectDataManagement::L28_Status::Einsatzbereit:
|
|
return ADLER_OPERATIONAL;
|
|
case ProjectDataManagement::L28_Status::NichtEinsatzbereit:
|
|
return ADLER_NOT_OPERATIONAL;
|
|
|
|
default:
|
|
WARNING_LOG(m_logger) << "Status " << status << " not handled in switch";
|
|
break;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
QVector<Geschoss> PpmHandler::sumUpAnzahlForSameGeschoss(const QVector<Geschoss> &geschosse) const
|
|
{
|
|
using GeschossInfo = std::tuple<QString, QString, QString>;
|
|
|
|
QMap<GeschossInfo, Geschoss> summedUpGeschosseMap;
|
|
|
|
for (const Geschoss &geschoss : geschosse)
|
|
{
|
|
const GeschossInfo geschossInfo(geschoss.geschosssorte, geschoss.ladung, geschoss.zuender);
|
|
|
|
if (summedUpGeschosseMap.contains(geschossInfo))
|
|
{
|
|
summedUpGeschosseMap[geschossInfo].anzahl += geschoss.anzahl;
|
|
|
|
continue;
|
|
}
|
|
|
|
summedUpGeschosseMap.insert(geschossInfo, geschoss);
|
|
}
|
|
|
|
return summedUpGeschosseMap.values().toVector();
|
|
}
|
|
|
|
} // namespace AdlerJson
|