Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# monitoring of the target areas
|
||||
# $Id: CMakeLists.txt 64216 2024-12-02 05:24:17Z fritsche_h $
|
||||
# $HeadURL: svn://slssvn/TDS/branches/product/features/25_03_etb_uas/Lts/Services/CentralEffectSimulation/Plugins/Jamming/CMakeLists.txt $
|
||||
# $Author: fritsche_h $
|
||||
#
|
||||
|
||||
SET(SRCS
|
||||
plugin.cpp
|
||||
plugin.h
|
||||
ces_mission_plan_handler.cpp
|
||||
ces_mission_plan_handler.h
|
||||
ces_mission_plan_object.cpp
|
||||
ces_mission_plan_object.h
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(AAR SV cesPluginCES_MissionPlan MODULE ${SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(cesPluginCES_MissionPlan
|
||||
PUBLIC
|
||||
Qt5::Network
|
||||
Qt5::Widgets
|
||||
cesPluginInterface
|
||||
ngldb
|
||||
svcCesDDSCommon
|
||||
LtsUtilsCore
|
||||
LtsUtilsSettings
|
||||
# ProjectConfig
|
||||
)
|
||||
NGL_INSTALL_TARGET(cesPluginCES_MissionPlan)
|
||||
|
||||
+264
@@ -0,0 +1,264 @@
|
||||
/**
|
||||
* Plugin CES Mission Plan
|
||||
* $Id: $
|
||||
* $HeadURL: svn://slssvn/TDS/branches/product/features/25_03_etb_uas/Lts/Services/CentralEffectSimulation/Plugins/MissionPlan/ces_mission_plan_handler.cpp $
|
||||
* $Author: Kemayou_s $
|
||||
* Created by Steve Kemayou, ESZS, 2025-06-25
|
||||
*/
|
||||
|
||||
#include "ces_mission_plan_handler.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QDateTime>
|
||||
#include <QRandomGenerator>
|
||||
|
||||
#include <LtsUtilsCore/dds_bitarray.h>
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <ProjectDataManagement/pdm_enums.hpp>
|
||||
|
||||
namespace dds
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
inline uint qHash(ProjectDataManagement::EventType et)
|
||||
{
|
||||
return ::qHash(et.underlying());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace CES_MISSIONPLAN
|
||||
{
|
||||
|
||||
|
||||
CesMissionPlanHandler::CesMissionPlanHandler(const std::shared_ptr<CentralEffectSimulation::DdsHandler> &ddsHandler,
|
||||
const std::shared_ptr<CentralEffectSimulation::HandlerParticipant> &participantHandler,
|
||||
QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_ddsHandler(ddsHandler)
|
||||
, m_handlerParticipant(participantHandler)
|
||||
, m_logger(CentralEffectSimulation::getLogger("Plugin.MissionPlan.CesMissionPlanHandler"))
|
||||
{
|
||||
} // end of ctor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CesMissionPlanHandler::~CesMissionPlanHandler()
|
||||
{
|
||||
qDeleteAll(m_missionPlanObjects);
|
||||
} // end of dtor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool CesMissionPlanHandler::init()
|
||||
{
|
||||
// TAB FTC
|
||||
m_ddsHandler->dtcPpm()->enableUAS();
|
||||
m_ddsHandler->dtcPpm()->enableMissionPlan();
|
||||
m_ddsHandler->dtcPpm()->enableParticipantGearEvent();
|
||||
m_ddsHandler->ftcPpm()->enableSetMissionActionFulfilled();
|
||||
m_ddsHandler->ftcAes()->enableExplosionClusterModify();
|
||||
m_ddsHandler->ftcTab()->enableSendUasWaypoint();
|
||||
|
||||
connect (m_ddsHandler->dtcPpm().get(), &ParticipantManagement::Interface::Dtc::uASChanged,
|
||||
this, &CesMissionPlanHandler::onUasChanged);
|
||||
|
||||
connect (m_ddsHandler->dtcPpm().get(), &ParticipantManagement::Interface::Dtc::missionPlanChanged,
|
||||
this, &CesMissionPlanHandler::onMissionPlanChanged);
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << " -- MissionPlanHandler::init() finished.";
|
||||
return true;
|
||||
}
|
||||
|
||||
void CesMissionPlanHandler::updateMissionPlanList(const ParticipantManagement::MissionPlan &data)
|
||||
{
|
||||
CesMissionPlanObject *obj = m_missionPlanObjects.value(data.id(), nullptr);
|
||||
|
||||
if (obj)
|
||||
{
|
||||
m_missionPlanObjects[data.id()]->setMissionPlan(data);
|
||||
return;
|
||||
}
|
||||
|
||||
// check if mission start is in the future before proceeding..
|
||||
DEBUG_LOG(m_logger)<<" -- [updateMissionPlanList] new missionPlan : "<<data.name()<< " planId: "<<data.id();
|
||||
|
||||
if (data.missionStart() < m_ddsHandler->currentPartitionTime())
|
||||
{
|
||||
WARNING_LOG(m_logger) << " -- updateMissionPlanList mission startTime ("<<data.missionStart()<<") in the past ignore mission plan id: "<<data.id()
|
||||
<< " name: " << data.name() << " - now: " << m_ddsHandler->currentPartitionTime();
|
||||
return;
|
||||
}
|
||||
|
||||
obj = new CesMissionPlanObject(data, m_ddsHandler, this);
|
||||
connect(obj, &CesMissionPlanObject::ready2SendNextAction, this,
|
||||
&CesMissionPlanHandler::onSendNextMissionAction, Qt::UniqueConnection);
|
||||
|
||||
const int planId = obj->planId();
|
||||
std::function<void(void)> onDeleteObj = [this, planId]()
|
||||
{
|
||||
DEBUG_LOG(m_logger)<<" -- remove ces mission object from container planId: "<<planId;
|
||||
m_missionPlanObjects.remove(planId);
|
||||
};
|
||||
connect(obj, &CesMissionPlanObject::destroyed, this, onDeleteObj);
|
||||
|
||||
m_missionPlanObjects.insert(data.id(), obj);
|
||||
}
|
||||
|
||||
void CesMissionPlanHandler::onUasChanged(const ParticipantManagement::UAS &data, DataModification modType)
|
||||
{
|
||||
Q_UNUSED(modType)
|
||||
DEBUG_LOG(m_logger)<<" -- onUasChanged : uas.id = "<<data.id() <<" participantId = "<<data.participantId();
|
||||
// get mission object of corresponding uas participant
|
||||
// if drone status is manual mode then cancel mission.
|
||||
if (data.uasState() != ProjectDataManagement::UasState_def::Manual && modType != DataModification::eRemoved)
|
||||
return;
|
||||
|
||||
for (auto planObj : m_missionPlanObjects)
|
||||
{
|
||||
if (planObj->participantId() != data.participantId())
|
||||
continue;
|
||||
|
||||
// if waypoint started and state switched to manual abord mission
|
||||
if (planObj->missionPlan().missionStart() < m_ddsHandler->currentPartitionTime())
|
||||
planObj->abortMission();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CesMissionPlanHandler::onMissionPlanChanged(const ParticipantManagement::MissionPlan &data, DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger)<<" -- onMissionPlanChanged : missionPlanName: "<<data.name() << ", modType: " << (int)modType;
|
||||
if (data.id() <= 0)
|
||||
return;
|
||||
switch (modType)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
updateMissionPlanList(data);
|
||||
break;
|
||||
case DataModification::eRemoved:
|
||||
{
|
||||
auto obj = m_missionPlanObjects.value(data.id(), nullptr);
|
||||
if (!obj)
|
||||
return;
|
||||
delete obj;
|
||||
|
||||
m_missionPlanObjects.remove(data.id());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool CesMissionPlanHandler::isUasInAutoMode(int participantId)
|
||||
{
|
||||
|
||||
m_ddsHandler->dtcPpm()->waitForHistoricalDataUAS(3000);
|
||||
const auto uas = m_ddsHandler->dtcPpm()->getUasByParticipantId(participantId, m_ddsHandler->getExerciseId());
|
||||
|
||||
if (uas.id() < 1)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "no uas for pid " << participantId;
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "uas with pid " << participantId << " is in mode: " << (int)uas.uasState().underlying();
|
||||
|
||||
return (uas.uasState() == ProjectDataManagement::UasState::Auto);
|
||||
}
|
||||
|
||||
// stolen from Lts/Plugins/ParticipantManagement/Gui/ParticipantInfo/participant_info_dialog.cpp
|
||||
bool CesMissionPlanHandler::isUasCombatReady(int participantId)
|
||||
{
|
||||
|
||||
m_ddsHandler->dtcPpm()->waitForHistoricalDataDynamicParticipantData(3000);
|
||||
const auto data = m_ddsHandler->dtcPpm()->dynamicParticipantData(participantId);
|
||||
|
||||
if (data.participantId() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//Current State
|
||||
DEBUG_LOG(m_logger) << "stateHistory count" << data.stateHistory().size();
|
||||
if (data.stateHistory().empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto &history = data.stateHistory();
|
||||
|
||||
//LasState is the last "real" state, that has a VBG <=8 (Castastrophic)
|
||||
//It's not the last state received, as there can be other state changes like Sanitation, or NearMiss
|
||||
auto lastState = m_ddsHandler->dtcPpm()->youngestStateInformation(history/*, true*/ /* debug */);
|
||||
decltype(lastState) youngestState;
|
||||
youngestState.stateTime(0);
|
||||
for (const auto &si : history)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "StateInformation "
|
||||
<< " time=" << si.stateTime()
|
||||
<< " vulnerabilityBits=" << si.vulnerabilityBits()
|
||||
<< " vulnerabilityKindId=" << si.vulnerabilityKindId();
|
||||
if (youngestState.stateTime() < si.stateTime())
|
||||
youngestState = si;
|
||||
}
|
||||
|
||||
return (youngestState.vulnerabilityState() == ProjectDataManagement::VulnerabilityState::CombatReady);
|
||||
}
|
||||
|
||||
void CesMissionPlanHandler::onSendNextMissionAction(const ParticipantManagement::MissionAction &msa)
|
||||
{
|
||||
auto missionPlan = m_missionPlanObjects.value(msa.planId(), nullptr);
|
||||
if (!missionPlan)
|
||||
{
|
||||
DEBUG_LOG(m_logger)<<" -- [SEND NEXT MISSION] Object not found. PlanId: "<<msa.planId();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// send to TAB
|
||||
const auto participantId = missionPlan->m_missionPlan.participantId();
|
||||
const auto participant = m_handlerParticipant->participant(participantId);
|
||||
|
||||
if (!participant.equipmentNumber())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "unable to send next mission action to uav without equipment number";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (!isUasInAutoMode(participantId))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "unable to send next mission action to uav that is not in auto mode";
|
||||
//TODO: fulfill all other missions or mark as incomplete
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!isUasCombatReady(participantId))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "unable to send next mission action to uav that is not combat ready";
|
||||
//TODO: fulfill all other missions or mark as incomplete
|
||||
return;
|
||||
}
|
||||
|
||||
const auto eqId = participant.equipmentNumber().value();
|
||||
|
||||
try
|
||||
{
|
||||
// send action to uav via tab - if this doesn't throw, waypoint is now executing
|
||||
m_ddsHandler->ftcTab()->sendUasWaypointRequest(TrainingAreaBase::SendUasWaypointRequest(eqId, participantId, msa.actionNumber(), msa.itemNumber(), msa.planId(), msa.name(), msa.properties()));
|
||||
// PPM will send a change request to the current active action, which in return tell us (updateMissionPlanList) and finally we will start the next action - so we are done here for now
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "unable to send next mission action to uav: " << ex.what();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace CES_MISSIONPLAN
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Plugin CES Mission Plan
|
||||
* $Id: $
|
||||
* $HeadURL: svn://slssvn/TDS/branches/product/features/25_03_etb_uas/Lts/Services/CentralEffectSimulation/Plugins/MissionPlan/ces_mission_plan_handler.h $
|
||||
* $Author: Kemayou_s $
|
||||
* Created by Steve Kemayou, ESZS, 2025-06-25
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <CentralEffectSimulation/logger.h>
|
||||
#include <CentralEffectSimulation/dds_handler.h>
|
||||
#include <CentralEffectSimulation/handler_participant.h>
|
||||
#include <AreaEffectSimulation/aes_dtc.h>
|
||||
#include "ces_mission_plan_object.h"
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/QObject>
|
||||
|
||||
// AES-Handling for participants
|
||||
namespace CES_MISSIONPLAN
|
||||
{
|
||||
struct EnterLeaveType
|
||||
{
|
||||
ProjectDataManagement::EventType eventType = ProjectDataManagement::EventType_def::Unknown;
|
||||
bool isAlreadySupplied = false;
|
||||
};
|
||||
|
||||
|
||||
class CesMissionPlanHandler : public QObject
|
||||
//, protected TrainingAreaBase::Interface::Ftc::SendCesHitReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CesMissionPlanHandler(const std::shared_ptr<CentralEffectSimulation::DdsHandler> &ddsHandler,
|
||||
const std::shared_ptr<CentralEffectSimulation::HandlerParticipant> &participantHandler,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
~CesMissionPlanHandler();
|
||||
|
||||
/**
|
||||
* Initialize the handler to manage information from player management
|
||||
*/
|
||||
bool init();
|
||||
void updateMissionPlanList(const ParticipantManagement::MissionPlan &data);
|
||||
protected:
|
||||
void sendNextMissionAction();
|
||||
private Q_SLOTS:
|
||||
|
||||
void onUasChanged(const ParticipantManagement::UAS &data, DataModification modType);
|
||||
void onMissionPlanChanged(const ParticipantManagement::MissionPlan &data, DataModification modType);
|
||||
void onSendNextMissionAction(const ParticipantManagement::MissionAction &msa);
|
||||
|
||||
private: // methoden
|
||||
|
||||
|
||||
ProjectDataManagement::EventType leaveEventTypeForAesType(AreaEffectSimulation::AesType aesTypeId);
|
||||
bool isUasInAutoMode(int participantId);
|
||||
bool isUasCombatReady(int participantId);
|
||||
|
||||
private: // attributes
|
||||
|
||||
std::shared_ptr<CentralEffectSimulation::DdsHandler> m_ddsHandler; ///< Pointer to VOM DDS handler
|
||||
std::shared_ptr<CentralEffectSimulation::HandlerParticipant> m_handlerParticipant;
|
||||
|
||||
QHash<int/*PlanId*/, CesMissionPlanObject *> m_missionPlanObjects; // Only: MissionBegin is reached and fulfilled = 0;
|
||||
int m_requestId = 1;
|
||||
NGL::INGLLogger &m_logger; ///< Interface to the Logging-Facility
|
||||
};
|
||||
} // namespace CES_MISSIONPLAN
|
||||
|
||||
+308
@@ -0,0 +1,308 @@
|
||||
/**
|
||||
* Plugin CES Mission Plan
|
||||
* $Id: $
|
||||
* $HeadURL: svn://slssvn/TDS/branches/product/features/25_03_etb_uas/Lts/Services/CentralEffectSimulation/Plugins/MissionPlan/ces_mission_plan_object.cpp $
|
||||
* $Author: Kemayou_s $
|
||||
* Created by Steve Kemayou, ESZS, 2025-06-25
|
||||
*/
|
||||
|
||||
#include "ces_mission_plan_object.h"
|
||||
#include "qobject.h"
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
namespace CES_MISSIONPLAN
|
||||
{
|
||||
|
||||
CesMissionPlanObject::CesMissionPlanObject(const ParticipantManagement::MissionPlan &missionPlan,
|
||||
const std::shared_ptr<CentralEffectSimulation::DdsHandler> &ddsHandler,
|
||||
QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_missionStartimer(new QTimer(this))
|
||||
, m_loiterTimer(new QTimer(this))
|
||||
, m_ddsHandler(ddsHandler)
|
||||
, m_missionPlan(missionPlan)
|
||||
, m_logger(CentralEffectSimulation::getLogger("Plugin.MissionPlan.CesMissionPlanObject"))
|
||||
{
|
||||
///1- set missionStartTimer for mission start
|
||||
///2- set loiterTimer: he is use when a mission action requires it
|
||||
|
||||
m_missionStartimer->setSingleShot(true);
|
||||
connect(m_missionStartimer, &QTimer::timeout, this, &CesMissionPlanObject::sendNextMissionAction);
|
||||
if (missionPlan.missionStart() > m_ddsHandler->currentPartitionTime())
|
||||
{
|
||||
const int time = m_missionPlan.missionStart() - m_ddsHandler->currentPartitionTime();
|
||||
// DEBUG_LOG(m_logger)<<" -- [CesMissionPlanObject] start mission after << "<<time/1000<<" sec.";
|
||||
m_missionStartimer->start(time);
|
||||
}
|
||||
|
||||
m_loiterTimer->setSingleShot(true);
|
||||
connect(m_loiterTimer, &QTimer::timeout, this, [this]()
|
||||
{
|
||||
setMissionActionFulfilled(getNextAction());
|
||||
});
|
||||
}
|
||||
|
||||
void CesMissionPlanObject::setMissionActionFulfilled(const ParticipantManagement::MissionAction &msa)
|
||||
{
|
||||
///1- set mission action param fulfilled
|
||||
///2- send setFulfillment request to svcParticipantManagement
|
||||
///3- get next action ready for TAB
|
||||
///4- if no actions left send misson plan completed signal
|
||||
///5- else send next mission action to TAB
|
||||
|
||||
//DEBUG_LOG(m_logger)<<" -- [setMissionActionFullfiled] -> msa.number: "<<msa.actionNumber()<<" planId: "<<msa.planId();
|
||||
// actionNumb=-1 && itemNumb=-1 |-> mission will be aborted
|
||||
if (msa.itemNumber() < 0 && msa.actionNumber() < 0)
|
||||
{
|
||||
ParticipantManagement::SetMissionActionFulfilledRequest abortReq(m_missionPlan.id(),
|
||||
m_ddsHandler->currentPartitionTime(),
|
||||
-1,
|
||||
-1);
|
||||
if ( !m_ddsHandler->ftcPpm()->setMissionActionFulfilledRequest(abortReq))
|
||||
WARNING_LOG(m_logger) << " -- unable to abort mission with planId:"<<abortReq.missionId();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (msa.itemNumber() >= static_cast<int>(m_missionPlan.items().size()) )
|
||||
{
|
||||
//WARNING_LOG(m_logger)<<" -- [setMissionActionFulfilled] item size invalid !!";
|
||||
return;
|
||||
}
|
||||
|
||||
const int actionCount = m_missionPlan.items()[msa.itemNumber()].actions().size();
|
||||
if (msa.actionNumber() >= actionCount)
|
||||
{
|
||||
//WARNING_LOG(m_logger)<<" -- [setMissionActionFulfilled] actions size invalid !!";
|
||||
return;
|
||||
}
|
||||
|
||||
auto &action = m_missionPlan.items()[msa.itemNumber()].actions()[msa.actionNumber()];
|
||||
action.fulfilled(m_ddsHandler->currentPartitionTime());
|
||||
ParticipantManagement::SetMissionActionFulfilledRequest req;
|
||||
req.actionNumber(action.actionNumber());
|
||||
req.fulfilled(action.fulfilled());
|
||||
req.itemNumber(action.itemNumber());
|
||||
req.missionId(m_missionPlan.id());
|
||||
|
||||
if (!m_ddsHandler->ftcPpm()->setMissionActionFulfilledRequest(req))
|
||||
WARNING_LOG(m_logger) << " -- unable to setMissionActionFulfilledRequest: planId:"<<req.missionId();
|
||||
|
||||
}
|
||||
|
||||
int CesMissionPlanObject::planId() const
|
||||
{
|
||||
return m_missionPlan.id();
|
||||
}
|
||||
|
||||
int CesMissionPlanObject::participantId() const
|
||||
{
|
||||
return m_missionPlan.participantId();
|
||||
}
|
||||
|
||||
bool CesMissionPlanObject::isMissionFulfilled(const ParticipantManagement::MissionPlan &mission)
|
||||
{
|
||||
int itemCount = 0;
|
||||
int actionCount = 0;
|
||||
for (const auto &item : mission.items())
|
||||
{
|
||||
actionCount = 0;
|
||||
for (const auto &a : item.actions())
|
||||
{
|
||||
//DEBUG_LOG(m_logger)<<" -- [setMissionPlan] action.Num : "<<a.actionNumber()<<" itemNum: "<<a.itemNumber()<<" fulfilled: "<<a.fulfilled();
|
||||
if (a.fulfilled() > 0)
|
||||
actionCount++;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
if (actionCount == (int) item.actions().size())
|
||||
itemCount++;
|
||||
}
|
||||
|
||||
return (itemCount == (int)mission.items().size());
|
||||
}
|
||||
|
||||
void CesMissionPlanObject::sendActionAttact()
|
||||
{
|
||||
//1- set aes element
|
||||
//2- send request
|
||||
//3- setActionFulfilled
|
||||
int ret = m_ddsHandler->ftcAes()->explosionClusterSingleEffectOnlyModifyRequest(getExplosionCluster());
|
||||
if (!ret)
|
||||
WARNING_LOG(m_logger)<<" -- sendActionAttact ret error for planId: "<<m_missionPlan.id();
|
||||
|
||||
setMissionActionFulfilled(getNextAction());
|
||||
}
|
||||
|
||||
AreaEffectSimulation::ExplosionClusterSingleEffectOnlyRequest CesMissionPlanObject::getExplosionCluster()
|
||||
{
|
||||
auto msa = getNextAction();
|
||||
|
||||
QJsonObject jsobj = QJsonDocument::fromJson(QByteArray::fromStdString(msa.properties())).object();
|
||||
const int chargeTypeId = jsobj.value(QStringLiteral("chargeTypeId")).toInt();
|
||||
|
||||
|
||||
const ParticipantManagement::Participant participant = m_ddsHandler->dtcPpm()->participant(m_missionPlan.participantId());
|
||||
const ParticipantManagement::UAS uas = m_ddsHandler->dtcPpm()->getUasByParticipantId(m_missionPlan.participantId(),
|
||||
m_ddsHandler->dds()->getPartitionId());
|
||||
|
||||
QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(m_ddsHandler->currentPartitionTime());
|
||||
timeStamp = timeStamp.addSecs(10);
|
||||
const QString exploName = QStringLiteral("%1_%2").arg(QString::fromStdString(uas.deviceIdentifier())).arg(DTG::toStringMSec(timeStamp.toMSecsSinceEpoch(), DTG::DisplayFormat::Short));
|
||||
Core::GeoPosition geoPos(jsobj.value(QStringLiteral("location_x")).toDouble(),
|
||||
jsobj.value(QStringLiteral("location_y")).toDouble(), 0.0);
|
||||
|
||||
AreaEffectSimulation::ExplosionClusterSingleEffectOnlyRequest ecReq;
|
||||
ecReq.id(0);
|
||||
ecReq.effectStart(timeStamp.toMSecsSinceEpoch());
|
||||
ecReq.name(exploName.toStdString());
|
||||
ecReq.element(ecReq.name());
|
||||
ecReq.impactPosition(geoPos);
|
||||
ecReq.chargeTypeId(chargeTypeId);
|
||||
ecReq.partyId(participant.partyId());
|
||||
// ecReq.externalId(0); // not used!!
|
||||
|
||||
return ecReq;
|
||||
}
|
||||
|
||||
|
||||
void CesMissionPlanObject::sendNextMissionAction()
|
||||
{
|
||||
///1- get next mission action to fulfill
|
||||
///2- if there is no mission action left send mission plan completed
|
||||
///3- check what the next action is.
|
||||
///4- if actionType is loiter start Timer. On timeout setMissionActionFulfilled
|
||||
///5- send mission action to mission handler
|
||||
|
||||
ParticipantManagement::MissionAction action = getNextAction();
|
||||
|
||||
//DEBUG_LOG(m_logger)<<" -- ########## ###### SEND NEXT ACTION ###### #############";
|
||||
|
||||
// set mission plan completed! or aborted
|
||||
if (isMissionFulfilled(m_missionPlan) || m_missionPlan.aborted())
|
||||
{
|
||||
DEBUG_LOG(m_logger)<<" -- [sendNextMissionAction] No action mission Completed for plan id: "<<m_missionPlan.id();
|
||||
deleteMissionPlanObject();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (action.actionType().underlying()) {
|
||||
case ParticipantManagement::MissionActionType::MoveTo:
|
||||
{
|
||||
emit ready2SendNextAction(action);
|
||||
break;
|
||||
}
|
||||
case ParticipantManagement::MissionActionType::Loiter:
|
||||
{
|
||||
m_loiterTimer->start(action.duration() * 1000); // duration is in sec -> in msec: x * 1000
|
||||
return;
|
||||
}
|
||||
case ParticipantManagement::MissionActionType::Attack:
|
||||
{
|
||||
sendActionAttact();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CesMissionPlanObject::setMissionPlan(const ParticipantManagement::MissionPlan &plan)
|
||||
{
|
||||
///1- update mission plan
|
||||
///2- if plan fulfilled delete object
|
||||
///3- send Next Mission Action
|
||||
|
||||
m_missionPlan = plan;
|
||||
if (plan.missionStart() > m_ddsHandler->currentPartitionTime())
|
||||
{
|
||||
//DEBUG_LOG(m_logger)<<" -- [setMissionPlan] restart Timer for plan.id: "<<plan.id();
|
||||
m_missionStartimer->start(m_missionPlan.missionStart() - m_ddsHandler->currentPartitionTime());
|
||||
return;
|
||||
}
|
||||
|
||||
if (isMissionFulfilled(plan) || plan.aborted())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "setMissionPlan deleteMissionPlanObject";
|
||||
deleteMissionPlanObject();
|
||||
return;
|
||||
}
|
||||
|
||||
sendNextMissionAction();
|
||||
}
|
||||
|
||||
ParticipantManagement::MissionPlan &CesMissionPlanObject::missionPlan()
|
||||
{
|
||||
return m_missionPlan;
|
||||
}
|
||||
|
||||
const ParticipantManagement::MissionAction CesMissionPlanObject::getNextAction()
|
||||
{
|
||||
|
||||
DEBUG_LOG(m_logger)<<" -- [getNextAction]: planId: "<<m_missionPlan.id()<<" itemSize: "<<m_missionPlan.items().size();
|
||||
std::vector<ParticipantManagement::MissionItem> items = m_missionPlan.items();
|
||||
|
||||
// std::sort(items.begin(), items.end(), [](const ParticipantManagement::MissionItem &itemA, const ParticipantManagement::MissionItem &itemB){ return (itemA.itemNumber() < itemB.itemNumber()); });
|
||||
|
||||
for (auto &item : m_missionPlan.items())
|
||||
{
|
||||
for (auto &msa : item.actions())
|
||||
{
|
||||
if (msa.fulfilled() > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
DEBUG_LOG(m_logger)<<" -- [getNextActopm]mission with planId: " << m_missionPlan.id() << " // action_number " << msa.actionNumber()
|
||||
<< " // action_type " << msa.actionType();
|
||||
|
||||
return msa;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
void CesMissionPlanObject::setMissionCompleted()
|
||||
{
|
||||
const ParticipantManagement::MissionPlan &msp = m_missionPlan;
|
||||
ParticipantManagement::ModifyMissionPlanRequest req;
|
||||
req.missionStart(msp.missionStart());
|
||||
req.jumpToStart(msp.jumpToStart());
|
||||
req.id(msp.id());
|
||||
req.items(msp.items());
|
||||
req.name(msp.name());
|
||||
req.participantId(msp.participantId());
|
||||
req.properties(msp.properties());
|
||||
req.repeat(msp.repeat());
|
||||
|
||||
if (!m_ddsHandler->ftcPpm()->modifyMissionPlanRequest(req))
|
||||
ERROR_LOG(m_logger)<<" -- couldn't modify mission plan ";
|
||||
|
||||
// delete object object is connected with handler
|
||||
// it will be automatically removed from object list in handler
|
||||
deleteMissionPlanObject();
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief CesMissionPlanObject::abortMission
|
||||
* Mission is aborted when uas switched to manual mode.
|
||||
* Notification to PPM is done by setting actionNumb and itemNumb to -1
|
||||
*/
|
||||
void CesMissionPlanObject::abortMission()
|
||||
{
|
||||
DEBUG_LOG(m_logger)<<" -- [abortMission] abord mission with planId: "<<m_missionPlan.id()<<" // uas id: "<<m_missionPlan.participantId();
|
||||
ParticipantManagement::MissionAction msa = getNextAction();
|
||||
msa.actionNumber(-1);
|
||||
msa.itemNumber(-1);
|
||||
setMissionActionFulfilled(msa);
|
||||
}
|
||||
|
||||
void CesMissionPlanObject::deleteMissionPlanObject()
|
||||
{
|
||||
DEBUG_LOG(m_logger)<<" -- [DELETE OBJECT] plan fullfiled: delete Object planId: "<<m_missionPlan.id();
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Plugin CES Mission Plan
|
||||
* $Id: $
|
||||
* $HeadURL: svn://slssvn/TDS/branches/product/features/25_03_etb_uas/Lts/Services/CentralEffectSimulation/Plugins/MissionPlan/ces_mission_plan_object.h $
|
||||
* $Author: Kemayou_s $
|
||||
* Created by Steve Kemayou, ESZS, 2025-06-25
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ParticipantManagement/ppm_db.h>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <ParticipantManagement/logger.h>
|
||||
#include <CentralEffectSimulation/dds_handler.h>
|
||||
|
||||
#include <CentralEffectSimulation/logger.h>
|
||||
#include <QTimer>
|
||||
|
||||
#include <QObject>
|
||||
namespace CES_MISSIONPLAN
|
||||
{
|
||||
|
||||
class CesMissionPlanHandler;
|
||||
class CesMissionPlanObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CesMissionPlanObject(const ParticipantManagement::MissionPlan &missionPlan,
|
||||
const std::shared_ptr<CentralEffectSimulation::DdsHandler> &ddsHandler,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
friend class CesMissionPlanHandler;
|
||||
|
||||
void setMissionActionFulfilled(const ParticipantManagement::MissionAction &msa);
|
||||
int planId() const;
|
||||
int participantId() const; /// uas participantId
|
||||
bool isMissionFulfilled(const ParticipantManagement::MissionPlan &mission);
|
||||
protected:
|
||||
void sendActionAttact();
|
||||
AreaEffectSimulation::ExplosionClusterSingleEffectOnlyRequest getExplosionCluster();
|
||||
ParticipantManagement::MissionPlan &missionPlan();
|
||||
const ParticipantManagement::MissionAction getNextAction() ;
|
||||
|
||||
public slots:
|
||||
void sendNextMissionAction();
|
||||
void setMissionPlan(const ParticipantManagement::MissionPlan &plan);
|
||||
void setMissionCompleted();
|
||||
void abortMission();
|
||||
|
||||
signals:
|
||||
void ready2SendNextAction(const ParticipantManagement::MissionAction & msa);
|
||||
void missionPlanCompleted(const int planId);
|
||||
void missionPlanCompleted(const ParticipantManagement::MissionPlan &missionPlan);
|
||||
void missionActionFulfilled(const ParticipantManagement::MissionAction &missionAction);
|
||||
// void missionAction
|
||||
|
||||
private: // private methods
|
||||
void deleteMissionPlanObject();
|
||||
private:
|
||||
|
||||
QTimer *m_missionStartimer{nullptr};
|
||||
QTimer *m_loiterTimer{nullptr};
|
||||
std::shared_ptr<CentralEffectSimulation::DdsHandler> m_ddsHandler;
|
||||
ParticipantManagement::MissionPlan m_missionPlan;
|
||||
NGL::INGLLogger &m_logger; ///< Interface to the Logging-Facility
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Plugin CES Mission Plan
|
||||
* $Id: $
|
||||
* $HeadURL: svn://slssvn/TDS/branches/product/features/25_03_etb_uas/Lts/Services/CentralEffectSimulation/Plugins/MissionPlan/plugin.cpp $
|
||||
* $Author: Kemayou_s $
|
||||
* Created by Steve Kemayou, ESZS, 2025-06-25
|
||||
*/
|
||||
|
||||
#include "plugin.h"
|
||||
#include "settings.h"
|
||||
|
||||
namespace CES_MISSIONPLAN
|
||||
{
|
||||
|
||||
|
||||
std::shared_ptr<CentralEffectSimulation::Plugin::Interface> CesMissionPlanPlugin::createInterface(CentralEffectSimulation::Plugin::DataProvider *pdp,
|
||||
const std::shared_ptr<DDSConnector::DdsConnector> &dDSConnector,
|
||||
NGL::Settings *settings,
|
||||
CentralEffectSimulation::MainHandler *mainHandler)
|
||||
{
|
||||
return std::make_shared<CES_MissionPlanInterfaceImpl>(pdp, dDSConnector, settings, mainHandler);
|
||||
}
|
||||
|
||||
|
||||
CES_MissionPlanInterfaceImpl::CES_MissionPlanInterfaceImpl(CentralEffectSimulation::Plugin::DataProvider *pdp,
|
||||
const std::shared_ptr<DDSConnector::DdsConnector> &dDSConnector,
|
||||
NGL::Settings *settings,
|
||||
CentralEffectSimulation::MainHandler *mainHandler)
|
||||
: m_pdp(pdp)
|
||||
, m_ddsConnector(dDSConnector)
|
||||
, m_mainHandler(mainHandler)
|
||||
, m_ddsHandler(m_mainHandler->dds())
|
||||
, m_db(m_mainHandler->db())
|
||||
, m_handlerParticipant(m_mainHandler->handlerParticipant())
|
||||
, m_logger(CentralEffectSimulation::getLogger("Plugin.MissionPlan.MissionPlanHandler"))
|
||||
{
|
||||
Q_UNUSED(settings)
|
||||
|
||||
ERROR_LOG(m_logger) << " >>> constructor CES_MissionPlanInterfaceImpl";
|
||||
}
|
||||
|
||||
CES_MissionPlanInterfaceImpl::~CES_MissionPlanInterfaceImpl()
|
||||
{
|
||||
m_missionPlanHandler.reset();
|
||||
}
|
||||
|
||||
|
||||
bool CES_MissionPlanInterfaceImpl::init(int domainId, int exerciseId)
|
||||
{
|
||||
m_domainId = domainId;
|
||||
m_exerciseId = exerciseId;
|
||||
ERROR_LOG(m_logger) << "CES_MissionPlanInterfaceImpl::init()"
|
||||
<< " m_domainId=" << m_domainId
|
||||
<< " m_exerciseId=" << m_exerciseId;
|
||||
|
||||
|
||||
|
||||
// initialize MissionPlanHandler
|
||||
m_missionPlanHandler = std::make_shared<CesMissionPlanHandler>(m_ddsHandler,
|
||||
m_handlerParticipant,
|
||||
this);
|
||||
|
||||
if (!m_missionPlanHandler->init())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Initialisation m_handlerFunctionalArea failed.";
|
||||
return false;
|
||||
}
|
||||
|
||||
INFO_LOG(m_logger) << "CES_MissionPlanInterfaceImpl::init() return true";
|
||||
return true;
|
||||
}
|
||||
|
||||
QString CES_MissionPlanInterfaceImpl::echo(const QString &message)
|
||||
{
|
||||
|
||||
QString ret(QStringLiteral("<<<< %1 >>>> CES_MissionPlanInterfaceImpl::echo").arg(message));
|
||||
INFO_LOG(m_logger) << "CES_MissionPlanInterfaceImpl::echo return:" << ret;
|
||||
DEBUG_LOG(m_logger) << "DEBUG: CES_MissionPlanInterfaceImpl::echo return:" << ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
} //namespace CES_MISSIONPLAN
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Plugin CES Mission Plan
|
||||
* $Id: $
|
||||
* $HeadURL: svn://slssvn/TDS/branches/product/features/25_03_etb_uas/Lts/Services/CentralEffectSimulation/Plugins/MissionPlan/plugin.h $
|
||||
* $Author: Kemayou_s $
|
||||
* Created by Steve Kemayou, ESZS, 2025-06-25
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <CentralEffectSimulation/logger.h>
|
||||
|
||||
#include "ces_mission_plan_handler.h"
|
||||
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
#include <CentralEffectSimulation/ces_plugin_interface.h>
|
||||
#include <CentralEffectSimulation/main_handler.h>
|
||||
#include <CentralEffectSimulation/dds_handler.h>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
|
||||
namespace CES_MISSIONPLAN
|
||||
{
|
||||
|
||||
class CesMissionPlanPlugin : public QObject, public CentralEffectSimulation::Plugin::Plugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "special:3:ces.CesMissionPlanPlugin")
|
||||
Q_INTERFACES(CentralEffectSimulation::Plugin::Plugin)
|
||||
|
||||
public:
|
||||
CesMissionPlanPlugin() = default;
|
||||
~CesMissionPlanPlugin() = default;
|
||||
std::shared_ptr<CentralEffectSimulation::Plugin::Interface> createInterface(CentralEffectSimulation::Plugin::DataProvider *pdp,
|
||||
const std::shared_ptr<DDSConnector::DdsConnector> &dDSConnector,
|
||||
NGL::Settings *settings,
|
||||
CentralEffectSimulation::MainHandler *mainHandler) override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class CES_MissionPlanInterfaceImpl final : public CentralEffectSimulation::Plugin::Interface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CES_MissionPlanInterfaceImpl(CentralEffectSimulation::Plugin::DataProvider *pdp,
|
||||
const std::shared_ptr<DDSConnector::DdsConnector> &dDSConnector,
|
||||
NGL::Settings *settings,
|
||||
CentralEffectSimulation::MainHandler *mainHandler);
|
||||
~CES_MissionPlanInterfaceImpl();
|
||||
//bool init();
|
||||
const char *name() const override { return "CesMissionPlanPlugin"; }
|
||||
QString echo(const QString &message) override;
|
||||
|
||||
private Q_SLOTS:
|
||||
bool init(int domainId, int exerciseId) override;
|
||||
private:
|
||||
|
||||
private:
|
||||
CentralEffectSimulation::Plugin::DataProvider *m_pdp{nullptr};
|
||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
|
||||
CentralEffectSimulation::MainHandler *m_mainHandler{nullptr};
|
||||
|
||||
std::shared_ptr<CentralEffectSimulation::DdsHandler> m_ddsHandler;
|
||||
std::shared_ptr<CentralEffectSimulation::DatabaseInterface> m_db;
|
||||
std::shared_ptr<CentralEffectSimulation::HandlerParticipant> m_handlerParticipant; ///< Pointer to handler for all participants
|
||||
|
||||
std::shared_ptr<CesMissionPlanHandler> m_missionPlanHandler; ///
|
||||
|
||||
|
||||
CentralEffectSimulation::LOGGER_T &m_logger; ///< Interface to the Logging-Facility
|
||||
int m_domainId = 0;
|
||||
int m_exerciseId = 0;
|
||||
};
|
||||
|
||||
} // namespace CES_MISSIONPLAN
|
||||
Reference in new issue
Block a user