diff --git a/SimDynamics/DynamicsEngine/BulletEngine/BulletObject.cpp b/SimDynamics/DynamicsEngine/BulletEngine/BulletObject.cpp
index b73366f4811e82cfbb065ba2f8b66fe34ce2d64e..680bb732dcd1a5c81f63c851998dbbbc6167b939 100644
--- a/SimDynamics/DynamicsEngine/BulletEngine/BulletObject.cpp
+++ b/SimDynamics/DynamicsEngine/BulletEngine/BulletObject.cpp
@@ -281,10 +281,9 @@ namespace SimDynamics
     {
         MutexLockPtr lock = getScopedLock();
         /* convert to local coord system, apply comoffset and convert back*/
-        Eigen::Matrix4f poseLocal = sceneObject->getGlobalPose().inverse() * pose;
-        poseLocal.block(0, 3, 3, 1) += com;
-        Eigen::Matrix4f poseGlobal = sceneObject->getGlobalPose() * poseLocal;
-        this->rigidBody->setWorldTransform(BulletEngine::getPoseBullet(poseGlobal));
+        Eigen::Matrix4f poseCom = pose;
+        poseCom.block(0, 3, 3, 1) += com;
+        this->rigidBody->setWorldTransform(BulletEngine::getPoseBullet(poseCom));
 
         // notify motionState of non-robot nodes
         if(!boost::dynamic_pointer_cast<VirtualRobot::RobotNode>(sceneObject))
@@ -296,7 +295,7 @@ namespace SimDynamics
     void BulletObject::setPose(const Eigen::Matrix4f& pose)
     {
         MutexLockPtr lock = getScopedLock();
-        DynamicsObject::setPose(pose);
+        //DynamicsObject::setPose(pose);
         setPoseIntern(pose);
     }
 
diff --git a/SimDynamics/DynamicsEngine/BulletEngine/BulletRobot.cpp b/SimDynamics/DynamicsEngine/BulletEngine/BulletRobot.cpp
index 73bc8835297cb36df37d79c8587bf1d8e16399ea..50ffce4a2b1bc70b054f46492019f4f32a1bb3b8 100644
--- a/SimDynamics/DynamicsEngine/BulletEngine/BulletRobot.cpp
+++ b/SimDynamics/DynamicsEngine/BulletEngine/BulletRobot.cpp
@@ -13,15 +13,12 @@
 #include <VirtualRobot/Nodes/ForceTorqueSensor.h>
 #include <VirtualRobot/Nodes/ContactSensor.h>
 
-// either hinge or generic6DOF constraints can be used
-//#define USE_BULLET_GENERIC_6DOF_CONSTRAINT
 
 //#define DEBUG_FIXED_OBJECTS
 //#define DEBUG_SHOW_LINKS
 using namespace VirtualRobot;
 using namespace std;
 
-//#define PRINT_TEST_DEBUG_MESSAGES
 
 namespace SimDynamics
 {
@@ -31,7 +28,7 @@ namespace SimDynamics
         // should be enough for up to 10ms/step
         , bulletMaxMotorImulse(30 * BulletObject::ScaleFactor)
     {
-        ignoreTranslationalJoints = true;
+        ignoreTranslationalJoints = false;
 
         buildBulletModels(enableJointMotors);
 
@@ -221,12 +218,6 @@ namespace SimDynamics
         btVector3 pivot1 = BulletEngine::getVecBullet(anchor_inNode1.block(0, 3, 3, 1));
         btVector3 pivot2 = BulletEngine::getVecBullet(anchor_inNode2.block(0, 3, 3, 1));
 
-
-
-#ifdef USE_BULLET_GENERIC_6DOF_CONSTRAINT
-        THROW_VR_EXCEPTION("USE_BULLET_GENERIC_6DOF_CONSTRAINT nyi in this method...");
-#endif
-
         // we need to align coord system joint, so that z-axis is rotation axis
 
         MathTools::Quaternion q1 = MathTools::getRotation(Eigen::Vector3f::UnitZ(), axisLocal);
@@ -260,6 +251,35 @@ namespace SimDynamics
         return hinge;
     }
 
+    boost::shared_ptr<btTypedConstraint> BulletRobot::createTranslationalJoint(boost::shared_ptr<btRigidBody> btBody1, boost::shared_ptr<btRigidBody> btBody2, Eigen::Matrix4f &coordSystemNode1, Eigen::Matrix4f &coordSystemNode2, Eigen::Matrix4f& anchor_inNode1, Eigen::Matrix4f& anchor_inNode2, Eigen::Vector3f &directionLocal, Eigen::Matrix4f& coordSystemJoint, double limMinBT, double limMaxBT)
+    {
+        // we need to align coord system joint, so that z-axis is rotation axis
+
+        btVector3 pivot1 = BulletEngine::getVecBullet(anchor_inNode1.block(0, 3, 3, 1));
+        btVector3 pivot2 = BulletEngine::getVecBullet(anchor_inNode2.block(0, 3, 3, 1));
+
+        MathTools::Quaternion q1 = MathTools::getRotation(Eigen::Vector3f::UnitX(), directionLocal); // dont ask me why this has to be the X axis...
+        Eigen::Matrix4f rotationzAlignment = MathTools::quat2eigen4f(q1);
+        Eigen::Matrix4f coordSystemJoint_zAligned =  coordSystemJoint * rotationzAlignment;
+
+        // now we need to pivot points in local coord systems
+        btTransform tr1 = BulletEngine::getPoseBullet(coordSystemNode1.inverse() * coordSystemJoint_zAligned);
+        btTransform tr2 = BulletEngine::getPoseBullet(coordSystemNode2.inverse() * coordSystemJoint_zAligned);
+        tr1.getOrigin() = pivot1;
+        tr2.getOrigin() = pivot2;
+
+        boost::shared_ptr<btSliderConstraint> joint(new btSliderConstraint(*btBody1, *btBody2, tr1, tr2, true));
+
+        // disable agular part
+        joint->setLowerAngLimit(btScalar(0));
+        joint->setUpperAngLimit(btScalar(0));
+
+        joint->setLowerLinLimit(btScalar(limMinBT));
+        joint->setUpperLinLimit(btScalar(limMaxBT));
+
+        return joint;
+    }
+
     boost::shared_ptr<btTypedConstraint> BulletRobot::createFixedJoint(boost::shared_ptr<btRigidBody> btBody1, boost::shared_ptr<btRigidBody> btBody2, Eigen::Matrix4f& anchor_inNode1, Eigen::Matrix4f& anchor_inNode2)
     {
         btTransform localA, localB;
@@ -344,9 +364,22 @@ namespace SimDynamics
         double vr2bulletOffset = 0.0f;
 
 
-        THROW_VR_EXCEPTION_IF((!ignoreTranslationalJoints && joint->isTranslationalJoint()), "Translational joints nyi...");
+        if (joint->isTranslationalJoint() && !ignoreTranslationalJoints)
+        {
+            boost::shared_ptr<RobotNodePrismatic> rnPrisJoint = boost::dynamic_pointer_cast<RobotNodePrismatic>(joint);
+
+            double limMin, limMax;
+            btScalar diff = joint->getJointValueOffset();
+            limMin = (joint->getJointLimitLo() + diff) / 1000 * BulletObject::ScaleFactor; //mm -> m
+            limMax = (joint->getJointLimitHi() + diff) / 1000 * BulletObject::ScaleFactor; //mm -> m
+
+            Eigen::Vector3f directionLocal = rnPrisJoint->getJointTranslationDirectionJointCoordSystem();
+
+            jointbt = createTranslationalJoint(btBody1, btBody2, coordSystemNode1, coordSystemNode2, anchor_inNode1, anchor_inNode2, directionLocal, coordSystemJoint, limMin, limMax);
 
-        if (joint->isRotationalJoint())
+            vr2bulletOffset = diff;
+        }
+        else if (joint->isRotationalJoint())
         {
             // create joint
             boost::shared_ptr<RobotNodeRevolute> rnRevJoint = boost::dynamic_pointer_cast<RobotNodeRevolute>(joint);
@@ -433,7 +466,7 @@ namespace SimDynamics
         links.push_back(i);
 #ifndef DEBUG_FIXED_OBJECTS
 
-        if (enableJointMotors && joint->isRotationalJoint())
+        if (enableJointMotors && (joint->isRotationalJoint() || (joint->isTranslationalJoint()) && !ignoreTranslationalJoints))
         {
             // start standard actuator
             actuateNode(joint, joint->getJointValue());
@@ -497,99 +530,123 @@ namespace SimDynamics
             //cout << "it:" << it->first << ", name: " << it->first->getName() << endl;
             VelocityMotorController& controller = actuationControllers[it->first];
 
-            if (it->second.node->isRotationalJoint())
-            {
-                LinkInfo link = getLink(it->second.node);
+            if (!it->second.node->isRotationalJoint() && !it->second.node->isTranslationalJoint())
+                continue;
 
-                const ActuationMode& actuation = it->second.actuation;
+            LinkInfo link = getLink(it->second.node);
 
-                btScalar posTarget = btScalar(it->second.jointValueTarget + link.jointValueOffset);
-                btScalar posActual = btScalar(getJointAngle(it->first));
-                btScalar velActual = btScalar(getJointSpeed(it->first));
-                btScalar velocityTarget = btScalar(it->second.jointVelocityTarget);
-                controller.setName(it->first->getName());
-#ifdef USE_BULLET_GENERIC_6DOF_CONSTRAINT
-                boost::shared_ptr<btGeneric6DofConstraint> dof = boost::dynamic_pointer_cast<btGeneric6DofConstraint>(link.joint);
-                VR_ASSERT(dof);
-                btRotationalLimitMotor* m = dof->getRotationalLimitMotor(0);
-                VR_ASSERT(m);
+            const ActuationMode& actuation = it->second.actuation;
 
-                if (actuation.mode == 0)
+            // CHECK FOR DISABLED MOTORS
+            if (actuation.mode == 0)
+            {
+                if (it->second.node->isRotationalJoint())
                 {
-                    m->m_enableMotor = false;
+                    boost::shared_ptr<btHingeConstraint> hinge = boost::dynamic_pointer_cast<btHingeConstraint>(link.joint);
+                    hinge->enableMotor(false);
                     continue;
                 }
-
-                m->m_enableMotor = true;
-
-                if (actuation.modes.position && actuation.modes.velocity)
+                else if (it->second.node->isTranslationalJoint() && !ignoreTranslationalJoints)
                 {
-                    m->m_targetVelocity = controller.update(posTarget - posActual, velocityTarget, actuation, dt);
-                }
-                else if (actuation.modes.position)
-                {
-                    m->m_targetVelocity = controller.update(posTarget - posActual, 0, actuation, dt);
+                    boost::shared_ptr<btSliderConstraint> slider = boost::dynamic_pointer_cast<btSliderConstraint>(link.joint);
+                    slider->setPoweredLinMotor(false);
+                    continue;
                 }
-                else if (actuation.modes.velocity)
+             }
+
+
+            if (actuation.modes.torque)
+            {
+                // TORQUE MODES
+
+                 if (it->second.node->isRotationalJoint())
+                 {
+                     boost::shared_ptr<btHingeConstraint> hinge = boost::dynamic_pointer_cast<btHingeConstraint>(link.joint);
+                     auto torque = it->second.jointTorqueTarget;
+                     btVector3 hingeAxisLocalA =
+                             hinge->getFrameOffsetA().getBasis().getColumn(2);
+                     btVector3 hingeAxisLocalB =
+                             hinge->getFrameOffsetB().getBasis().getColumn(2);
+                     btVector3 hingeAxisWorldA =
+                             hinge->getRigidBodyA().getWorldTransform().getBasis() *
+                             hingeAxisLocalA;
+                     btVector3 hingeAxisWorldB =
+                             hinge->getRigidBodyB().getWorldTransform().getBasis() *
+                             hingeAxisLocalB;
+
+
+                     int sign = torque > 0?1:-1;
+                     torque = std::min<double>(fabs(torque), it->first->getMaxTorque()) * sign;
+
+                     btVector3 hingeTorqueA = - torque * hingeAxisWorldA;
+                     btVector3 hingeTorqueB =   torque * hingeAxisWorldB;
+                     hinge->enableMotor(false);
+                     hinge->getRigidBodyA().applyTorque(hingeTorqueA);
+                     hinge->getRigidBodyB().applyTorque(hingeTorqueB);
+                 }
+                 else
+                 {
+                     // not yet tested!
+                     boost::shared_ptr<btSliderConstraint> slider = boost::dynamic_pointer_cast<btSliderConstraint>(link.joint);
+                     auto torque = it->second.jointTorqueTarget;
+                     btVector3 sliderAxisLocalA =
+                             slider->getFrameOffsetA().getBasis().getColumn(2);
+                     btVector3 sliderAxisLocalB =
+                             slider->getFrameOffsetB().getBasis().getColumn(2);
+                     btVector3 sliderAxisWorldA =
+                             slider->getRigidBodyA().getWorldTransform().getBasis() *
+                             sliderAxisLocalA;
+                     btVector3 sliderAxisWorldB =
+                             slider->getRigidBodyB().getWorldTransform().getBasis() *
+                             sliderAxisLocalB;
+
+
+                     int sign = torque > 0?1:-1;
+                     torque = std::min<double>(fabs(torque), it->first->getMaxTorque()) * sign;
+
+                     btVector3 sliderTorqueA = - torque * sliderAxisWorldA;
+                     btVector3 sliderTorqueB =   torque * sliderAxisWorldB;
+                     slider->setPoweredLinMotor(false);
+                     slider->btTypedConstraint::getRigidBodyA().applyCentralForce(sliderTorqueA);
+                     slider->btTypedConstraint::getRigidBodyB().applyCentralForce(sliderTorqueB);
+                 }
+            }
+            else if (actuation.modes.position || actuation.modes.velocity)
+            {
+                // POSITION, VELOCITY OR POSITION&VELOCITY MODE
+
+                btScalar velActual = btScalar(getJointSpeed(it->first));
+                btScalar velocityTarget = btScalar(it->second.jointVelocityTarget);
+
+                if (actuation.modes.velocity && !actuation.modes.position)
                 {
-                    m->m_targetVelocity = controller.update(0, velocityTarget, actuation, dt);
+                    // bullet is buggy here and cannot reach velocity targets for some joints, use a position-velocity mode as workaround
+                    it->second.jointValueTarget += velocityTarget * dt;
                 }
 
-                // FIXME torque based control is ignored
-#else
-                boost::shared_ptr<btHingeConstraint> hinge = boost::dynamic_pointer_cast<btHingeConstraint>(link.joint);
+                btScalar posTarget = btScalar(it->second.jointValueTarget + link.jointValueOffset);
+                btScalar posActual = btScalar(getJointAngle(it->first));
+                controller.setName(it->first->getName());
 
-                if (actuation.mode == 0)
+                if (it->second.node->isTranslationalJoint())
                 {
-                    hinge->enableMotor(false);
-                    continue;
+                    posTarget *= 0.001;
+                    posActual *= 0.001;
+                    velActual *= 0.001;
+                    velocityTarget *= 0.001;
                 }
 
                 double targetVelocity;
-                if (actuation.modes.position && actuation.modes.velocity)
+                if (!actuation.modes.position)
                 {
-//                    cout << "################### " << it->second.node->getName() <<  " error: " << (posTarget - posActual) << ", velTarget:" << velocityTarget << endl;
-                    targetVelocity = controller.update(posTarget - posActual, velocityTarget, actuation, btScalar(dt));
-                }
-                else if (actuation.modes.position)
-                {
-//                    cout << "################### " << it->second.node->getName() <<  " error: " << (posTarget - posActual) << ", posTarget " << posTarget << endl;
-                    targetVelocity = controller.update(posTarget - posActual, 0.0, actuation, btScalar(dt));
-                }
-                else if (actuation.modes.velocity)
-                {
-                    // bullet is buggy here and cannot reach velocity targets for some joints, use a position-velocity mode as workaround
-                    it->second.jointValueTarget += velocityTarget * dt;
+                    // we always use position or position-velocity mode
                     ActuationMode tempAct = actuation;
                     tempAct.modes.position = 1;
-                    targetVelocity = controller.update(it->second.jointValueTarget - posActual, velocityTarget, tempAct, btScalar(dt));
-//                    if (it->first->getName() == "Upperarm R")
-//                        cout << "################### " << target.node->getName() << " velActual:" << velActual << ", velTarget " << velocityTarget << " targetVelocity " << targetVelocity <<  " pos target: " << target.jointValueTarget <<  " posActual: " << posActual << endl;
+                    targetVelocity = controller.update(posTarget - posActual, velocityTarget, tempAct, btScalar(dt));
                 }
-                else if (actuation.modes.torque)
+                else
                 {
-                    //cout << "################### torque:" << it->second.jointTorqueTarget << endl;
-                    auto torque = it->second.jointTorqueTarget;
-                    btVector3 hingeAxisLocalA =
-                            hinge->getFrameOffsetA().getBasis().getColumn(2);
-                    btVector3 hingeAxisLocalB =
-                            hinge->getFrameOffsetB().getBasis().getColumn(2);
-                    btVector3 hingeAxisWorldA =
-                            hinge->getRigidBodyA().getWorldTransform().getBasis() *
-                            hingeAxisLocalA;
-                    btVector3 hingeAxisWorldB =
-                            hinge->getRigidBodyB().getWorldTransform().getBasis() *
-                            hingeAxisLocalB;
-
-
-                    int sign = torque > 0?1:-1;
-                    torque = std::min<double>(fabs(torque), it->first->getMaxTorque()) * sign;
-
-                    btVector3 hingeTorqueA = - torque * hingeAxisWorldA;
-                    btVector3 hingeTorqueB =   torque * hingeAxisWorldB;
-                    hinge->enableMotor(false);
-                    hinge->getRigidBodyA().applyTorque(hingeTorqueA);
-                    hinge->getRigidBodyB().applyTorque(hingeTorqueB);
+                    targetVelocity = controller.update(posTarget - posActual, velocityTarget, actuation, btScalar(dt));
                 }
 
                 btScalar maxImpulse = bulletMaxMotorImulse;
@@ -599,29 +656,23 @@ namespace SimDynamics
                     maxImpulse = it->second.node->getMaxTorque() * btScalar(dt) * BulletObject::ScaleFactor  * BulletObject::ScaleFactor * BulletObject::ScaleFactor;
                     //cout << "node:" << it->second.node->getName() << ", max impulse: " << maxImpulse << ", dt:" << dt << ", maxImp:" << it->second.node->getMaxTorque() << endl;
                 }
-#ifdef PRINT_TEST_DEBUG_MESSAGES
-
-                if (it->first->getName() == "LegL_Ank1_joint")
-//                if(posTarget - posActual > 0.05)
-                {
-                    double p,i,d;
-                    controller.getPosPID(p,i,d);
-                    std::cout << it->first->getName() << ": " << (actuation.modes.velocity?true:false) << " " << (actuation.modes.position?true:false) << " p: " << p;
-                    cout << "################### " << it->first->getName() <<" error: " << (posTarget - posActual)<< ", actvel:"  << velActual << ", target vel:" << targetVelocity << ", maxImpulse: " << maxImpulse << " applied impulse " << hinge->internalGetAppliedImpulse() << endl;
-                }
-
-#endif
                 if(fabs(targetVelocity) > 0.00001)
                 {
                     link.dynNode1->getRigidBody()->activate();
                     link.dynNode2->getRigidBody()->activate();
                 }
-                if (!actuation.modes.torque)
+                if (it->second.node->isRotationalJoint())
                 {
+                    boost::shared_ptr<btHingeConstraint> hinge = boost::dynamic_pointer_cast<btHingeConstraint>(link.joint);
                     hinge->enableAngularMotor(true, btScalar(targetVelocity), maxImpulse);
                 }
-
-#endif
+                else if (it->second.node->isTranslationalJoint() && !ignoreTranslationalJoints)
+                {
+                    boost::shared_ptr<btSliderConstraint> slider = boost::dynamic_pointer_cast<btSliderConstraint>(link.joint);
+                    slider->setMaxLinMotorForce(maxImpulse * 1000); // Magic number!!!
+                    slider->setTargetLinMotorVelocity(btScalar(targetVelocity));
+                    slider->setPoweredLinMotor(true);
+                }
             }
         }
 
@@ -957,7 +1008,7 @@ namespace SimDynamics
         MutexLockPtr lock = getScopedLock();
         VR_ASSERT(node);
 
-        if (node->isRotationalJoint())
+        if (node->isRotationalJoint() || (node->isTranslationalJoint() && !ignoreTranslationalJoints))
         {
             if (!hasLink(node))
             {
@@ -965,52 +1016,18 @@ namespace SimDynamics
                 return;
             }
 
-            LinkInfo link = getLink(node);
-#ifdef USE_BULLET_GENERIC_6DOF_CONSTRAINT
-            boost::shared_ptr<btGeneric6DofConstraint> dof = boost::dynamic_pointer_cast<btGeneric6DofConstraint>(link.joint);
-            VR_ASSERT(dof);
-            btRotationalLimitMotor* m = dof->getRotationalLimitMotor(0);
-            VR_ASSERT(m);
-            m->m_enableMotor = true;
-            m->m_maxMotorForce = 5;//bulletMaxMotorImulse; //?!
-            m->m_maxLimitForce = 300;
             DynamicsRobot::actuateNode(node, jointValue);
-#else
-            boost::shared_ptr<btHingeConstraint> hinge = boost::dynamic_pointer_cast<btHingeConstraint>(link.joint);
-
-            /*if (!hinge)
+        }
+        else
+        {
+            if (node->isTranslationalJoint() && ignoreTranslationalJoints)
             {
-                // hinge2 / universal joint
-                boost::shared_ptr<btUniversalConstraint> hinge2 = boost::dynamic_pointer_cast<btUniversalConstraint>(link.joint);
-                VR_ASSERT(hinge2);
-                btRotationalLimitMotor* m;
-
-                if (node == link.nodeJoint)
-                {
-                    m = hinge2->getRotationalLimitMotor(1); // second motor
-                }
-                else
-                {
-                    VR_ASSERT(node == link.nodeJoint2);
-                    m = hinge2->getRotationalLimitMotor(2); // third motor
-                }
-
-                VR_ASSERT(m);
-                m->m_enableMotor = true;
-                m->m_maxMotorForce = 5;//bulletMaxMotorImulse; //?!
-                m->m_maxLimitForce = 300;
+                VR_WARNING << "Translational joints ignored. (ignoring node " << node->getName() << ")." << endl;
             }
             else
             {
-                //hinge->enableAngularMotor(true,0.0f,bulletMaxMotorImulse);// is max impulse ok?! (10 seems to be ok, 1 oscillates)
-            }*/
-
-            DynamicsRobot::actuateNode(node, jointValue);
-#endif
-        }
-        else
-        {
-            VR_ERROR << "Only Revolute joints implemented so far (ignoring node " << node->getName() << ")." << endl;
+                VR_ERROR << "Only Revolute and translational joints implemented so far (ignoring node " << node->getName() << ")." << endl;
+            }
         }
     }
 
@@ -1018,60 +1035,22 @@ namespace SimDynamics
     {
         MutexLockPtr lock = getScopedLock();
         VR_ASSERT(node);
-        if (node->isRotationalJoint())
-        {
-            if (!hasLink(node))
-            {
-                VR_ERROR << "No link for node " << node->getName() << endl;
-                return;
-            }
-
-            LinkInfo link = getLink(node);
-#ifdef USE_BULLET_GENERIC_6DOF_CONSTRAINT
-            boost::shared_ptr<btGeneric6DofConstraint> dof = boost::dynamic_pointer_cast<btGeneric6DofConstraint>(link.joint);
-            VR_ASSERT(dof);
-            btRotationalLimitMotor* m = dof->getRotationalLimitMotor(0);
-            VR_ASSERT(m);
-            m->m_enableMotor = true;
-            m->m_maxMotorForce = 5;//bulletMaxMotorImulse; //?!
-            m->m_maxLimitForce = 300;
-            DynamicsRobot::actuateNodeVel(node, jointVelocity);
-#else
-            boost::shared_ptr<btHingeConstraint> hinge = boost::dynamic_pointer_cast<btHingeConstraint>(link.joint);
 
-            /*if (!hinge)
-            {
-                // hinge2 / universal joint
-                boost::shared_ptr<btUniversalConstraint> hinge2 = boost::dynamic_pointer_cast<btUniversalConstraint>(link.joint);
-                VR_ASSERT(hinge2);
-                btRotationalLimitMotor* m;
-
-                if (node == link.nodeJoint)
-                {
-                    m = hinge2->getRotationalLimitMotor(1); // second motor
-                }
-                else
-                {
-                    VR_ASSERT(node == link.nodeJoint2);
-                    m = hinge2->getRotationalLimitMotor(2); // third motor
-                }
+        if (!hasLink(node))
+        {
+            VR_ERROR << "No link for node " << node->getName() << endl;
+            return;
+        }
 
-                VR_ASSERT(m);
-                m->m_enableMotor = true;
-                m->m_maxMotorForce = 5;//bulletMaxMotorImulse; //?!
-                m->m_maxLimitForce = 300;
-            }
-            else
-            {
-                //hinge->enableAngularMotor(true,jointVelocity,bulletMaxMotorImulse);// is max impulse ok?! (10 seems to be ok, 1 oscillates)
-            }*/
+        LinkInfo link = getLink(node);
 
+        if (node->isRotationalJoint() || node->isTranslationalJoint())
+        {
             DynamicsRobot::actuateNodeVel(node, jointVelocity); // inverted joint direction in bullet
-#endif
         }
         else
         {
-            VR_ERROR << "Only Revolute joints implemented so far (node: " << node->getName() <<")..." << endl;
+            VR_ERROR << "Only Revolute and Prismatic joints implemented so far (node: " << node->getName() <<")..." << endl;
         }
     }
 
@@ -1087,59 +1066,25 @@ namespace SimDynamics
         }
 
         LinkInfo link = getLink(rn);
-#ifdef USE_BULLET_GENERIC_6DOF_CONSTRAINT
-        boost::shared_ptr<btGeneric6DofConstraint> dof = boost::dynamic_pointer_cast<btGeneric6DofConstraint>(link.joint);
-        VR_ASSERT(dof);
-        btRotationalLimitMotor* m = dof->getRotationalLimitMotor(0);
-        VR_ASSERT(m);
-        dof->calculateTransforms();
-        double a1 = dof->getAngle(0);
-        double a2 = m->m_currentPosition;
 
-        if (fabs(a1 - a2) > 0.05f)
+        if (rn->isRotationalJoint())
         {
-            VR_INFO << "Angle diff " << a1 << ", " << a2 << endl;
-        }
-
-        return (a2 - link.jointValueOffset); // inverted joint direction in bullet
-#else
-        boost::shared_ptr<btHingeConstraint> hinge = boost::dynamic_pointer_cast<btHingeConstraint>(link.joint);
-        if (!hinge)
-            return 0.0f;
+            boost::shared_ptr<btHingeConstraint> hinge = boost::dynamic_pointer_cast<btHingeConstraint>(link.joint);
+            VR_ASSERT(hinge);
 
-        /*if (!hinge)
+            return (hinge->getHingeAngle() - link.jointValueOffset); // inverted joint direction in bullet
+        }
+        else if (rn->isTranslationalJoint())
         {
-            // hinge2 / universal joint
-            boost::shared_ptr<btUniversalConstraint> hinge2 = boost::dynamic_pointer_cast<btUniversalConstraint>(link.joint);
+            boost::shared_ptr<btSliderConstraint> slider = boost::dynamic_pointer_cast<btSliderConstraint>(link.joint);
+            VR_ASSERT(slider);
 
-            if (!hinge2)
-            {
-                return 0.0f;
-            }
-
-            btRotationalLimitMotor* m;
-
-            if (rn == link.nodeJoint)
-            {
-                m = hinge2->getRotationalLimitMotor(1); // second motor
-            }
-            else if (rn == link.nodeJoint2)
-            {
-                m = hinge2->getRotationalLimitMotor(2); // third motor
-            }
-            else
-            {
-                return 0.0f;
-            }
-
-            VR_ASSERT(m);
-            hinge2->calculateTransforms();
-            double a2 = m->m_currentPosition;
-            return (a2 - link.jointValueOffset); // inverted joint direction in bullet
-        }*/
-
-        return (hinge->getHingeAngle() - link.jointValueOffset); // inverted joint direction in bullet
-#endif
+            return (slider->getLinearPos() - link.jointValueOffset) * 1000 / BulletObject::ScaleFactor; // m -> mm
+        }
+        else
+        {
+            return 0.0;
+        }
     }
 
     double BulletRobot::getJointTargetSpeed(VirtualRobot::RobotNodePtr rn)
