Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Services/ParticipantManagement/UasHandling/object_mission_plan.cpp
T
berrux-dev 598fc2560e Complete Qt6 migration: full clean build green across groups G1-G12 incl. runtime plugin set
new_docker_build.sh gains Group 12 (212 GUI/Data plugins); fixes LtsUtilsGuiDds visibility (LTO-stripped exports), LtsProjectionWorkstation unity name shadow, 6 unity-off dirs (dup file-scope statics, ddsftc INTERFACE sources) and reconfigures BUILD_FILTERMANAGEMENT/BUILD_PLUGINS_SERVICEMONITOR=ON
2026-10-20 09:36:57 +02:00

400 lines
14 KiB
C++
Executable File

/**
* The ObjectMissionPlan class represents a ObjectMissionPlan. It holds the data and offers some conversion methods.
* $Id$
* $HeadURL$
* $Author$
* Created by Steve Kemayou, ESZS, 2025-04-08
*/
#include "object_mission_plan.h"
#include <utility>
#include <ngldb/dbtransaction.h>
namespace ParticipantManagement
{
namespace UasHandling
{
ObjectMissionPlan::ObjectMissionPlan(const std::shared_ptr<DdsHandler> &ddsHandler,
const std::shared_ptr<DatabaseInterface> &db,
const ParticipantManagement::MissionPlan & missionPlan,
QObject *parent)
: QObject(parent)
, m_ddsHandler(ddsHandler)
, m_db(db)
, m_missionplan(missionPlan)
, m_logger(getLogger("ObjectMissionPlan"))
{
DEBUG_LOG(m_logger)<<" - ctor ObjectMissionPlan: planId: "<<m_missionplan.id;
}
int32_t ObjectMissionPlan::id() const
{
return m_missionplan.id;
}
int32_t ObjectMissionPlan::participantId() const
{
return m_missionplan.participantId;
}
Database::PpmMissionPlan ObjectMissionPlan::toDbMissionPlan(const ModifyMissionPlanRequest &mp)
{
Database::PpmMissionPlan result;
result.id = mp.id;
result.name = QString::fromStdString(mp.name);
result.missionStart = QDateTime::fromMSecsSinceEpoch(mp.missionStart);
result.repeat = mp.repeat;
result.jumpToStart = mp.jumpToStart;
result.participantId = mp.participantId;
return result;
}
MissionPlan ObjectMissionPlan::fillMissionPlanData(const ModifyMissionPlanRequest &in)
{
MissionPlan out;
out.id = in.id;
out.name = in.name;
out.missionStart = in.missionStart;
out.properties = in.properties;
out.items = in.items;
out.participantId = in.participantId;
out.jumpToStart = in.jumpToStart;
out.repeat = in.repeat;
return out;
}
MissionPlan ObjectMissionPlan::getMissionPlanData() const
{
return m_missionplan;
}
void ObjectMissionPlan::setDbMissionItems(const QMap<int, ParticipantManagement::Database::PpmMissionItem> &dbItems,
const QMultiMap<int, Database::PpmMissionAction> &dbActions)
{
m_mapMissionItems.clear();
m_dbMissionActions.clear();
for (const ParticipantManagement::Database::PpmMissionItem &item : std::as_const(dbItems))
{
ParticipantManagement::MissionItem msi;
msi.actions.reserve(dbActions.size());
msi.name = item.name.toStdString();
msi.location = Core::GeoPosition(item.location.x(), item.location.y(), item.location.z());
msi.itemNumber = item.elementNumber;
std::vector<Database::PpmMissionAction> actionsVec;
for (const auto &action : dbActions)
{
if (action.missionItemId == item.id)
{
ParticipantManagement::MissionAction msa;
msa.actionType = action.missionActionTypeId;
msa.duration = action.duration;
msa.fulfilled = action.fulfilled.toMSecsSinceEpoch();
msa.properties = action.properties.toStdString();
msa.name = action.name.toStdString();
msa.actionNumber = action.elementNumber;
msa.planId = item.missionPlanId;
msi.actions.push_back(msa);
actionsVec.push_back(action);
}
}
m_mapMissionItems.insert(item.id, msi);
m_dbMissionActions.push_back(actionsVec);
}
}
const MissionPlan &ObjectMissionPlan::missionPlan() const
{
return m_missionplan;
}
Core::FunctionReplyObject ObjectMissionPlan::createMissionPlan(Database::PpmMissionPlan newMissionPlan, const std::vector<MissionItem> &missionItems)
{
/// 1- insert in DB Mission plan
/// 2- insert in DB Mission Items
/// 3- insert in DB Mission Actions
DBTransaction trans(m_db->database());
newMissionPlan.aborted = false;
if (!m_db->insert(newMissionPlan))
{
QString error = QStringLiteral("Could not insert mission plan into database");
ERROR_LOG(m_logger)<< error;
return Core::FunctionReplyObject(error.toStdString().c_str());
}
std::vector<MissionItem> itemVec = missionItems;
m_mapMissionItems.clear();
m_mapMissionItems.reserve(itemVec.size());
std::vector<std::vector<Database::PpmMissionAction>>itemsVec;
m_dbMissionActions.clear();
for ( auto &item : itemVec)
{
Database::PpmMissionItem dbItem;
dbItem.missionPlanId = newMissionPlan.id;
dbItem.name = QString::fromStdString(item.name);
dbItem.elementNumber = item.itemNumber;
dbItem.location = LtsUtils::QPoint3D(item.location.lon,item.location.lat, item.location.z);
if (!m_db->insert(dbItem))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error adding 'Mission Item' to database"));
std::vector<Database::PpmMissionAction> actionsVec;
actionsVec.reserve(item.actions.size());
for (auto &action : item.actions)
{
action.planId = newMissionPlan.id;
Database::PpmMissionAction dbAction;
dbAction.missionActionTypeId = action.actionType;
dbAction.missionItemId = dbItem.id;
dbAction.duration = action.duration;
dbAction.name = QString::fromStdString(action.name);
dbAction.properties = QString::fromStdString(action.properties);
dbAction.fulfilled = QDateTime::fromMSecsSinceEpoch(action.fulfilled);
dbAction.elementNumber = action.actionNumber;
if (!m_db->insert(dbAction))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error adding 'Mission Action' to database"));
actionsVec.push_back(dbAction);
}//loop mission actions
m_mapMissionItems.insert(dbItem.id, item);
m_dbMissionActions.push_back(actionsVec); // [elNumber][actionNumber]
}//loop mission items
m_missionplan.id = newMissionPlan.id;
m_missionplan.name = newMissionPlan.name.toStdString();
m_missionplan.missionStart = newMissionPlan.missionStart.toMSecsSinceEpoch();
m_missionplan.participantId = newMissionPlan.participantId;
m_missionplan.jumpToStart = newMissionPlan.jumpToStart;
m_missionplan.repeat = newMissionPlan.repeat;
m_missionplan.items = itemVec;
m_missionplan.fulfilled = 0;
m_missionplan.itemsFulfilled = 0;
for (auto &item : m_missionplan.items)
{
for (auto &action : item.actions)
DEBUG_LOG(m_logger)<<"[CREATE] itemIdx: "<<item.itemNumber
<<" act.Num: "<<action.actionNumber<<" act.ItemNum: "<<action.itemNumber<<" itemFul:"<<action.fulfilled;
}
trans.commit();
DEBUG_LOG(m_logger)<< ">> [NEW] mission plan with id( "<<newMissionPlan.id<<" ) inserted !!";
return Core::FunctionReplyObject(newMissionPlan.id);
}
Core::FunctionReplyObject ObjectMissionPlan::updateMissionPlan(Database::PpmMissionPlan newMissionPlan, const std::vector<MissionItem> &missionItems)
{
if (missionItems.size() == 0)
return Core::FunctionReplyObject(newMissionPlan.id, tr_lts("dds", "Could not modify MissionPlan without segments."));
/// 1- update missipn plan table
/// 2- remove items and their actions
/// 3- insert new items and their actions
DBTransaction trans(m_db->database());
const auto tmpDbMissionItems = m_mapMissionItems;
newMissionPlan.aborted = false;
/// update mission plan table
if (!m_db->update(newMissionPlan))
{
QString error = QStringLiteral("Could not update mission plan! ");
ERROR_LOG(m_logger)<< error;
return Core::FunctionReplyObject(error.toStdString().c_str());
}
/// remove all items and their actions from the database
for (const auto &itemId : tmpDbMissionItems.keys())
{
if (!m_db->removePpmMissionItem(itemId))
{
QString error = QStringLiteral("Could not remove mission plan from database");
ERROR_LOG(m_logger)<< error;
return Core::FunctionReplyObject(0, tr_lts("dds", "Could not update mission plan into!"));
}
}
/// insert new items with their actions in the data base;
m_mapMissionItems.clear();
m_mapMissionItems.reserve(missionItems.size());
m_dbMissionActions.clear();
std::vector<MissionItem> itemVec = missionItems;
for (auto &item : itemVec)
{
Database::PpmMissionItem dbItem;
dbItem.missionPlanId = newMissionPlan.id;
dbItem.name = QString::fromStdString(item.name);
dbItem.elementNumber = item.itemNumber;
dbItem.location = LtsUtils::QPoint3D(item.location.lon,item.location.lat, item.location.z);
if (!m_db->insert(dbItem))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error adding 'Mission Item' to database"));
std::vector<Database::PpmMissionAction> actionsVec;
actionsVec.reserve(item.actions.size());
for (auto &action : item.actions)
{
action.planId = newMissionPlan.id;
Database::PpmMissionAction dbAction;
dbAction.missionActionTypeId = action.actionType;
dbAction.missionItemId = dbItem.id;
dbAction.duration = action.duration;
dbAction.name = QString::fromStdString(action.name);
dbAction.properties = QString::fromStdString(action.properties);
dbAction.fulfilled = QDateTime::fromMSecsSinceEpoch(action.fulfilled);
dbAction.elementNumber = action.actionNumber;
if (!m_db->insert(dbAction))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error adding 'Mission Action' to database"));
actionsVec.push_back(dbAction);
}//loop mission actions
m_mapMissionItems.insert(dbItem.id, item);
m_dbMissionActions.push_back(actionsVec); // [elNumber][actionNumber]
}//loop mission items
trans.commit();
m_missionplan.id = newMissionPlan.id;
m_missionplan.name = newMissionPlan.name.toStdString();
m_missionplan.missionStart = newMissionPlan.missionStart.toMSecsSinceEpoch();
m_missionplan.participantId = newMissionPlan.participantId;
m_missionplan.jumpToStart = newMissionPlan.jumpToStart;
m_missionplan.repeat = newMissionPlan.repeat;
m_missionplan.items = itemVec;
m_missionplan.itemsFulfilled = 0; // on update items and action entries will be cleared
m_missionplan.fulfilled = 0;
DEBUG_LOG(m_logger)<< ">> [UPDATE] mission plan with id( "<<m_missionplan.id<<" ) Updated !!";
return Core::FunctionReplyObject(m_missionplan.id);
}
Core::FunctionReplyObject ObjectMissionPlan::removeMissionPlan(int id)
{
DBTransaction trans(m_db->database());
if (!m_db->removePpmMissionPlan(id))
{
QString error = QStringLiteral("Could not remove mission plan ! ");
ERROR_LOG(m_logger)<< error;
return Core::FunctionReplyObject(error.toStdString().c_str());
}
trans.commit();
m_dbMissionActions.clear();
m_mapMissionItems.clear();
DEBUG_LOG(m_logger)<< ">> [REMOVE] mission Action with id( "<<id<<" ) deleted !!";
return Core::FunctionReplyObject();
}
Core::FunctionReplyObject ObjectMissionPlan::setMissionActionFulfilled(SetMissionActionFulfilledRequest req, qint64 currentTimeMSec)
{
//0- if actionNumb and itemNumb are -1 -> missionplan is aborted. only update missionPlan table with status aborted = true
//1- get db mission action from actionNumber
//2- set mission action as fulfilled
//3- set mission action save in db
//4- update cache data
if (!m_db)
{
ERROR_LOG(m_logger) << "no init yet....";
return Core::FunctionReplyObject("");
}
if (req.missionId != m_missionplan.id)
{
QString error = QStringLiteral("Wrong missionPlan Object caught Request: %1 / currPlanId: %2").arg(req.missionId).arg(m_missionplan.id);
ERROR_LOG(m_logger)<< error;
return Core::FunctionReplyObject(error.toStdString().c_str());
}
// Abort in case itemNumb=-1 && actionNumb=-1
if (req.actionNumber < 0 && req.itemNumber < 0)
{
m_missionplan.aborted = true;
return setMissionPlanAborted(true);
}
auto &dbActions = m_dbMissionActions[req.itemNumber]; //[elemNum][actionNum]
if (dbActions.empty()
|| req.actionNumber >= static_cast<int>(dbActions.size())
|| req.actionNumber < 0
|| req.itemNumber < 0) // actionNumber start by 0
{
QString error = QStringLiteral("Could not set mission action with id: %1 ! ").arg(req.actionNumber);
ERROR_LOG(m_logger)<< error;
return Core::FunctionReplyObject(error.toStdString().c_str());
}
Database::PpmMissionAction &dbAction = dbActions[req.actionNumber];
dbAction.fulfilled = QDateTime::fromMSecsSinceEpoch(currentTimeMSec);
if (!m_db->update(dbAction))
{
QString error = QStringLiteral("Could not update mission action! ");
ERROR_LOG(m_logger)<< error;
return Core::FunctionReplyObject(error.toStdString().c_str());
}
//update item in case actions fulfilled
//1- actions count
//2- number of actions fulfilled
//3- check if action count == item.actions.size()
//4- if yes update missioPlan & missionItem fulfilled
MissionItem &msi = m_mapMissionItems[dbAction.missionItemId];
msi.fulfilled = dbAction.fulfilled.toMSecsSinceEpoch();
msi.actionsFulfilled = msi.actionsFulfilled + 1;
MissionAction &msa = m_mapMissionItems[dbAction.missionItemId].actions[dbAction.elementNumber];
msa.fulfilled = dbAction.fulfilled.toMSecsSinceEpoch();
m_missionplan.items[req.itemNumber] = m_mapMissionItems[dbAction.missionItemId]; // item in MissionPlan updated through elementNumber
/// update fulfilled time for items and mission plan
/// update fulfilled items count
int numbItemFulfilled = 0;
for(const auto &item : m_mapMissionItems)
{
if (item.actionsFulfilled == static_cast<int>(item.actions.size()))
numbItemFulfilled++;
}
m_missionplan.itemsFulfilled = numbItemFulfilled;
m_missionplan.fulfilled = dbAction.fulfilled.toMSecsSinceEpoch();
return Core::FunctionReplyObject(m_missionplan.id);
}
Core::FunctionReplyObject ObjectMissionPlan::setMissionPlanAborted(bool state)
{
DEBUG_LOG(m_logger)<<" -- [setMissionPlanAborted] abort mission plan: "<<m_missionplan.id;
Database::PpmMissionPlan dbMissionPlan;
// m_db->selectPpmMissionPlan(m_missionplan.id(),dbMissionPlan);
dbMissionPlan.missionStart = QDateTime::fromMSecsSinceEpoch(m_missionplan.missionStart);
dbMissionPlan.jumpToStart = m_missionplan.jumpToStart;
dbMissionPlan.id = m_missionplan.id;
dbMissionPlan.name = QString::fromStdString(m_missionplan.name);
dbMissionPlan.participantId = m_missionplan.participantId;
dbMissionPlan.repeat = m_missionplan.repeat;
dbMissionPlan.aborted = state;
/// update mission plan table
if (!m_db->update(dbMissionPlan))
{
QString error = QStringLiteral("Could not update mission plan! ");
ERROR_LOG(m_logger)<< error;
return Core::FunctionReplyObject(error.toStdString().c_str());
}
return Core::FunctionReplyObject(m_missionplan.id);
}
} // namespace UasHandling
} // namespace ParticipantManagement