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
400 lines
14 KiB
C++
Executable File
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
|