@@ -1154,38 +1099,19 @@ namespace SimDynamics
         }
 
         LinkInfo link = getLink(rn);
-        boost::shared_ptr<btHingeConstraint> hinge = boost::dynamic_pointer_cast<btHingeConstraint>(link.joint);
 
-        /*if (!hinge)
+        if (rn->isRotationalJoint())
         {
-            // hinge2 / universal joint
-            boost::shared_ptr<btUniversalConstraint> hinge2 = boost::dynamic_pointer_cast<btUniversalConstraint>(link.joint);
-
-            if (!hinge2)
-            {
-                return 0.0f;
-            }
-
-            btRotationalLimitMotor* m;
-
-            if (rn == link.nodeJoint)
-            {
-                m = hinge2->getRotationalLimitMotor(1); // second motor
-            }
-            else if (rn == link.nodeJoint2)
-            {
-                m = hinge2->getRotationalLimitMotor(2); // third motor
-            }
-            else
-            {
-                return 0.0f;
-            }
+            boost::shared_ptr<btHingeConstraint> hinge = boost::dynamic_pointer_cast<btHingeConstraint>(link.joint);
 
-            VR_ASSERT(m);
-            return m->m_targetVelocity;
-        }*/
+            return hinge->getMotorTargetVelosity();
+        }
+        else if (rn->isTranslationalJoint())
+        {
+            boost::shared_ptr<btSliderConstraint> slider = boost::dynamic_pointer_cast<btSliderConstraint>(link.joint);
 
-        return hinge->getMotorTargetVelosity();
+            return slider->getTargetLinMotorVelocity() * 1000; // / BulletObject::ScaleFactor; m -> mm
+        }
     }
 
     double BulletRobot::getJointSpeed(VirtualRobot::RobotNodePtr rn)
