WorkingMemoryExample.cpp
Go to the documentation of this file.
1/*
2* This file is part of ArmarX.
3*
4* ArmarX is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License version 2 as
6* published by the Free Software Foundation.
7*
8* ArmarX is distributed in the hope that it will be useful, but
9* WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program. If not, see <http://www.gnu.org/licenses/>.
15*
16* @package MemoryX::WorkingMemoryExample
17* @author (kozlov at kit dot edu)
18* @date 2012
19* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20* GNU General Public License
21*/
22
24
25#include <fstream>
26#include <thread>
27
29
31
34#include <MemoryX/interface/memorytypes/MemoryEntities.h>
39
40namespace memoryx
41{
42 void
44 {
45 std::cout << "onInitComponent" << std::endl;
46
47 usingProxy("WorkingMemory");
48 usingProxy("LongtermMemory");
49 usingProxy("RobotStateComponent");
50
51
52 // don't request topic here, see below why
53 // usingTopic("WorkingMemoryUpdates");
54
55 testToRun = getProperty<std::string>("TestToRun").getValue();
56 }
57
58 void
60 {
61 std::cout << "onStartComponent" << std::endl;
62
63 std::cout << "Starting WorkingMemoryExample" << std::endl;
64
65 const Ice::CommunicatorPtr ic = getIceManager()->getCommunicator();
66
67 memoryPrx = getProxy<WorkingMemoryInterfacePrx>("WorkingMemory");
68 longtermMemoryPrx = getProxy<LongtermMemoryInterfacePrx>("LongtermMemory");
69 robotStateComponentPrx =
71
72 // load snapshot, if specified
73 const std::string snapshotName = getProperty<std::string>("SnapshotName").getValue();
74 ARMARX_INFO << "Snapshot name: " << snapshotName;
75
76 if (!snapshotName.empty())
77 {
78 longtermMemoryPrx->loadWorkingMemorySnapshot(snapshotName, memoryPrx);
79 ARMARX_INFO << "Snapshot succcessfully loaded: " << snapshotName;
80 }
81 else
82 {
83 ARMARX_ERROR << "SnapshotName parameter must be specified!";
84 }
85
86 if (testToRun == "UpdateNotifications")
87 {
88 // Note, that all topics that have been spcified in onInitComponent are registered *after* the onConnectComponent method.
89 // So for this special test case where the topic is neede within the onConnectComponent method we must subscribe "by hand" in this method
90 // to be sure that the topic is available for our testcase.
91 usingTopic("WorkingMemoryUpdates");
92 testUpdateObserver();
93 }
94 else if (testToRun == "FileTransfer")
95 {
96 testFileTransfer();
97 }
98 else if (testToRun == "ObjectMove")
99 {
100 testObjectMovement();
101 }
102 else if (testToRun == "SnapshotLoad")
103 {
104 testSnapshots();
105 }
106 else if (testToRun == "CommonPlaces")
107 {
108 testCommonPlaces();
109 }
110 else if (testToRun == "Agent")
111 {
112 testAgent();
113 }
114 else
115 {
116 std::cout << "Unknown test name: " << testToRun << std::endl;
117 }
118 }
119
120 void
121 WorkingMemoryExample::reportEntityCreated(const std::string& segmentName,
122 const memoryx::EntityBasePtr& entity,
123 const Ice::Current&)
124 {
125 std::cout << "Entity created: " << EntityPtr::dynamicCast(entity) << std::endl << std::endl;
126 }
127
128 void
129 WorkingMemoryExample::reportEntityUpdated(const std::string& segmentName,
130 const memoryx::EntityBasePtr& entityOld,
131 const memoryx::EntityBasePtr& entityNew,
132 const Ice::Current&)
133 {
134 std::cout << "Entity changed: " << std::endl;
135 std::cout << "Old: " << EntityPtr::dynamicCast(entityOld) << std::endl;
136 std::cout << "New: " << EntityPtr::dynamicCast(entityNew) << std::endl << std::endl;
137 }
138
139 void
140 WorkingMemoryExample::reportEntityRemoved(const std::string& segmentName,
141 const memoryx::EntityBasePtr& entity,
142 const Ice::Current&)
143 {
144 std::cout << "Entity removed: id = " << entity->getId() << std::endl << std::endl;
145 }
146
147 void
148 WorkingMemoryExample::reportSnapshotLoaded(const std::string& segmentName, const Ice::Current&)
149 {
150 std::cout << "Snapshot loaded!" << std::endl << std::endl;
151 }
152
153 void
154 WorkingMemoryExample::reportMemoryCleared(const std::string& segmentName, const Ice::Current&)
155 {
156 std::cout << "Scene cleared!" << std::endl << std::endl;
157 }
158
159 void
160 WorkingMemoryExample::testFileTransfer()
161 {
162 ObjectInstanceMemorySegmentBasePrx objectInstancesMemoryPrx =
163 memoryPrx->getObjectInstancesSegment();
164 GridFileManagerPtr fileManager(new GridFileManager(memoryPrx->getCommonStorage()));
165
166 int ivCount = 0;
167 size_t totalBytes = 0;
168 EntityIdList ids = objectInstancesMemoryPrx->getAllEntityIds();
169
170 for (EntityIdList::const_iterator it = ids.begin(); it != ids.end(); ++it)
171 {
172 const EntityBasePtr obj = objectInstancesMemoryPrx->getEntityById(*it);
173
174 if (obj->hasAttribute("IvFile"))
175 {
176
177 std::ifstream fs;
178 fileManager->getFileStream(obj->getAttribute("IvFile"), fs);
179
180 char ivFile[128];
181 fs.getline(ivFile, 128);
182
183 std::cout << ivFile << std::endl;
184
185 ivCount++;
186 // totalBytes += datalen;
187 }
188 }
189
190 std::cout << "# of fetched iv-files: " << ivCount << std::endl;
191 std::cout << "Bytes transfered: " << totalBytes << std::endl;
192 }
193
194 void
195 WorkingMemoryExample::testUpdateObserver()
196 {
197 const Ice::CommunicatorPtr ic = getIceManager()->getCommunicator();
198 ObjectInstanceMemorySegmentBasePrx objectInstancesMemoryPrx =
199 memoryPrx->getObjectInstancesSegment();
200 RelationMemorySegmentBasePrx relationsMemoryPrx = memoryPrx->getRelationsSegment();
201
202 ObjectInstancePtr cup = new ObjectInstance("cup1");
203 cup->putAttribute("Weight", 0.3f, new UnivariateNormalDistribution(0.3f, 0.5f));
204 cup->putAttribute("Description", "my favourite cup");
205
206 cup->addClass("Cup", 0.6f);
207 cup->addClass("Mug", 0.4f);
208 std::string cupId = objectInstancesMemoryPrx->addEntity(cup);
209
210 cup->setId(cupId);
211 std::cout << "Stored object " << cup->getName() << " in WorkingMemory with id = " << cupId
212 << std::endl;
213 std::cout << "Most probable class is <" << cup->getMostProbableClass()
214 << "> with prob = " << cup->getClassProbability(cup->getMostProbableClass())
215 << std::endl;
216
217 Eigen::Vector3f posVec(1., 2., 3.);
219 new armarx::FramedPosition(posVec, armarx::GlobalFrame, "");
220 cup->setPosition(curPos);
221
222 FloatVector posStdVec(posVec.data(), posVec.data() + 3);
224 posDist->setMean(posStdVec);
225 posDist->setCovariance(0, 0, 0.5);
226 posDist->setCovariance(1, 1, 0.5);
227 posDist->setCovariance(2, 2, 0.5);
228 cup->setPositionUncertainty(posDist);
229
230 objectInstancesMemoryPrx->updateEntity(cupId, cup);
231 std::cout << "Updated object " << cup->getName() << " in WorkingMemory with id = " << cupId
232 << std::endl;
233
234 ObjectInstancePtr cupClone = ObjectInstancePtr::dynamicCast(cup->ice_clone());
235 std::cout << "Cloned object: " << cupClone << std::endl;
236
237 ObjectInstancePtr fridge = new ObjectInstance("Fridge");
238 fridge->setClass("Fridge", 1.f);
239 const std::string fridgeId = objectInstancesMemoryPrx->addEntity(fridge);
240
241 std::cout << "Stored object " << fridge->getName()
242 << " in WorkingMemory with id = " << fridgeId << std::endl;
243
244 EntityPtr juice = new ObjectInstance("Juice");
245 const std::string juiceId = objectInstancesMemoryPrx->addEntity(juice);
246
247 std::cout << "Stored object " << juice->getName()
248 << " in WorkingMemory with id = " << juiceId << std::endl;
249
250 EntityRefBasePtr cupRef = objectInstancesMemoryPrx->getEntityRefById(cupId);
251 ARMARX_CHECK_EXPRESSION(cupRef->entityId == cupId);
252 EntityRefBasePtr fridgeRef = objectInstancesMemoryPrx->getEntityRefById(fridgeId);
253 EntityRefBasePtr juiceRef = objectInstancesMemoryPrx->getEntityRefById(juiceId);
254
255 RelationBasePtr rel1 = new Relation("isIn", {cupRef, fridgeRef});
256 relationsMemoryPrx->addEntity(rel1);
257
258 RelationBasePtr rel2 = new Relation("isIn", {juiceRef, fridgeRef}, true, 0.7);
259 relationsMemoryPrx->addEntity(rel2);
260
261 RelationList rels = relationsMemoryPrx->getRelationsByEntityId(cupRef->entityId);
262 std::cout << "Found relations: " << rels.size() << std::endl;
263
264 for (RelationList::const_iterator it = rels.begin(); it != rels.end(); ++it)
265 {
266 RelationBasePtr relation = *it;
267 std::cout << relation->getName() << ": " << std::endl;
268
269 for (EntityRefBasePtr entityRef : relation->getEntities())
270 {
271 std::cout << " * " << entityRef->entityName << std::endl;
272 }
273 }
274
275
276 memoryPrx->print();
277
278 // memoryPrx->saveSnapshot("snapshot1");
279
280 // memoryPrx->removeObject(fridgeId);
281
282 /* EntityBasePtr cup2 = memoryPrx->getObjectById(cupId);
283 // SceneEntityPtr cup22 = SceneEntityPtr::dynamicCast(cup2);
284
285 armarx::JSONObjectPtr jsonSerializer = new armarx::JSONObject(ic);
286 cup2->serialize(jsonSerializer);
287 const std::string jsonString = jsonSerializer->asString(true);
288 // std::cout << "JSON for cup: " << jsonString << std::endl << std::endl;
289
290 armarx::JSONObjectPtr jsonDeserializer = new armarx::JSONObject(ic);
291 jsonDeserializer->fromString(jsonString);
292 EntityBasePtr newCup = new ObjectInstance();
293 newCup->deserialize(jsonDeserializer);
294
295 jsonSerializer = new armarx::JSONObject(ic);
296 newCup->serialize(jsonSerializer);*/
297 // std::cout << "cup deserialized from JSON: " << jsonSerializer->toString() << std::endl << std::endl;
298
299 // memoryPrx->removeAll();
300 // memoryPrx->saveSnapshot("db_alex.objects");
301
302 // memoryPrx->printMemory();
303 }
304
305 void
306 WorkingMemoryExample::testObjectMovement()
307 {
308 ObjectInstanceMemorySegmentBasePrx objectInstancesMemoryPrx =
309 memoryPrx->getObjectInstancesSegment();
310
311 ObjectInstancePtr cup = new ObjectInstance("cup");
312 cup->setClass("cup", 1.f);
313
314 Eigen::Vector3f posVec(-5000., 2500, 1000.);
316 new armarx::FramedPosition(posVec, armarx::GlobalFrame, "");
317 cup->setPosition(curPos);
318
319 FloatVector posStdVec(posVec.data(), posVec.data() + 3);
321 posDist->setMean(posStdVec);
322 posDist->setCovariance(0, 0, 80.);
323 posDist->setCovariance(1, 1, 20.);
324 posDist->setCovariance(2, 2, 200.);
325 cup->setPositionUncertainty(posDist);
326
327 Eigen::Quaternionf quat(0., 0., 0., 1.);
328 armarx::FramedOrientationBasePtr orient =
329 new armarx::FramedOrientation(quat.toRotationMatrix(), armarx::GlobalFrame, "");
330 cup->setOrientation(orient);
331
332 cup->putAttribute("Weight", 0.3f, new UnivariateNormalDistribution(0.3f, 0.01f));
333
334 const std::string cupId = objectInstancesMemoryPrx->addEntity(cup);
335 cup->setId(cupId);
336
337 memoryPrx->print();
338
339 // this attribute, while not present in current observation,
340 // must be copied from old object instance by AttributeReplacementFusion
341 cup->removeAttribute("Weight");
342
343 std::this_thread::sleep_for(std::chrono::milliseconds(3000));
344
345 for (int i = 0; i < 500; ++i)
346 {
347 curPos->x += 10;
348 posStdVec[0] = curPos->x;
349 posDist->setMean(posStdVec);
350 cup->setPosition(curPos);
351 cup->setPositionUncertainty(posDist);
352 cup->setExistenceCertainty(i / 500.);
353 objectInstancesMemoryPrx->updateEntity(cupId, cup);
354 std::this_thread::sleep_for(std::chrono::milliseconds(100));
355 ARMARX_INFO_S << "Moving Object to " << curPos->toEigen();
356 }
357
358 std::this_thread::sleep_for(std::chrono::milliseconds(10000));
359 objectInstancesMemoryPrx->removeEntity(cupId);
360 }
361
362 void
363 WorkingMemoryExample::testSnapshots()
364 {
365 ARMARX_INFO << "Content of memory after loading snapshot: ";
366 memoryPrx->print();
367 }
368
369 void
370 WorkingMemoryExample::testCommonPlaces()
371 {
372 ObjectInstanceMemorySegmentBasePrx objectInstancesMemoryPrx =
373 memoryPrx->getObjectInstancesSegment();
374
375 const std::string snapshotName =
376 getProperty<std::string>("CommonPlacesSnapshot").getValue();
377 WorkingMemorySnapshotInterfacePrx snapshot =
378 longtermMemoryPrx->getWorkingMemorySnapshotListSegment()->openSnapshot(snapshotName);
379 PersistentEntitySegmentBasePrx segObjects = snapshot->getSegment("objectInstances");
380
381 if (segObjects)
382 {
383 EntityIdList ids = segObjects->getAllEntityIds();
384
385 for (EntityIdList::const_iterator it = ids.begin(); it != ids.end(); ++it)
386 {
387 objectInstancesMemoryPrx->addEntity(segObjects->getEntityById(*it));
388 }
389 }
390 }
391
392 void
393 WorkingMemoryExample::testAgent()
394 {
395 AgentInstancesSegmentBasePrx agentsMemoryPrx = memoryPrx->getAgentInstancesSegment();
396
397 Ice::CommunicatorPtr iceCommunicator = getIceManager()->getCommunicator();
398 Eigen::Vector3f positionVector(0.0, 0.0, 0.0);
399 armarx::FramedPositionPtr currentPosition =
400 new armarx::FramedPosition(positionVector, armarx::GlobalFrame, "");
401 Eigen::Quaternionf quaternion(0.0, -1.0, 0.0, 1.0);
402 quaternion.normalize();
403 armarx::FramedOrientationBasePtr currentOrientation =
404 new armarx::FramedOrientation(quaternion.toRotationMatrix(), armarx::GlobalFrame, "");
405
406 auto robot = robotStateComponentPrx->getSynchronizedRobot();
407 AgentInstancePtr agent = new AgentInstance(robot->getName());
408 agent->setSharedRobot(robot);
409 agent->setStringifiedSharedRobotInterfaceProxy(iceCommunicator->proxyToString(robot));
410 agent->setAgentFilePath("Armar3/robotmodel/ArmarIII.xml");
411 agent->setOrientation(currentOrientation);
412 agent->setPosition(currentPosition);
413
414 std::string agentId = agentsMemoryPrx->addEntity(agent);
415
416 std::cout << "Agent Armar3 created in AgentInstancesSegment of WorkingMemory" << std::endl;
417
418 std::this_thread::sleep_for(std::chrono::milliseconds(3000));
419
420 for (int i = 0; i < 500; ++i)
421 {
422 currentPosition->x += 10;
423 agent->setPosition(currentPosition);
424 agentsMemoryPrx->updateEntity(agentId, agent);
425 std::this_thread::sleep_for(std::chrono::milliseconds(100));
426 }
427 }
428
429 void
431 {
432 ARMARX_INFO << "Snapshot completely loaded!";
433 }
434
435} // namespace memoryx
constexpr T c
Property< PropertyType > getProperty(const std::string &name)
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
IceManagerPtr getIceManager() const
Returns the IceManager.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
GridFileManager provides utility functions for working with files in Mongo GridFS and links to them s...
void onInitComponent() override
Pure virtual hook for the subclass.
void reportSnapshotLoaded(const std::string &segmentName, const ::Ice::Current &=Ice::emptyCurrent) override
void reportSnapshotCompletelyLoaded(const Ice::Current &c=Ice::emptyCurrent) override
void reportEntityRemoved(const std::string &segmentName, const ::memoryx::EntityBasePtr &entity, const ::Ice::Current &=Ice::emptyCurrent) override
void reportEntityUpdated(const std::string &segmentName, const ::memoryx::EntityBasePtr &entityOld, const ::memoryx::EntityBasePtr &entityNew, const ::Ice::Current &=Ice::emptyCurrent) override
void reportEntityCreated(const std::string &segmentName, const ::memoryx::EntityBasePtr &entity, const ::Ice::Current &=Ice::emptyCurrent) override
void onConnectComponent() override
Pure virtual hook for the subclass.
void reportMemoryCleared(const std::string &segmentName, const ::Ice::Current &=Ice::emptyCurrent) override
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_INFO_S
Definition Logging.h:202
std::string const GlobalFrame
Variable of the global coordinate system.
Definition FramedPose.h:65
Quaternion< float, 0 > Quaternionf
::IceInternal::Handle<::Ice::Communicator > CommunicatorPtr
Definition IceManager.h:49
const armarx::VariantTypeId MultivariateNormalDistribution
const armarx::VariantTypeId UnivariateNormalDistribution
::std::vector<::Ice::Float > FloatVector
IceInternal::Handle< FramedPosition > FramedPositionPtr
Definition FramedPose.h:149
VirtualRobot headers.
IceInternal::Handle< AgentInstance > AgentInstancePtr
Typedef of AgentEntityPtr as IceInternal::Handle<AgentEntity> for convenience.
IceInternal::Handle< ObjectInstance > ObjectInstancePtr
IceInternal::Handle< MultivariateNormalDistribution > MultivariateNormalDistributionPtr
IceInternal::Handle< Entity > EntityPtr
Typedef of EntityPtr as IceInternal::Handle<Entity> for convenience.
Definition Entity.h:45
std::shared_ptr< GridFileManager > GridFileManagerPtr