diff --git a/VirtualRobot/ManipulationObject.cpp b/VirtualRobot/ManipulationObject.cpp
index a64158b79367e2d7685b9bff2eef3ea6c03d9e5b..c2e23672256499eda6016ced98eb2ebab46c4be1 100644
--- a/VirtualRobot/ManipulationObject.cpp
+++ b/VirtualRobot/ManipulationObject.cpp
@@ -109,6 +109,7 @@ namespace VirtualRobot
         ManipulationObjectPtr result(new ManipulationObject(name, clonedVisualizationNode, clonedCollisionModel, physics, colChecker));
 
         result->setGlobalPose(getGlobalPose());
+        result->primitiveApproximation = primitiveApproximation;
 
         appendSensorsTo(result);
         appendGraspSetsTo(result);
diff --git a/VirtualRobot/Nodes/RobotNode.cpp b/VirtualRobot/Nodes/RobotNode.cpp
index 284e4e57904d69f4122bd7a6576e4321976b7e7e..c8ecce937fe31c10d018550bf11bf5de3be62116 100644
--- a/VirtualRobot/Nodes/RobotNode.cpp
+++ b/VirtualRobot/Nodes/RobotNode.cpp
@@ -611,6 +611,7 @@ namespace VirtualRobot
         }
         result->basePath = basePath;
         result->setScaling(actualScaling);
+        result->primitiveApproximation = primitiveApproximation.clone();
         return result;
     }
 
diff --git a/VirtualRobot/Obstacle.cpp b/VirtualRobot/Obstacle.cpp
index 3881df846ded2e30bb40be1cf1958af5f443d8ef..2f1121b9a902b2d65b300f6dfabc366c8c6538d7 100644
--- a/VirtualRobot/Obstacle.cpp
+++ b/VirtualRobot/Obstacle.cpp
@@ -301,6 +301,7 @@ namespace VirtualRobot
         ObstaclePtr result(new Obstacle(name, clonedVisualizationNode, clonedCollisionModel, physics, colChecker));
 
         result->setGlobalPose(getGlobalPose());
+        result->primitiveApproximation = primitiveApproximation;
 
         appendSensorsTo(result);
         appendGraspSetsTo(result);
diff --git a/VirtualRobot/Primitive.cpp b/VirtualRobot/Primitive.cpp
index 8a79daaa497aac4883e8b884a5855e31e5dbc5e1..5abec0115f45e9d536c3b3b5e81e65275d12f6b9 100644
--- a/VirtualRobot/Primitive.cpp
+++ b/VirtualRobot/Primitive.cpp
@@ -63,5 +63,13 @@ namespace VirtualRobot
             return getXMLString("Cylinder", format.str(), tabs);
         }
 
+        std::string Capsule::toXMLString(int tabs)
+        {
+            std::stringstream format;
+            format << "radius=\"" << radius
+                   << "\" height=\"" << height << "\"";
+            return getXMLString("Capsule", format.str(), tabs);
+        }
+
     } //namespace Primitive
 } //namespace VirtualRobot
diff --git a/VirtualRobot/Primitive.h b/VirtualRobot/Primitive.h
index 5e27bf5fb68ffcf2ece4a3962f33c7c757027fb3..dd3c97134ccf6e52754ded8ef45d83b74a165659 100644
--- a/VirtualRobot/Primitive.h
+++ b/VirtualRobot/Primitive.h
@@ -20,6 +20,8 @@ namespace VirtualRobot
 
             virtual std::string toXMLString(int tabs) = 0;
 
+            virtual std::unique_ptr<Primitive> clone() const = 0;
+
         protected:
             Primitive(int type) : type(type), transform(Eigen::Matrix4f::Identity()) {}
             std::string getTransformString(int tabs = 0);
@@ -38,6 +40,11 @@ namespace VirtualRobot
             float height;
             float depth;
             std::string toXMLString(int tabs = 0) override;
+
+            std::unique_ptr<Primitive> clone() const final
+            {
+                return std::make_unique<Box>(width, height, depth);
+            }
         };
 
         class VIRTUAL_ROBOT_IMPORT_EXPORT Sphere : public Primitive
@@ -48,6 +55,11 @@ namespace VirtualRobot
             Sphere(float radius) : Primitive(TYPE), radius(radius) {}
             float radius;
             std::string toXMLString(int tabs = 0) override;
