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
26int 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
48class MyOIFwdKinematicsInterface : public OIFwdKinematicsInterface
49{
50public:
51 MyOIFwdKinematicsInterface(int argc, char ** argv, std::string filename = "")
52 : MyOIFwdKinematicsInterface(argc, argv, filename) {}
53protected:
54 virtual bool buildScenery();
55};
56
57bool 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
67int
68main (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
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
126namespace 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 */
138 OIFwdKinematicsInterface::OIFwdKinematicsInterface(std::string filename /* = "" */) :
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();
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
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();
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
#define DSHT_OI_RENDERSIZE_Y
#define DSHT_OI_RENDERSIZE_X
#define M_PI
Definition MathTools.h:17
The header file for OIFwdKinematicsInterface.
virtual ~OIFwdKinematicsInterface()
The virtual destructor of the OIFwdKinematicsInterface class.
virtual bool buildScenery()
The virtual method OIFwdKinematicsInterface::buildScenery() is used to create a scenegraph.
OIFwdKinematicsInterface(std::string filename="")
The constructor of the OIFwdKinematicsInterface class.
SoSeparator * root
This is the root node of the scenegraph which gets rendered.
bool getTranslation(SbVec3f &translation, SoPath *p)
bool getPath(std::string name, SoPath *&p, SoNode *r=NULL)
bool readSceneryFromFile()
This method tries to read the scenegraph from the file OIFwdKinematicsInterface::sceneryFilename and ...
ArmarX headers.
double angle(const Point &a, const Point &b, const Point &c)
Definition point.hpp:109