@@ -1199,45 +1125,43 @@ namespace SimDynamics
             return 0.0f;
         }
 
-        LinkInfo link = getLink(rn);
-#ifdef USE_BULLET_GENERIC_6DOF_CONSTRAINT
-        VR_WARNING << "NYI" << endl;
-        return 0.0;
-#else
-        boost::shared_ptr<btHingeConstraint> hinge = boost::dynamic_pointer_cast<btHingeConstraint>(link.joint);
-
-        if (!hinge)
+        if (rn->isRotationalJoint())
         {
-            VR_WARNING << "NYI" << endl;
-            return 0.0;
-        }
+            LinkInfo link = getLink(rn);
+            boost::shared_ptr<btHingeConstraint> hinge = boost::dynamic_pointer_cast<btHingeConstraint>(link.joint);
 
-        boost::shared_ptr<RobotNodeRevolute> rnRevJoint = boost::dynamic_pointer_cast<RobotNodeRevolute>(link.nodeJoint);
+            VR_ASSERT(hinge);
 
-        Eigen::Vector3f deltaVel = link.dynNode2->getAngularVelocity() - link.dynNode1->getAngularVelocity();
-        double speed = deltaVel.dot(rnRevJoint->getJointRotationAxis());
-        return speed;//hinge->getMotorTargetVelosity();
+            boost::shared_ptr<RobotNodeRevolute> rnRevJoint = boost::dynamic_pointer_cast<RobotNodeRevolute>(link.nodeJoint);
 
