diff --git a/CMakeLists.txt b/CMakeLists.txt
index 93988c81df2ea454b1fd753585881cd5e1de95f4..00917e2003ad69622beb41ef159c59fc94b7d09b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -157,6 +157,7 @@ SET(${PROJECT_NAME}_PYTHON_HEADERS
   python/joint-dense.hpp
   python/joints-models.hpp
   python/joints-variant.hpp
+  python/frame.hpp
   python/model.hpp
   python/data.hpp
   python/algorithms.hpp
diff --git a/src/multibody/model.hpp b/src/multibody/model.hpp
index e5ad22eb491692f0fc6a02d88620be6419580d2d..4ffd5c8bd1e65e3ed07485343201548afbab2796 100644
--- a/src/multibody/model.hpp
+++ b/src/multibody/model.hpp
@@ -39,6 +39,26 @@ namespace se3
 {
   class Model;
   class Data;
+  struct Frame
+  {
+    typedef std::size_t Index;
+    
+    Frame(const std::string & name, Index parent, const SE3 & placement): name(name)
+                                                                        , parent_id(parent)
+                                                                        , frame_placement(placement)
+    {
+    }
+
+    bool operator == (const Frame & other) const
+    {
+      return name == other.name && parent_id == other.parent_id
+              && frame_placement == other.frame_placement ;
+    }
+
+    std::string name;
+    Index parent_id;
+    SE3 frame_placement;
+  };
 
   class Model
   {
@@ -49,6 +69,7 @@ namespace se3
     int nv;                               // Dimension of the velocity vector space
     int nbody;                            // Number of bodies (= number of joints + 1)
     int nFixBody;                         // Number of fixed-bodies (= number of fixed-joints)
+    int nExtraFrames;                     // Number of extra frames
 
     std::vector<Inertia> inertias;        // Spatial inertias of the body <i> in the supporting joint frame <i>
     std::vector<SE3> jointPlacements;     // Placement (SE3) of the input of joint <i> in parent joint output <li>
@@ -63,6 +84,8 @@ namespace se3
     std::vector<bool> fix_hasVisual;      // True iff fixed-body <i> has a visual mesh.
     std::vector<std::string> fix_bodyNames;// Name of fixed-joint <i>
 
+    std::vector<Frame> extra_frames;
+
     Motion gravity;                       // Spatial gravity
     static const Eigen::Vector3d gravity981; // Default 3D gravity (=(0,0,-9.81))
 
@@ -71,6 +94,7 @@ namespace se3
       , nv(0)
       , nbody(1)
       , nFixBody(0)
+      , nExtraFrames(0)
       , inertias(1)
       , jointPlacements(1)
       , joints(1)
@@ -107,6 +131,18 @@ namespace se3
     Index getJointId( const std::string & name ) const;
     bool existJointName( const std::string & name ) const;
     const std::string& getJointName( Index index ) const;
+
+    Index getFrameId ( const std::string & name ) const;
+    bool existFrame ( const std::string & name ) const;
+    const std::string & getFrameName ( Index index ) const;
+    const Index& getFrameParent( const std::string & name ) const;
+    const Index& getFrameParent( Index index ) const;
+    const SE3 & getJointToFrameTransform( const std::string & name ) const;
+    const SE3 & getJointToFrameTransform( Index index ) const;
+
+    void addFrame ( const Frame & frame );
+    void addFrame ( const std::string & name, Index index, const SE3 & placement );
+
   };
 
   class Data
@@ -128,6 +164,8 @@ namespace se3
     Eigen::VectorXd tau;                  // Joint forces
     Eigen::VectorXd nle;                  // Non linear effects
 
+    std::vector<SE3> oMef;                // Absolute position of extra frames
+
     std::vector<Inertia> Ycrb;            // Inertia of the sub-tree composit rigid body
     Eigen::MatrixXd M;                    // Joint Inertia
 
diff --git a/src/multibody/model.hxx b/src/multibody/model.hxx
index be4aa1980dfea392d4cef02f9e789289de0a9544..b7255ab95085023ace1097bc3223a43a25077194 100644
--- a/src/multibody/model.hxx
+++ b/src/multibody/model.hxx
@@ -27,6 +27,8 @@
 #include "pinocchio/multibody/joint/joint-variant.hpp"
 #include <iostream>
 
+#include <boost/bind.hpp>
+
 namespace se3
 {
   inline std::ostream& operator<< (std::ostream & os, const Model & model)
@@ -173,6 +175,67 @@ namespace se3
     return names[index];
   }
 
+  inline Model::Index Model::getFrameId ( const std::string & name ) const
+  {
+    std::vector<Frame>::const_iterator it = std::find_if( extra_frames.begin()
+                                                        , extra_frames.end()
+                                                        , boost::bind(&Frame::name, _1) == name
+                                                        );
+    return Model::Index(it - extra_frames.begin());
+  }
+
+  inline bool Model::existFrame ( const std::string & name ) const
+  {
+    return std::find_if( extra_frames.begin(), extra_frames.end(), boost::bind(&Frame::name, _1) == name) != extra_frames.end();
+  }
+
+  inline const std::string & Model::getFrameName ( Index index ) const
+  {
+    return extra_frames[index].name;
+  }
+
+  inline const Model::Index& Model::getFrameParent( const std::string & name ) const
+  {
+    std::vector<Frame>::const_iterator it = std::find_if( extra_frames.begin()
+                                                        , extra_frames.end()
+                                                        , boost::bind(&Frame::name, _1) == name
+                                                        );
+    return it->parent_id;
+  }
+
+  inline const Model::Index& Model::getFrameParent( Model::Index index ) const
+  {
+    return extra_frames[index].parent_id;
+  }
+
+  inline const SE3 & Model::getJointToFrameTransform( const std::string & name) const
+  {
+    assert(existFrame(name) && "The Frame you requested does not exist");
+    std::vector<Frame>::const_iterator it = std::find_if( extra_frames.begin()
+                                                        , extra_frames.end()
+                                                        , boost::bind(&Frame::name, _1) == name
+                                                        );
+    return it->frame_placement;
+  }
+
+  inline const SE3 & Model::getJointToFrameTransform( Model::Index index ) const
+  {
+    return extra_frames[index].frame_placement;
+  }
+
+  inline void Model::addFrame ( const Frame & frame )
+  {
+    if( !existFrame(frame.name) )
+      extra_frames.push_back(frame);nExtraFrames++;
+  }
+
+  inline void Model::addFrame ( const std::string & name, Index index, const SE3 & placement)
+  {
+    if( !existFrame(name) )
+      addFrame(Frame(name, index, placement));
+  }
+
+
   inline Data::Data (const Model & ref)
     :model(ref)
     ,joints(0)
diff --git a/src/multibody/parser/urdf.hxx b/src/multibody/parser/urdf.hxx
index ebf258f2c8bb05057b6d439cae06f2b9383b90e1..2cbdd1bd1c5e6595717d5a00baa63ab9ead9004a 100644
--- a/src/multibody/parser/urdf.hxx
+++ b/src/multibody/parser/urdf.hxx
@@ -345,6 +345,9 @@ namespace se3
           
           //add the fixed Body in the model for the viewer
           model.addFixedBody(parent_joint_id, nextPlacementOffset, link->name, has_visual);
+
+          // Add a frame in the model to keep trace of this fixed joint
+          model.addFrame(joint->name, parent_joint_id, nextPlacementOffset);
           
           //for the children of the current link, set their parent to be
           //the the parent of the current link.
diff --git a/src/python/frame.hpp b/src/python/frame.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a76df1697a845902b3fbe20196961cb5e877634c
--- /dev/null
+++ b/src/python/frame.hpp
@@ -0,0 +1,83 @@
+//
+// Copyright (c) 2016 CNRS
+//
+// This file is part of Pinocchio
+// Pinocchio is free software: you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation, either version
+// 3 of the License, or (at your option) any later version.
+//
+// Pinocchio is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Lesser Public License for more details. You should have
+// received a copy of the GNU Lesser General Public License along with
+// Pinocchio If not, see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef __se3_python_frame_hpp__
+#define __se3_python_frame_hpp__
+
+#include <eigenpy/exception.hpp>
+#include <eigenpy/eigenpy.hpp>
+#include "pinocchio/multibody/model.hpp"
+
+
+namespace se3
+{
+  namespace python
+  {
+    namespace bp = boost::python;
+
+    struct FramePythonVisitor
+      : public boost::python::def_visitor< FramePythonVisitor >
+    {
+      typedef eigenpy::UnalignedEquivalent<SE3>::type SE3_fx;
+      typedef Model::Index Index;
+
+    public:
+
+      static PyObject* convert(Frame const& f)
+      {
+        return boost::python::incref(boost::python::object(f).ptr());
+      }
+
+      template<class PyClass>
+      void visit(PyClass& cl) const 
+      {
+        cl
+          .def(bp::init<const std::string&,Index, const SE3_fx&> ((bp::arg("name"),bp::arg("parent id"), bp::arg("placement")),
+                "Initialize from name, parent id and placement wrt parent joint."))
+
+          .def("name", &FramePythonVisitor::getName)
+          .def("parent_id", &FramePythonVisitor::getParentId)
+          .def("placement", &FramePythonVisitor::getPlcaementWrtParentJoint)
+          ;
+      }
+
+
+      static std::string getName( const Frame & self) { return self.name; }
+      static Index getParentId( const Frame & self) { return self.parent_id; }
+      static SE3_fx getPlcaementWrtParentJoint( const Frame & self) { return self.frame_placement; }
+
+      static void expose()
+      {
+        bp::class_<Frame>("Frame",
+                           "ExtraFrames.\n\n",
+	                         bp::no_init
+                         )
+	                       .def(FramePythonVisitor())
+	                       ;
+    
+        bp::to_python_converter< Frame,FramePythonVisitor >();
+      }
+
+
+    };
+    
+
+  } // namespace python
+} // namespace se3
+
+#endif // ifndef __se3_python_frame_hpp__
+
diff --git a/src/python/model.hpp b/src/python/model.hpp
index 96162c6badede77df3e79878727da537d8775d20..6caba7c4bc47c067f273361234fe8621363ca5e3 100644
--- a/src/python/model.hpp
+++ b/src/python/model.hpp
@@ -132,6 +132,10 @@ namespace se3
       .add_property("fix_hasVisual", bp::make_function(&ModelPythonVisitor::fix_hasVisual, bp::return_internal_reference<>())  )
       .add_property("fix_bodyNames", bp::make_function(&ModelPythonVisitor::fix_bodyNames, bp::return_internal_reference<>())  )
 
+      .def("getFrameParentJoint", &ModelPythonVisitor::getFrameParent)
+      .def("getFramePositionInParent", &ModelPythonVisitor::getJointToFrameTransform)
+      .def("addExtraFrame", &ModelPythonVisitor::addExtraFrame)
+      .add_property("extra_frames", bp::make_function(&ModelPythonVisitor::extraFrames, bp::return_internal_reference<>()) )
 
       .add_property("gravity",&ModelPythonVisitor::gravity,&ModelPythonVisitor::setGravity)
 	  .def("BuildEmptyModel",&ModelPythonVisitor::maker_empty)
@@ -175,6 +179,14 @@ namespace se3
       static std::vector<bool> & fix_hasVisual ( ModelHandler & m ) { return m->fix_hasVisual; }
       static std::vector<std::string> & fix_bodyNames ( ModelHandler & m ) { return m->fix_bodyNames; }
 
+      static Model::Index  getFrameParent( ModelHandler & m, const std::string & name ) { return m->getFrameParent(name); }
+      static SE3  getJointToFrameTransform( ModelHandler & m, const std::string & name ) { return m->getJointToFrameTransform(name); }
+      static void  addExtraFrame( ModelHandler & m, const std::string & frameName, Index parent, const SE3_fx & placementWrtParent )
+      {
+        m->addFrame(frameName, parent, placementWrtParent);
+      }
+      static std::vector<Frame> & extraFrames (ModelHandler & m ) { return m->extra_frames;}
+
       static Motion gravity( ModelHandler & m ) { return m->gravity; }
       static void setGravity( ModelHandler & m,const Motion_fx & g ) { m->gravity = g; }
 
@@ -232,6 +244,8 @@ namespace se3
           .def(bp::vector_indexing_suite< std::vector<double> >());
         bp::class_< JointModelVector >("StdVec_JointModelVector")
           .def(bp::vector_indexing_suite< JointModelVector, true >());
+        bp::class_< std::vector<Frame> >("StdVec_FrameVector")
+          .def(bp::vector_indexing_suite< std::vector<Frame> >());
 
   bp::class_<ModelHandler>("Model",
          "Articulated rigid body model (const)",
diff --git a/src/python/python.cpp b/src/python/python.cpp
index eddca903957f9c6fcdbc6d933f3c858721a7c6bc..36b4a99b3f0cc8f6ed6afa79b91006deb5a76625 100644
--- a/src/python/python.cpp
+++ b/src/python/python.cpp
@@ -24,6 +24,7 @@
 #include "pinocchio/python/joint-dense.hpp"
 #include "pinocchio/python/joints-variant.hpp"
 
+#include "pinocchio/python/frame.hpp"
 #include "pinocchio/python/model.hpp"
 #include "pinocchio/python/data.hpp"
 #include "pinocchio/python/algorithms.hpp"
@@ -65,6 +66,7 @@ namespace se3
     }
     void exposeModel()
     {
+      FramePythonVisitor::expose();
       ModelPythonVisitor::expose();
       DataPythonVisitor::expose();
 #ifdef WITH_HPP_FCL