+
+            std::unique_ptr<Primitive> clone() const final
+            {
+                return std::make_unique<Sphere>(radius);
+            }
         };
 
         class VIRTUAL_ROBOT_IMPORT_EXPORT Cylinder : public Primitive
@@ -59,6 +71,30 @@ namespace VirtualRobot
             float radius;
             float height;
             std::string toXMLString(int tabs = 0) override;
+
+            std::unique_ptr<Primitive> clone() const final
+            {
+                return std::make_unique<Cylinder>(radius, height);
+            }
+        };
+
+        /**
+         * @brief The Capsule class. The capsule is extended along the y-axis.
+         */
+        class VIRTUAL_ROBOT_IMPORT_EXPORT Capsule : public Primitive
+        {
+        public:
+            static const int TYPE = 4;
+            Capsule() : Primitive(TYPE) {}
+            Capsule(float radius, float height) : Primitive(TYPE), radius(radius), height(height) {}
+            float radius;
+            float height;
+            std::string toXMLString(int tabs = 0) override;
+
+            std::unique_ptr<Primitive> clone() const final
+            {
+                return std::make_unique<Capsule>(radius, height);
+            }
         };
 
         typedef std::shared_ptr<Primitive> PrimitivePtr;
diff --git a/VirtualRobot/Robot.cpp b/VirtualRobot/Robot.cpp
index a5b3652b05ce4f6852e82a75db699af4d762b6a0..0310836a129da4565007c25597504ba7436c8488 100644
--- a/VirtualRobot/Robot.cpp
+++ b/VirtualRobot/Robot.cpp
@@ -923,6 +923,7 @@ namespace VirtualRobot
         {
             result->registerHumanMapping(getHumanMapping().value());
         }
+        result->primitiveApproximation = primitiveApproximation.clone();
 
         return result;
     }
diff --git a/VirtualRobot/SceneObject.cpp b/VirtualRobot/SceneObject.cpp
index af42dc2bbd2a9dd82dc4e439f6a4ddb39d00be97..4a5abee893c8ac1be62e455ca5a989dfc2415190 100644
--- a/VirtualRobot/SceneObject.cpp
+++ b/VirtualRobot/SceneObject.cpp
@@ -985,6 +985,7 @@ namespace VirtualRobot
         result->setGlobalPose(getGlobalPose());
         result->scaling = scaling;
         result->basePath = basePath;
+        result->primitiveApproximation = primitiveApproximation.clone();
         return result;
     }
 
@@ -1470,9 +1471,14 @@ namespace VirtualRobot
             std::vector<char> cstr(collisionModelXML.size() + 1);  // Create char buffer to store string copy
             strcpy(cstr.data(), collisionModelXML.c_str());             // Copy string into char buffer
             doc.parse<0>(cstr.data());
-            collisionModel = BaseIO::processCollisionTag(doc.first_node(), name, basePath);
-            if (collisionModel && scaling != 1.0f) { 
-                collisionModel = collisionModel->clone(collisionChecker, scaling);
+            auto collisionModel = BaseIO::processCollisionTag(doc.first_node(), name, basePath);
+            if (collisionModel && scaling != 1.0f)
+            {
+                setCollisionModel(collisionModel->clone(collisionChecker, scaling));
+            }
+            else
+            {
+                setCollisionModel(collisionModel);
             }
             reloaded = true;
         }
@@ -1483,10 +1489,18 @@ namespace VirtualRobot
             strcpy(cstr.data(), visualizationModelXML.c_str());             // Copy string into char buffer
             doc.parse<0>(cstr.data());
             bool useAsColModel;
-            visualizationModel = BaseIO::processVisualizationTag(doc.first_node(), name, basePath, useAsColModel);
-            if (visualizationModel && scaling != 1.0f) visualizationModel = visualizationModel->clone(true, scaling);
-            if (visualizationModel && collisionModel == nullptr && (useVisAsColModelIfMissing || useAsColModel)) {
-                collisionModel.reset(new CollisionModel(visualizationModel->clone(true), getName() + "_VISU_ColModel", CollisionCheckerPtr()));
+            auto visualizationModel = BaseIO::processVisualizationTag(doc.first_node(), name, basePath, useAsColModel);
+            if (visualizationModel && scaling != 1.0f)
+            {
+                setVisualization(visualizationModel->clone(true, scaling));
+            }
+            else
+            {
+                setVisualization(visualizationModel);
+            }
+            if (visualizationModel && collisionModel == nullptr && (useVisAsColModelIfMissing || useAsColModel))
+            {
+                setCollisionModel(std::make_shared<CollisionModel>(visualizationModel->clone(true), getName() + "_VISU_ColModel", CollisionCheckerPtr()));
             }
             reloaded = true;
         }