-        /*
-         * // does the same:
-         double result = 0;
-         Eigen::Vector3f globalAxis = rnRevJoint->getJointRotationAxis();
-         result += globalAxis.dot(link.dynNode2->getAngularVelocity());
-         result -= globalAxis.dot(link.dynNode1->getAngularVelocity());
-         return result;*/
+            Eigen::Vector3f deltaVel = link.dynNode2->getAngularVelocity() - link.dynNode1->getAngularVelocity();
+            double speed = deltaVel.dot(rnRevJoint->getJointRotationAxis());
+            return speed;//hinge->getMotorTargetVelosity();
+        }
+        else if (rn->isTranslationalJoint())
+        {
+            LinkInfo link = getLink(rn);
+            boost::shared_ptr<btSliderConstraint> slider = boost::dynamic_pointer_cast<btSliderConstraint>(link.joint);
 
-#endif
+            VR_ASSERT(slider);
+
+            boost::shared_ptr<RobotNodePrismatic> rnPrisJoint = boost::dynamic_pointer_cast<RobotNodePrismatic>(link.nodeJoint);
+
+            Eigen::Vector3f jointDirection = rnPrisJoint->getGlobalPose().block<3, 3>(0, 0) * rnPrisJoint->getJointTranslationDirectionJointCoordSystem();
+            Eigen::Vector3f deltaVel = (link.dynNode2->getLinearVelocity() - link.dynNode1->getLinearVelocity());
+            return jointDirection.dot(deltaVel) / jointDirection.norm();
+        }
+        else
+        {
+            VR_WARNING << "Only translational and rotational joints implemented." << endl;
+            return 0.0;
+        }
     }
 
     double BulletRobot::getNodeTarget(VirtualRobot::RobotNodePtr node)
     {
         MutexLockPtr lock = getScopedLock();
-#ifdef USE_BULLET_GENERIC_6DOF_CONSTRAINT
-        return DynamicsRobot::getNodeTarget(node);
-#else
         return DynamicsRobot::getNodeTarget(node);
-#endif
-
     }
 
     Eigen::Vector3f BulletRobot::getJointTorques(RobotNodePtr rn)
