3#include <SimoxUtility/algorithm/get_map_keys_values.h>
10#include <RobotAPI/libraries/ArmarXObjects/aron/ObjectID.aron.generated.h>
16#include <RobotAPI/libraries/armem_objects/aron/ObjectClass.aron.generated.h>
17#include <RobotAPI/libraries/armem_objects/aron/ObjectInstance.aron.generated.h>
19#include <RobotAPI/libraries/armem_robot_state/aron/Robot.aron.generated.h>
20#include <RobotAPI/libraries/armem_robot_state/aron/RobotDescription.aron.generated.h>
33 const std::string prefix = propertyPrefix;
35 def->optional(properties.memoryName, prefix +
"MemoryName");
37 def->optional(properties.coreInstanceSegmentName,
38 prefix +
"CoreSegment",
39 "Name of the memory core segment to use for object instances.");
40 def->optional(properties.coreClassSegmentName,
41 prefix +
"CoreSegment",
42 "Name of the memory core segment to use for object classes.");
46 properties.providerName, prefix +
"write.ProviderName",
"Name of this provider");
53 ARMARX_IMPORTANT <<
"Writer: Waiting for memory '" << properties.memoryName <<
"' ...";
56 memoryWriter = memoryNameSystem.
useWriter(properties.memoryName);
57 memoryReader = memoryNameSystem.
useReader(properties.memoryName);
58 ARMARX_IMPORTANT <<
"Writer: Connected to memory '" << properties.memoryName <<
"'";
66 const auto resultCoreClassSegment =
67 memoryWriter.addSegment(properties.coreClassSegmentName, properties.providerName);
69 const auto resultCoreInstanceSegmentName =
70 memoryWriter.addSegment(properties.coreInstanceSegmentName, properties.providerName);
74 std::optional<armem::MemoryID>
80 const std::unordered_map<std::string, MemoryID> knownObjects = queryDescriptions(
Time::Now());
81 ARMARX_VERBOSE <<
"Known articulated objects " << simox::alg::get_keys(knownObjects);
83 const auto objectId = knownObjects.find(
obj.description.name);
86 if (objectId != knownObjects.end())
88 return objectId->second;
93 throw LocalException(
"articulated object class " +
obj.description.name +
" not found");
96 if (properties.allowClassCreation)
104 std::optional<armem::MemoryID>
107 std::lock_guard g{memoryWriterMutex};
109 ARMARX_DEBUG <<
"Trying to create core segment + provider segment";
113 memoryWriter.addSegment(properties.coreClassSegmentName, properties.providerName);
115 if (not result.success)
117 ARMARX_ERROR <<
"Creating core segment failed. Reason: " << result.errorMessage;
124 const auto entityID =
125 providerId.withEntityName(
obj.description.name).withTimestamp(
timestamp);
128 update.entityID = entityID;
130 arondto::RobotDescription aronArticulatedObjectDescription;
131 toAron(aronArticulatedObjectDescription,
obj.description);
133 update.instancesData = {aronArticulatedObjectDescription.toAron()};
153 return properties.providerName;
159 this->properties.providerName = providerName;
165 std::lock_guard g{memoryWriterMutex};
170 const std::string entityName =
obj.description.name +
"/" +
obj.
instance;
172 ARMARX_DEBUG <<
"Storing articulated object instance '" << entityName <<
"' (provider '"
173 << properties.providerName <<
"')";
181 update.entityID = providerId.withEntityName(entityName);
187 arondto::ObjectInstance objectInstance;
190 const std::optional<armem::MemoryID> classId = storeOrGetClass(
obj);
199 toAron(objectInstance.classID, *classId);
211 <<
"An object instance name must be provided!";
213 armarx::arondto::ObjectID cs;
216 cs.dataset = objectId.
dataset();
218 objectInstance.pose.objectID = cs;
219 objectInstance.pose.providerName = properties.providerName;
220 objectInstance.pose.attachmentValid =
false;
222 objectInstance.pose.isStatic = isStatic;
223 objectInstance.pose.confidence = 1.0;
225 update.instancesData = {objectInstance.toAron()};
244 const std::optional<armem::MemoryID> classId = storeOrGetClass(
obj);
248 ARMARX_WARNING <<
"Could not get class id for object " <<
obj.description.name <<
"! "
249 <<
"Known classes are " << simox::alg::get_keys(queryDescriptions(
Time::Now()));
257 std::optional<robot_state::description::RobotDescription>
262 .getCoreSegment(properties.coreClassSegmentName)
263 .getProviderSegment(properties.providerName);
277 std::unordered_map<std::string, armem::MemoryID>
283 std::unordered_map<std::string, armem::MemoryID> descriptions;
296 const armem::MemoryID snapshotID(sn.
id());
297 descriptions.insert({robotDescription->name, snapshotID});
305 std::unordered_map<std::string, armem::MemoryID>
309 armem::client::query::Builder qb;
319 const armem::client::QueryResult qResult = memoryReader.query(qb.
buildQueryInput());
323 if (not qResult.success)
328 return getRobotDescriptions(qResult.memory);
#define ARMARX_CHECK_NOT_EMPTY(c)
A known object ID of the form "Dataset/ClassName" or "Dataset/ClassName/InstanceName".
std::string className() const
std::string instanceName() const
std::string dataset() const
MemoryID withProviderSegmentName(const std::string &name) const
MemoryID withCoreSegmentName(const std::string &name) const
MemoryID withMemoryName(const std::string &name) const
MemoryID withEntityName(const std::string &name) const
void setEntityID(const MemoryID &id)
MemoryID getEntityID() const
void connect(armem::client::MemoryNameSystem &memoryNameSystem)
bool store(const ArticulatedObject &obj, bool isStatic) const override
bool storeInstance(const ArticulatedObject &obj, bool isStatic) const
std::string getProviderName() const
void setProviderName(const std::string &providerName)
std::optional< armem::MemoryID > storeClass(const ArticulatedObject &obj) const
void registerPropertyDefinitions(armarx::PropertyDefinitionsPtr &def)
EntitySnapshotT & getFirstSnapshot()
Return the snapshot with the least recent timestamp.
EntityInstanceT & getInstance(int index)
Get the given instance.
CoreSegmentT & getCoreSegment(const std::string &name)
The memory name system (MNS) client.
Writer useWriter(const MemoryID &memoryID)
Use a memory server and get a writer for it.
Reader useReader(const MemoryID &memoryID)
Use a memory server and get a reader for it.
QueryInput buildQueryInput() const
CoreSegmentSelector & coreSegments()
Start specifying core segments.
CoreSegmentSelector & withName(const std::string &name) override
ProviderSegmentSelector & providerSegments()
Start specifying provider segments.
EntitySelector & all() override
SnapshotSelector & snapshots()
Start specifying entity snapshots.
EntitySelector & entities()
Start specifying entities.
ProviderSegmentSelector & all() override
SnapshotSelector & beforeTime(Time timestamp, long maxEntries=1)
Indicates that a query to the Memory Name System failed.
Client-side working memory core segment.
Client-side working entity instance.
Client-side working memory.
Client-side working memory provider segment.
Brief description of class memory.
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_INFO
The normal logging level.
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
#define ARMARX_VERBOSE
The logging level for verbose information.
armarx::armem::robot_state::Robot ArticulatedObject
std::optional< robot_state::description::RobotDescription > convertRobotDescription(const armem::wm::EntityInstance &instance)
const ContainerT::EntityInstanceT * findFirstInstance(const ContainerT &container)
armarx::core::time::DateTime Time
void toAron(arondto::MemoryID &dto, const MemoryID &bo)
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Result of an EntityUpdate.
An update of an entity for a specific point in time.
bool forEachEntity(FunctionT &&func)