@@ -1499,4 +1513,109 @@ namespace VirtualRobot
     const std::string &SceneObject::getVisualizationModelXML() const {
         return visualizationModelXML;
     }
+
+    const SceneObject::PrimitiveApproximation &SceneObject::getPrimitiveApproximation() const
+    {
+        return primitiveApproximation;
+    }
+
+    SceneObject::PrimitiveApproximation &SceneObject::getPrimitiveApproximation()
+    {
+        return primitiveApproximation;
+    }
+
+    void SceneObject::setPrimitiveApproximationModel(const std::vector<std::string> &ids, bool loadDefault)
+    {
+        auto primitives = getPrimitiveApproximation().getModels(ids, loadDefault);
+        if (primitives.empty())
+        {
+            setCollisionModel(nullptr);
+        }
+        else
+        {
+            VisualizationFactoryPtr visualizationFactory = VisualizationFactory::first(NULL);
+            setCollisionModel(std::make_shared<CollisionModel>(visualizationFactory->getVisualizationFromPrimitives(primitives),
+                                                               getName() + "_PrimitiveModel", CollisionCheckerPtr()));
+        }
+
+        // recursive
+        for (auto &child : children)
+        {
+            child->setPrimitiveApproximationModel(ids, loadDefault);
+        }
+    }
+
+    void SceneObject::getPrimitiveApproximationIDs(std::set<std::string> &ids) const
+    {
+        primitiveApproximation.getPrimitiveApproximationIDs(ids);
+
+        // recursive
+        for (auto &child : children)
+        {
+            child->getPrimitiveApproximationIDs(ids);
+        }
+    }
+
+
+
+    std::vector<Primitive::PrimitivePtr> SceneObject::PrimitiveApproximation::getModels(const std::vector<std::string> &ids, bool loadDefault) const
+    {
+        std::vector<Primitive::PrimitivePtr> result;
+        if (loadDefault)
+        {
+            result.insert(result.end(), defaultPrimitives.begin(), defaultPrimitives.end());
+        }
+        for (const std::string &id : ids)
+        {
+            if (primitives.count(id) > 0)
+            {
+                result.insert(result.end(), primitives.at(id).begin(), primitives.at(id).end());
+            }
+        }
+        return result;
+    }
+
+
+    void SceneObject::PrimitiveApproximation::addModel(const std::vector<Primitive::PrimitivePtr> &primitives, const std::string &id)
+    {
+        if (id.empty())
+        {
+            defaultPrimitives.insert(defaultPrimitives.end(), primitives.begin(), primitives.end());
+        }
+        else if (this->primitives.count(id) == 0)
+        {
+            this->primitives[id] = primitives;
+        }
+        else
+        {
+            this->primitives[id].insert(this->primitives[id].end(), primitives.begin(), primitives.end());
+        }
+    }
+
+    void SceneObject::PrimitiveApproximation::getPrimitiveApproximationIDs(std::set<std::string> &ids) const
+    {
+        for (const auto& [id, _] : primitives) {
+            ids.insert(id);
+        }
+    }
+
+    SceneObject::PrimitiveApproximation SceneObject::PrimitiveApproximation::clone() const
+    {
+        PrimitiveApproximation cloned;
+        for (const auto &primitive : this->defaultPrimitives)
+        {
+            cloned.defaultPrimitives.push_back(primitive->clone());
+        }
+        for (const auto &[id, primitives] : this->primitives)
+        {
+            std::vector<Primitive::PrimitivePtr> clonedPrimitives;
+            for (const auto &primitive : primitives)
+            {
+                clonedPrimitives.push_back(primitive->clone());
+            }
+            cloned.primitives[id] = clonedPrimitives;
+        }
+        return cloned;
+    }
+
 } // namespace
