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/SbVec3f.h>
32 #include <Inventor/SbRotation.h>
33 
34 // MemoryXInterface
35 #include <MemoryX/interface/components/WorkingMemoryInterface.h>
36 #include <MemoryX/interface/memorytypes/MemorySegments.h>
38 
40 #include "../controller/AddOperation.h"
41 #include "../controller/RemoveOperation.h"
42 #include "../controller/RotateTranslateOperation.h"
43 
44 memoryxcontroller::WorkingMemoryController::WorkingMemoryController(const memoryx::WorkingMemoryInterfacePrx& workingMemoryPrx, const std::string& workingMemoryUpdatesTopic, const std::string& objectInstancesSegmentName, const memoryxcontroller::MemoryXControllerPtr& memoryXController) :
45  workingMemoryPrx(workingMemoryPrx),
46  workingMemoryUpdatesTopic(workingMemoryUpdatesTopic)
47 
48 {
49  this->objectInstancesPrx = memoryx::ObjectInstanceMemorySegmentBasePrx::uncheckedCast(workingMemoryPrx->getSegment(objectInstancesSegmentName));
50  this->memoryXController = memoryXController;
51 
52  std::string s1 = "SceneEditor.WorkingMemoryController";
53  std::string s2 = IceUtil::generateUUID();
54 
55  this->setName(s1 + s2);
56 }
57 
59 {
60 }
61 
62 std::string memoryxcontroller::WorkingMemoryController::addObjectInstance(const std::string& objectName, const memoryx::ObjectClassPtr& objectClassPtr)
63 {
64  memoryx::ObjectInstancePtr newObject = new memoryx::ObjectInstance(objectName);
65  memoryx::NameList attributeNames = objectClassPtr->getAttributeNames();
66 
67  for (memoryx::NameList::const_iterator it = attributeNames.begin(); it != attributeNames.end(); ++it)
68  {
69  newObject->putAttribute(objectClassPtr->getAttribute(*it));
70  }
71 
72  newObject->setClass(objectClassPtr->getName(), 1.0f);
73  newObject->setExistenceCertainty(1.0f);
74 
75  this->currentChangedInstances.push_back(newObject);
76 
77  std::string objectID = this->objectInstancesPrx->addEntity(newObject);
78  newObject->setId(objectID);
79 
80  return objectID;
81 }
82 
83 std::vector<std::string> memoryxcontroller::WorkingMemoryController::addObjectInstances(const std::vector<memoryx::ObjectInstancePtr>& objectInstances)
84 {
85  std::vector<std::string> addedIds;
86 
87  if (!objectInstances.empty())
88  {
89  std::shared_ptr<std::vector<controller::OperationPtr> > operations(new std::vector<controller::OperationPtr>());
90 
91  if (std::shared_ptr<memoryxcontroller::MemoryXController> memXController = this->memoryXController.lock())
92  {
93  if (controller::ControllerPtr controller = memXController->getController())
94  {
95  for (std::vector<memoryx::ObjectInstancePtr>::const_iterator it = objectInstances.begin(); it != objectInstances.end(); ++it)
96  {
97  memoryx::ObjectInstancePtr objectInstance = *it;
98 
99  auto pose = objectInstance->getPose();
100 
101  if (pose->getFrame() != armarx::GlobalFrame && !pose->frame.empty())
102  {
103  // FIXME: The localization timestamp is ignored.
104  // This causes stuttering objects during robot motion
105  auto newPose = workingMemoryPrx->getAgentInstancesSegment()->convertToWorldPose(pose->agent, pose);
106 
107  if (newPose)
108  {
109  objectInstance->setPose(newPose);
110  }
111  else
112  {
113  ARMARX_ERROR_S << "could not convert local pose to global pose" << std::endl;
114  }
115  }
116 
117  this->currentChangedInstances.push_back(objectInstance);
118  std::string objectID = this->objectInstancesPrx->addEntity(objectInstance);
119  objectInstance->setId(objectID);
120 
121  addedIds.push_back(objectID);
122 
123  controller::OperationPtr operation(new controller::AddOperation(memXController,
124  controller->getScene(),
125  objectInstance->getName(),
126  memXController->getPriorKnowlegdeController()->getCollection(objectInstance),
127  getSbVec3fFromInstance(objectInstance),
128  getSbRotationFromInstance(objectInstance),
129  objectInstance->getId()));
130 
131  operations->push_back(operation);
132  }
133 
135  }
136  }
137  }
138 
139  return addedIds;
140 }
141 
143 {
144  if (this->objectInstancesPrx->getEntityById(id))
145  {
146 
147  this->currentChangedInstances.push_back(memoryx::ObjectInstancePtr::dynamicCast(this->objectInstancesPrx->getEntityById(id)));
148 
149  this->objectInstancesPrx->removeEntity(id);
150  }
151  else
152  {
153  throw std::invalid_argument("There is no objectInstance with given ID.");
154  }
155 }
156 
157 void memoryxcontroller::WorkingMemoryController::rotateTranslateObject(const std::string& id, const SbRotation& newOrientation, const SbVec3f& newPosition)
158 {
159  memoryx::ObjectInstanceBasePtr objectBase = this->objectInstancesPrx->getObjectInstanceById(id);
160 
161  if (objectBase)
162  {
163 
164  memoryx::ObjectInstancePtr object = memoryx::ObjectInstancePtr::dynamicCast(objectBase);
165 
166  float x, y, z;
167  newPosition.getValue(x, y, z);
168  // The new position values have to be multiplied with 1000 because in the workingmemory the unit the position is stored is meter
169  // and in this local coin-scene the unit is millimeter.
170  const Eigen::Vector3f vec(x * 1000.0f, y * 1000.0f, z * 1000.0f);
172  object->setPosition(newPos);
173 
174  float pw, px, py, pz;
175  newOrientation.getValue(px, py, pz, pw);
176  Eigen::Quaternionf quat(pw, px, py, pz);
177  armarx::FramedOrientationPtr newOrient = new armarx::FramedOrientation(quat.toRotationMatrix(), armarx::GlobalFrame, "");
178  object->setOrientation(newOrient);
179 
180  this->currentChangedInstances.push_back(object);
181 
182  this->objectInstancesPrx->setObjectPoseWithoutMotionModel(id, object->getPose());
183  }
184  else
185  {
186  throw std::invalid_argument("There is no objectInstance with given ID.");
187  }
188 }
189 
191 {
192  if (std::shared_ptr<memoryxcontroller::MemoryXController> memXController = this->memoryXController.lock())
193  {
194  if (controller::ControllerPtr controller = memXController->getController())
195  {
196  std::unique_lock lock(mutexEntities);
197 
198  memoryx::EntityIdList ids = this->objectInstancesPrx->getAllEntityIds();
199  std::shared_ptr<std::vector<controller::OperationPtr> > operations(new std::vector<controller::OperationPtr>());
200 
201  for (memoryx::EntityIdList::const_iterator it = ids.begin(); it != ids.end(); ++it)
202  {
203  memoryx::ObjectInstancePtr object = memoryx::ObjectInstancePtr::dynamicCast(this->objectInstancesPrx->getObjectInstanceById(*it));
204 
205  auto pose = object->getPose();
206 
207  if (pose->getFrame() != armarx::GlobalFrame && !pose->frame.empty())
208  {
209  auto newPose = workingMemoryPrx->getAgentInstancesSegment()->convertToWorldPose(pose->agent, pose);
210 
211  if (newPose)
212  {
213  object->setPose(newPose);
214  }
215  else
216  {
217  ARMARX_ERROR_S << "could not convert local pose to global pose" << std::endl;
218  }
219  }
220 
221  controller::OperationPtr operation(new controller::AddOperation(memXController,
222  controller->getScene(),
223  object->getName(),
224  memXController->getPriorKnowlegdeController()->getCollection(object),
225  getSbVec3fFromInstance(object),
226  getSbRotationFromInstance(object),
227  object->getId()));
228  operations->push_back(operation);
229  }
230 
232  }
233  }
234 }
235 
236 void memoryxcontroller::WorkingMemoryController::reportEntityCreated(const std::string& segmentName, const memoryx::EntityBasePtr& entity,
237  const Ice::Current&)
238 {
239  if (0 == objectInstancesPrx->getIceId().name.compare(objectInstancesPrx->getIceId().name.length() - segmentName.length(), segmentName.length(), segmentName))
240  {
241  memoryx::ObjectInstancePtr ptr = memoryx::ObjectInstancePtr::dynamicCast(entity);
242 
243  auto pose = ptr->getPose();
244 
245  if (pose->getFrame() != armarx::GlobalFrame && !pose->frame.empty())
246  {
247  auto newPose = workingMemoryPrx->getAgentInstancesSegment()->convertToWorldPose(pose->agent, pose);
248 
249  if (newPose)
250  {
251  ptr->setPose(newPose);
252  }
253  else
254  {
255  ARMARX_ERROR_S << "could not convert local pose to global pose" << std::endl;
256  }
257  }
258 
259  if (!(this->findAndRemoveInstanceFromList(this->currentChangedInstances, ptr)))
260  {
261  std::shared_ptr<std::vector<controller::OperationPtr> > operations(new std::vector<controller::OperationPtr>());
262 
263  if (std::shared_ptr<MemoryXController> memXController = this->memoryXController.lock())
264  {
265  if (controller::ControllerPtr controller = memXController->getController())
266  {
267  controller::OperationPtr operation(new controller::AddOperation(memXController,
268  controller->getScene(),
269  ptr->getName(),
270  memXController->getPriorKnowlegdeController()->getCollection(ptr),
271  getSbVec3fFromInstance(ptr),
272  getSbRotationFromInstance(ptr),
273  ptr->getId()));
274  operations->push_back(operation);
276  }
277  }
278  }
279  }
280 }
281 
282 void memoryxcontroller::WorkingMemoryController::reportEntityUpdated(const std::string& segmentName,
283  const memoryx::EntityBasePtr& entityOld,
284  const memoryx::EntityBasePtr& entityNew, const Ice::Current&)
285 {
286 
287 
288  if (0 == objectInstancesPrx->getIceId().name.compare(objectInstancesPrx->getIceId().name.length() - segmentName.length(), segmentName.length(), segmentName))
289  {
290  memoryx::ObjectInstancePtr ptr_new = memoryx::ObjectInstancePtr::dynamicCast(entityNew);
291  auto pose = ptr_new->getPose();
292 
293  if (pose->getFrame() != armarx::GlobalFrame && !pose->frame.empty())
294  {
295  auto newPose = workingMemoryPrx->getAgentInstancesSegment()->convertToWorldPose(pose->agent, pose);
296 
297  if (newPose)
298  {
299  ptr_new->setPose(newPose);
300  }
301  else
302  {
303  ARMARX_ERROR_S << "could not convert local pose to global pose" << std::endl;
304  }
305  }
306 
307  if (!(this->findAndRemoveInstanceFromList(this->currentChangedInstances, ptr_new)))
308  {
309  memoryx::ObjectInstancePtr ptr_old = memoryx::ObjectInstancePtr::dynamicCast(entityOld);
310 
311  auto pose = ptr_old->getPose();
312 
313  if (pose->getFrame() != armarx::GlobalFrame && !pose->frame.empty())
314  {
315  auto newPose = workingMemoryPrx->getAgentInstancesSegment()->convertToWorldPose(pose->agent, pose);
316 
317  if (newPose)
318  {
319  ptr_old->setPose(newPose);
320  }
321  else
322  {
323  ARMARX_ERROR_S << "could not convert local pose to global pose" << std::endl;
324  }
325  }
326 
327  std::shared_ptr<std::vector<controller::OperationPtr> > operations(new std::vector<controller::OperationPtr>());
328 
329  if (std::shared_ptr<MemoryXController> memXController = this->memoryXController.lock())
330  {
331  if (controller::ControllerPtr controller = memXController->getController())
332  {
334  controller->getScene(),
335  ptr_new->getId(),
336  getSbRotationFromInstance(ptr_old),
337  getSbRotationFromInstance(ptr_new),
338  getSbVec3fFromInstance(ptr_old),
339  getSbVec3fFromInstance(ptr_new)));
340  operations->push_back(operation);
342  }
343  }
344  }
345  }
346 }
347 
348 void memoryxcontroller::WorkingMemoryController::reportEntityRemoved(const std::string& segmentName, const memoryx::EntityBasePtr& entity,
349  const Ice::Current&)
350 {
351  if (0 == objectInstancesPrx->getIceId().name.compare(objectInstancesPrx->getIceId().name.length() - segmentName.length(), segmentName.length(), segmentName))
352  {
353  memoryx::ObjectInstancePtr ptr = memoryx::ObjectInstancePtr::dynamicCast(entity);
354 
355  if (!(this->findAndRemoveInstanceFromList(this->currentChangedInstances, ptr)))
356  {
357  std::shared_ptr<std::vector<controller::OperationPtr> > operations(new std::vector<controller::OperationPtr>());
358 
359  if (std::shared_ptr<MemoryXController> memXController = this->memoryXController.lock())
360  {
361  if (controller::ControllerPtr controller = memXController->getController())
362  {
363  controller::OperationPtr operation(new controller::RemoveOperation(memXController,
364  controller->getScene(),
365  ptr->getId()));
366  operations->push_back(operation);
368  }
369  }
370  }
371  }
372 }
373 
374 void memoryxcontroller::WorkingMemoryController::reportMemoryCleared(const std::string& segmentName, const Ice::Current&)
375 {
376 }
377 
378 void memoryxcontroller::WorkingMemoryController::reportSnapshotLoaded(const std::string& segmentName, const Ice::Current&)
379 {
380 
381 }
382 
383 
385 {
386  usingTopic(workingMemoryUpdatesTopic);
387 }
388 
390 {
391 
392 }
393 
395 {
396  return "SceneEditor.WorkingMemoryController";
397 }
398 
399 
401 {
402  armarx::FramedOrientationPtr ptr = objectInstance->getOrientation();
403  SbRotation orientation(SbRotation(ptr->qx, ptr->qy, ptr->qz, ptr->qw));
404  return orientation;
405 }
406 
408 {
409  armarx::FramedPositionPtr ptr = objectInstance->getPosition();
410  // The new position values have to be devided by 1000 because in the workingmemory the unit the position is stored is meter
411  // and in this local coin-scene the unit is millimeter.
412  SbVec3f pos(SbVec3f(ptr->x * 0.001f, ptr->y * 0.001f, ptr->z * 0.001f));
413  return pos;
414 }
415 
416 bool memoryxcontroller::WorkingMemoryController::findAndRemoveInstanceFromList(std::list<memoryx::ObjectInstancePtr>& instanceList, const memoryx::ObjectInstancePtr& instance) const
417 {
418  for (std::list<memoryx::ObjectInstancePtr>::const_iterator it = instanceList.begin(); it != instanceList.end(); ++it)
419  {
420  memoryx::ObjectInstancePtr temp = *it;
421 
422  if (temp->getId() == instance->getId() && temp->getPosition()->toEigen() == instance->getPosition()->toEigen())
423  {
424  instanceList.remove(temp);
425  return true;
426  }
427  }
428 
429  return false;
430 }
431 
432 bool memoryxcontroller::WorkingMemoryController::saveSceneInSnapshot(const std::string& snapshotName, const memoryx::LongtermMemoryInterfacePrx& longtermMemoryPrx) const
433 {
434  return longtermMemoryPrx->saveWorkingMemorySnapshot(snapshotName, this->workingMemoryPrx);
435 }
436 
437 bool memoryxcontroller::WorkingMemoryController::saveObjectsInSnapshot(const std::string& snapshotName, const memoryx::LongtermMemoryInterfacePrx& longtermMemoryPrx, const std::vector<std::string>& objectIds) const
438 {
439  return longtermMemoryPrx->getWorkingMemorySnapshotListSegment()->createSubsetSnapshot(snapshotName, this->workingMemoryPrx, objectIds);
440 }
WorkingMemoryController.h
memoryxcontroller::WorkingMemoryController::rotateTranslateObject
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.
Definition: WorkingMemoryController.cpp:157
controller::Controller::EXECUTE_ON_SCENE
static const int EXECUTE_ON_SCENE
A flag to execute operations on the Scene.
Definition: Controller.h:73
memoryxcontroller::WorkingMemoryController::onInitComponent
void onInitComponent() override
Definition: WorkingMemoryController.cpp:384
memoryxcontroller::WorkingMemoryController::reportEntityUpdated
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.
armarx::GlobalFrame
const std::string GlobalFrame
Definition: FramedPose.h:62
memoryx::ObjectInstance
Definition: ObjectInstance.h:47
IceInternal::Handle< ObjectClass >
memoryxcontroller::WorkingMemoryController::WorkingMemoryController
WorkingMemoryController(const memoryx::WorkingMemoryInterfacePrx &workingMemoryPrx, const std::string &workingMemoryUpdatesTopic, const std::string &objectInstancesSegmentName, const std::shared_ptr< MemoryXController > &memoryXController)
Constructor.
memoryxcontroller::WorkingMemoryController::onConnectComponent
void onConnectComponent() override
Definition: WorkingMemoryController.cpp:389
memoryxcontroller::WorkingMemoryController::saveSceneInSnapshot
bool saveSceneInSnapshot(const std::string &snapshotName, const memoryx::LongtermMemoryInterfacePrx &longtermMemoryPrx) const
Saves the whole scene in a snapshot with the given name.
Definition: WorkingMemoryController.cpp:432
controller::Controller::UNDOABLE
static const int UNDOABLE
A flag to save the executed operations to the history.
Definition: Controller.h:80
controller
Definition: AddOperation.h:39
controller::ControllerPtr
std::shared_ptr< Controller > ControllerPtr
Definition: ClassDefinitions.h:41
ARMARX_ERROR_S
#define ARMARX_ERROR_S
Definition: Logging.h:209
memoryxcontroller::WorkingMemoryController::addObjectInstances
std::vector< std::string > addObjectInstances(const std::vector< memoryx::ObjectInstancePtr > &instancePtrs)
Adds all given object instances to the working memory.
Definition: WorkingMemoryController.cpp:83
memoryxcontroller::WorkingMemoryController::reportMemoryCleared
void reportMemoryCleared(const std::string &segmentName, const ::Ice::Current &=Ice::emptyCurrent) override
Recognises when an entity is created on the working memory.
memoryxcontroller::WorkingMemoryController::getSbVec3fFromInstance
static SbVec3f getSbVec3fFromInstance(const memoryx::ObjectInstancePtr &objectInstance)
Returns the position of a object instance.
Definition: WorkingMemoryController.cpp:407
memoryxcontroller::WorkingMemoryController::getSbRotationFromInstance
static SbRotation getSbRotationFromInstance(const memoryx::ObjectInstancePtr &objectInstance)
Returns the rotation of a object instance.
Definition: WorkingMemoryController.cpp:400
memoryxcontroller::WorkingMemoryController::reportSnapshotLoaded
void reportSnapshotLoaded(const std::string &segmentName, const ::Ice::Current &=Ice::emptyCurrent) override
Recognises when a segment was loaded from a snapshot.
memoryxcontroller::WorkingMemoryController::saveObjectsInSnapshot
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.
Definition: WorkingMemoryController.cpp:437
ObjectInstance.h
armarx::VariantType::FramedOrientation
const VariantTypeId FramedOrientation
Definition: FramedPose.h:40
armarx::Quaternion< float, 0 >
memoryxcontroller::WorkingMemoryController::addAllInstancesToLocalScene
void addAllInstancesToLocalScene() const
Adds all object instances of the working memory to the local scene.
Definition: WorkingMemoryController.cpp:190
controller::OperationPtr
std::shared_ptr< Operation > OperationPtr
Definition: ClassDefinitions.h:54
controller::RotateTranslateOperation
A operation to rotate and translate a object.
Definition: RotateTranslateOperation.h:46
memoryxcontroller::WorkingMemoryController::reportEntityRemoved
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.
memoryxcontroller::WorkingMemoryController::getDefaultName
std::string getDefaultName() const override
Returns the default name of this managed ice object.
Definition: WorkingMemoryController.cpp:394
memoryxcontroller::WorkingMemoryController::addObjectInstance
std::string addObjectInstance(const std::string &objectName, const memoryx::ObjectClassPtr &objectClassPtr)
Adds a new object instance to the working memory.
Definition: WorkingMemoryController.cpp:62
armarx::VariantType::FramedPosition
const VariantTypeId FramedPosition
Definition: FramedPose.h:39
memoryxcontroller::WorkingMemoryController::reportEntityCreated
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.
controller::RemoveOperation
A Operation to remove a object in the scene and the WorkingMemory.
Definition: RemoveOperation.h:47
controller::AddOperation
A Operation to create a new object in the scene and the WorkingMemory.
Definition: AddOperation.h:46
memoryxcontroller::WorkingMemoryController::~WorkingMemoryController
~WorkingMemoryController() override
Destructor.
Definition: WorkingMemoryController.cpp:58
memoryxcontroller::MemoryXControllerPtr
std::shared_ptr< MemoryXController > MemoryXControllerPtr
Definition: MemoryXController.h:146
memoryxcontroller::WorkingMemoryController::removeObjectInstance
void removeObjectInstance(const std::string &id)
Removes the object instance with the given id.
Definition: WorkingMemoryController.cpp:142