From 09ff77e30dbc0034823a00a5a554a76167db0460 Mon Sep 17 00:00:00 2001 From: vahrenkamp <vahrenkamp@042f3d55-54a8-47e9-b7fb-15903f145c44> Date: Sat, 17 Mar 2012 12:20:44 +0000 Subject: [PATCH] Fixing cyclic references between RobotNodes and Robot which resulted in memory leaks. Adding trajectory support to Scene. Adding trajectory IO and visualization methods. git-svn-id: http://svn.code.sf.net/p/simox/code/trunk@216 042f3d55-54a8-47e9-b7fb-15903f145c44 --- VirtualRobot/Nodes/RobotNode.cpp | 3 +- VirtualRobot/Nodes/RobotNode.h | 4 +- VirtualRobot/Robot.cpp | 8 +- VirtualRobot/Scene.cpp | 93 ++++++++++- VirtualRobot/Scene.h | 26 +++- VirtualRobot/Trajectory.cpp | 34 +++- VirtualRobot/Trajectory.h | 13 +- .../CoinVisualizationFactory.cpp | 104 +++++++++++++ .../CoinVisualizationFactory.h | 3 + .../OSGVisualizationFactory.cpp | 6 + .../OSGVisualizationFactory.h | 1 + .../Visualization/VisualizationFactory.h | 1 + .../Visualization/VisualizationNode.cpp | 1 + VirtualRobot/XML/BaseIO.cpp | 145 ++++++++++++++++++ VirtualRobot/XML/BaseIO.h | 11 ++ VirtualRobot/XML/ObjectIO.cpp | 10 +- VirtualRobot/XML/SceneIO.cpp | 39 +++-- VirtualRobot/XML/SceneIO.h | 1 + 18 files changed, 476 insertions(+), 27 deletions(-) diff --git a/VirtualRobot/Nodes/RobotNode.cpp b/VirtualRobot/Nodes/RobotNode.cpp index d0864f4e5..59bbf814e 100644 --- a/VirtualRobot/Nodes/RobotNode.cpp +++ b/VirtualRobot/Nodes/RobotNode.cpp @@ -549,7 +549,8 @@ std::vector<RobotNodePtr> RobotNode::getAllParents( RobotNodeSetPtr rns ) VirtualRobot::RobotNodePtr RobotNode::getParent() { - return parent; + RobotNodePtr p = parent.lock(); + return p; } void RobotNode::setJointLimits( float lo, float hi ) diff --git a/VirtualRobot/Nodes/RobotNode.h b/VirtualRobot/Nodes/RobotNode.h index 3284ee1e5..2e7133709 100644 --- a/VirtualRobot/Nodes/RobotNode.h +++ b/VirtualRobot/Nodes/RobotNode.h @@ -274,7 +274,7 @@ private: // Use the private setters and getters instead float jointValue; //< The joint value std::vector<std::string> childrenNames; std::vector< RobotNodePtr > children; - RobotNodePtr parent; + RobotNodeWeakPtr parent; Eigen::Matrix4f preJointTransformation; Eigen::Matrix4f postJointTransformation; @@ -290,7 +290,7 @@ protected: //Stefan virtual std::vector<std::string> getChildrenNames() const {return childrenNames;}; - virtual std::string getParentName() const {if (parent) return parent->getName(); else return std::string();}; + virtual std::string getParentName() const {RobotNodePtr p = parent.lock();if (p) return p->getName(); else return std::string();}; float jointValueOffset; float jointLimitLo,jointLimitHi; diff --git a/VirtualRobot/Robot.cpp b/VirtualRobot/Robot.cpp index 19868c234..9b439aebe 100644 --- a/VirtualRobot/Robot.cpp +++ b/VirtualRobot/Robot.cpp @@ -19,11 +19,17 @@ Robot::Robot() { } -Robot::~Robot(){} +Robot::~Robot() +{ +} LocalRobot::~LocalRobot() { + //int i = (int)rootNode.use_count(); robotNodeSetMap.clear(); + robotNodeMap.clear(); + rootNode.reset(); + //i = (int)rootNode.use_count(); } LocalRobot::LocalRobot(const std::string &name, const std::string &type) : Robot (name, type){ diff --git a/VirtualRobot/Scene.cpp b/VirtualRobot/Scene.cpp index ee0d3257a..26de7daaa 100644 --- a/VirtualRobot/Scene.cpp +++ b/VirtualRobot/Scene.cpp @@ -3,6 +3,7 @@ #include "VirtualRobotException.h" #include "ManipulationObject.h" #include "SceneObjectSet.h" +#include "Trajectory.h" #include "XML/BaseIO.h" namespace VirtualRobot @@ -17,6 +18,12 @@ Scene::Scene(const std::string &name) Scene::~Scene() { + robots.clear(); + robotConfigs.clear(); + obstacles.clear(); + manipulationObjects.clear(); + sceneObjectSets.clear(); + trajectories.clear(); } void Scene::registerRobot( RobotPtr robot ) @@ -94,6 +101,44 @@ void Scene::deRegisterObstacle( const std::string &name ) } + +void Scene::registerTrajectory( TrajectoryPtr t ) +{ + THROW_VR_EXCEPTION_IF(!t,"NULL data"); + if (hasTrajectory(t)) + return; + trajectories.push_back(t); +} + +void Scene::deRegisterTrajectory( TrajectoryPtr t ) +{ + THROW_VR_EXCEPTION_IF(!t,"NULL data"); + if (!hasTrajectory(t)) + return; + for (std::vector< TrajectoryPtr >::iterator i=trajectories.begin();i!=trajectories.end();i++) + { + if ( (*i) == t ) + { + trajectories.erase(i); + break; + } + } +} + +void Scene::deRegisterTrajectory( const std::string &name ) +{ + if (!hasTrajectory(name)) + return; + for (std::vector< TrajectoryPtr >::iterator i=trajectories.begin();i!=trajectories.end();i++) + { + if ((*i)->getName() == name) + { + trajectories.erase(i); + break; + } + } +} + void Scene::registerManipulationObject( ManipulationObjectPtr manipulationObject ) { THROW_VR_EXCEPTION_IF(!manipulationObject,"NULL data"); @@ -174,6 +219,29 @@ bool Scene::hasObstacle( const std::string &name ) const } + +bool Scene::hasTrajectory( TrajectoryPtr t ) const +{ + THROW_VR_EXCEPTION_IF(!t,"NULL data"); + for (std::vector< TrajectoryPtr >::const_iterator i=trajectories.begin();i!=trajectories.end();i++) + { + if (*i == t) + return true; + } + return false; +} + +bool Scene::hasTrajectory( const std::string &name ) const +{ + for (std::vector< TrajectoryPtr >::const_iterator i=trajectories.begin();i!=trajectories.end();i++) + { + if ((*i)->getName() == name) + return true; + } + return false; +} + + bool Scene::hasManipulationObject( ManipulationObjectPtr manipulationObject ) const { THROW_VR_EXCEPTION_IF(!manipulationObject,"NULL data"); @@ -219,6 +287,18 @@ VirtualRobot::ObstaclePtr Scene::getObstacle( const std::string &name ) return ObstaclePtr(); } +VirtualRobot::TrajectoryPtr Scene::getTrajectory( const std::string &name ) +{ + for (std::vector< TrajectoryPtr >::const_iterator i=trajectories.begin();i!=trajectories.end();i++) + { + if ((*i)->getName() == name) + return *i; + } + + VR_WARNING << "No Trajectory with name " << name << " registered in scene " << this->name << endl; + return TrajectoryPtr(); +} + VirtualRobot::ManipulationObjectPtr Scene::getManipulationObject( const std::string &name ) { for (std::vector< ManipulationObjectPtr >::const_iterator i=manipulationObjects.begin();i!=manipulationObjects.end();i++) @@ -349,6 +429,11 @@ std::vector< ObstaclePtr > Scene::getObstacles() return obstacles; } +std::vector< TrajectoryPtr > Scene::getTrajectories() +{ + return trajectories; +} + std::vector< ManipulationObjectPtr > Scene::getManipulationObjects() { return manipulationObjects; @@ -505,7 +590,6 @@ std::string Scene::getXMLString( const std::string &basePath ) ss << "\n"; } - // process sceneObjectSets for (size_t i=0;i<sceneObjectSets.size();i++) { @@ -513,6 +597,13 @@ std::string Scene::getXMLString( const std::string &basePath ) ss << "\n"; } + // process trajectories + for (size_t i=0;i<trajectories.size();i++) + { + ss << trajectories[i]->getXMLString(1); + ss << "\n"; + } + ss << "</Scene>\n"; return ss.str(); diff --git a/VirtualRobot/Scene.h b/VirtualRobot/Scene.h index 2d50918d9..e6468ed88 100644 --- a/VirtualRobot/Scene.h +++ b/VirtualRobot/Scene.h @@ -29,6 +29,7 @@ #include "RobotConfig.h" #include "Nodes/RobotNode.h" #include "Obstacle.h" +#include "Trajectory.h" #include "ManipulationObject.h" #include "RobotConfig.h" #include <string> @@ -127,6 +128,25 @@ public: std::vector< ObstaclePtr > getObstacles(); + /*! + Registers the Trajectory to this scene. If an Trajectory with the same name is already registered nothing happens. + */ + void registerTrajectory(TrajectoryPtr t); + + /*! + Removes the Trajectory to from this scene. If the Trajectory is not registered nothing happens. + */ + void deRegisterTrajectory(TrajectoryPtr t); + void deRegisterTrajectory(const std::string &name); + + bool hasTrajectory(TrajectoryPtr t) const; + bool hasTrajectory(const std::string &name) const; + + TrajectoryPtr getTrajectory(const std::string &name); + + std::vector< TrajectoryPtr > getTrajectories(); + + /*! @@ -181,6 +201,7 @@ protected: std::vector< ObstaclePtr > obstacles; std::vector< ManipulationObjectPtr > manipulationObjects; std::vector< SceneObjectSetPtr > sceneObjectSets; + std::vector< TrajectoryPtr > trajectories; }; @@ -198,19 +219,22 @@ boost::shared_ptr<T> Scene::getVisualization(SceneObject::VisualizationType visu std::vector<VirtualRobot::RobotPtr> collectedRobots = getRobots(); std::vector<VirtualRobot::ObstaclePtr> collectedObstacles = getObstacles(); std::vector<VirtualRobot::ManipulationObjectPtr> collectedManipulationObjects = getManipulationObjects(); + std::vector<VirtualRobot::TrajectoryPtr> collectedTrajectories = getTrajectories(); // collect all robotnodes std::vector<VirtualRobot::RobotNodePtr> collectedRobotNodes; for (size_t i=0;i<collectedRobots.size();i++) collectedRobots[i]->getRobotNodes(collectedRobotNodes,false); - std::vector<VisualizationNodePtr> collectedVisualizationNodes(collectedRobotNodes.size() + collectedObstacles.size() + collectedManipulationObjects.size()); + std::vector<VisualizationNodePtr> collectedVisualizationNodes(collectedRobotNodes.size() + collectedObstacles.size() + collectedManipulationObjects.size() + collectedTrajectories.size()); for (size_t i=0;i<collectedRobotNodes.size();i++) collectedVisualizationNodes[i] = collectedRobotNodes[i]->getVisualization(visuType); for (size_t i=0;i<collectedObstacles.size();i++) collectedVisualizationNodes[i+collectedRobotNodes.size()] = collectedObstacles[i]->getVisualization(visuType); for (size_t i=0;i<collectedManipulationObjects.size();i++) collectedVisualizationNodes[i+collectedRobotNodes.size()+collectedObstacles.size()] = collectedManipulationObjects[i]->getVisualization(visuType); + for (size_t i=0;i<collectedTrajectories.size();i++) + collectedVisualizationNodes[i+collectedRobotNodes.size()+collectedObstacles.size()+collectedManipulationObjects.size()] = collectedTrajectories[i]->getVisualization(T::getFactoryName()); boost::shared_ptr<T> visualization(new T(collectedVisualizationNodes)); diff --git a/VirtualRobot/Trajectory.cpp b/VirtualRobot/Trajectory.cpp index 8a4e2b65b..aa1ce070a 100644 --- a/VirtualRobot/Trajectory.cpp +++ b/VirtualRobot/Trajectory.cpp @@ -1,4 +1,5 @@ #include "Trajectory.h" +#include "Robot.h" #include "VirtualRobotException.h" #include <iostream> #include <sstream> @@ -322,7 +323,12 @@ std::string Trajectory::getXMLString(int tabs) const for (int i=0;i<tabs;i++) tab += "\t"; - ss << tab << "<Trajectory RobotNodeSet='" << rns->getName() << "' name='" << name << "' dim=" << dimension << ">\n"; + RobotPtr robot = rns->getRobot(); + + THROW_VR_EXCEPTION_IF(( !robot || !rns),"Need a valid robot and rns"); + + + ss << tab << "<Trajectory Robot='" << robot->getType() << "' RobotNodeSet='" << rns->getName() << "' name='" << name << "' dim='" << dimension << "'>\n"; for (unsigned int i = 0; i < path.size(); i++) { @@ -344,4 +350,30 @@ void Trajectory::print() const VR_INFO << s << endl; } +std::string Trajectory::getName() const +{ + return name; +} + +VirtualRobot::RobotNodeSetPtr Trajectory::getRobotNodeSet() +{ + return rns; +} + +VisualizationNodePtr Trajectory::getVisualization(std::string visualizationFactoryName) +{ + VisualizationFactoryPtr visualizationFactory; + if (visualizationFactoryName.empty()) + visualizationFactory=VisualizationFactory::first(NULL); + else + visualizationFactory = VisualizationFactory::fromName(visualizationFactoryName, NULL); + if (!visualizationFactory) + { + VR_ERROR << "Could not create factory for visu type " << visualizationFactoryName << endl; + return VisualizationNodePtr(); + } + + return visualizationFactory->createTrajectory(shared_from_this()); +} + } diff --git a/VirtualRobot/Trajectory.h b/VirtualRobot/Trajectory.h index 3744753f7..7f8d9c545 100644 --- a/VirtualRobot/Trajectory.h +++ b/VirtualRobot/Trajectory.h @@ -35,7 +35,7 @@ namespace VirtualRobot { /*! A representation of a trajectory in joint space, associated with a RobotNodeSet. */ -class VIRTUAL_ROBOT_IMPORT_EXPORT Trajectory +class VIRTUAL_ROBOT_IMPORT_EXPORT Trajectory : public boost::enable_shared_from_this<Trajectory> { public: EIGEN_MAKE_ALIGNED_OPERATOR_NEW @@ -135,7 +135,7 @@ public: //! For quick access to data. const std::vector <Eigen::VectorXf >& getData() const; - + VirtualRobot::RobotNodeSetPtr getRobotNodeSet(); /*! Creates the corresponding trajectory in workspace. @@ -150,6 +150,14 @@ public: */ virtual std::string getXMLString(int tabs = 0) const; + std::string getName() const; + + /*! + Gte a visualization for this trajectory. + \param visualizationFactoryName The string that identifies the factory. If not given, the first registered factory (which is usually the only one) is used. + */ + VisualizationNodePtr getVisualization(std::string visualizationFactoryName = ""); + protected: std::vector < Eigen::VectorXf > path; //!< vector with configurations which represent the path RobotNodeSetPtr rns; @@ -157,6 +165,7 @@ protected: unsigned int dimension; //!< dimension of rns }; + } // namespace VirtualRobot #endif /* _VirtualRobot_Trajectory_h_ */ diff --git a/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.cpp b/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.cpp index 94980fef2..707b4bf95 100644 --- a/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.cpp +++ b/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.cpp @@ -12,6 +12,7 @@ #include "CoinVisualization.h" #include "../../Robot.h" #include "../../Grasp.h" +#include "../../Trajectory.h" #include "../../GraspSet.h" #include "../../SceneObject.h" #include "../TriMeshModel.h" @@ -804,6 +805,7 @@ SoNode * CoinVisualizationFactory::getCoinVisualization( EndEffector::ContactInf } } }*/ + result->unrefNoDelete(); return result; } @@ -1140,6 +1142,14 @@ VirtualRobot::VisualizationNodePtr CoinVisualizationFactory::createArrow( const return node; } +VirtualRobot::VisualizationNodePtr CoinVisualizationFactory::createTrajectory(TrajectoryPtr t, Color colorNode, Color colorLine, float nodeSize, float lineSize ) +{ + SoNode *res = getCoinVisualization(t,colorNode,colorLine,nodeSize,lineSize); + + VisualizationNodePtr node(new CoinVisualizationNode(res)); + return node; +} + SoNode* CoinVisualizationFactory::getCoinVisualization(WorkspaceRepresentationPtr reachSpace, int a, int b, int c, /*const Eigen::Vector3f &positionGlobal,*/ int nrBestEntries, SoSeparator* arrow, const VirtualRobot::ColorMap &cm, bool transformToGlobalPose, unsigned char minValue) { @@ -1446,6 +1456,7 @@ SoNode* CoinVisualizationFactory::getCoinVisualization(WorkspaceRepresentationPt } } } + res->unrefNoDelete(); return res; } @@ -1521,6 +1532,99 @@ SoNode* CoinVisualizationFactory::getCoinVisualization(WorkspaceRepresentationPt } } } + res->unrefNoDelete(); + return res; +} + +SoNode * CoinVisualizationFactory::getCoinVisualization( TrajectoryPtr t, Color colorNode, Color colorLine, float nodeSize, float lineSize ) +{ + SoSeparator *res = new SoSeparator; + if (!t) + return res; + res->ref(); + RobotNodeSetPtr rns = t->getRobotNodeSet(); + Eigen::VectorXf c; + rns->getJointValues(c); + std::vector<Eigen::Matrix4f> ws = t->createWorkspaceTrajectory(); + + SoMaterial *materialNodeSolution = new SoMaterial(); + SoMaterial *materialLineSolution = new SoMaterial(); + materialNodeSolution->ambientColor.setValue(colorNode.r,colorNode.g,colorNode.b); + materialNodeSolution->diffuseColor.setValue(colorNode.r,colorNode.g,colorNode.b); + materialLineSolution->ambientColor.setValue(colorLine.r,colorLine.g,colorLine.b); + materialLineSolution->diffuseColor.setValue(colorLine.r,colorLine.g,colorLine.b); + SoSphere *sphereNodeSolution = new SoSphere(); + sphereNodeSolution->radius.setValue(nodeSize); + SoDrawStyle *lineSolutionStyle = new SoDrawStyle(); + lineSolutionStyle->lineWidth.setValue(lineSize); + + Eigen::VectorXf actConfig; + Eigen::VectorXf parentConfig; + float x,y,z; + float x2 = 0.0f,y2 = 0.0f,z2 = 0.0f; + + SoSeparator *sep = new SoSeparator(); + + SoComplexity *comple; + comple = new SoComplexity(); + comple->value = 1.0f; + sep->addChild(comple); + + + for (size_t i = 0; i <ws.size(); i++) + { + // create 3D model for nodes + SoSeparator *s = new SoSeparator(); + s->addChild(materialNodeSolution); + SoTranslation *t = new SoTranslation(); + + Eigen::Matrix4f m; + m = ws[i]; + x = m(0,3); + y = m(1,3); + z = m(2,3); + + t->translation.setValue(x,y,z); + s->addChild(t); + // display a solution node different + s->addChild(sphereNodeSolution); + sep->addChild(s); + + if (i>0) // lines for all configurations + { + // create line to parent + SoSeparator *s2 = new SoSeparator(); + + SbVec3f points[2]; + points[0].setValue(x2,y2,z2); + points[1].setValue(x,y,z); + + s2->addChild(lineSolutionStyle); + s2->addChild(materialLineSolution); + + SoCoordinate3* coordinate3 = new SoCoordinate3; + coordinate3->point.set1Value(0,points[0]); + coordinate3->point.set1Value(1,points[1]); + s2->addChild(coordinate3); + + SoLineSet* lineSet = new SoLineSet; + lineSet->numVertices.setValue(2); + lineSet->startIndex.setValue(0); + s2->addChild(lineSet); + + sep->addChild(s2); + } + x2 = x; + y2 = y; + z2 = z; + } // for + + + res->addChild(sep); + + rns->setJointValues(c); + + res->unrefNoDelete(); return res; } diff --git a/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.h b/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.h index 0a1e7c659..c4a138fa5 100644 --- a/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.h +++ b/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.h @@ -65,6 +65,7 @@ public: virtual VisualizationNodePtr createTriMeshModelVisualization(TriMeshModelPtr model, bool showNormals, Eigen::Matrix4f &pose); virtual VisualizationNodePtr createPlane(const Eigen::Vector3f &position, const Eigen::Vector3f &normal, float extend, float transparency, float colorR = 0.5f, float colorG = 0.5f, float colorB = 0.5f); virtual VisualizationNodePtr createArrow(const Eigen::Vector3f &n, float length = 50.0f, float width = 2.0f, const Color &color = Color::Gray()); + virtual VisualizationNodePtr createTrajectory(TrajectoryPtr t, Color colorNode = Color::Blue(), Color colorLine = Color::Gray(), float nodeSize = 15.0f, float lineSize = 4.0f); /*! Create an empty VisualizationNode. @@ -129,6 +130,8 @@ public: static SoNode *getCoinVisualization(TriMeshModelPtr model, bool shownormals, VisualizationFactory::Color color = VisualizationFactory::Color::Gray()); + + static SoNode *getCoinVisualization(TrajectoryPtr t, Color colorNode = Color::Blue(), Color colorLine = Color::Gray(), float nodeSize = 15.0f, float lineSize = 4.0f); /*! Create a visualization of the reachability data. */ diff --git a/VirtualRobot/Visualization/OSGVisualization/OSGVisualizationFactory.cpp b/VirtualRobot/Visualization/OSGVisualization/OSGVisualizationFactory.cpp index a22fad2e4..336133209 100644 --- a/VirtualRobot/Visualization/OSGVisualization/OSGVisualizationFactory.cpp +++ b/VirtualRobot/Visualization/OSGVisualization/OSGVisualizationFactory.cpp @@ -305,6 +305,12 @@ VirtualRobot::VisualizationNodePtr OSGVisualizationFactory::createPlane( const E return VisualizationNodePtr(); } +VirtualRobot::VisualizationNodePtr OSGVisualizationFactory::createTrajectory(TrajectoryPtr t, Color colorNode = Color::Blue(), Color colorLine = Color::Gray(), float nodeSize = 15.0f, float lineSize = 4.0f) +{ + VR_INFO << "init nyi..." << endl; + return VisualizationNodePtr(); +} + void OSGVisualizationFactory::switchToWireframe( osg::Node *srcNode ) { if( !srcNode ) diff --git a/VirtualRobot/Visualization/OSGVisualization/OSGVisualizationFactory.h b/VirtualRobot/Visualization/OSGVisualization/OSGVisualizationFactory.h index 011e0f23a..2643105ff 100644 --- a/VirtualRobot/Visualization/OSGVisualization/OSGVisualizationFactory.h +++ b/VirtualRobot/Visualization/OSGVisualization/OSGVisualizationFactory.h @@ -62,6 +62,7 @@ public: virtual VisualizationNodePtr createTriMeshModelVisualization(TriMeshModelPtr model, bool showNormals, Eigen::Matrix4f &pose); virtual VisualizationNodePtr createPlane(const Eigen::Vector3f &position, const Eigen::Vector3f &normal, float extend, float transparency, float colorR = 0.5f, float colorG = 0.5f, float colorB = 0.5f); virtual VisualizationNodePtr createArrow(const Eigen::Vector3f &n, float length = 50.0f, float width = 2.0f, const Color &color = Color::Gray()); + virtual VisualizationNodePtr createTrajectory(TrajectoryPtr t, Color colorNode = Color::Blue(), Color colorLine = Color::Gray(), float nodeSize = 15.0f, float lineSize = 4.0f); /*! Create an empty VisualizationNode. diff --git a/VirtualRobot/Visualization/VisualizationFactory.h b/VirtualRobot/Visualization/VisualizationFactory.h index 2b18375e7..49e689c1c 100644 --- a/VirtualRobot/Visualization/VisualizationFactory.h +++ b/VirtualRobot/Visualization/VisualizationFactory.h @@ -70,6 +70,7 @@ public: virtual VisualizationNodePtr createPlane(const Eigen::Vector3f &position, const Eigen::Vector3f &normal, float extend, float transparency, float colorR = 0.5f, float colorG = 0.5f, float colorB = 0.5f){return VisualizationNodePtr();} virtual VisualizationNodePtr createPlane(const MathTools::Plane &plane, float extend, float transparency, float colorR = 0.5f, float colorG = 0.5f, float colorB = 0.5f){return createPlane(plane.p, plane.n,extend,transparency,colorR,colorG,colorB);} virtual VisualizationNodePtr createArrow(const Eigen::Vector3f &n, float length = 50.0f, float width = 2.0f, const Color &color = Color::Gray()){return VisualizationNodePtr();} + virtual VisualizationNodePtr createTrajectory(TrajectoryPtr t, Color colorNode = Color::Blue(), Color colorLine = Color::Gray(), float nodeSize = 15.0f, float lineSize = 4.0f){return VisualizationNodePtr();} /*! Create an empty VisualizationNode. diff --git a/VirtualRobot/Visualization/VisualizationNode.cpp b/VirtualRobot/Visualization/VisualizationNode.cpp index 89443701c..4068e4c87 100644 --- a/VirtualRobot/Visualization/VisualizationNode.cpp +++ b/VirtualRobot/Visualization/VisualizationNode.cpp @@ -24,6 +24,7 @@ VisualizationNode::VisualizationNode() VisualizationNode::~VisualizationNode() { + attachedVisualizations.clear(); } VirtualRobot::VisualizationNodePtr VisualizationNode::clone(bool deepCopy) diff --git a/VirtualRobot/XML/BaseIO.cpp b/VirtualRobot/XML/BaseIO.cpp index 7a5e4a220..adfbbe2d6 100644 --- a/VirtualRobot/XML/BaseIO.cpp +++ b/VirtualRobot/XML/BaseIO.cpp @@ -1,7 +1,9 @@ #include "BaseIO.h" +#include "../Robot.h" #include "../RobotFactory.h" #include "../RobotNodeSet.h" +#include "../Trajectory.h" #include "../RuntimeEnvironment.h" #include "../VirtualRobotException.h" #include "../EndEffector/EndEffector.h" @@ -61,6 +63,21 @@ float BaseIO::convertToFloat(const char* s) return result; } +int BaseIO::convertToInt(const char* s) +{ + THROW_VR_EXCEPTION_IF(NULL == s, "Passing Null string to convertToInt()"); + std::stringstream intStream; + intStream << std::string(s); + int result; + + if (!(intStream >> result)) + { + THROW_VR_EXCEPTION("The string can not be parsed into an int value"); + } + + return result; +} + /** * This method gets the attribute \p attributeName from xml_node \p xmlNode and @@ -972,5 +989,133 @@ RobotNodeSetPtr BaseIO::processRobotNodeSet(rapidxml::xml_node<char>* setXMLNode return rns; } +bool BaseIO::processFloatValueTags(rapidxml::xml_node<char> *XMLNode, int dim, Eigen::VectorXf &stroreResult) +{ + if (!XMLNode || dim<=0) + return false; + stroreResult.resize(dim); + int entry = 0; + rapidxml::xml_node<>* node = XMLNode->first_node(); + while (node) + { + std::string nodeName = getLowerCase(node->name()); + if (nodeName == "c") + { + THROW_VR_EXCEPTION_IF(entry>=dim, "Too many entries in trajectory's point definition..." << endl); + stroreResult(entry) = getFloatByAttributeName(node,"value"); + } else + { + THROW_VR_EXCEPTION("XML definition <" << nodeName << "> not supported in trajectory point definition" << endl); + } + entry++; + node = node->next_sibling(); + } + THROW_VR_EXCEPTION_IF(entry<dim, "Not enough entries in trajectory's point definition..." << endl); + return true; +} + +TrajectoryPtr BaseIO::processTrajectory(rapidxml::xml_node<char> *trajectoryXMLNode, std::vector<RobotPtr> &robots) +{ + THROW_VR_EXCEPTION_IF(!trajectoryXMLNode, "NULL data for trajectoryXMLNode"); + + std::string robotName; + std::string nodeSetName; + std::string trajName; + int dim = -1; + + // get name and root + rapidxml::xml_attribute<> *attr = trajectoryXMLNode->first_attribute(); + while (attr) + { + std::string name = getLowerCase(attr->name()); + if (name=="name") + { + THROW_VR_EXCEPTION_IF(!trajName.empty(), "Trajectory contains multiple definitions of attribute name. First value is: " << trajName); + trajName = attr->value(); + } else if (name=="robot") + { + THROW_VR_EXCEPTION_IF(!robotName.empty(), "Trajectory contains multiple definitions of attribute Robot. First value is: " << robotName); + robotName = attr->value(); + } else if (name=="robotnodeset") + { + THROW_VR_EXCEPTION_IF(!nodeSetName.empty(), "Trajectory contains multiple definitions of attribute RobotNodeSet. First value is: " << nodeSetName); + nodeSetName = attr->value(); + } else if (name=="dim" || name=="dimension") + { + THROW_VR_EXCEPTION_IF(dim!=-1, "Trajectory contains multiple definitions of attribute dim. First value of dim: " << dim); + dim = convertToInt(attr->value()); + } + attr = attr->next_attribute(); + } + + THROW_VR_EXCEPTION_IF(robotName.empty(),"Invalid or missing Robot attribute"); + THROW_VR_EXCEPTION_IF(nodeSetName.empty(),"Invalid or missing RobotNodeSet attribute"); + + if (trajName.empty()) + { + trajName = "Trajectory"; + VR_WARNING << "Trajectory definition expects attribute 'RobotNodeSet'. Setting to " << trajName << endl; + } + RobotPtr r; + for (size_t i=0;i<robots.size();i++) + { + if (robots[i]->getType() == robotName) + { + r = robots[i]; + break; + } + } + THROW_VR_EXCEPTION_IF(!r,"Could not find robot with name " << robotName); + RobotNodeSetPtr rns = r->getRobotNodeSet(nodeSetName); + THROW_VR_EXCEPTION_IF(!rns,"Could not find RNS with name " << nodeSetName << " in robot " << robotName); + if (dim != rns->getSize()) + { + VR_WARNING << " Invalid dim attribute (" << dim << "). Setting dimension to " << rns->getSize() << endl; + dim = rns->getSize(); + } + + TrajectoryPtr res(new Trajectory(rns,trajName)); + rapidxml::xml_node<>* node = trajectoryXMLNode->first_node(); + while (node) + { + std::string nodeName = getLowerCase(node->name()); + if (nodeName == "point") + { + Eigen::VectorXf p; + + if (!processFloatValueTags(node,dim,p)) + { + VR_ERROR << "Error in processing configuration. Skipping entry" << endl; + } else + { + res->addPoint(p); + } + + } else + { + THROW_VR_EXCEPTION ("XML definition <" << nodeName << "> not supported in trajectory definition with name '" << trajName << "'." << endl); + } + + node = node->next_sibling(); + } + return res; +} + +bool BaseIO::writeXMLFile(const std::string &filename, const std::string &content, bool overwrite) +{ + if (!overwrite && boost::filesystem::exists(filename)) + return false; + + // save file + std::ofstream out(filename.c_str(),std::ios::out|std::ios::trunc); + + if (!out.is_open()) + return false; + + out << content; + out.close(); + return true; +} + } // namespace VirtualRobot diff --git a/VirtualRobot/XML/BaseIO.h b/VirtualRobot/XML/BaseIO.h index 1bb544645..74e079a90 100644 --- a/VirtualRobot/XML/BaseIO.h +++ b/VirtualRobot/XML/BaseIO.h @@ -54,6 +54,14 @@ public: static void makeAbsolutePath( const std::string &basePath, std::string &filename ); static void makeRelativePath( const std::string &basePath, std::string &filename ); + /*! + Create a file and store XML content. + \param filename The filename + \param content The XML content as string. No checks are performed. + \param overwrite If true, a potentionally existing file is silently overwritten. + \return True on success + */ + static bool writeXMLFile(const std::string &filename, const std::string &content, bool overwrite = true); protected: // instantiation not allowed @@ -62,6 +70,7 @@ protected: static bool isTrue(const char* s); static float convertToFloat(const char* s); + static int convertToInt(const char* s); static void processNodeList(rapidxml::xml_node<char>* parentNode, RobotPtr robot, std::vector<RobotNodePtr>& nodeList, bool clearList = true); static void processLimitsNode(rapidxml::xml_node<char> *limitsXMLNode, float &jointLimitLo, float &jointLimitHi); static std::string processFileNode(rapidxml::xml_node<char> *fileNode, const std::string &basePath); @@ -82,7 +91,9 @@ protected: static CollisionModelPtr processCollisionTag(rapidxml::xml_node<char> *colXMLNode, const std::string &tagName, const std::string &basePath); static void processPhysicsTag(rapidxml::xml_node<char> *physicsXMLNode, const std::string &nodeName, SceneObject::Physics &physics); static RobotNodeSetPtr processRobotNodeSet(rapidxml::xml_node<char>* setXMLNode, RobotPtr robo, const std::string& robotRootNode, int& robotNodeSetCounter ); + static TrajectoryPtr processTrajectory(rapidxml::xml_node<char> *trajectoryXMLNode,std::vector<RobotPtr> &robots); static Eigen::Matrix3f process3x3Matrix(rapidxml::xml_node<char> *matrixXMLNode); + static bool processFloatValueTags(rapidxml::xml_node<char> *XMLNode, int dim, Eigen::VectorXf &stroreResult); static bool hasUnitsAttribute(rapidxml::xml_node<char> *node); static std::vector< Units > getUnitsAttributes(rapidxml::xml_node<char> *node); static void getAllAttributes(rapidxml::xml_node<char> *node, const std::string &attrString, std::vector<std::string> &storeValues); diff --git a/VirtualRobot/XML/ObjectIO.cpp b/VirtualRobot/XML/ObjectIO.cpp index a235ed6f6..7f911cc83 100644 --- a/VirtualRobot/XML/ObjectIO.cpp +++ b/VirtualRobot/XML/ObjectIO.cpp @@ -334,15 +334,7 @@ bool ObjectIO::saveManipulationObject( ManipulationObjectPtr object, const std:: std::string xmlString = object->getXMLString(basePath); // save file - std::ofstream out(xmlFile.c_str()); - - if (!out.is_open()) - return false; - - out << xmlString; - out.close(); - - return true; + return BaseIO::writeXMLFile(xmlFile,xmlString,true); } diff --git a/VirtualRobot/XML/SceneIO.cpp b/VirtualRobot/XML/SceneIO.cpp index 319c1be27..e6a32aee5 100644 --- a/VirtualRobot/XML/SceneIO.cpp +++ b/VirtualRobot/XML/SceneIO.cpp @@ -6,6 +6,7 @@ #include <boost/filesystem.hpp> #include "RobotIO.h" #include "ObjectIO.h" +#include "../Trajectory.h" #include "../SceneObjectSet.h" namespace VirtualRobot { @@ -203,6 +204,18 @@ bool SceneIO::processSceneObstacle(rapidxml::xml_node<char>* sceneXMLNode, Scene return true; } +bool SceneIO::processSceneTrajectory(rapidxml::xml_node<char>* sceneXMLNode, ScenePtr scene ) +{ + THROW_VR_EXCEPTION_IF(!sceneXMLNode || !scene, "NULL data in processSceneTrajectory"); + + TrajectoryPtr o = BaseIO::processTrajectory(sceneXMLNode, scene->getRobots()); + if (!o) + return false; + + scene->registerTrajectory(o); + return true; +} + ScenePtr SceneIO::processScene(rapidxml::xml_node<char>* sceneXMLNode, const std::string& basePath) { THROW_VR_EXCEPTION_IF(!sceneXMLNode, "No <Scene> tag in XML definition"); @@ -213,6 +226,7 @@ ScenePtr SceneIO::processScene(rapidxml::xml_node<char>* sceneXMLNode, const std // process xml nodes std::vector<rapidxml::xml_node<char>* > sceneSetNodes; + std::vector<rapidxml::xml_node<char>* > trajectoryNodes; rapidxml::xml_node<> *XMLNode = sceneXMLNode->first_node(NULL,0,false); @@ -245,6 +259,9 @@ ScenePtr SceneIO::processScene(rapidxml::xml_node<char>* sceneXMLNode, const std std::string failedNodeName = processNameAttribute(XMLNode); THROW_VR_EXCEPTION("Failed to create ManipulationObject " << failedNodeName << " in scene " << scene->getName() << endl); } + } else if (nodeName=="trajectory") + { + trajectoryNodes.push_back(XMLNode); } else if (nodeName=="sceneobjectset") { sceneSetNodes.push_back(XMLNode); @@ -267,6 +284,18 @@ ScenePtr SceneIO::processScene(rapidxml::xml_node<char>* sceneXMLNode, const std } } + + // process all trajectories + for (size_t i=0;i<trajectoryNodes.size();i++) + { + bool r = processSceneTrajectory(trajectoryNodes[i], scene); + if (!r) + { + std::string failedNodeName = processNameAttribute(XMLNode); + THROW_VR_EXCEPTION("Failed to create trajectory " << failedNodeName << " in scene " << scene->getName() << endl); + } + } + return scene; } @@ -335,15 +364,7 @@ bool SceneIO::saveScene( ScenePtr s, const std::string &xmlFile ) std::string xmlString = s->getXMLString(basePath); // save file - std::ofstream out(xmlFile.c_str()); - - if (!out.is_open()) - return false; - - out << xmlString; - out.close(); - - return true; + return BaseIO::writeXMLFile(xmlFile,xmlString,true); } diff --git a/VirtualRobot/XML/SceneIO.h b/VirtualRobot/XML/SceneIO.h index 029bb4fb6..5c66d17b9 100644 --- a/VirtualRobot/XML/SceneIO.h +++ b/VirtualRobot/XML/SceneIO.h @@ -71,6 +71,7 @@ protected: static ScenePtr processSceneAttributes(rapidxml::xml_node<char>* sceneXMLNode); static bool processSceneRobot(rapidxml::xml_node<char>* sceneXMLNode, ScenePtr scene, const std::string& basePath ); static bool processSceneObstacle(rapidxml::xml_node<char>* sceneXMLNode, ScenePtr scene, const std::string& basePath ); + static bool processSceneTrajectory(rapidxml::xml_node<char>* sceneXMLNode, ScenePtr scene ); static bool processSceneManipulationObject(rapidxml::xml_node<char>* sceneXMLNode, ScenePtr scene, const std::string& basePath ); static bool processSceneObjectSet(rapidxml::xml_node<char>* sceneXMLNode, ScenePtr scene ); }; -- GitLab