3 #include <QApplication>
16 #include <Ice/Exception.h>
18 #include <SimoxUtility/algorithm/get_map_keys_values.h>
19 #include <SimoxUtility/algorithm/string/string_tools.h>
28 #include <RobotAPI/interface/armem/actions.h>
29 #include <RobotAPI/interface/armem/memory.h>
30 #include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h>
46 QGroupBox* memoryGroupBox,
47 QLayout* memoryGroupBoxParentLayout,
48 QGroupBox* instanceGroupBox,
49 QLayout* instanceGroupBoxParentLayout,
50 QBoxLayout* diskControlWidgetLayout,
56 this->statusLabel->clear();
58 statusLabel->setContextMenuPolicy(Qt::CustomContextMenu);
60 &QLabel::customContextMenuRequested,
64 menu.addAction(
"Copy to clipboard",
66 { QApplication::clipboard()->setText(
statusLabel->text()); });
86 std::stringstream sstream;
87 sstream <<
"Predictions are not available for memory '" << entityID.memoryName
89 this->statusLabel->setText(QString::fromStdString(sstream.str()));
93 std::map<MemoryID, std::vector<PredictionEngine>> predictionEngines;
100 catch (
const Ice::LocalException& e)
102 std::stringstream sstream;
103 sstream <<
"Could not get prediction engines and type from memory: " << e.what();
104 this->statusLabel->setText(QString::fromStdString(sstream.str()));
105 return {
nullptr, {}};
112 if (providerSegment !=
nullptr)
114 entityType = providerSegment->aronType();
133 if (diskControlWidgetLayout)
151 connect(
this, &
This::connected,
this, &This::startPeriodicUpdateTimer);
235 armem::mns::MemoryNameSystemInterfacePrx mnsProxy;
236 component.getProxy(mnsProxy,
mnsName);
237 mns = client::MemoryNameSystem(mnsProxy);
267 MemoryViewer::collapseAll()
273 MemoryViewer::startPeriodicUpdateTimer()
278 const armem::wm::Memory*
279 MemoryViewer::getSingleMemoryData(
const std::string&
memoryName)
284 std::stringstream ss;
285 ss <<
"Memory name '" <<
memoryName <<
"' is unknown. Known are: "
286 << simox::alg::join(simox::alg::get_keys(
memoryData),
", ");
287 statusLabel->setText(QString::fromStdString(ss.str()));
310 if (
std::find(enabledMemories.begin(), enabledMemories.end(), name) ==
311 enabledMemories.end())
320 server::dto::DirectlyStoreInput
input;
321 input.memory = q_res.toIce().memory;
322 reader.directlyStore(
input);
326 std::string
s =
"Query of memory " + name +
" was unsuccessful.";
344 if (
std::find(enabledMemories.begin(), enabledMemories.end(), name) ==
345 enabledMemories.end())
349 reader.startRecording();
365 if (
std::find(enabledMemories.begin(), enabledMemories.end(), name) ==
366 enabledMemories.end())
370 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);
442 QThread* thread =
new QThread;
443 QObject* worker =
new QObject;
445 worker->moveToThread(thread);
450 [
this, thread, worker, directory]()
457 QTimer::singleShot(0,
this, [
this, thread, worker]()
465 worker->deleteLater();
466 thread->deleteLater();
474 MemoryViewer::startQueries()
480 MemoryViewer::processQueryResults()
482 const std::map<std::string, client::QueryResult> results = collectQueryResults();
484 if (results.size() > 0)
488 applyQueryResults(results, &errorCount);
490 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()
836 std::map<std::string, const armem::wm::Memory*> memoriesToUpdate;
843 ARMARX_INFO <<
"updating memory tree for " << name;
844 memoriesToUpdate[name] = &
data;
859 new Variant(GuiUpdateMemoryTree.toMilliSecondsDouble()));
861 catch (
const Ice::Exception&)
875 auto showMenu = [menu, pos]()
888 mns::dto::MemoryServerInterfaces prx;
896 QString::fromStdString(e.
makeMsg(
memoryID,
"Could not resolve memory server.")));
903 std::stringstream ss;
904 ss <<
"Memory server " <<
memoryID <<
" does not support actions or is offline.";
905 statusLabel->setText(QString::fromStdString(ss.str()));
910 actions::GetActionsOutputSeq result;
913 result = prx.actions->getActions({{armarx::toIce<data::MemoryID>(
memoryID)}});
915 catch (
const Ice::LocalException& e)
917 std::stringstream ss;
918 ss <<
"Could not get actions for " <<
memoryID <<
".";
919 statusLabel->setText(QString::fromStdString(ss.str()));
924 if (result.size() == 0)
934 actions::data::ExecuteActionOutputSeq result;
937 result = prx.actions->executeActions(
938 {{armarx::toIce<armem::data::MemoryID>(
memoryID), path}});
940 catch (
const Ice::LocalException& e)
942 std::stringstream ss;
943 ss <<
"Failed to execute action: " << e.what();
944 statusLabel->setText(QString::fromStdString(ss.str()));
947 for (
const auto& [
success, errorMessage] : result)
951 std::stringstream ss;
952 ss <<
"Failed to execute action: " << errorMessage;
953 statusLabel->setText(QString::fromStdString(ss.str()));
962 actionsMenu->exec(pos);
966 menu->addMenu(actionsMenu);
975 const std::string& engineID)
978 std::stringstream errorStream;
979 auto showError = [
this, &errorStream]()
980 {
statusLabel->setText(QString::fromStdString(errorStream.str())); };
984 errorStream <<
"Could not convert " << entityID <<
" to valid entity ID.";
990 errorStream <<
"Not connected to memory '" << entityID.
memoryName
991 <<
"', cannot make prediction.";
998 errorStream <<
"Predictions are not available for memory '" << entityID.
memoryName
1009 result = reader.
predict({request}).at(0);
1011 catch (
const Ice::LocalException& e)
1013 errorStream <<
"Could not make prediction request: " << e.what();
1020 errorStream <<
"Prediction failed: " << result.
errorMessage;
1030 const static std::string CONFIG_KEY_MEMORY =
"MemoryViewer.MemoryNameSystem";
1031 const static std::string CONFIG_KEY_DEBUG_OBSERVER =
"MemoryViewer.DebugObserverName";
1036 mnsName = settings->value(QString::fromStdString(CONFIG_KEY_MEMORY),
"MemoryNameSystem")
1040 settings->value(QString::fromStdString(CONFIG_KEY_DEBUG_OBSERVER),
"DebugObserver")
1048 settings->setValue(QString::fromStdString(CONFIG_KEY_MEMORY),
1049 QString::fromStdString(
mnsName));
1050 settings->setValue(QString::fromStdString(CONFIG_KEY_DEBUG_OBSERVER),
1057 dialog->
addProxyFinder<armarx::armem::mns::MemoryNameSystemInterfacePrx>(
1058 {CONFIG_KEY_MEMORY,
"MemoryNameSystem",
"MemoryNameSystem"});
1060 {CONFIG_KEY_DEBUG_OBSERVER,
"Debug Observer",
"DebugObserver"});