OIFwdKinematicsInterface.cpp
Go to the documentation of this file.
1 /*
2  * OIFwdKinematicsInterface.cpp
3  *
4  *
5  * Created by A. Bierbaumm on 28.03.08.
6  * Copyright 2008 IAIM Universitaet Karlsruhe.
7  * All rights reserved.
8  *
9  */
10 
11 /** \file OIFwdKinematicsInterface.cpp
12 * The source file for OIFwdKinematicsInterface.
13 */
14 
15 /** \class OIFwdKinematicsInterface
16 * Defines the OIFwdKinematicsInterface class.
17 * To use this class you can either create a direct instance of this class
18 * or you can create a subclass and override the OIFwdKinematicsInterface::buildScenery()
19 * method.\n
20 * If you create a direct instance of the OIFwdKinematicsInterface your code usually would
21 * look like this:
22 \code
23 
24 #include "OIFwdKinematicsInterface.h"
25 
26 int main (int argc, char ** argv)
27 {
28  OIFwdKinematicsInterface viewer(argc, argv, "FileToOpen.iv");
29  // create an instance of the OIFwdKinematicsInterface
30  viewer.run(); // start the visualisation/simulation
31  return 0;
32 }
33 
34 \endcode
35 *
36 * If you create a subclass of OIFwdKinematicsInterface you need to override the constructor
37 * and the OIFwdKinematicsInterface::buildScenery() method. If you create custom variables
38 * in the constructor or in OIFwdKinematicsInterface::buildScenery() you also need to create
39 * a destructor and free the memory of those variables.\n
40 * A short example:
41 \code
42 
43 #include <iostream>
44 
45 #include "OIFwdKinematicsInterface.h"
46 #include <ipsaclasses.h>
47 
48 class MyOIFwdKinematicsInterface : public OIFwdKinematicsInterface
49 {
50 public:
51  MyOIFwdKinematicsInterface(int argc, char ** argv, std::string filename = "")
52  : MyOIFwdKinematicsInterface(argc, argv, filename) {}
53 protected:
54  virtual bool buildScenery();
55 };
56 
57 bool MyOIFwdKinematicsInterface::buildScenery()
58 {
59  // omit this line if you do not want to read a scenegraph from a file
60  if ( true == this->readSceneryFromFile() )
61  return true;
62  // create your own scenegraph
63  root = new SoSeparator;
64  // the remaining code
65 }
66 
67 int
68 main (int argc, char ** argv)
69 {
70  std::string sceneFilename = "";
71  if ( 2 <= argc )
72  {
73  // this can be omitted if you do not want to read a file
74  // the third parameter can also be left out in this case
75  sceneFilename = argv[1];
76  std::cout << "\n\nOpen file: " << sceneFilename << std::endl << std::endl;
77  }
78  MyOIFwdKinematicsInterface viewer(argc, argv, sceneFilename);
79  viewer.run();
80  return 0;
81 }
82 
83 \endcode
84 */
85 
86 /** \var SoSeparator OIFwdKinematicsInterface::root
87 * This is the root node of the scenegraph which gets rendered.\n
88 * You can create a new node in the OIFwdKinematicsInterface::buildScenery() method
89 * because it gets referenced and unreferenced in the OIFwdKinematicsInterface::run()
90 * method.
91 */
92 
93 /** \var SO_WINDOW OIFwdKinematicsInterface::window
94 * Depending on the platfrom this is either a HWND on Windows or
95 * a QWidget on Linux/Mac OS X.
96 */
97 
98 /** \var SO_EXAMINER_VIEWER OIFwdKinematicsInterface::viewer
99 * Depending on the platfrom this is either an SoWinExaminerViewer on Windows or
100 * an SoQtExaminerViewer on Linux/Mac OS X.
101 */
102 
103 /** \var std::string OIFwdKinematicsInterface::sceneryFilename
104 * This is the filename of the inventor scenegraph which can be loaded
105 * by the OIFwdKinematicsInterface::readSceneryFromFile() method.
106 */
107 
108 #include <stdlib.h>
109 
110 #include <iostream>
111 
112 #include <qwidget.h>
113 
114 #include "../HandLocalisationConstants.h"
116 #include <Inventor/SoDB.h>
117 #include <Inventor/SoFullPath.h>
118 #include <Inventor/SoInput.h>
119 #include <Inventor/actions/SoGetMatrixAction.h>
120 #include <Inventor/actions/SoSearchAction.h>
121 #include <Inventor/nodes/SoFile.h>
122 #include <Inventor/nodes/SoGroup.h>
123 #include <Inventor/nodes/SoNode.h>
124 #include <Inventor/nodes/SoTransform.h>
125 
126 namespace visionx
127 {
128  /**
129  * The constructor of the OIFwdKinematicsInterface class.\n
130  * It initializes OIFwdKinematicsInterface::root with NULL,
131  * the OIFwdKinematicsInterface::sceneryFilename with the \param filename
132  * and initializes the OIFwdKinematicsInterface::window variable.
133  *
134  * \param int argc the argument count passed into the main method
135  * \param char **argv the argument array passed into the main method
136  * \param std::string filename the file getting opened by OIFwdKinematicsInterface::readSceneryFromFile(). Default value is an empty string.
137  */
139  root(NULL),
140  argc(0),
141  args(NULL),
142  iQApplication(NULL),
143  sceneryFilename(filename),
144  window(NULL),
145  viewer(NULL),
146  iReady(false)
147  {
148  }
149 
150  /**
151  * The virtual destructor of the OIFwdKinematicsInterface class.
152  */
154  {
155  if (NULL != viewer)
156  {
157  delete viewer;
158  }
159  if (NULL != window)
160  {
161  delete window;
162  }
163  if (NULL != iQApplication)
164  {
165  delete iQApplication;
166  }
167  }
168 
169  void
171  {
172  if (iReady)
173  {
174  // assert(iQApplication != NULL);
175  // #ifdef QT_THREAD_SUPPORT
176  // iQApplication->lock();
177  // #endif
178  // iQApplication->processEvents();
179  // viewer->render();
180  // #ifdef QT_THREAD_SUPPORT
181  // iQApplication->unlock();
182  // #endif
183 
184  //*** Collision detection
185 #ifdef HAVE_COLLISION_DET
186  //ida->apply(root);
187 #endif
188 
189  // meins
191  }
192  }
193 
194  void
196  {
197  // iQApplication = new QApplication(argc,args);
198  // window = new QWidget();
199  // SoQt::init(window);
200 
201  // meins
202  SoDB::init();
203  m_pViewportRegion = new SbViewportRegion();
204  m_pViewportRegion->setWindowSize(DSHT_OI_RENDERSIZE_X, DSHT_OI_RENDERSIZE_Y); //760, 570
205  //m_pViewportRegion->setPixelsPerInch(25.4); // = 1 px/mm
206  m_pCamera = new SoPerspectiveCamera;
207  m_pLight = new SoDirectionalLight;
208  m_pDavidsRoot = new SoSeparator;
209  m_pCamera->position.setValue(0, 0, 0);
210  m_pCamera->orientation.setValue(SbRotation(SbVec3f(1, 0, 0), M_PI));
211  float alpha = 2 * atan(0.5 * DSHT_OI_RENDERSIZE_Y / m_fFocalLengthY);
212  m_pCamera->heightAngle.setValue(
213  alpha); //640x480 -> 0.85047002; alpha = 2 * atan(240/focallength)
214  //m_pCamera->aspectRatio.setValue(1.00409544);
215  m_pCamera->farDistance.setValue(2000);
216  m_pLight->direction.setValue(0.01, 0.01, 1.0);
217  //m_pLight->on.setValue(false);
218 
219 #ifdef HAVE_COLLISION_DET
220  ida = new SoIntersectionDetectionAction();
221  ida->addIntersectionCallback(intersectionCB, NULL);
222  ida->setIntersectionDetectionEpsilon(10.0f);
223  SoInteraction::init();
224 #endif
225 
226  iReady = true;
227 
228  if (false == buildScenery())
229  {
230  return;
231  }
232  root->ref();
233 
234  // meins
235  m_pDavidsRoot->addChild(m_pCamera);
236  m_pDavidsRoot->addChild(m_pLight);
237  m_pDavidsRoot->addChild(root);
238  m_pDavidsRoot->ref();
239  m_pOffscreenRenderer = new SoOffscreenRenderer(*m_pViewportRegion);
240  m_pOffscreenRenderer->setBackgroundColor(*(new SbColor(255, 0, 0)));
241  printf("\nbefore m_pOffscreenRenderer->render()\n\n");
242  bool bResult = m_pOffscreenRenderer->render(m_pDavidsRoot);
243  printf("\nafter m_pOffscreenRenderer->render() which returned %d\n\n", bResult);
244 
245 
246 #ifdef HAVE_COLLISION_DET
247  ida = new SoIntersectionDetectionAction();
248  ida->addIntersectionCallback(intersectionCB, NULL);
249  ida->setIntersectionDetectionEpsilon(10.0f);
250 #endif
251 
252  /* viewer = new SoQtExaminerViewer(window);
253  viewer->setSceneGraph(root);
254  viewer->setTitle("ForwardKinematicsViewer");
255  viewer->viewAll();
256  viewer->setFeedbackVisibility(true);
257  viewer->setAutoRedraw(false);
258  viewer->show();
259  window->show();
260  */
261  }
262 
263 #ifdef HAVE_COLLISION_DET
264  SoIntersectionDetectionAction::Resp
265  OIFwdKinematicsInterface::intersectionCB(void* closure,
266  const SoIntersectingPrimitive* pr1,
267  const SoIntersectingPrimitive* pr2)
268  {
269  SbName n1, n2;
270  int l = pr1->path->getLength();
271 
272  for (int i = 0; i < l; i++)
273  {
274  n1 = pr1->path->getNodeFromTail(i)->getName();
275  if (n1.getLength() > 0)
276  {
277  break;
278  }
279  }
280  l = pr2->path->getLength();
281  for (int i = 0; i < l; i++)
282  {
283  n2 = pr2->path->getNodeFromTail(i)->getName();
284  if (n2.getLength() > 0)
285  {
286  break;
287  }
288  }
289  if ((n1.getLength() > 0) || (n2.getLength() > 0))
290  {
291  printf("intersection hit: [%s], [%s]\n", n1.getString(), n2.getString());
292  }
293 
294  return SoIntersectionDetectionAction::NEXT_PRIMITIVE;
295  }
296 #endif
297 
298  bool
299  OIFwdKinematicsInterface::getPath(std::string name, SoPath*& p, SoNode* r)
300  {
301  if (NULL == r)
302  {
303  r = root;
304  }
305  p = NULL;
306 
307  SoNode* lnode = SoNode::getByName(name.c_str());
308  if (NULL == lnode)
309  {
310  return false;
311  }
312 
313  SoSearchAction* searchaction = new SoSearchAction;
314  searchaction->setNode(lnode);
315  searchaction->apply(r);
316 
317  p = searchaction->getPath();
318  if (NULL == p)
319  {
320  return false;
321  }
322 
323  return true;
324  }
325 
326  bool
327  OIFwdKinematicsInterface::getTranslation(SbVec3f& translation, SoPath* p)
328  {
329  if (NULL == p)
330  {
331  std::cerr << "OI: getTranslation path is NULL! " << std::endl;
332  return false;
333  }
334 
335  // Apply the SoGetMatrixAction to get the full transformation
336  // matrix from world space.
337 
338  //SoGetMatrixAction * getmatrixaction = new SoGetMatrixAction(viewer->getViewportRegion());
339  SoGetMatrixAction* getmatrixaction = new SoGetMatrixAction(*m_pViewportRegion);
340  getmatrixaction->apply(p);
341 
342  SbMatrix transformation = getmatrixaction->getMatrix();
343 
344  // And if you want to access the individual transformation
345  // components of the matrix:
346 
347  //SbVec3f translation;
348  SbRotation rotation;
349  SbVec3f scalevector;
350  SbRotation scaleorientation;
351 
352  transformation.getTransform(translation, rotation, scalevector, scaleorientation);
353 
354  return true;
355  }
356 
357  bool
359  {
360  if (NULL == p)
361  {
362  std::cerr << "OI: setJointAngle path is NULL! " << std::endl;
363  return false;
364  }
365 
366  SoNode* n0 = p->getNodeFromTail(0);
367  if (!n0->isOfType(SoTransform::getClassTypeId()))
368  {
369  printf("setJointAngle: node type is [%s] instead Transform!\n",
370  n0->getClassTypeId().getName().getString());
371  return false;
372  }
373  SoTransform* t = static_cast<SoTransform*>(n0);
374  SbVec3f axis;
375  float a0;
376 
377  //*** Keep angle in interval [-2Pi,2Pi] (required for coin!)
378  if (abs(angle) > 2 * M_PI)
379  {
380  angle = angle - (floor(angle / (2 * M_PI)) * 2 * M_PI);
381  }
382  //*** Keep angle positive (required for coin!)
383  if (angle <= 0.0f) // This is mandatory: Coin uses quaternions internally and can thus not
384  {
385  angle =
386  2 * M_PI +
387  angle; // reflect angles of 0deg without change of axis. Therefore set to 2Pi instead.
388  }
389 
390  t->rotation.getValue(axis, a0);
391  t->rotation.setValue(axis, angle);
392  //t->rotation.getValue(axis,a0); // just for control in debugger,if all is fine...
393 
394  return true;
395  }
396 
397  /**
398  * The virtual method OIFwdKinematicsInterface::buildScenery() is used to create
399  * a scenegraph.\n
400  * If you want to create your own scenegraph just override this method.
401  * Otherwise it reads the scenegraph stored in the file OIFwdKinematicsInterface::sceneryFilename.
402  * \return true if everything went well.
403  * \return false if no scenery could be created.
404  */
405  bool
407  {
408  return this->readSceneryFromFile();
409  }
410 
411  /**
412  * This method tries to read the scenegraph from the file OIFwdKinematicsInterface::sceneryFilename
413  * and stores it in OIFwdKinematicsInterface::root.
414  *
415  * \return true if everything went well and the scenegraph could be read.
416  * \return false if the file couldn't be opened or a problem was encountered while reading the file.
417  */
418  bool
420  {
421  if (this->sceneryFilename.empty())
422  {
423  return false;
424  }
425 
426  SoInput mySceneInput;
427  if (!mySceneInput.openFile(this->sceneryFilename.c_str()))
428  {
429  std::cerr << "OI: Cannot open file " << this->sceneryFilename << std::endl;
430  return false;
431  }
432 
433 
434  // Read the whole file into the database
435  root = SoDB::readAll(&mySceneInput);
436 
437 
438  if (NULL == root)
439  {
440  std::cerr << "OI: Problem reading file " << this->sceneryFilename << std::endl;
441  return false;
442  }
443  mySceneInput.closeFile();
444  expandFileNodes();
445  return true;
446  }
447 
448  //
449  // This routine searches for and expands all SoFile nodes in the
450  // given scene graph. It does this by making all the children of a
451  // SoFile node the children of its parent.
452  // (Code for this function taken from ivcat)
453  //
454  void
456  {
457  //
458  // Special case: if root is a file node, replace it with a group.
459  //
460  if (root->isOfType(SoFile::getClassTypeId()))
461  {
462  SoFile* f = (SoFile*)root;
463  SoGroup* g = f->copyChildren();
464  root->unref();
465  root = dynamic_cast<SoSeparator*>(g);
466  root->ref();
467  }
468 
469  // Search for all file nodes
470  SoSearchAction sa;
471  sa.setType(SoFile::getClassTypeId());
472  sa.setInterest(SoSearchAction::FIRST);
473  sa.setSearchingAll(TRUE);
474 
475  root->ref(); // why do I need to ref here ?
476  sa.apply(root);
477 
478  // We'll keep on searching until there are no more file nodes
479  // left. We don't search for all file nodes at once, because we
480  // need to modify the scene graph, and so the paths returned may
481  // be truncated (if there are several file nodes under a group, if
482  // there are files within files, etc). Dealing properly with that
483  // is complicated-- it is easier (but slower) to just reapply the
484  // search until it fails.
485  // We need an SoFullPath here because we're searching node kit
486  // contents.
487  SoFullPath* p = (SoFullPath*)sa.getPath();
488  while (p != NULL)
489  {
490  SoGroup* parent = (SoGroup*)p->getNodeFromTail(1);
491  assert(parent != NULL);
492 
493  SoFile* file = (SoFile*)p->getTail();
494 
495  // If the filename includes a directory path, add the directory name
496  // to the list of directories where to look for input files
497  SbString filename = file->name.getValue();
498 
499  std::cout << "OI: expanding file " << filename.getString() << std::endl;
500  //printf("OI: expanding file %s\n",filename.getString());
501 
502  int slashIndex = filename.find("/");
503  if (-1 != slashIndex)
504  {
505  SbString searchPath = filename.getSubString(0, slashIndex - 1);
506  SoInput::addDirectoryFirst(searchPath.getString());
507  }
508 
509  int fileIndex = p->getIndexFromTail(0);
510  assert(fileIndex != -1);
511 
512  // Now, add group of all children to file's parent's list of children,
513  // right after the file node:
514  SoGroup* fileGroup = file->copyChildren();
515  fileGroup->ref();
516  if (fileGroup != NULL)
517  {
518  parent->insertChild(fileGroup, fileIndex + 1);
519  }
520  else
521  {
522  // So we can at least see where the file node contents were
523  // supposed to go.
524  parent->insertChild(new SoGroup, fileIndex + 1);
525  }
526 
527 
528  // And expand the child node from the group.
529  // Note that if the File node is multiply instanced,
530  // the groups will not be instanced, but the children of the
531  // groups will be.
532  parent->removeChild(fileIndex);
533 
534  sa.apply(root);
535  p = (SoFullPath*)sa.getPath();
536  }
537  }
538 
539  bool
541  {
542  return iReady;
543  }
544 } // namespace visionx
DSHT_OI_RENDERSIZE_Y
#define DSHT_OI_RENDERSIZE_Y
Definition: HandLocalisationConstants.h:131
visionx::OIFwdKinematicsInterface::m_pCamera
SoPerspectiveCamera * m_pCamera
Definition: OIFwdKinematicsInterface.h:77
OIFwdKinematicsInterface.h
visionx::OIFwdKinematicsInterface::m_fFocalLengthY
float m_fFocalLengthY
Definition: OIFwdKinematicsInterface.h:81
visionx
ArmarX headers.
Definition: OpenPoseStressTest.h:38
visionx::OIFwdKinematicsInterface::root
SoSeparator * root
Definition: OIFwdKinematicsInterface.h:87
visionx::OIFwdKinematicsInterface::OIFwdKinematicsInterface
OIFwdKinematicsInterface(std::string filename="")
The constructor of the OIFwdKinematicsInterface class.
Definition: OIFwdKinematicsInterface.cpp:138
visionx::OIFwdKinematicsInterface::getPath
bool getPath(std::string name, SoPath *&p, SoNode *r=NULL)
Definition: OIFwdKinematicsInterface.cpp:299
visionx::OIFwdKinematicsInterface::getTranslation
bool getTranslation(SbVec3f &translation, SoPath *p)
Definition: OIFwdKinematicsInterface.cpp:327
visionx::OIFwdKinematicsInterface::m_pDavidsRoot
SoSeparator * m_pDavidsRoot
Definition: OIFwdKinematicsInterface.h:79
armarx::abs
std::vector< T > abs(const std::vector< T > &v)
Definition: VectorHelpers.h:281
visionx::OIFwdKinematicsInterface::m_pOffscreenRenderer
SoOffscreenRenderer * m_pOffscreenRenderer
Definition: OIFwdKinematicsInterface.h:80
M_PI
#define M_PI
Definition: MathTools.h:17
visionx::OIFwdKinematicsInterface::update
void update()
Definition: OIFwdKinematicsInterface.cpp:170
visionx::OIFwdKinematicsInterface::expandFileNodes
void expandFileNodes()
Definition: OIFwdKinematicsInterface.cpp:455
visionx::OIFwdKinematicsInterface::readSceneryFromFile
bool readSceneryFromFile()
This method tries to read the scenegraph from the file OIFwdKinematicsInterface::sceneryFilename and ...
Definition: OIFwdKinematicsInterface.cpp:419
visionx::OIFwdKinematicsInterface::initviewer
void initviewer()
Definition: OIFwdKinematicsInterface.cpp:195
visionx::OIFwdKinematicsInterface::~OIFwdKinematicsInterface
virtual ~OIFwdKinematicsInterface()
The virtual destructor of the OIFwdKinematicsInterface class.
Definition: OIFwdKinematicsInterface.cpp:153
filename
std::string filename
Definition: VisualizationRobot.cpp:86
visionx::OIFwdKinematicsInterface::m_pLight
SoDirectionalLight * m_pLight
Definition: OIFwdKinematicsInterface.h:78
visionx::OIFwdKinematicsInterface::buildScenery
virtual bool buildScenery()
The virtual method OIFwdKinematicsInterface::buildScenery() is used to create a scenegraph.
Definition: OIFwdKinematicsInterface.cpp:406
angle
double angle(const Point &a, const Point &b, const Point &c)
Definition: point.hpp:109
visionx::OIFwdKinematicsInterface::isInitialized
bool isInitialized()
Definition: OIFwdKinematicsInterface.cpp:540
visionx::OIFwdKinematicsInterface::setJointAngle
bool setJointAngle(SoPath *p, float angle)
Definition: OIFwdKinematicsInterface.cpp:358
visionx::OIFwdKinematicsInterface::m_pViewportRegion
SbViewportRegion * m_pViewportRegion
Definition: OIFwdKinematicsInterface.h:76
DSHT_OI_RENDERSIZE_X
#define DSHT_OI_RENDERSIZE_X
Definition: HandLocalisationConstants.h:130