399 lines
14 KiB
C++
Executable File
399 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 <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 QMap<int, Database::PpmMissionAction> &dbActions)
|
|
{
|
|
m_mapMissionItems.clear();
|
|
m_dbMissionActions.clear();
|
|
|
|
for (const ParticipantManagement::Database::PpmMissionItem &item : qAsConst(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
|