@@ -1255,11 +1179,15 @@ namespace SimDynamics
 
         LinkInfo link = getLink(rn);
 
-        if (rn->isRotationalJoint())
+        if (rn->isRotationalJoint() || rn->isTranslationalJoint())
         {
             enableForceTorqueFeedback(link, true);
             result = getJointForceTorqueGlobal(link).tail(3);
         }
+        else
+        {
+            VR_WARNING << "Only translational and rotational joints implemented." << endl;
+        }
 
         return result;
     }
@@ -1277,17 +1205,20 @@ namespace SimDynamics
 
         LinkInfo link = getLink(rn);
 
-        if (!rn->isRotationalJoint())
+        if (rn->isRotationalJoint() || rn->isTranslationalJoint())
         {
-            return 0.0;
-        }
-
-        enableForceTorqueFeedback(link, true);
-        Eigen::Vector3f torqueVector = getJointForceTorqueGlobal(link).tail(3);
+            enableForceTorqueFeedback(link, true);
+            Eigen::Vector3f torqueVector = getJointForceTorqueGlobal(link).tail(3);
 
-        // project onto joint axis
-        double troque = (torqueVector.adjoint() * link.nodeJoint->getGlobalPose().block(0, 2, 3, 1))(0, 0);
-        return troque;
+            // project onto joint axis
+            double troque = (torqueVector.adjoint() * link.nodeJoint->getGlobalPose().block(0, 2, 3, 1))(0, 0);
+            return troque;
+        }
+        else
+        {
+            VR_WARNING << "Only translational and rotational joints implemented." << endl;
+        }
+        return 0.0;
     }
 
     Eigen::Vector3f BulletRobot::getJointForces(RobotNodePtr rn)