diff --git a/VirtualRobot/SceneObject.h b/VirtualRobot/SceneObject.h
index ad6bce5d835f3d1cecd452fcf1eeb753b068b434..1832ffe6f23d02983e4f888b55afa785e8db13ea 100644
--- a/VirtualRobot/SceneObject.h
+++ b/VirtualRobot/SceneObject.h
@@ -30,6 +30,9 @@
 #include <string>
 #include <vector>
 #include <filesystem>
+#include <map>
+#include <set>
+#include "Primitive.h"
 
 
 namespace VirtualRobot
@@ -86,6 +89,21 @@ namespace VirtualRobot
             std::vector< std::string > ignoreCollisions; // ignore collisions with other objects (only used within collision engines)
         };
 
+        struct VIRTUAL_ROBOT_IMPORT_EXPORT PrimitiveApproximation
+        {
+            std::vector<Primitive::PrimitivePtr> getModels(const std::vector<std::string> &ids, bool loadDefault = true) const;
+
+            void addModel(const std::vector<Primitive::PrimitivePtr> &primitives, const std::string &id = std::string());
+
+            void getPrimitiveApproximationIDs(std::set<std::string> &ids) const;
+
+            PrimitiveApproximation clone() const;
+
+        private:
+            std::vector<Primitive::PrimitivePtr> defaultPrimitives;
+            std::map<std::string, std::vector<Primitive::PrimitivePtr>> primitives;
+        };
+
         /*!
         */
         SceneObject(const std::string& name, VisualizationNodePtr visualization = VisualizationNodePtr(), CollisionModelPtr collisionModel = CollisionModelPtr(), const Physics& p = Physics(), CollisionCheckerPtr colChecker = CollisionCheckerPtr());
@@ -398,6 +416,19 @@ namespace VirtualRobot
 
         const std::string& getVisualizationModelXML() const;
 
+        const PrimitiveApproximation& getPrimitiveApproximation() const;
+
+        PrimitiveApproximation& getPrimitiveApproximation();
+
+        void setPrimitiveApproximation(const PrimitiveApproximation& primitiveApproximation)
+        {
+            this->primitiveApproximation = primitiveApproximation;
+        }
+
+        void setPrimitiveApproximationModel(const std::vector<std::string> &ids, bool loadDefault = true);
+
+        void getPrimitiveApproximationIDs(std::set<std::string> &ids) const;
+
     protected:
         virtual SceneObject* _clone(const std::string& name, CollisionCheckerPtr colChecker = CollisionCheckerPtr(), float scaling = 1.0f) const;
 
@@ -447,6 +478,8 @@ namespace VirtualRobot
         CollisionCheckerPtr collisionChecker;
 
         float scaling = 1.0f;
+
+        PrimitiveApproximation primitiveApproximation;
     };
 
 
diff --git a/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.cpp b/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.cpp
index fe1f660317cbf154589b0043317103130b54a625..466541151c7872ff286175bcc0284b893b12eb4d 100644
--- a/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.cpp
+++ b/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.cpp
@@ -205,6 +205,37 @@ namespace VirtualRobot
             soCylinder->height = cylinder->height / 1000.f;
             coinVisualization->addChild(soCylinder);
         }
+        else if (primitive->type == Primitive::Capsule::TYPE)
+        {
+            // TODO find a better visualization for capsule
+            Primitive::Capsule* cylinder = std::dynamic_pointer_cast<Primitive::Capsule>(primitive).get();
+            SoCylinder* soCylinder = new SoCylinder;
+            soCylinder->radius = cylinder->radius / 1000.f;
+            soCylinder->height = cylinder->height / 1000.f;
+            coinVisualization->addChild(soCylinder);
+
+            {
+                SoSeparator* sep = new SoSeparator();
+                SoTranslation* transl = new SoTranslation;
+                sep->addChild(transl);
+                transl->translation.setValue(0, -cylinder->height / 2000.f, 0.);
+                SoSphere* soSphere = new SoSphere;
+                soSphere->radius = soCylinder->radius;
+                sep->addChild(soSphere);
+                coinVisualization->addChild(sep);
+            }
+
+            {
+                SoSeparator* sep = new SoSeparator();
+                SoTranslation* transl = new SoTranslation;
+                sep->addChild(transl);
+                transl->translation.setValue(0, cylinder->height / 2000.f, 0.);
+                SoSphere* soSphere = new SoSphere;
+                soSphere->radius = soCylinder->radius;
+                sep->addChild(soSphere);
+                coinVisualization->addChild(sep);
+            }
+        }
 
         if (boundingBox && coinVisualization)
         {
diff --git a/VirtualRobot/XML/BaseIO.cpp b/VirtualRobot/XML/BaseIO.cpp
index fdfd4161c58e646a5a0687aebbfc1975eb7a7626..988ca660b74dd8b791ab359ca9f29020cfc9a8d3 100644
--- a/VirtualRobot/XML/BaseIO.cpp
+++ b/VirtualRobot/XML/BaseIO.cpp
@@ -1258,6 +1258,22 @@ namespace VirtualRobot
         return collisionModel;
     }
 
