3 #include <QApplication>
15 #include <Ice/Exception.h>
17 #include <SimoxUtility/algorithm/get_map_keys_values.h>
18 #include <SimoxUtility/algorithm/string/string_tools.h>
27 #include <RobotAPI/interface/armem/actions.h>
28 #include <RobotAPI/interface/armem/memory.h>
29 #include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h>
43 QGroupBox* memoryGroupBox,
44 QLayout* memoryGroupBoxParentLayout,
45 QGroupBox* instanceGroupBox,
46 QLayout* instanceGroupBoxParentLayout,
47 QBoxLayout* diskControlWidgetLayout,
53 this->statusLabel->clear();
55 statusLabel->setContextMenuPolicy(Qt::CustomContextMenu);
57 &QLabel::customContextMenuRequested,
61 menu.addAction(
"Copy to clipboard",
63 { QApplication::clipboard()->setText(
statusLabel->text()); });
83 std::stringstream sstream;
84 sstream <<
"Predictions are not available for memory '" << entityID.memoryName
86 this->statusLabel->setText(QString::fromStdString(sstream.str()));
90 std::map<MemoryID, std::vector<PredictionEngine>> predictionEngines;
97 catch (
const Ice::LocalException& e)
99 std::stringstream sstream;
100 sstream <<
"Could not get prediction engines and type from memory: " << e.what();
101 this->statusLabel->setText(QString::fromStdString(sstream.str()));
102 return {
nullptr, {}};
109 if (providerSegment !=
nullptr)
111 entityType = providerSegment->aronType();
130 if (diskControlWidgetLayout)
148 connect(
this, &
This::connected,
this, &This::startPeriodicUpdateTimer);
233 armem::mns::MemoryNameSystemInterfacePrx mnsProxy;
234 component.getProxy(mnsProxy,
mnsName);
235 mns = client::MemoryNameSystem(mnsProxy);
265 MemoryViewer::collapseAll()
271 MemoryViewer::startPeriodicUpdateTimer()
276 const armem::wm::Memory*
277 MemoryViewer::getSingleMemoryData(
const std::string&
memoryName)
282 std::stringstream ss;
283 ss <<
"Memory name '" <<
memoryName <<
"' is unknown. Known are: "
284 << simox::alg::join(simox::alg::get_keys(
memoryData),
", ");
285 statusLabel->setText(QString::fromStdString(ss.str()));
308 if (
std::find(enabledMemories.begin(), enabledMemories.end(), name) ==
309 enabledMemories.end())
318 server::dto::DirectlyStoreInput
input;
319 input.memory = q_res.toIce().memory;
320 reader.directlyStore(
input);
324 std::string
s =
"Query of memory " + name +
" was unsuccessful.";
342 if (
std::find(enabledMemories.begin(), enabledMemories.end(), name) ==
343 enabledMemories.end())
347 reader.startRecording();
363 if (
std::find(enabledMemories.begin(), enabledMemories.end(), name) ==
364 enabledMemories.end())
368 reader.stopRecording();
386 ARMARX_INFO <<
"Committing to " << memoryIDStr <<
" the data: " << aronJSONStr;
393 <<
"' does not contain an entity.";
398 nlohmann::json json = nlohmann::json::parse(aronJSONStr);
408 <<
"' available for commit.";
413 auto& entityUpdate = comm.
add();
415 entityUpdate.confidence = 1.0;
416 entityUpdate.instancesData = {aron};
417 entityUpdate.referencedTime = now;
418 it->second.commit(comm);
431 std::vector<wm::Memory> memoryDataVec = simox::alg::get_values(
memoryData);
443 std::map<std::filesystem::path, wm::Memory>
data =
448 std::string name =
memory.id().memoryName;
460 <<
"' available for commit. Create new virtual memory.";
465 std::string virtualMemoryName = name;
466 memory.id().memoryName = virtualMemoryName;
477 MemoryViewer::startQueries()
483 MemoryViewer::processQueryResults()
485 const std::map<std::string, client::QueryResult> results = collectQueryResults();
488 applyQueryResults(results, &errorCount);
491 updateStatusLabel(errorCount);
495 MemoryViewer::updateStatusLabel(
int errorCount)
500 auto now = std::chrono::system_clock::now();
501 auto in_time_t = std::chrono::system_clock::to_time_t(now);
503 std::stringstream ss;
504 ss <<
"Last update: " << std::put_time(std::localtime(&in_time_t),
"%Y-%m-%d %X");
505 ss <<
"\nThe query produced " << errorCount <<
" errors! Please check log.";
507 statusLabel->setText(QString::fromStdString(ss.str()));
512 MemoryViewer::startDueQueries()
524 if (
std::find(enabledMemories.begin(), enabledMemories.end(), pair.first) ==
525 enabledMemories.end())
530 const auto& name = pair.first;
531 const auto& reader = pair.second;
543 [reader,
input, recursionDepth,
this]()
547 ? reader.query(
input.toIce())
548 : reader.query(
input.toIce(),
mns, recursionDepth);
553 std::map<std::string, client::QueryResult>
554 MemoryViewer::collectQueryResults()
559 std::map<std::string, client::QueryResult> results;
562 const std::string& name = it->first;
563 std::future<armem::query::data::Result>* queryPromise = &it->second;
565 if (queryPromise->wait_for(std::chrono::seconds(0)) == std::future_status::ready)
573 catch (
const Ice::ConnectionRefusedException&)
595 {
"t Collect Query Results [ms]",
596 new Variant(tCollectQueryResults.toMilliSecondsDouble())},
597 {
"# Collected Query Results",
new Variant(
static_cast<int>(results.size()))},
605 MemoryViewer::applyQueryResults(
const std::map<std::string, client::QueryResult>& results,
609 for (
const auto& [name, result] : results)
617 ARMARX_WARNING <<
"Querying memory server '" << name <<
"' produced an error: \n"
618 << result.errorMessage;
645 if (
std::find(enabledMemories.begin(), enabledMemories.end(), it->first) ==
646 enabledMemories.end())
669 {
"t Process Query Results [ms]",
670 new Variant(tProcessQueryResults.toMilliSecondsDouble())},
671 {
"# Processed Query Results",
new Variant(
static_cast<int>(results.size()))},
688 if (not
id.hasTimestamp())
696 id.timestamp = snapshot->
time();
698 if (not
id.hasInstanceIndex())
704 snapshot = &
data->getSnapshot(
id);
714 if (snapshot && snapshot->size() > 0)
716 id.instanceIndex = 0;
719 if (
id.hasInstanceIndex())
731 auto handleError = [
this](
const std::string& msg)
739 handleError(
"Memory name is empty.");
743 std::optional<wm::EntityInstance> instance;
748 segmentType =
data->getProviderSegment(
id).aronType();
750 if (
id.hasInstanceIndex())
752 instance =
data->getInstance(
id);
754 else if (
id.hasTimestamp())
756 instance =
data->getSnapshot(
id).getInstance(0);
760 instance =
data->getEntity(
id).getLatestSnapshot().getInstance(0);
787 view->update(*instance, segmentType);
797 MemoryViewer::updateListOfActiveMemories()
806 std::vector<std::string> activeMemoryNames;
811 std::back_inserter(activeMemoryNames),
812 [](
const auto& p) { return p.first; });
828 <<
"MNS not ready yet. Skip update of available memories in query widget.";
833 MemoryViewer::updateMemoryTree()
835 std::map<std::string, const armem::wm::Memory*> memoriesToUpdate;
840 memoriesToUpdate[name] = &
data;
854 new Variant(GuiUpdateMemoryTree.toMilliSecondsDouble()));
856 catch (
const Ice::Exception&)
870 auto showMenu = [menu, pos]()
883 mns::dto::MemoryServerInterfaces prx;
891 QString::fromStdString(e.
makeMsg(
memoryID,
"Could not resolve memory server.")));
898 std::stringstream ss;
899 ss <<
"Memory server " <<
memoryID <<
" does not support actions or is offline.";
900 statusLabel->setText(QString::fromStdString(ss.str()));
905 actions::GetActionsOutputSeq result;
908 result = prx.actions->getActions({{armarx::toIce<data::MemoryID>(
memoryID)}});
910 catch (
const Ice::LocalException& e)
912 std::stringstream ss;
913 ss <<
"Could not get actions for " <<
memoryID <<
".";
914 statusLabel->setText(QString::fromStdString(ss.str()));
919 if (result.size() == 0)
929 actions::data::ExecuteActionOutputSeq result;
932 result = prx.actions->executeActions(
933 {{armarx::toIce<armem::data::MemoryID>(
memoryID), path}});
935 catch (
const Ice::LocalException& e)
937 std::stringstream ss;
938 ss <<
"Failed to execute action: " << e.what();
939 statusLabel->setText(QString::fromStdString(ss.str()));
942 for (
const auto& [
success, errorMessage] : result)
946 std::stringstream ss;
947 ss <<
"Failed to execute action: " << errorMessage;
948 statusLabel->setText(QString::fromStdString(ss.str()));
957 actionsMenu->exec(pos);
961 menu->addMenu(actionsMenu);
970 const std::string& engineID)
973 std::stringstream errorStream;
974 auto showError = [
this, &errorStream]()
975 {
statusLabel->setText(QString::fromStdString(errorStream.str())); };
979 errorStream <<
"Could not convert " << entityID <<
" to valid entity ID.";
985 errorStream <<
"Not connected to memory '" << entityID.
memoryName
986 <<
"', cannot make prediction.";
993 errorStream <<
"Predictions are not available for memory '" << entityID.
memoryName
1004 result = reader.
predict({request}).at(0);
1006 catch (
const Ice::LocalException& e)
1008 errorStream <<
"Could not make prediction request: " << e.what();
1015 errorStream <<
"Prediction failed: " << result.
errorMessage;
1025 const static std::string CONFIG_KEY_MEMORY =
"MemoryViewer.MemoryNameSystem";
1026 const static std::string CONFIG_KEY_DEBUG_OBSERVER =
"MemoryViewer.DebugObserverName";
1031 mnsName = settings->value(QString::fromStdString(CONFIG_KEY_MEMORY),
"MemoryNameSystem")
1035 settings->value(QString::fromStdString(CONFIG_KEY_DEBUG_OBSERVER),
"DebugObserver")
1043 settings->setValue(QString::fromStdString(CONFIG_KEY_MEMORY),
1044 QString::fromStdString(
mnsName));
1045 settings->setValue(QString::fromStdString(CONFIG_KEY_DEBUG_OBSERVER),
1052 dialog->
addProxyFinder<armarx::armem::mns::MemoryNameSystemInterfacePrx>(
1053 {CONFIG_KEY_MEMORY,
"MemoryNameSystem",
"MemoryNameSystem"});
1055 {CONFIG_KEY_DEBUG_OBSERVER,
"Debug Observer",
"DebugObserver"});