@@ -1305,11 +1236,15 @@ namespace SimDynamics
 
         LinkInfo link = getLink(rn);
 
-        if (rn->isRotationalJoint())
+        if (rn->isRotationalJoint() || rn->isTranslationalJoint())
         {
             enableForceTorqueFeedback(link, true);
             result = getJointForceTorqueGlobal(link).head(3);
         }
+        else
+        {
+            VR_WARNING << "Only translational and rotational joints implemented." << endl;
+        }
 
         return result;
     }
diff --git a/SimDynamics/DynamicsEngine/BulletEngine/BulletRobot.h b/SimDynamics/DynamicsEngine/BulletEngine/BulletRobot.h
index e94a9599da76f2c806f574a8c467a669c9673bf7..d8d1395f2a504f8dcf222375e62f9f5085d62a9b 100644
--- a/SimDynamics/DynamicsEngine/BulletEngine/BulletRobot.h
+++ b/SimDynamics/DynamicsEngine/BulletEngine/BulletRobot.h
@@ -232,6 +232,7 @@ namespace SimDynamics
         btScalar bulletMaxMotorImulse;
         boost::shared_ptr<btTypedConstraint> createFixedJoint(boost::shared_ptr<btRigidBody> btBody1, boost::shared_ptr<btRigidBody> btBody2, Eigen::Matrix4f& anchor_inNode1, Eigen::Matrix4f& anchor_inNode2);
         boost::shared_ptr<btTypedConstraint> createHingeJoint(boost::shared_ptr<btRigidBody> btBody1, boost::shared_ptr<btRigidBody> btBody2, Eigen::Matrix4f& coordSystemNode1, Eigen::Matrix4f& coordSystemNode2,  Eigen::Matrix4f& anchor_inNode1, Eigen::Matrix4f& anchor_inNode2, Eigen::Vector3f& axisGlobal, Eigen::Vector3f& axisLocal, Eigen::Matrix4f& coordSystemJoint, double limMinBT, double limMaxBT);