+    void BaseIO::processPrimitiveModelTag(SceneObject::PrimitiveApproximation& primitiveApproximation,
+                                          const rapidxml::xml_node<char>* primitiveApproximationXMLNode)
+    {
+        rapidxml::xml_attribute<>* attr = primitiveApproximationXMLNode->first_attribute("enable", 0, false);
+        if (!attr || isTrue(attr->value()))
+        {
+            auto primitives = processPrimitives(primitiveApproximationXMLNode);
+            rapidxml::xml_attribute<>* idAttr = primitiveApproximationXMLNode->first_attribute("id", 0, false);
+            std::string id = idAttr ? idAttr->value() : std::string();
+            if (primitives.size() > 0)
+            {
+                primitiveApproximation.addModel(primitives, id);
+            }
+        }
+    }
+
     std::vector<VisualizationNodePtr> BaseIO::processVisuFiles(const rapidxml::xml_node<char>* visualizationXMLNode, const std::string& basePath, std::string& fileType)
     {
         const rapidxml::xml_node<>* node = visualizationXMLNode;
@@ -1415,6 +1431,13 @@ namespace VirtualRobot
                 cylinder->height = convertToFloat(primitiveXMLNode->first_attribute("height", 0, false)->value()) * lenFactor;
                 primitive.reset(cylinder);
             }
+            else if (pName == "capsule")
+            {
+                Primitive::Capsule* capsule = new Primitive::Capsule;
+                capsule->radius = convertToFloat(primitiveXMLNode->first_attribute("radius", 0, false)->value()) * lenFactor;
+                capsule->height = convertToFloat(primitiveXMLNode->first_attribute("height", 0, false)->value()) * lenFactor;
+                primitive.reset(capsule);
+            }
             else
             {
                 VR_ERROR << "Unknown primitive type \"" << pName << "\"; skipping";
diff --git a/VirtualRobot/XML/BaseIO.h b/VirtualRobot/XML/BaseIO.h
index 41a2d9a2507d686d994d2fe2a7001dd1b6db7bd9..7115303b2d9a88d30a01ef4627f9644092ce2843 100644
--- a/VirtualRobot/XML/BaseIO.h
+++ b/VirtualRobot/XML/BaseIO.h
@@ -98,6 +98,7 @@ namespace VirtualRobot
 
         static VisualizationNodePtr processVisualizationTag(const rapidxml::xml_node<char>* visuXMLNode, const std::string& tagName, const std::string& basePath, bool& useAsColModel);
         static CollisionModelPtr processCollisionTag(const rapidxml::xml_node<char>* colXMLNode, const std::string& tagName, const std::string& basePath);
+        static void processPrimitiveModelTag(SceneObject::PrimitiveApproximation& primitiveApproximation, const rapidxml::xml_node<char>* colXMLNode);
         static std::vector<Primitive::PrimitivePtr> processPrimitives(const rapidxml::xml_node<char>* primitivesXMLNode);
         static void processPhysicsTag(const rapidxml::xml_node<char>* physicsXMLNode, const std::string& nodeName, SceneObject::Physics& physics);
         static RobotNodeSetPtr processRobotNodeSet(const rapidxml::xml_node<char>* setXMLNode, RobotPtr robo, const std::string& robotRootNode, int& robotNodeSetCounter);
diff --git a/VirtualRobot/XML/ObjectIO.cpp b/VirtualRobot/XML/ObjectIO.cpp
index c47299a9a8f82827654e26d91a0496d74f20b4ff..25f5c295d61c643a97306c69b4647e1efe4933a1 100644
--- a/VirtualRobot/XML/ObjectIO.cpp
+++ b/VirtualRobot/XML/ObjectIO.cpp
@@ -152,6 +152,7 @@ namespace VirtualRobot
         SceneObject::Physics physics;
         bool physicsDefined = false;
         Eigen::Matrix4f globalPose = Eigen::Matrix4f::Identity();
+        SceneObject::PrimitiveApproximation primitiveApproximation;
 
         // get name
         std::string objName = processNameAttribute(objectXMLNode);
@@ -218,6 +219,10 @@ namespace VirtualRobot
                 collisionModel = processCollisionTag(node, objName, basePath);
                 colProcessed = true;
             }
