Controller.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 "Controller.h"
25 
26 #include <fstream>
27 #include <stdexcept>
28 #include <vector>
29 
30 #include <QApplication>
31 #include <QMetaObject>
32 #include <QMetaType>
33 #include <QThread>
34 #include <QtDesigner/abstractpropertyeditor.h>
35 
36 #include <SimoxUtility/json.h>
37 
40 
41 #include "DeleteGroupOperation.h"
42 #include "DeselectOperation.h"
44 #include "RemoveOperation.h"
45 
46 controller::Controller::Controller() : QObject(), lastSelected(NULL)
47 {
48  qRegisterMetaType<OperationPtrListPtr>("OperationPtrListPtr");
49 }
50 
53 {
55 
56  controller->undoRedoStack.reset(new controller::UndoRedoStack());
58  controller->memoryXController.reset(new memoryxcontroller::MemoryXController());
59  controller->shortcutController.reset(new gui::ShortcutController);
60 
61  return controller;
62 }
63 
65 {
66 }
67 
68 void
69 controller::Controller::execute(int flags, const OperationPtrListPtr& operations, bool blocking)
70 {
71  QMetaObject::invokeMethod(
72  this,
73  "executeQtThread",
74  blocking ? (QApplication::instance()->thread() == QThread::currentThread() ||
75  QApplication::instance()->thread() == NULL
76  ? Qt::DirectConnection
77  : Qt::BlockingQueuedConnection)
78  : Qt::QueuedConnection,
79  Q_ARG(int, flags),
80  Q_ARG(OperationPtrListPtr, operations));
81 }
82 
83 void
84 controller::Controller::executeQtThread(int flags, const OperationPtrListPtr& operations)
85 {
86  std::unique_lock lock(execute_mutex);
87  bool failed = false;
88  controller::vector_string objectIds;
89  std::vector<controller::OperationPtr>::size_type i = 0;
90 
91  for (; i != operations->size(); i++)
92  {
93  if (!operations->at(i)->isExecuteable())
94  {
95  std::unique_lock lock(queue_mutex);
96  queuedOperations.push_back(std::make_pair(flags, operations->at(i)));
97  continue;
98  }
99 
101  {
102  std::string tmp = operations->at(i)->getObjectId();
103  OperationPtr op = operations->at(i);
104  try
105  {
106  op->executeOnWorkingMemory();
107  }
108  catch (std::exception& e)
109  {
110  ARMARX_ERROR_S << "executeOnWorkingMemory failed: " << op->getObjectId()
111  << e.what();
112  failed = true;
113  break;
114  }
115  catch (...)
116  {
117  failed = true;
118  break;
119  }
120 
121  if (tmp != operations->at(i)->getObjectId())
122  {
123  if (getScene()->getObjectManager()->getObjectById(operations->at(i)->getObjectId()))
124  {
125  // the new id should never be used in the local scene
126  throw std::runtime_error("New id is already used in local scene.");
127  }
128 
129  std::string newId = operations->at(i)->getObjectId();
130  undoRedoStack->updateObjectId(tmp, newId);
131 
132  // if the current vector is not updated, update it
133  if (operations->at(i)->getObjectId() == newId)
134  {
135  for (auto ito = operations->begin(); ito != operations->end(); ito++)
136  {
137  if (ito->get()->getObjectId() == tmp)
138  {
139  ito->get()->setObjectId(newId);
140  }
141  else if (ito->get()->getObjectId() == newId)
142  {
143  ito->get()->setObjectId(tmp);
144  }
145  }
146  }
147 
148  // The IDs of all operations in the vector were swapped.
149  // We have revert the swap on the current operation, because it was already the new ID.
150  operations->at(i)->setObjectId(newId);
151  }
152  }
153 
155  {
156  std::string tmp = operations->at(i)->getObjectId();
157  OperationPtr op = operations->at(i);
158  try
159  {
160  op->executeOnScene();
161  }
162  catch (std::exception& e)
163  {
164  ARMARX_ERROR_S << "executeOnScene failed: " << op->getObjectId() << e.what();
165  failed = true;
166  break;
167  }
168  catch (...)
169  {
170  failed = true;
171  break;
172  }
173 
174  if (tmp != operations->at(i)->getObjectId())
175  {
176  throw std::runtime_error("ID changed while execution on local Scene.");
177  }
178  }
179 
180  objectIds.push_back(operations->at(i)->getObjectId());
181  }
182 
183  if (failed)
184  {
185  std::cerr << "Could not execute operations. Trying to revert." << std::endl;
186 
187  // try to revert operations
188  if (i > 0)
189  {
190  int j = i - 1; // i is the failed operation
191 
192  for (; j >= 0; j--)
193  {
194  controller::OperationPtr inverse = operations->at(j)->createInverseOperation();
195 
197  {
198  try
199  {
200  inverse->executeOnScene();
201  }
202  catch (...)
203  {
204  std::cerr << "Could not revert operation on the local scene. Trying to "
205  "revert the other operations."
206  << std::endl;
207  }
208  }
209 
211  {
212  try
213  {
214  inverse->executeOnWorkingMemory();
215  }
216  catch (...)
217  {
218  std::cerr << "Could not revert operation on WorkingMemory. Trying to "
219  "revert the other operations."
220  << std::endl;
221  }
222  }
223  }
224  }
225  }
226  else if (controller::Controller::UNDOABLE & flags)
227  {
228  undoRedoStack->push(operations);
229  }
230 
231  std::vector<scene3D::SceneObjectPtr> allSelected =
232  scene->getSelectionManager()->getAllSelected();
233  scene3D::SceneObjectPtr newSelected =
234  allSelected.size() == 0 ? NULL : allSelected[allSelected.size() - 1];
235 
236  if (newSelected != lastSelected)
237  {
238  lastSelected = newSelected;
239  triggerSceneObjectSelected(newSelected);
240  }
241 
242  qRegisterMetaType<controller::vector_string>("controller::vector_string");
243  emit operationExecuted(objectIds);
244 }
245 
246 void
248 {
249  {
250  std::unique_lock lock(queue_mutex);
251 
252  for (auto it = queuedOperations.begin(); it != queuedOperations.end(); ++it)
253  {
254  controller::OperationPtrListPtr queuedOperationsTmp(
255  new std::vector<controller::OperationPtr>);
256  queuedOperationsTmp->push_back((*it).second);
257  this->execute((*it).first, queuedOperationsTmp, blocking);
258  }
259 
260  queuedOperations.clear();
261  }
262 }
263 
264 void
266 {
267  if (!memoryXController->getWorkingMemoryController())
268  {
269  throw std::runtime_error("Not initialized");
270  }
271 
272  // remove all local objects
273  std::vector<scene3D::SceneObjectPtr> currentLocalObjects =
274  scene->getObjectManager()->getAllObjects();
275 
276  for (scene3D::SceneObjectPtr object : currentLocalObjects)
277  {
278  scene->getObjectManager()->removeObject(object);
279  }
280 
281  // clear the UndoRedoStack
282  undoRedoStack->clear();
283  // load the current state of the WorkingMemory
284  memoryXController->getWorkingMemoryController()->addAllInstancesToLocalScene();
285  emit reloadScene();
286 }
287 
288 const std::shared_ptr<scene3D::Scene>
290 {
291  return scene;
292 }
293 
294 const std::shared_ptr<memoryxcontroller::MemoryXController>
296 {
297  return memoryXController;
298 }
299 
300 const std::shared_ptr<gui::ShortcutController>
302 {
303  return shortcutController;
304 }
305 
306 void
308 {
310  undoRedoStack->undo());
311 }
312 
313 void
315 {
317  undoRedoStack->redo());
318 }
319 
320 void
322  const std::string& collection)
323 {
324  emit objectClassSelected(objectClass, collection);
325 }
326 
327 void
329 {
330  emit sceneObjectSelected(object);
331 }
332 
333 void
335 {
336  emit minimapClicked();
337 }
338 
339 void
341 {
342  emit objectsChanged(objectIds);
343 }
344 
345 void
347 {
348  std::shared_ptr<std::vector<controller::OperationPtr>> operations(
349  new std::vector<controller::OperationPtr>());
350  std::vector<scene3D::SceneObjectPtr> selectedObjects =
351  getScene()->getSelectionManager()->getAllSelected();
352 
353  for (auto it = selectedObjects.rbegin(); it != selectedObjects.rend(); ++it)
354  {
356  getMemoryXController(), getScene(), (*it)->getObjectId()));
357  operations->push_back(operation);
358  }
359 
360  std::vector<scene3D::SceneObjectPtr> allObjects =
361  getScene()->getObjectManager()->getAllObjects();
362  std::vector<scene3D::SceneGroupPtr> groups = getScene()->getGroupManager()->getAllGroups();
363 
364  for (auto itG = groups.begin(); itG != groups.end(); ++itG)
365  {
366  std::vector<scene3D::SceneObjectPtr> groupObjects = (*itG)->getAllObjects();
367 
368  for (auto it = groupObjects.rbegin(); it != groupObjects.rend(); ++it)
369  {
370  controller::OperationPtr removeFromGroupOperation(
371  new controller::RemoveFromGroupOperation(getMemoryXController(),
372  getScene(),
373  (*itG)->getGroupId(),
374  (*it)->getObjectId()));
375  operations->push_back(removeFromGroupOperation);
376  }
377 
379  getMemoryXController(), getScene(), (*itG)->getGroupId()));
380  operations->push_back(deleteGroupOperation);
381  }
382 
383  for (auto it = allObjects.rbegin(); it != allObjects.rend(); ++it)
384  {
386  getMemoryXController(), getScene(), (*it)->getObjectId()));
387  operations->push_back(operation);
388  }
389 
392  operations);
393 }
394 
395 void
396 controller::Controller::saveSnapshotAsJSON(std::string const& snapshotName)
397 {
398  std::shared_ptr<scene3D::Scene> scene = getScene();
399  scene3D::SceneObjectManagerPtr objectManager = scene->getObjectManager();
400  std::vector<scene3D::SceneObjectPtr> objects = objectManager->getAllObjects();
401 
403  for (scene3D::SceneObjectPtr const& object : objects)
404  {
405  armarx::objects::SceneObject& objData = data.objects.emplace_back();
406 
407  SbVec3f translation = object->getTranslation();
408  objData.position.x() = translation[0];
409  objData.position.y() = translation[1];
410  objData.position.z() = translation[2];
411  objData.position *= 1000; // m to mm
412 
413  SbRotation rotation = object->getRotation();
414  objData.orientation.x() = rotation[0];
415  objData.orientation.y() = rotation[1];
416  objData.orientation.z() = rotation[2];
417  objData.orientation.w() = rotation[3];
418 
419  objData.collection = object->getCollection();
420 
421  objData.className = object->getClassId();
422  }
423  nlohmann::json j = data;
424 
425  // TODO: We have to be able to define the folder somehow
426  const std::string filename = snapshotName + ".json";
427  try
428  {
429  nlohmann::write_json(filename, j, 2);
430  ARMARX_INFO << "Saved snapshot as JSON at \n" << std::filesystem::absolute(filename);
431  }
432  catch (const std::ios_base::failure& e)
433  {
434  ARMARX_WARNING << "Failed to save snapshot as JSON at \n"
435  << std::filesystem::absolute(filename) << ":\n"
436  << e.what();
437  }
438 }
RemoveOperation.h
controller::Controller::redo
void redo()
Goes one step forward in the history and redoes the corresponding Operations.
Definition: Controller.cpp:314
controller::Controller::triggerMinimapClicked
void triggerMinimapClicked()
Triggers signal controller:Controller::minimapClicked.
Definition: Controller.cpp:334
controller::Controller::triggerObjectsChanged
void triggerObjectsChanged(controller::vector_string objectIds)
Triggers signal controller:Controller::objectsChanged with given parameter.
Definition: Controller.cpp:340
controller::Controller::getShortcutController
const std::shared_ptr< gui::ShortcutController > getShortcutController() const
Returns the ShortcutController.
Definition: Controller.cpp:301
controller::Controller::create
static ControllerPtr create()
Creates a new instance of the Controller, initializes the Scene and the MemoryXController and returns...
Definition: Controller.cpp:52
armarx::objects::SceneObject::orientation
Eigen::Quaternionf orientation
Definition: Scene.h:44
controller::Controller::triggerSceneObjectSelected
void triggerSceneObjectSelected(scene3D::SceneObjectPtr object)
Triggers signal controller:Controller::sceneObjectSelected with given parameter.
Definition: Controller.cpp:328
controller::OperationPtrListPtr
std::shared_ptr< std::vector< OperationPtr > > OperationPtrListPtr
Definition: ClassDefinitions.h:55
execute
Use of this software is granted under one of the following two to be chosen freely by the user Boost Software License Version Marcin Kalicinski Permission is hereby free of to any person or organization obtaining a copy of the software and accompanying documentation covered by this execute
Definition: license.txt:12
controller::Controller::EXECUTE_ON_SCENE
static const int EXECUTE_ON_SCENE
A flag to execute operations on the Scene.
Definition: Controller.h:73
armarx::objects::SceneObject::position
Eigen::Vector3f position
Definition: Scene.h:43
controller::Controller::saveSnapshotAsJSON
void saveSnapshotAsJSON(std::string const &snapshotName)
Definition: Controller.cpp:396
scene3D::Scene::create
static ScenePtr create(controller::ControllerPtr controller)
Creates a new instance of the Scene.
Definition: Scene.cpp:35
controller::Controller::triggerObjectClassSelected
void triggerObjectClassSelected(const std::string &objectClass, const std::string &collection)
Triggers signal controller:Controller::objectClassSelected with given parameter.
Definition: Controller.cpp:321
memoryxcontroller::MemoryXController
Definition: MemoryXController.h:52
controller::Controller::getScene
const std::shared_ptr< scene3D::Scene > getScene() const
Returns the Scene.
Definition: Controller.cpp:289
controller::Controller::~Controller
~Controller() override
A destructor.
Definition: Controller.cpp:64
controller::Controller::getMemoryXController
const std::shared_ptr< memoryxcontroller::MemoryXController > getMemoryXController() const
Returns the MemoryXController.
Definition: Controller.cpp:295
Scene.h
armarx::objects::SceneObject
Definition: Scene.h:37
gui::ShortcutController
The class ShortcutController manages all shortcuts that can be set in the widget.
Definition: ShortcutController.h:50
controller::Controller::clearScene
void clearScene()
Deletes all objects in local scene and in WorkingMemory and deletes all groups.
Definition: Controller.cpp:346
Controller.h
controller::vector_string
std::vector< std::string > vector_string
Definition: Controller.h:47
newId
auto newId
Definition: GraspingManager.cpp:76
RemoveFromGroupOperation.h
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
json_conversions.h
controller::ControllerPtr
std::shared_ptr< Controller > ControllerPtr
Definition: ClassDefinitions.h:41
controller::UndoRedoStack
A Stack to save a history of Actions.
Definition: UndoRedoStack.h:44
ARMARX_ERROR_S
#define ARMARX_ERROR_S
Definition: Logging.h:216
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
controller::RemoveFromGroupOperation
A operation to removes a object from a existing group.
Definition: RemoveFromGroupOperation.h:41
filename
std::string filename
Definition: VisualizationRobot.cpp:86
controller::Controller
A class to execute Operations, maintain the execution history and initialize Scene and MemoryXControl...
Definition: Controller.h:55
controller::Controller::reloadLocalScene
void reloadLocalScene()
Deletes all objects in the local Scene and loads the current objects from the WorkingMemory in the Sc...
Definition: Controller.cpp:265
DeleteGroupOperation.h
scene3D::SceneObjectManagerPtr
std::shared_ptr< SceneObjectManager > SceneObjectManagerPtr
Definition: PointerDefinitions.h:58
armarx::objects::Scene
Definition: Scene.h:55
armarx::objects::SceneObject::collection
std::string collection
Definition: Scene.h:41
controller::DeselectOperation
A operation to deselect a object.
Definition: DeselectOperation.h:41
controller::Controller::executeQueuedOperations
void executeQueuedOperations(bool blocking=true)
Executes the Operations, which are queued because the object, which would be affected by this was bus...
Definition: Controller.cpp:247
controller::DeleteGroupOperation
A operation to delete a group.
Definition: DeleteGroupOperation.h:41
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
controller::OperationPtr
std::shared_ptr< Operation > OperationPtr
Definition: ClassDefinitions.h:54
controller::Controller::undo
void undo()
Goes one step back in the history and undoes the corresponding Operations.
Definition: Controller.cpp:307
scene3D::SceneObjectPtr
boost::intrusive_ptr< SceneObject > SceneObjectPtr
Definition: PointerDefinitions.h:40
DeselectOperation.h
armarx::objects::SceneObject::className
std::string className
Definition: Scene.h:39
controller::Controller::EXECUTE_ON_WM
static const int EXECUTE_ON_WM
A Flag to execute operations on the WorkingMemory.
Definition: Controller.h:66
controller::Controller::execute
void execute(int flags, const OperationPtrListPtr &operations, bool blocking=true)
Executes multiple operations.
Definition: Controller.cpp:69
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
controller::RemoveOperation
A Operation to remove a object in the scene and the WorkingMemory.
Definition: RemoveOperation.h:47