+        boost::shared_ptr<btTypedConstraint> createTranslationalJoint(boost::shared_ptr<btRigidBody> btBody1, boost::shared_ptr<btRigidBody> btBody2, Eigen::Matrix4f& coordSystemNode1, Eigen::Matrix4f& coordSystemNode2, Eigen::Matrix4f& anchor_inNode1, Eigen::Matrix4f& anchor_inNode2, Eigen::Vector3f& directionLocal, Eigen::Matrix4f& coordSystemJoint, double limMinBT, double limMaxBT);
 
 
         bool ignoreTranslationalJoints;
diff --git a/SimDynamics/DynamicsEngine/DynamicsRobot.cpp b/SimDynamics/DynamicsEngine/DynamicsRobot.cpp
index b9d252f78c4aff2e95a57418fcc24c232f75bb19..1558a3b90cb189e3174468e7d9e280557b3bd439 100644
--- a/SimDynamics/DynamicsEngine/DynamicsRobot.cpp
+++ b/SimDynamics/DynamicsEngine/DynamicsRobot.cpp
@@ -396,15 +396,13 @@ namespace SimDynamics
     void DynamicsRobot::setGlobalPose(const Eigen::Matrix4f& gp)
     {
         MutexLockPtr lock = getScopedLock();
-        Eigen::Matrix4f currentPose = robot->getGlobalPose();
-        Eigen::Matrix4f delta = gp * currentPose.inverse();
 
-        robot->setGlobalPose(gp);
         std::map<VirtualRobot::RobotNodePtr, DynamicsObjectPtr>::iterator it = dynamicRobotNodes.begin();
 
+        robot->setGlobalPose(gp);
         while (it != dynamicRobotNodes.end())
         {
-            Eigen::Matrix4f newPose = it->second->getSceneObject()->getGlobalPose() * delta;
+            Eigen::Matrix4f newPose = it->second->getSceneObject()->getGlobalPose();
             it->second->setPose(newPose);
             it++;
         }
diff --git a/SimDynamics/examples/SimDynamicsViewer/simDynamicsWindow.cpp b/SimDynamics/examples/SimDynamicsViewer/simDynamicsWindow.cpp
index da321445cda255d92f6718fbb9713e249c063a98..c52db5f787da3bc4a1a5b37b70215012f04aa69d 100644
--- a/SimDynamics/examples/SimDynamicsViewer/simDynamicsWindow.cpp
+++ b/SimDynamics/examples/SimDynamicsViewer/simDynamicsWindow.cpp
@@ -307,16 +307,11 @@ void SimDynamicsWindow::updateJoints()
 
     for (size_t i = 0; i < nodes.size(); i++)
     {
-        if (nodes[i]->isRotationalJoint())
+        if (nodes[i]->isRotationalJoint() || nodes[i]->isTranslationalJoint())
         {
-            RobotNodeRevolutePtr rn = boost::dynamic_pointer_cast<RobotNodeRevolute>(nodes[i]);
-
-            if (rn)
-            {
-                robotNodes.push_back(rn);
-                QString qstr(rn->getName().c_str());
-                UI.comboBoxRobotNode->addItem(qstr);
-            }
+            robotNodes.push_back(nodes[i]);
+            QString qstr(nodes[i]->getName().c_str());
+            UI.comboBoxRobotNode->addItem(qstr);
         }
     }
 
@@ -382,7 +377,7 @@ bool SimDynamicsWindow::loadRobot(std::string robotFilename)
 void SimDynamicsWindow::selectRobotNode(int n)
 {
     UI.comboBoxRobotNode->setCurrentIndex(n);
-    RobotNodeRevolutePtr rn;
+    RobotNodePtr rn;
 
     if (n >= 0 && n < (int)robotNodes.size())
     {
@@ -428,12 +423,16 @@ void SimDynamicsWindow::updateJointInfo()
     QString qVisu("VISU (simox): 0/0/0");
     QString qCom("COM (bullet): 0/0/0");
     QString tmp;
-    RobotNodeRevolutePtr rn;
+    RobotNodePtr rn;
 
     if (n >= 0 && n < (int)robotNodes.size())
     {
         rn = robotNodes[n];
     }
+    else
+    {
+        return;
+    }
 
     SimDynamics::DynamicsObjectPtr dynRN = dynamicsRobot->getDynamicsRobotNode(rn);
     SimDynamics::BulletObjectPtr bulletRN = boost::dynamic_pointer_cast<SimDynamics::BulletObject>(dynRN);
@@ -772,7 +771,7 @@ void SimDynamicsWindow::jointValueChanged(int n)
     #endif
     */
     int j = UI.comboBoxRobotNode->currentIndex();
-    RobotNodeRevolutePtr rn;
+    RobotNodePtr rn;
 
     if (j >= 0 && j < (int)robotNodes.size())
     {
diff --git a/SimDynamics/examples/SimDynamicsViewer/simDynamicsWindow.h b/SimDynamics/examples/SimDynamicsViewer/simDynamicsWindow.h
index 0fe095ef7d94caa537cb98ad521c1ed4f41e44a0..adbe11a5a2f80561f8cd7943741b525829e50e64 100644
--- a/SimDynamics/examples/SimDynamicsViewer/simDynamicsWindow.h
+++ b/SimDynamics/examples/SimDynamicsViewer/simDynamicsWindow.h
@@ -104,7 +104,7 @@ protected:
 
     SoTimerSensor* timerSensor;
 
-    std::vector<VirtualRobot::RobotNodeRevolutePtr> robotNodes;
+    std::vector<VirtualRobot::RobotNodePtr> robotNodes;
 
     std::map< VirtualRobot::RobotNodePtr, SoSeparator* > comVisuMap;