+            else if (nodeName == "primitivemodel")
+            {
+                processPrimitiveModelTag(primitiveApproximation, node);
+            }
             else if (nodeName == "physics")
             {
                 THROW_VR_EXCEPTION_IF(physicsDefined, "Two physics tags defined in Obstacle '" << objName << "'." << endl);
@@ -239,6 +244,7 @@ namespace VirtualRobot
         // build object
         ObstaclePtr object(new Obstacle(objName, visualizationNode, collisionModel, physics));
         object->setGlobalPose(globalPose);
+        object->setPrimitiveApproximation(primitiveApproximation);
         return object;
     }
 
@@ -300,6 +306,7 @@ namespace VirtualRobot
         std::vector<GraspSetPtr> graspSets;
         Eigen::Matrix4f globalPose = Eigen::Matrix4f::Identity();
         std::vector< rapidxml::xml_node<>* > sensorTags;
+        SceneObject::PrimitiveApproximation primitiveApproximation;
 
         // get name
         std::string objName = processNameAttribute(objectXMLNode);
@@ -366,6 +373,10 @@ namespace VirtualRobot
                 collisionModel = processCollisionTag(node, objName, basePath);
                 colProcessed = true;
             }
+            else if (nodeName == "primitivemodel")
+            {
+                processPrimitiveModelTag(primitiveApproximation, node);
+            }
             else if (nodeName == "physics")
             {
                 THROW_VR_EXCEPTION_IF(physicsDefined, "Two physics tags defined in ManipulationObject '" << objName << "'." << endl);
@@ -412,6 +423,7 @@ namespace VirtualRobot
         }
 
         object->setGlobalPose(globalPose);
+        object->setPrimitiveApproximation(primitiveApproximation);
 
         return object;
     }
diff --git a/VirtualRobot/XML/RobotIO.cpp b/VirtualRobot/XML/RobotIO.cpp
index 4c6e2e61c8a1c1073b329258ee95dd1cc1c38524..01b3ec6bbd087ba004eca36a54a55bf639851791 100644
--- a/VirtualRobot/XML/RobotIO.cpp
+++ b/VirtualRobot/XML/RobotIO.cpp
@@ -649,6 +649,8 @@ namespace VirtualRobot
         SceneObject::Physics physics;
         bool physicsDefined = false;
         Eigen::Matrix4f transformMatrix = Eigen::Matrix4f::Identity();
+        SceneObject::PrimitiveApproximation primitiveApproximation;
+        //primitiveApproximation.addModel({ std::make_shared<Primitive::Cylinder>(10, 10) }, "test");
 
         rapidxml::xml_node<>* node = robotNodeXMLNode->first_node();
         rapidxml::xml_node<>* jointNodeXML = nullptr;
@@ -718,6 +720,10 @@ namespace VirtualRobot
                     collisionModelXML = ss.str();
                 }
             }
+            else if (nodeName == "primitivemodel")
+            {
+                processPrimitiveModelTag(primitiveApproximation, node);
+            }
             else if (nodeName == "child")
             {
                 processChildNode(node, childrenNames);
@@ -776,6 +782,7 @@ namespace VirtualRobot
         robotNode->basePath = basePath;
         robotNode->visualizationModelXML = visualizationModelXML;
         robotNode->collisionModelXML = collisionModelXML;
+        robotNode->setPrimitiveApproximation(primitiveApproximation);
 
         // process sensors
         for (auto& sensorTag : sensorTags)