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