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