WorkingMemoryController.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package MemoryX::gui-plugins::SceneEditor
19 * @date 2015
20 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
21 * GNU General Public License
22 */
23
24#include <stdexcept>
25#include <string>
26#include <vector>
27
28#include <IceUtil/UUID.h>
29
30// Coin3D
31#include <Inventor/SbRotation.h>
32#include <Inventor/SbVec3f.h>
33
34// MemoryXInterface
39#include <MemoryX/interface/components/WorkingMemoryInterface.h>
40#include <MemoryX/interface/memorytypes/MemorySegments.h>
42
44 const memoryx::WorkingMemoryInterfacePrx& workingMemoryPrx,
45 const std::string& workingMemoryUpdatesTopic,
46 const std::string& objectInstancesSegmentName,
47 const memoryxcontroller::MemoryXControllerPtr& memoryXController) :
48 workingMemoryPrx(workingMemoryPrx), workingMemoryUpdatesTopic(workingMemoryUpdatesTopic)
49
50{
51 this->objectInstancesPrx = memoryx::ObjectInstanceMemorySegmentBasePrx::uncheckedCast(
52 workingMemoryPrx->getSegment(objectInstancesSegmentName));
53 this->memoryXController = memoryXController;
54
55 std::string s1 = "SceneEditor.WorkingMemoryController";
56 std::string s2 = IceUtil::generateUUID();
57
58 this->setName(s1 + s2);
59}
60
64
65std::string
67 const std::string& objectName,
68 const memoryx::ObjectClassPtr& objectClassPtr)
69{
70 memoryx::ObjectInstancePtr newObject = new memoryx::ObjectInstance(objectName);
71 memoryx::NameList attributeNames = objectClassPtr->getAttributeNames();
72
73 for (memoryx::NameList::const_iterator it = attributeNames.begin(); it != attributeNames.end();
74 ++it)
75 {
76 newObject->putAttribute(objectClassPtr->getAttribute(*it));
77 }
78
79 newObject->setClass(objectClassPtr->getName(), 1.0f);
80 newObject->setExistenceCertainty(1.0f);
81
82 this->currentChangedInstances.push_back(newObject);
83
84 std::string objectID = this->objectInstancesPrx->addEntity(newObject);
85 newObject->setId(objectID);
86
87 return objectID;
88}
89
90std::vector<std::string>
92 const std::vector<memoryx::ObjectInstancePtr>& objectInstances)
93{
94 std::vector<std::string> addedIds;
95
96 if (!objectInstances.empty())
97 {
98 std::shared_ptr<std::vector<controller::OperationPtr>> operations(
99 new std::vector<controller::OperationPtr>());
100
101 if (std::shared_ptr<memoryxcontroller::MemoryXController> memXController =
102 this->memoryXController.lock())
103 {
104 if (controller::ControllerPtr controller = memXController->getController())
105 {
106 for (std::vector<memoryx::ObjectInstancePtr>::const_iterator it =
107 objectInstances.begin();
108 it != objectInstances.end();
109 ++it)
110 {
111 memoryx::ObjectInstancePtr objectInstance = *it;
112
113 auto pose = objectInstance->getPose();
114
115 if (pose->getFrame() != armarx::GlobalFrame && !pose->frame.empty())
116 {
117 // FIXME: The localization timestamp is ignored.
118 // This causes stuttering objects during robot motion
119 auto newPose =
120 workingMemoryPrx->getAgentInstancesSegment()->convertToWorldPose(
121 pose->agent, pose);
122
123 if (newPose)
124 {
125 objectInstance->setPose(newPose);
126 }
127 else
128 {
129 ARMARX_ERROR_S << "could not convert local pose to global pose"
130 << std::endl;
131 }
132 }
133
134 this->currentChangedInstances.push_back(objectInstance);
135 std::string objectID = this->objectInstancesPrx->addEntity(objectInstance);
136 objectInstance->setId(objectID);
137
138 addedIds.push_back(objectID);
139
141 memXController,
142 controller->getScene(),
143 objectInstance->getName(),
144 memXController->getPriorKnowlegdeController()->getCollection(
145 objectInstance),
146 getSbVec3fFromInstance(objectInstance),
147 getSbRotationFromInstance(objectInstance),
148 objectInstance->getId()));
149
150 operations->push_back(operation);
151 }
152
155 operations);
156 }
157 }
158 }
159
160 return addedIds;
161}
162
163void
165{
166 if (this->objectInstancesPrx->getEntityById(id))
167 {
168
169 this->currentChangedInstances.push_back(
170 memoryx::ObjectInstancePtr::dynamicCast(this->objectInstancesPrx->getEntityById(id)));
171
172 this->objectInstancesPrx->removeEntity(id);
173 }
174 else
175 {
176 throw std::invalid_argument("There is no objectInstance with given ID.");
177 }
178}
179
180void
182 const SbRotation& newOrientation,
183 const SbVec3f& newPosition)
184{
185 memoryx::ObjectInstanceBasePtr objectBase = this->objectInstancesPrx->getObjectInstanceById(id);
186
187 if (objectBase)
188 {
189
190 memoryx::ObjectInstancePtr object = memoryx::ObjectInstancePtr::dynamicCast(objectBase);
191
192 float x, y, z;
193 newPosition.getValue(x, y, z);
194 // The new position values have to be multiplied with 1000 because in the workingmemory the unit the position is stored is meter
195 // and in this local coin-scene the unit is millimeter.
196 const Eigen::Vector3f vec(x * 1000.0f, y * 1000.0f, z * 1000.0f);
198 object->setPosition(newPos);
199
200 float pw, px, py, pz;
201 newOrientation.getValue(px, py, pz, pw);
202 Eigen::Quaternionf quat(pw, px, py, pz);
204 new armarx::FramedOrientation(quat.toRotationMatrix(), armarx::GlobalFrame, "");
205 object->setOrientation(newOrient);
206
207 this->currentChangedInstances.push_back(object);
208
209 this->objectInstancesPrx->setObjectPoseWithoutMotionModel(id, object->getPose());
210 }
211 else
212 {
213 throw std::invalid_argument("There is no objectInstance with given ID.");
214 }
215}
216
217void
219{
220 if (std::shared_ptr<memoryxcontroller::MemoryXController> memXController =
221 this->memoryXController.lock())
222 {
223 if (controller::ControllerPtr controller = memXController->getController())
224 {
225 std::unique_lock lock(mutexEntities);
226
227 memoryx::EntityIdList ids = this->objectInstancesPrx->getAllEntityIds();
228 std::shared_ptr<std::vector<controller::OperationPtr>> operations(
229 new std::vector<controller::OperationPtr>());
230
231 for (memoryx::EntityIdList::const_iterator it = ids.begin(); it != ids.end(); ++it)
232 {
233 memoryx::ObjectInstancePtr object = memoryx::ObjectInstancePtr::dynamicCast(
234 this->objectInstancesPrx->getObjectInstanceById(*it));
235
236 auto pose = object->getPose();
237
238 if (pose->getFrame() != armarx::GlobalFrame && !pose->frame.empty())
239 {
240 auto newPose = workingMemoryPrx->getAgentInstancesSegment()->convertToWorldPose(
241 pose->agent, pose);
242
243 if (newPose)
244 {
245 object->setPose(newPose);
246 }
247 else
248 {
249 ARMARX_ERROR_S << "could not convert local pose to global pose"
250 << std::endl;
251 }
252 }
253
255 memXController,
256 controller->getScene(),
257 object->getName(),
258 memXController->getPriorKnowlegdeController()->getCollection(object),
261 object->getId()));
262 operations->push_back(operation);
263 }
264
266 }
267 }
268}
269
270void
272 const std::string& segmentName,
273 const memoryx::EntityBasePtr& entity,
274 const Ice::Current&)
275{
276 if (0 == objectInstancesPrx->getIceId().name.compare(
277 objectInstancesPrx->getIceId().name.length() - segmentName.length(),
278 segmentName.length(),
279 segmentName))
280 {
281 memoryx::ObjectInstancePtr ptr = memoryx::ObjectInstancePtr::dynamicCast(entity);
282
283 auto pose = ptr->getPose();
284
285 if (pose->getFrame() != armarx::GlobalFrame && !pose->frame.empty())
286 {
287 auto newPose =
288 workingMemoryPrx->getAgentInstancesSegment()->convertToWorldPose(pose->agent, pose);
289
290 if (newPose)
291 {
292 ptr->setPose(newPose);
293 }
294 else
295 {
296 ARMARX_ERROR_S << "could not convert local pose to global pose" << std::endl;
297 }
298 }
299
300 if (!(this->findAndRemoveInstanceFromList(this->currentChangedInstances, ptr)))
301 {
302 std::shared_ptr<std::vector<controller::OperationPtr>> operations(
303 new std::vector<controller::OperationPtr>());
304
305 if (std::shared_ptr<MemoryXController> memXController = this->memoryXController.lock())
306 {
307 if (controller::ControllerPtr controller = memXController->getController())
308 {
309 controller::OperationPtr operation(new controller::AddOperation(
310 memXController,
311 controller->getScene(),
312 ptr->getName(),
313 memXController->getPriorKnowlegdeController()->getCollection(ptr),
314 getSbVec3fFromInstance(ptr),
315 getSbRotationFromInstance(ptr),
316 ptr->getId()));
317 operations->push_back(operation);
318 controller->execute(controller::Controller::EXECUTE_ON_SCENE, operations);
319 }
320 }
321 }
322 }
323}
324
325void
327 const std::string& segmentName,
328 const memoryx::EntityBasePtr& entityOld,
329 const memoryx::EntityBasePtr& entityNew,
330 const Ice::Current&)
331{
332
333
334 if (0 == objectInstancesPrx->getIceId().name.compare(
335 objectInstancesPrx->getIceId().name.length() - segmentName.length(),
336 segmentName.length(),
337 segmentName))
338 {
339 memoryx::ObjectInstancePtr ptr_new = memoryx::ObjectInstancePtr::dynamicCast(entityNew);
340 auto pose = ptr_new->getPose();
341
342 if (pose->getFrame() != armarx::GlobalFrame && !pose->frame.empty())
343 {
344 auto newPose =
345 workingMemoryPrx->getAgentInstancesSegment()->convertToWorldPose(pose->agent, pose);
346
347 if (newPose)
348 {
349 ptr_new->setPose(newPose);
350 }
351 else
352 {
353 ARMARX_ERROR_S << "could not convert local pose to global pose" << std::endl;
354 }
355 }
356
357 if (!(this->findAndRemoveInstanceFromList(this->currentChangedInstances, ptr_new)))
358 {
359 memoryx::ObjectInstancePtr ptr_old = memoryx::ObjectInstancePtr::dynamicCast(entityOld);
360
361 auto pose = ptr_old->getPose();
362
363 if (pose->getFrame() != armarx::GlobalFrame && !pose->frame.empty())
364 {
365 auto newPose = workingMemoryPrx->getAgentInstancesSegment()->convertToWorldPose(
366 pose->agent, pose);
367
368 if (newPose)
369 {
370 ptr_old->setPose(newPose);
371 }
372 else
373 {
374 ARMARX_ERROR_S << "could not convert local pose to global pose" << std::endl;
375 }
376 }
377
378 std::shared_ptr<std::vector<controller::OperationPtr>> operations(
379 new std::vector<controller::OperationPtr>());
380
381 if (std::shared_ptr<MemoryXController> memXController = this->memoryXController.lock())
382 {
383 if (controller::ControllerPtr controller = memXController->getController())
384 {
385 controller::OperationPtr operation(
386 new controller::RotateTranslateOperation(memXController,
387 controller->getScene(),
388 ptr_new->getId(),
389 getSbRotationFromInstance(ptr_old),
390 getSbRotationFromInstance(ptr_new),
391 getSbVec3fFromInstance(ptr_old),
392 getSbVec3fFromInstance(ptr_new)));
393 operations->push_back(operation);
394 controller->execute(controller::Controller::EXECUTE_ON_SCENE, operations);
395 }
396 }
397 }
398 }
399}
400
401void
403 const std::string& segmentName,
404 const memoryx::EntityBasePtr& entity,
405 const Ice::Current&)
406{
407 if (0 == objectInstancesPrx->getIceId().name.compare(
408 objectInstancesPrx->getIceId().name.length() - segmentName.length(),
409 segmentName.length(),
410 segmentName))
411 {
412 memoryx::ObjectInstancePtr ptr = memoryx::ObjectInstancePtr::dynamicCast(entity);
413
414 if (!(this->findAndRemoveInstanceFromList(this->currentChangedInstances, ptr)))
415 {
416 std::shared_ptr<std::vector<controller::OperationPtr>> operations(
417 new std::vector<controller::OperationPtr>());
418
419 if (std::shared_ptr<MemoryXController> memXController = this->memoryXController.lock())
420 {
421 if (controller::ControllerPtr controller = memXController->getController())
422 {
423 controller::OperationPtr operation(new controller::RemoveOperation(
424 memXController, controller->getScene(), ptr->getId()));
425 operations->push_back(operation);
426 controller->execute(controller::Controller::EXECUTE_ON_SCENE, operations);
427 }
428 }
429 }
430 }
431}
432
433void
435 const Ice::Current&)
436{
437}
438
439void
441 const Ice::Current&)
442{
443}
444
445void
450
451void
455
456std::string
458{
459 return "SceneEditor.WorkingMemoryController";
460}
461
462SbRotation
464 const memoryx::ObjectInstancePtr& objectInstance)
465{
466 armarx::FramedOrientationPtr ptr = objectInstance->getOrientation();
467 SbRotation orientation(SbRotation(ptr->qx, ptr->qy, ptr->qz, ptr->qw));
468 return orientation;
469}
470
471SbVec3f
473 const memoryx::ObjectInstancePtr& objectInstance)
474{
475 armarx::FramedPositionPtr ptr = objectInstance->getPosition();
476 // The new position values have to be devided by 1000 because in the workingmemory the unit the position is stored is meter
477 // and in this local coin-scene the unit is millimeter.
478 SbVec3f pos(SbVec3f(ptr->x * 0.001f, ptr->y * 0.001f, ptr->z * 0.001f));
479 return pos;
480}
481
482bool
483memoryxcontroller::WorkingMemoryController::findAndRemoveInstanceFromList(
484 std::list<memoryx::ObjectInstancePtr>& instanceList,
485 const memoryx::ObjectInstancePtr& instance) const
486{
487 for (std::list<memoryx::ObjectInstancePtr>::const_iterator it = instanceList.begin();
488 it != instanceList.end();
489 ++it)
490 {
492
493 if (temp->getId() == instance->getId() &&
494 temp->getPosition()->toEigen() == instance->getPosition()->toEigen())
495 {
496 instanceList.remove(temp);
497 return true;
498 }
499 }
500
501 return false;
502}
503
504bool
506 const std::string& snapshotName,
507 const memoryx::LongtermMemoryInterfacePrx& longtermMemoryPrx) const
508{
509 return longtermMemoryPrx->saveWorkingMemorySnapshot(snapshotName, this->workingMemoryPrx);
510}
511
512bool
514 const std::string& snapshotName,
515 const memoryx::LongtermMemoryInterfacePrx& longtermMemoryPrx,
516 const std::vector<std::string>& objectIds) const
517{
518 return longtermMemoryPrx->getWorkingMemorySnapshotListSegment()->createSubsetSnapshot(
519 snapshotName, this->workingMemoryPrx, objectIds);
520}
The FramedOrientation class.
Definition FramedPose.h:216
The FramedPosition class.
Definition FramedPose.h:158
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
A Operation to create a new object in the scene and the WorkingMemory.
static const int UNDOABLE
A flag to save the executed operations to the history.
Definition Controller.h:80
static const int EXECUTE_ON_SCENE
A flag to execute operations on the Scene.
Definition Controller.h:73
static SbRotation getSbRotationFromInstance(const memoryx::ObjectInstancePtr &objectInstance)
Returns the rotation of a object instance.
WorkingMemoryController(const memoryx::WorkingMemoryInterfacePrx &workingMemoryPrx, const std::string &workingMemoryUpdatesTopic, const std::string &objectInstancesSegmentName, const std::shared_ptr< MemoryXController > &memoryXController)
Constructor.
void reportSnapshotLoaded(const std::string &segmentName, const ::Ice::Current &=Ice::emptyCurrent) override
Recognises when a segment was loaded from a snapshot.
void addAllInstancesToLocalScene() const
Adds all object instances of the working memory to the local scene.
std::string addObjectInstance(const std::string &objectName, const memoryx::ObjectClassPtr &objectClassPtr)
Adds a new object instance to the working memory.
void reportEntityRemoved(const std::string &segmentName, const ::memoryx::EntityBasePtr &entity, const ::Ice::Current &=Ice::emptyCurrent) override
Recognises when an entity is removed from the working memory.
static SbVec3f getSbVec3fFromInstance(const memoryx::ObjectInstancePtr &objectInstance)
Returns the position of a object instance.
void reportEntityUpdated(const std::string &segmentName, const ::memoryx::EntityBasePtr &entityOld, const ::memoryx::EntityBasePtr &entityNew, const ::Ice::Current &=Ice::emptyCurrent) override
Recognises when an entity is updated in the working memory.
void removeObjectInstance(const std::string &id)
Removes the object instance with the given id.
void rotateTranslateObject(const std::string &id, const SbRotation &newOrientation, const SbVec3f &newPosition)
Applies the given orientation and position to the object instance with the given id.
bool saveObjectsInSnapshot(const std::string &snapshotName, const memoryx::LongtermMemoryInterfacePrx &longtermMemoryPrx, const std::vector< std::string > &objectIds) const
Saves the object instances with the given ids in a snapshot with the given name.
void reportEntityCreated(const std::string &segmentName, const ::memoryx::EntityBasePtr &entity, const ::Ice::Current &=Ice::emptyCurrent) override
Recognises when an entity is created in the working memory.
bool saveSceneInSnapshot(const std::string &snapshotName, const memoryx::LongtermMemoryInterfacePrx &longtermMemoryPrx) const
Saves the whole scene in a snapshot with the given name.
std::vector< std::string > addObjectInstances(const std::vector< memoryx::ObjectInstancePtr > &instancePtrs)
Adds all given object instances to the working memory.
void reportMemoryCleared(const std::string &segmentName, const ::Ice::Current &=Ice::emptyCurrent) override
Recognises when an entity is created on the working memory.
std::string getDefaultName() const override
Returns the default name of this managed ice object.
#define ARMARX_ERROR_S
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:216
std::string const GlobalFrame
Variable of the global coordinate system.
Definition FramedPose.h:65
Quaternion< float, 0 > Quaternionf
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< FramedPosition > FramedPositionPtr
Definition FramedPose.h:149
IceInternal::Handle< FramedOrientation > FramedOrientationPtr
Definition FramedPose.h:207
std::shared_ptr< Controller > ControllerPtr
std::shared_ptr< Operation > OperationPtr
IceInternal::Handle< ObjectInstance > ObjectInstancePtr
IceInternal::Handle< ObjectClass > ObjectClassPtr
Definition ObjectClass.h:35
std::shared_ptr< MemoryXController > MemoryXControllerPtr