16#include <Ice/Current.h>
17#include <Ice/Exception.h>
18#include <Ice/LocalException.h>
22#include <ArmarXCore/core/ice_conversions/ice_conversions_templates.tpp>
24#include <ArmarXCore/interface/core/time.h>
38#include <RobotAPI/interface/armem/prediction.h>
39#include <RobotAPI/interface/armem/query.h>
40#include <RobotAPI/interface/armem/server/PredictingMemoryInterface.h>
41#include <RobotAPI/interface/armem/server/ReadingLongTermMemoryInterface.h>
42#include <RobotAPI/interface/armem/server/ReadingMemoryInterface.h>
43#include <RobotAPI/interface/armem/server/RecordingMemoryInterface.h>
44#include <RobotAPI/libraries/armem/aron/MemoryID.aron.generated.h>
45#include <RobotAPI/libraries/armem/aron/MemoryLink.aron.generated.h>
60 server::PredictingMemoryInterfacePrx predictingMemory,
61 server::ReadingLongTermMemoryInterfacePrx readingLtmMemory) :
66 ctx[
"clientPid"] = std::to_string(getpid());
70 this->
readingPrx = readingMemory->ice_context(ctx);
88 armem::query::data::Result
91 armem::query::data::Result result;
95 "Reading interface proxy must be set to perform a query.");
102 catch (const ::Ice::ConnectionRefusedException& e)
107 catch (
const Ice::LocalException& e)
109 std::stringstream sstream;
110 sstream <<
"Memory query failed.\nReason: " << e.what();
111 result.errorMessage = sstream.str();
124 armem::query::data::Result
127 armem::query::data::Result result;
131 "Reading interface proxy must be set to perform a query.");
138 catch (const ::Ice::ConnectionRefusedException& e)
141 ARMARX_INFO <<
"Proxy is invalid. Must reconnect.";
143 catch (
const Ice::LocalException& e)
145 std::stringstream sstream;
146 sstream <<
"Memory query failed.\nReason: " << e.what();
147 result.errorMessage = sstream.str();
157 return this->query(armem::query::data::MemoryQuerySeq{
query}, dataMode);
166 input.dataMode = dataMode;
167 return this->
query(input);
179 int recursionDepth)
const
184 armem::query::data::Result
187 int recursionDepth)
const
192 "Reading interface proxy must be set to perform a query.");
195 armem::query::data::Result result;
202 { resolveMemoryLinks(instance, bObj.
memory,
mns, recursionDepth); });
203 result = bObj.
toIce();
205 catch (
const Ice::LocalException& e)
207 std::stringstream sstream;
208 sstream <<
"Memory query failed.\nReason: " << e.what();
209 result.errorMessage = sstream.str();
213 std::stringstream sstream;
214 sstream <<
"Encountered malformed MemoryLink: " << e.what();
215 result.errorMessage = sstream.str();
224 int recursionDepth)
const
226 return this->query(armem::query::data::MemoryQuerySeq{
query},
mns, recursionDepth);
232 int recursionDepth)
const
236 return this->
query(input,
mns, recursionDepth);
242 int recursionDepth)
const
257 std::optional<std::pair<MemoryID, aron::data::VariantPtr>>
262 static const aron::Path memoryLinkIDPath{{
"memoryID"}};
263 static const aron::Path memoryLinkDataPath{{
"data"}};
264 armem::arondto::MemoryID
dto;
267 dto.fromAron(memoryIDDict);
271 ARMARX_INFO <<
"Encountered unresolvable MemoryID '" << memoryID.
str()
279 ARMARX_WARNING <<
"Could not retrieve data for " << memoryID.
str() <<
", skipping...";
283 if (!nextDataAndType)
286 <<
" not available in memory containing that MemoryID.";
289 auto [nextData, nextType] = nextDataAndType.value();
292 std::string nextObjectName = nextType->getObjectNameWithTemplateInstantiations();
293 if (nextType->getObjectName() != linkTemplate)
296 << nextType->getObjectName() <<
", but the link requires the type "
303 nextData->toAronDTO(),
304 linkData->getPath().withElement(memoryLinkDataPath.toString()))}};
313 static const aron::Path memoryLinkDataPath{{
"data"}};
316 static const std::string linkType =
317 arondto::MemoryLink<arondto::MemoryID>::ToAronType()->getFullName();
319 std::set<armem::MemoryID> seenIDs{instance.
id()};
320 std::vector<aron::Path> currentPaths{{{
""}}};
321 std::vector<aron::Path> nextPaths;
327 ARMARX_INFO <<
"Instance '" << instance.
id().
str() <<
"' does not have a defined type.";
330 auto [instanceData, instanceType] = dataAndType.value();
331 while (!currentPaths.empty() && (recursionDepth == -1 || depth < recursionDepth))
333 for (
const auto& path : currentPaths)
335 aron::SubObjectFinder finder(linkType);
336 if (path.getFirstElement().empty())
343 instanceData->navigateAbsolute(path),
344 instanceType->navigateAbsolute(path));
347 for (
auto& [linkPathStr, linkDataAndType] : finder.getFoundObjects())
349 auto [linkData, linkType] = linkDataAndType;
353 auto [
memoryID, dataToAppend] = result.value();
354 if (seenIDs.find(memoryID) != seenIDs.end())
358 seenIDs.insert(memoryID);
361 memoryLinkDataPath.toString(), dataToAppend);
363 linkData->getPath().withElement(memoryLinkDataPath.toString()));
367 currentPaths = std::move(nextPaths);
384 if (
id.hasTimestamp())
396 std::optional<wm::EntitySnapshot>
399 std::vector<MemoryID> snapshotIDs = _snapshotIDs;
405 for (
const MemoryID& snapshotID : snapshotIDs)
420 ARMARX_INFO <<
"Error querying " << snapshotIDs.size() <<
" STT snapshots:\n"
430 if (!
id.isWellDefined())
439 ?
core.providerSegments(withID(
id))
440 :
core.providerSegments(all());
448 std::optional<wm::EntitySnapshot>
454 std::optional<wm::EntitySnapshot> latest = std::nullopt;
458 if (not entity.
empty())
461 if (not latest.has_value() or latest->time() < snapshot.
time())
472 ARMARX_INFO <<
"Error querying latest snapshot in " << id;
485 return this->
query(qb);
496 return this->
query(qb);
499 server::dto::DirectlyStoreResult
502 server::RecordingMemoryInterfacePrx storingMemoryPrx =
503 server::RecordingMemoryInterfacePrx::checkedCast(
readingPrx);
504 if (storingMemoryPrx)
506 return storingMemoryPrx->directlyStore(input);
510 ARMARX_WARNING <<
"Could not store a query into the LTM. It seems like the Memory does "
511 "not implement the StoringMemoryInterface.";
519 server::RecordingMemoryInterfacePrx storingMemoryPrx =
520 server::RecordingMemoryInterfacePrx::checkedCast(
readingPrx);
521 if (storingMemoryPrx)
523 server::dto::StartRecordInput i;
524 i.executionTime = armarx::core::time::dto::DateTime();
525 i.startTime = armarx::core::time::dto::DateTime();
527 i.configuration.clear();
533 storingMemoryPrx->begin_startRecord(i);
538 ARMARX_WARNING <<
"Could not store a query into the LTM. It seems like the Memory does "
539 "not implement the StoringMemoryInterface.";
546 server::RecordingMemoryInterfacePrx storingMemoryPrx =
547 server::RecordingMemoryInterfacePrx::checkedCast(
readingPrx);
548 if (storingMemoryPrx)
554 storingMemoryPrx->begin_stopRecord();
559 ARMARX_WARNING <<
"Could not store a query into the LTM. It seems like the Memory does "
560 "not implement the StoringMemoryInterface.";
576 std::vector<PredictionResult>
582 "PredictingMemoryInterfacePrx",
583 "Prediction interface proxy must be set to request a prediction.");
586 armem::prediction::data::PredictionRequestSeq iceRequests;
587 for (
const auto& request : requests)
589 iceRequests.push_back(request.toIce());
592 armem::prediction::data::PredictionResultSeq results;
597 catch (
const Ice::LocalException& e)
599 armem::prediction::data::PredictionResult
failure;
601 std::stringstream sstream;
602 sstream <<
"Prediction request failed. Reason: " << e.what();
603 failure.errorMessage = sstream.str();
605 for (
size_t i = 0; i < requests.size(); ++i)
611 std::vector<PredictionResult> boResults;
612 for (
const auto& result : results)
620 std::map<MemoryID, std::vector<PredictionEngine>>
626 "PredictingMemoryInterfacePrx",
627 "Prediction interface proxy must be set to request a prediction.");
630 armem::prediction::data::EngineSupportMap engines;
635 catch (
const Ice::LocalException& e)
640 std::map<MemoryID, std::vector<PredictionEngine>> boMap;
bool isWellDefined() const
Indicate whether this ID is well-defined.
bool hasEntityName() const
std::string str(bool escapeDelimiters=true) const
Get a string representation of this memory ID.
The memory name system (MNS) client.
void stopRecording() const
std::map< MemoryID, std::vector< PredictionEngine > > getAvailablePredictionEngines() const
Get the list of prediction engines supported by the memory.
QueryResult query(const QueryInput &input) const
Perform a query on the WM.
std::optional< wm::EntitySnapshot > getLatestSnapshotIn(const MemoryID &id, armem::query::DataMode dataMode=armem::query::DataMode::WithData) const
Get the latest snapshot under the given memory ID.
Reader(const Reader &)=default
Construct a memory reader.
server::ReadingMemoryInterfacePrx readingPrx
void startRecording() const
QueryResult getLatestSnapshotsIn(const MemoryID &id, armem::query::DataMode dataMode=armem::query::DataMode::WithData) const
Get the latest snapshots under the given memory ID.
QueryResult getAll(armem::query::DataMode dataMode=armem::query::DataMode::WithData) const
Get the whole memory content.
QueryResult queryMemoryIDs(const std::vector< MemoryID > &ids, armem::query::DataMode dataMode=armem::query::DataMode::WithData) const
Query a specific set of memory IDs.
void setReadingMemory(server::ReadingMemoryInterfacePrx readingMemory)
void setPredictingMemory(server::PredictingMemoryInterfacePrx predictingMemory)
server::dto::DirectlyStoreResult directlyStore(const server::dto::DirectlyStoreInput &input) const
std::vector< PredictionResult > predict(const std::vector< PredictionRequest > &requests) const
Get a prediction for the state of multiple entity instances in the future.
server::PredictingMemoryInterfacePrx predictionPrx
QueryResult getAllLatestSnapshots(armem::query::DataMode dataMode=armem::query::DataMode::WithData) const
Get all latest snapshots in the memory.
QueryResult queryLTM(const QueryInput &input, bool storeIntoWM=false) const
Queries the linked ltms.
server::ReadingLongTermMemoryInterfacePrx readingLtmPrx
std::optional< wm::EntitySnapshot > getLatestSnapshotOf(const std::vector< MemoryID > &snapshotIDs) const
Query the given snapshot and return the latest existing snapshot.
The query::Builder class provides a fluent-style specification of hierarchical queries.
QueryInput buildQueryInput() const
CoreSegmentSelector & coreSegments()
Start specifying core segments.
ProviderSegmentSelector & providerSegments()
Start specifying provider segments.
SnapshotSelector & snapshots()
Start specifying entity snapshots.
EntitySelector & entities()
Start specifying entities.
Base class for all exceptions thrown by the armem library.
Indicates that a memory ID is invalid, e.g.
Indicates that a proxy required for an operation wasn't usable.
Client-side working entity instance.
Client-side working memory.
static VariantPtr FromAronDTO(const data::dto::GenericDataPtr &, const Path &=Path())
create a variant from a dto object
static PointerType DynamicCastAndCheck(const VariantPtr &n)
static std::shared_ptr< Object > DynamicCastAndCheck(const VariantPtr &n)
This exception is thrown if the macro ARMARX_CHECK_EXPRESSION is used.
#define ARMARX_INFO
The normal logging level.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
#define ARMARX_VERBOSE
The logging level for verbose information.
This file is part of ArmarX.
std::optional< std::pair< MemoryID, aron::data::VariantPtr > > findDataForLink(const aron::data::VariantPtr &linkData, const aron::type::VariantPtr &linkType, armem::client::MemoryNameSystem &mns)
Get the MemoryID and data required to fill in the given MemoryLink.
query::Builder QueryBuilder
armem::wm::EntitySnapshot EntitySnapshot
bool compareTimestampDecreasing(const MemoryID &lhs, const MemoryID &rhs)
lhs.timestamp > rhs.timstamp
std::optional< std::pair< armarx::aron::data::DictPtr, armarx::aron::type::ObjectPtr > > extractDataAndType(const armarx::armem::wm::Memory &memory, const armarx::armem::MemoryID &memoryID)
get the data and type of the given MemoryID in the given Memory.
std::optional< armarx::armem::wm::Memory > resolveID(armarx::armem::client::MemoryNameSystem &mns, const armarx::armem::MemoryID &memoryID)
resolve a single MemoryID with the given MemoryNameSystem.
std::shared_ptr< Variant > VariantPtr
void visitRecursive(RecursiveVisitorImplementation &v, typename RecursiveVisitorImplementation::Input &o)
std::shared_ptr< Variant > VariantPtr
void fromAron(const T &dto, T &bo)
void fromIce(const std::map< IceKeyT, IceValueT > &iceMap, boost::container::flat_map< CppKeyT, CppValueT > &cppMap)
static PredictionResult fromIce(const armem::prediction::data::PredictionResult &ice)
bool forEachInstance(InstanceFunctionT &&func)
bool forEachEntity(FunctionT &&func)
auto & getSnapshot(const MemoryID &snapshotID)
Retrieve an entity snapshot.
auto & getLatestSnapshot(int snapshotIndex=0)
Retrieve the latest entity snapshot.
wm::Memory memory
The slice of the memory that matched the query.
static QueryResult fromIce(const armem::query::data::Result &ice)
armem::query::data::Result toIce() const