diff --git a/include/curves/helpers/effector_spline_rotation.h b/include/curves/helpers/effector_spline_rotation.h
index e230e407617eb944f9e9ab7cc494d66b09f8ceac..ad503e7a763647069e3a71e13cef7a8f48ea1ebb 100644
--- a/include/curves/helpers/effector_spline_rotation.h
+++ b/include/curves/helpers/effector_spline_rotation.h
@@ -44,6 +44,7 @@ class rotation_spline : public curve_abc_quat_t {
       : curve_abc_quat_t(),
         quat_from_(quat_from.data()),
         quat_to_(quat_to.data()),
+        dim_(4),
         min_(min),
         max_(max),
         time_reparam_(computeWayPoints()) {}
@@ -54,6 +55,7 @@ class rotation_spline : public curve_abc_quat_t {
   rotation_spline& operator=(const rotation_spline& from) {
     quat_from_ = from.quat_from_;
     quat_to_ = from.quat_to_;
+    dim_ = from.dim_;
     min_ = from.min_;
     max_ = from.max_;
     time_reparam_ = exact_cubic_constraint_one_dim(from.time_reparam_);
diff --git a/include/curves/linear_variable.h b/include/curves/linear_variable.h
index 67348fa2df735b3ffa41292f8afce00d5e8aa326..ffcb27a73f578d36131a34a60fec49867bf6ba9a 100644
--- a/include/curves/linear_variable.h
+++ b/include/curves/linear_variable.h
@@ -81,6 +81,10 @@ struct linear_variable : public serialization::Serializable {
 
   Numeric norm() const { return isZero() ? 0 : (B_.norm() + c_.norm()); }
 
+  bool isApprox(const linear_variable_t& other,const double prec = Eigen::NumTraits<Numeric>::dummy_precision()){
+    return (*this - other).norm() < prec;
+  }
+
   const matrix_x_t& B() const { return B_; }
   const vector_x_t& c() const { return c_; }
   bool isZero() const { return zero; }
diff --git a/include/curves/piecewise_curve.h b/include/curves/piecewise_curve.h
index 6601846024c14066d9229b8a4ad30def105ad963..1557385142da2495b895a1b18f81b55ba23b2e49 100644
--- a/include/curves/piecewise_curve.h
+++ b/include/curves/piecewise_curve.h
@@ -24,10 +24,12 @@ namespace curves {
 template <typename Time = double, typename Numeric = Time, bool Safe = false,
           typename Point = Eigen::Matrix<Numeric, Eigen::Dynamic, 1>,
           typename T_Point = std::vector<Point, Eigen::aligned_allocator<Point> >,
-          typename Curve = curve_abc<Time, Numeric, Safe, Point> >
-struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point> {
+          typename Curve = curve_abc<Time, Numeric, Safe, Point>,
+          typename Point_derivate = Point >
+struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_derivate> {
   typedef Point point_t;
   typedef T_Point t_point_t;
+  typedef Point_derivate point_derivate_t;
   typedef Time time_t;
   typedef Numeric num_t;
   typedef Curve curve_t;
@@ -41,17 +43,17 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point> {
 
   /// \brief Constructor.
   /// Initialize a piecewise curve by giving the first curve.
-  /// \param pol   : a polynomial curve.
+  /// \param cf   : a curve.
   ///
   piecewise_curve(const curve_t& cf) {
-    dim_ = cf(cf.min()).size();
+    dim_ = cf.dim();
     size_ = 0;
     add_curve(cf);
   }
 
   piecewise_curve(const t_curve_t list_curves) {
     if (list_curves.size() != 0) {
-      dim_ = list_curves[0](list_curves[0].min()).size();
+      dim_ = list_curves[0].dim();
     }
     size_ = 0;
     for (std::size_t i = 0; i < list_curves.size(); i++) {
@@ -83,7 +85,7 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point> {
   ///  \param order : order of derivative.
   ///  \return \f$\frac{d^Np(t)}{dt^N}\f$ point corresponding on derivative spline of order N at time t.
   ///
-  virtual Point derivate(const Time t, const std::size_t order) const {
+  virtual point_derivate_t derivate(const Time t, const std::size_t order) const {
     check_if_not_empty();
     if (Safe & !(T_min_ <= t && t <= T_max_)) {
       throw std::invalid_argument("can't evaluate piecewise curve, out of range");
@@ -96,8 +98,8 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point> {
    * @param order order of derivative
    * @return
    */
-  piecewise_curve<Time, Numeric, Safe, Point, T_Point, Curve> compute_derivate(const std::size_t order) const {
-    piecewise_curve<Time, Numeric, Safe, Point, T_Point, Curve> res;
+  piecewise_curve<Time, Numeric, Safe, point_derivate_t, std::vector<point_derivate_t, Eigen::aligned_allocator<Point> >, Curve> compute_derivate(const std::size_t order) const {
+    piecewise_curve<Time, Numeric, Safe, point_derivate_t,  std::vector<point_derivate_t, Eigen::aligned_allocator<Point> >, Curve> res;
     for (typename t_curve_t::const_iterator itc = curves_.begin(); itc < curves_.end(); ++itc) {
       res.add_curve(itc->compute_derivate(order));
     }
@@ -111,23 +113,27 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point> {
   ///  \param cf : curve to add.
   ///
   void add_curve(const curve_t& cf) {
-    if (size_ == 0 && dim_ == 0) {
-      dim_ = cf(cf.min()).size();
+    if (size_ == 0 && dim_ == 0) { // first curve added
+      dim_ = cf.dim();
     }
-    // Check time continuity : Beginning time of pol must be equal to T_max_ of actual piecewise curve.
+    // Check time continuity : Beginning time of cf must be equal to T_max_ of actual piecewise curve.
     if (size_ != 0 && !(fabs(cf.min() - T_max_) < MARGIN)) {
       throw std::invalid_argument(
           "Can not add new Polynom to PiecewiseCurve : time discontinuity between T_max_ and pol.min()");
     }
+    if(cf.dim() != dim_){
+      throw std::invalid_argument(
+          "All the curves in a piecewiseCurve should have the same dimension");
+    }
     curves_.push_back(cf);
     size_ = curves_.size();
     T_max_ = cf.max();
-    time_curves_.push_back(T_max_);
     if (size_ == 1) {
       // First curve added
       time_curves_.push_back(cf.min());
       T_min_ = cf.min();
     }
+    time_curves_.push_back(T_max_);
   }
 
   ///  \brief Check if the curve is continuous of order given.
@@ -138,21 +144,30 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point> {
     check_if_not_empty();
     bool isContinuous = true;
     std::size_t i = 0;
-    point_t value_end, value_start;
-    while (isContinuous && i < (size_ - 1)) {
-      curve_t current = curves_.at(i);
-      curve_t next = curves_.at(i + 1);
-      if (order == 0) {
+    if(order ==0){
+      point_t value_end, value_start;
+      while (isContinuous && i < (size_ - 1)) {
+        curve_t current = curves_.at(i);
+        curve_t next = curves_.at(i + 1);
         value_end = current(current.max());
         value_start = next(next.min());
-      } else {
+        if (!value_end.isApprox(value_start,MARGIN)) {
+          isContinuous = false;
+        }
+        i++;
+      }
+    }else{
+      point_derivate_t value_end, value_start;
+      while (isContinuous && i < (size_ - 1)) {
+        curve_t current = curves_.at(i);
+        curve_t next = curves_.at(i + 1);
         value_end = current.derivate(current.max(), order);
         value_start = next.derivate(next.min(), order);
+        if (!value_end.isApprox(value_start,MARGIN)) {
+          isContinuous = false;
+        }
+        i++;
       }
-      if ((value_end - value_start).norm() > MARGIN) {
-        isContinuous = false;
-      }
-      i++;
     }
     return isContinuous;
   }
@@ -374,8 +389,8 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point> {
   }
 };  // End struct piecewise curve
 
-template <typename Time, typename Numeric, bool Safe, typename Point, typename T_Point, typename Curve>
-const double piecewise_curve<Time, Numeric, Safe, Point, T_Point, Curve>::MARGIN(0.001);
+template <typename Time, typename Numeric, bool Safe, typename Point, typename T_Point,typename Curve,typename Point_derivate>
+const double piecewise_curve<Time, Numeric, Safe, Point, T_Point, Curve,Point_derivate>::MARGIN(0.001);
 
 }  // namespace curves
 
diff --git a/python/curves_python.cpp b/python/curves_python.cpp
index 249c83948a68f0168e4c1e468ea42cb5cd2e7f55..33c7b08388d22d6bb28cf3084fb75a39335d440f 100644
--- a/python/curves_python.cpp
+++ b/python/curves_python.cpp
@@ -158,6 +158,14 @@ piecewise_bezier_linear_curve_t* wrapPiecewiseLinearBezierCurveConstructor(const
 piecewise_cubic_hermite_curve_t* wrapPiecewiseCubicHermiteCurveConstructor(const cubic_hermite_spline_t& ch) {
   return new piecewise_cubic_hermite_curve_t(ch);
 }
+
+piecewise_SE3_curve_t* wrapPiecewiseSE3Constructor(const SE3Curve_t& curve) {
+  return new piecewise_SE3_curve_t(curve);
+}
+
+piecewise_SE3_curve_t* wrapPiecewiseSE3EmptyConstructor() {
+  return new piecewise_SE3_curve_t();
+}
 static piecewise_polynomial_curve_t discretPointToPolynomialC0(const pointX_list_t& points,
                                                                const time_waypoints_t& time_points) {
   t_pointX_t points_list = vectorFromEigenArray<pointX_list_t, t_pointX_t>(points);
@@ -186,16 +194,20 @@ static piecewise_polynomial_curve_t discretPointToPolynomialC2(const pointX_list
   return piecewise_polynomial_curve_t::convert_discrete_points_to_polynomial<polynomial_t>(
       points_list, points_derivative_list, points_second_derivative_list, time_points_list);
 }
-void addFinalPointC0(piecewise_polynomial_curve_t self, const pointX_t& end, const real time) {
-  if (self.is_continuous(1))
+void addFinalPointC0(piecewise_polynomial_curve_t& self, const pointX_t& end, const real time) {
+  if(self.num_curves() == 0)
+    throw std::runtime_error("Piecewise append : you need to add at least one curve before using append(finalPoint) method.");
+  if (self.is_continuous(1) && self.num_curves()>1 )
     std::cout << "Warning: by adding this final point to the piecewise curve, you loose C1 continuity and only "
                  "guarantee C0 continuity."
               << std::endl;
   polynomial_t pol(self(self.max()), end, self.max(), time);
   self.add_curve(pol);
 }
-void addFinalPointC1(piecewise_polynomial_curve_t self, const pointX_t& end, const pointX_t& d_end, const real time) {
-  if (self.is_continuous(2))
+void addFinalPointC1(piecewise_polynomial_curve_t& self, const pointX_t& end, const pointX_t& d_end, const real time) {
+  if(self.num_curves() == 0)
+    throw std::runtime_error("Piecewise append : you need to add at least one curve before using append(finalPoint) method.");
+  if (self.is_continuous(2) && self.num_curves()>1 )
     std::cout << "Warning: by adding this final point to the piecewise curve, you loose C2 continuity and only "
                  "guarantee C1 continuity."
               << std::endl;
@@ -203,9 +215,11 @@ void addFinalPointC1(piecewise_polynomial_curve_t self, const pointX_t& end, con
   polynomial_t pol(self(self.max()), self.derivate(self.max(), 1), end, d_end, self.max(), time);
   self.add_curve(pol);
 }
-void addFinalPointC2(piecewise_polynomial_curve_t self, const pointX_t& end, const pointX_t& d_end,
+void addFinalPointC2(piecewise_polynomial_curve_t& self, const pointX_t& end, const pointX_t& d_end,
                      const pointX_t& dd_end, const real time) {
-  if (self.is_continuous(3))
+  if(self.num_curves() == 0)
+    throw std::runtime_error("Piecewise append : you need to add at least one curve before using append(finalPoint) method.");
+  if (self.is_continuous(3) && self.num_curves()>1 )
     std::cout << "Warning: by adding this final point to the piecewise curve, you loose C3 continuity and only "
                  "guarantee C2 continuity."
               << std::endl;
@@ -291,6 +305,10 @@ SE3Curve_t* wrapSE3CurveFromTransform(const matrix4_t& init_pose, const matrix4_
   return new SE3Curve_t(transform_t(init_pose), transform_t(end_pose), min, max);
 }
 
+SE3Curve_t* wrapSE3CurveFromPosAndRotation(const pointX_t& init_pos, const pointX_t& end_pos, const matrix3_t& init_rot, const matrix3_t& end_rot,const real& t_min, const real& t_max) {
+  return new SE3Curve_t(init_pos,end_pos,init_rot,end_rot, t_min, t_max);
+}
+
 SE3Curve_t* wrapSE3CurveFromBezier3Translation(bezier3_t& translation_curve, const matrix3_t& init_rot,
                                                const matrix3_t& end_rot) {
   bezier_t* translation = new bezier_t(translation_curve.waypoints().begin(), translation_curve.waypoints().end(),
@@ -336,6 +354,50 @@ pointX_t se3returnTranslation(const SE3Curve_t& curve, const real t) { return po
 
 /* End wrap SE3Curves */
 
+/* Wrap piecewiseSE3Curves */
+#ifdef CURVES_WITH_PINOCCHIO_SUPPORT
+typedef pinocchio::SE3Tpl<real, 0> SE3_t;
+typedef pinocchio::MotionTpl<real, 0> Motion_t;
+
+SE3_t piecewiseSE3ReturnPinocchio(const piecewise_SE3_curve_t& curve, const real t) { return SE3_t(curve(t).matrix()); }
+
+Motion_t piecewiseSE3ReturnDerivatePinocchio(const piecewise_SE3_curve_t& curve, const real t, const std::size_t order) {
+  return Motion_t(curve.derivate(t, order));
+}
+
+void addFinalSE3(piecewise_SE3_curve_t& self, const SE3_t& end, const real time) {
+  if(self.num_curves() == 0)
+    throw std::runtime_error("Piecewise append : you need to add at least one curve before using append(finalPoint) method.");
+  if (self.is_continuous(1) && self.num_curves()>1 )
+    std::cout << "Warning: by adding this final transform to the piecewise curve, you loose C1 continuity and only "
+                 "guarantee C0 continuity."
+              << std::endl;
+  SE3Curve_t curve(self(self.max()), transform_t(end.toHomogeneousMatrix()), self.max(), time);
+  self.add_curve(curve);
+}
+
+#endif  // CURVES_WITH_PINOCCHIO_SUPPORT
+
+matrix4_t piecewiseSE3Return(const piecewise_SE3_curve_t& curve, const real t) { return curve(t).matrix(); }
+
+
+matrix3_t piecewiseSE3returnRotation(const piecewise_SE3_curve_t& curve, const real t) { return curve(t).rotation(); }
+
+pointX_t piecewiseSE3returnTranslation(const piecewise_SE3_curve_t& curve, const real t) { return pointX_t(curve(t).translation()); }
+
+void addFinalTransform(piecewise_SE3_curve_t& self, const matrix4_t& end, const real time) {
+  if(self.num_curves() == 0)
+    throw std::runtime_error("Piecewise append : you need to add at least one curve before using append(finalPoint) method.");
+  if (self.is_continuous(1) && self.num_curves()>1 )
+    std::cout << "Warning: by adding this final transform to the piecewise curve, you loose C1 continuity and only "
+                 "guarantee C0 continuity."
+              << std::endl;
+  SE3Curve_t curve(self(self.max()), transform_t(end), self.max(), time);
+  self.add_curve(curve);
+}
+
+/* End wrap piecewiseSE3Curves */
+
 // TO DO : Replace all load and save function for serialization in class by using
 //         SerializableVisitor in archive_python_binding.
 BOOST_PYTHON_MODULE(curves) {
@@ -571,7 +633,7 @@ BOOST_PYTHON_MODULE(curves) {
            "Add a new curve to piecewise curve, which should be defined in T_{min},T_{max}] "
            "where T_{min} is equal toT_{max} of the actual piecewise curve.")
       .def("is_continuous", &piecewise_polynomial_curve_t::is_continuous,
-           "Check if the curve is continuous at the given order.")
+           "Check if the curve is continuous at the given order.",args("self,order"))
       .def("convert_piecewise_curve_to_bezier",
            &piecewise_polynomial_curve_t::convert_piecewise_curve_to_bezier<bezier_t>,
            "Convert a piecewise polynomial curve to to a piecewise bezier curve")
@@ -599,7 +661,7 @@ BOOST_PYTHON_MODULE(curves) {
       .def("__init__", make_constructor(&wrapPiecewiseBezierCurveConstructor))
       .def("compute_derivate", &piecewise_polynomial_curve_t::compute_derivate,
            "Return a piecewise_polynomial curve which is the derivate of this.", args("self", "order"))
-      .def("add_curve", &piecewise_bezier_curve_t::add_curve)
+      .def("append", &piecewise_bezier_curve_t::add_curve)
       .def("is_continuous", &piecewise_bezier_curve_t::is_continuous)
       .def("convert_piecewise_curve_to_polynomial",
            &piecewise_bezier_curve_t::convert_piecewise_curve_to_polynomial<polynomial_t>,
@@ -625,7 +687,7 @@ BOOST_PYTHON_MODULE(curves) {
 
   class_<piecewise_cubic_hermite_curve_t, bases<curve_abc_t> >("piecewise_cubic_hermite_curve", init<>())
       .def("__init__", make_constructor(&wrapPiecewiseCubicHermiteCurveConstructor))
-      .def("add_curve", &piecewise_cubic_hermite_curve_t::add_curve)
+      .def("append", &piecewise_cubic_hermite_curve_t::add_curve)
       .def("is_continuous", &piecewise_cubic_hermite_curve_t::is_continuous)
       .def("convert_piecewise_curve_to_polynomial",
            &piecewise_cubic_hermite_curve_t::convert_piecewise_curve_to_polynomial<polynomial_t>,
@@ -653,7 +715,7 @@ BOOST_PYTHON_MODULE(curves) {
 
   class_<piecewise_bezier_linear_curve_t, bases<curve_abc_t> >("piecewise_bezier_linear_curve_t", init<>())
       .def("__init__", make_constructor(&wrapPiecewiseLinearBezierCurveConstructor))
-      .def("add_curve", &piecewise_bezier_linear_curve_t::add_curve)
+      .def("append", &piecewise_bezier_linear_curve_t::add_curve)
       .def("is_continuous", &piecewise_bezier_linear_curve_t::is_continuous,
            "Check if the curve is continuous at the given order.")
       .def("curve_at_index", &piecewise_bezier_linear_curve_t::curve_at_index,
@@ -674,6 +736,61 @@ BOOST_PYTHON_MODULE(curves) {
       .def("loadFromBinary", &piecewise_bezier_linear_curve_t::loadFromBinary<piecewise_bezier_linear_curve_t>,
            bp::args("filename"), "Loads *this from a binary file.");
 
+class_<piecewise_SE3_curve_t, bases<curve_abc_t> >("piecewise_SE3_curve", init<>())
+      .def("__init__", make_constructor(&wrapPiecewiseSE3Constructor, default_call_policies(), arg("curve")),
+      "Create a piecewise-se3 curve containing the given se3 curve.")
+      .def("__init__", make_constructor(&wrapPiecewiseSE3EmptyConstructor),
+      "Create an empty piecewise-se3 curve.")
+//      .def("compute_derivate", &piecewise_SE3_curve_t::compute_derivate,
+//           "Return a piecewise_polynomial curve which is the derivate of this.", args("self", "order"))
+      .def("append", &piecewise_SE3_curve_t::add_curve,
+           "Add a new curve to piecewise curve, which should be defined in T_{min},T_{max}] "
+           "where T_{min} is equal toT_{max} of the actual piecewise curve.",
+           args("self,curve"))
+      .def("is_continuous", &piecewise_SE3_curve_t::is_continuous, "Check if the curve is continuous at the given order.",args("self,order"))
+      .def("curve_at_index", &piecewise_SE3_curve_t::curve_at_index, return_value_policy<copy_const_reference>())
+      .def("curve_at_time", &piecewise_SE3_curve_t::curve_at_time, return_value_policy<copy_const_reference>())
+      .def("num_curves", &piecewise_SE3_curve_t::num_curves)
+      .def("rotation", &piecewiseSE3returnRotation, "Output the rotation (as a 3x3 matrix) at the given time.",
+           args("self", "t"))
+      .def("translation", &piecewiseSE3returnTranslation, "Output the translation (as a vector 3) at the given time.",
+           args("self", "t"))
+      .def("__call__", &piecewiseSE3Return, "Evaluate the curve at the given time. Return as an homogeneous matrix",
+           args("self", "t"))
+      .def("derivate", &piecewise_SE3_curve_t::derivate,
+           "Evaluate the derivative of order N of curve at time t. Return as a vector 6", args("self", "t", "N"))
+      .def("min", &piecewise_SE3_curve_t::min, "Get the LOWER bound on interval definition of the curve.")
+      .def("max", &piecewise_SE3_curve_t::max, "Get the HIGHER bound on interval definition of the curve.")
+      .def("dim", &piecewise_SE3_curve_t::dim, "Get the dimension of the curve.")
+      .def("append", &addFinalTransform,
+       "Append a new linear SE3 curve at the end of the piecewise curve, defined between self.max() "
+       "and time and connecting exactly self(self.max()) and end",
+       args("self", "end", "time"))
+//      .def("saveAsText", &piecewise_bezier_curve_t::saveAsText<piecewise_bezier_curve_t>, bp::args("filename"),
+//           "Saves *this inside a text file.")
+//      .def("loadFromText", &piecewise_bezier_curve_t::loadFromText<piecewise_bezier_curve_t>, bp::args("filename"),
+//           "Loads *this from a text file.")
+//      .def("saveAsXML", &piecewise_bezier_curve_t::saveAsXML<piecewise_bezier_curve_t>,
+//           bp::args("filename", "tag_name"), "Saves *this inside a XML file.")
+//      .def("loadFromXML", &piecewise_bezier_curve_t::loadFromXML<piecewise_bezier_curve_t>,
+//           bp::args("filename", "tag_name"), "Loads *this from a XML file.")
+//      .def("saveAsBinary", &piecewise_bezier_curve_t::saveAsBinary<piecewise_bezier_curve_t>, bp::args("filename"),
+//           "Saves *this inside a binary file.")
+//      .def("loadFromBinary", &piecewise_bezier_curve_t::loadFromBinary<piecewise_bezier_curve_t>, bp::args("filename"),
+//           "Loads *this from a binary file.")
+        #ifdef CURVES_WITH_PINOCCHIO_SUPPORT
+          .def("evaluateAsSE3", &piecewiseSE3ReturnPinocchio, "Evaluate the curve at the given time. Return as a pinocchio.SE3 object",
+               args("self", "t"))
+          .def("derivateAsMotion", &piecewiseSE3ReturnDerivatePinocchio,
+               "Evaluate the derivative of order N of curve at time t. Return as a pinocchio.Motion",
+               args("self", "t", "N"))
+          .def("append", &addFinalSE3,
+           "Append a new linear SE3 curve at the end of the piecewise curve, defined between self.max() "
+           "and time and connecting exactly self(self.max()) and end",
+           args("self", "end", "time"))
+        #endif  // CURVES_WITH_PINOCCHIO_SUPPORT
+        ;
+
   /** END piecewise curve function **/
   /** BEGIN exact_cubic curve**/
   class_<exact_cubic_t, bases<curve_abc_t> >("exact_cubic", init<>())
@@ -763,6 +880,12 @@ BOOST_PYTHON_MODULE(curves) {
            "Create a SE3 curve between two transform, defined for t \in [min,max]."
            " Using linear interpolation for translation and slerp for rotation between init and end."
            " The input transform are expressed as 4x4 matrix.")
+      .def("__init__",
+           make_constructor(&wrapSE3CurveFromPosAndRotation, default_call_policies(),
+                            args("init_translation", "end_translation","init_rotation","end_rotation", "min", "max")),
+           "Create a SE3 curve between two transform, defined for t \in [min,max]."
+           " Using linear interpolation for translation and slerp for rotation between init and end."
+           " The input translations are expressed as 3d vector and the rotations as 3x3 matrix.")
       .def("__init__",
            make_constructor(&wrapSE3CurveFromTwoCurves, default_call_policies(),
                             args("translation_curve", "rotation_curve")),
@@ -802,9 +925,9 @@ BOOST_PYTHON_MODULE(curves) {
                             args("init_SE3", "end_SE3", "min", "max")),
            "Create a SE3 curve between two SE3 objects from Pinocchio, defined for t \in [min,max]."
            " Using linear interpolation for translation and slerp for rotation between init and end.")
-      .def("evaluateAsSE3", &se3Return, "Evaluate the curve at the given time. Return as a pinocchio.SE3 object",
+      .def("evaluateAsSE3", &se3ReturnPinocchio, "Evaluate the curve at the given time. Return as a pinocchio.SE3 object",
            args("self", "t"))
-      .def("derivateAsMotion", &se3ReturnDerivate,
+      .def("derivateAsMotion", &se3ReturnDerivatePinocchio,
            "Evaluate the derivative of order N of curve at time t. Return as a pinocchio.Motion",
            args("self", "t", "N"))
 #endif  // CURVES_WITH_PINOCCHIO_SUPPORT
diff --git a/python/python_variables.h b/python/python_variables.h
index 59ae2fad01b81c619f6eeaac5823437f0517efd2..bc380f7abdd4878f411e5941ec615dd1ad9da6b1 100644
--- a/python/python_variables.h
+++ b/python/python_variables.h
@@ -99,6 +99,7 @@ typedef curves::piecewise_curve<real, real, true, linear_variable_t,
 typedef curves::exact_cubic<real, real, true, pointX_t, t_pointX_t> exact_cubic_t;
 typedef SO3Linear<double, double, true> SO3Linear_t;
 typedef SE3Curve<double, double, true> SE3Curve_t;
+typedef curves::piecewise_curve<real, real, true, SE3Curve_t::point_t, t_pointX_t, SE3Curve_t,SE3Curve_t::point_derivate_t> piecewise_SE3_curve_t;
 typedef curves::Bern<double> bernstein_t;
 
 /*** TEMPLATE SPECIALIZATION FOR PYTHON ****/
@@ -117,6 +118,7 @@ EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::piecewise_bezier_linear_c
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::exact_cubic_t)
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::SO3Linear_t)
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::SE3Curve_t)
+EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::piecewise_SE3_curve_t)
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::matrix_x_t)
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::pointX_t)
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::linear_variable_t)
diff --git a/python/test/test.py b/python/test/test.py
index 2d3709567fe9113400beaf134682d980a05d4ddf..71be59d9f9390d4d622b9ce3867152d6a4fbd4d7 100644
--- a/python/test/test.py
+++ b/python/test/test.py
@@ -10,7 +10,7 @@ from numpy.linalg import norm
 from curves import (CURVES_WITH_PINOCCHIO_SUPPORT, Quaternion, SE3Curve, SO3Linear, bezier, bezier3,
                     bezier_from_hermite, bezier_from_polynomial, cubic_hermite_spline, curve_constraints, exact_cubic,
                     hermite_from_bezier, hermite_from_polynomial, piecewise_bezier_curve,
-                    piecewise_cubic_hermite_curve, piecewise_polynomial_curve, polynomial, polynomial_from_bezier,
+                    piecewise_cubic_hermite_curve, piecewise_polynomial_curve,piecewise_SE3_curve, polynomial, polynomial_from_bezier,
                     polynomial_from_hermite)
 
 eigenpy.switchToNumpyArray()
@@ -339,6 +339,37 @@ class TestCurves(unittest.TestCase):
         pc_test.loadFromText("serialization_pc.test")
         self.assertTrue((pc(0.4) == pc_test(0.4)).all())
         os.remove("serialization_pc.test")
+
+
+        waypoints3 = array([[1., 2., 3.,0.6,-9.], [-1., 1.6, 1.7,6.7,14]]).transpose()
+        c = polynomial(waypoints3, 3., 5.2)
+        with self.assertRaises(ValueError):# a and c doesn't have the same dimension
+          pc.append(c)
+
+        ### Test the different append methods :
+        pc = piecewise_polynomial_curve()
+        self.assertEqual(pc.num_curves(),0)
+        end_point1 = array([1.,3.,5.,6.5,-2.])
+        max1 = 2.5
+        with self.assertRaises(RuntimeError): # cannot add final point in an empty curve
+          pc.append(end_point1.reshape(-1,1),max1)
+        with self.assertRaises(ValueError):# a and end_point1 doesn't have the same dimension
+          pc.append(a)
+          pc.append(end_point1.reshape(-1,1),max1)
+
+        pc = piecewise_polynomial_curve()
+        d = polynomial(waypoints3, 0., 1.2)
+        self.assertEqual(pc.num_curves(),0)
+        pc.append(d)
+        self.assertEqual(pc.num_curves(),1)
+        pc.append(end_point1.reshape(-1,1),max1)
+        self.assertEqual(pc.num_curves(),2)
+        self.assertEqual(pc.min(),0.)
+        self.assertEqual(pc.max(),max1)
+        self.assertTrue(pc.is_continuous(0))
+        self.assertTrue(isclose(pc(0.),d(0.)).all())
+        self.assertTrue(isclose(pc(max1),end_point1).all())
+
         return
 
     def test_piecewise_from_points_list(self):
@@ -399,7 +430,7 @@ class TestCurves(unittest.TestCase):
         a = bezier(waypoints, 0., 1.)
         b = bezier(waypoints, 1., 2.)
         pc = piecewise_bezier_curve(a)
-        pc.add_curve(b)
+        pc.append(b)
         pc.min()
         pc.max()
         pc(0.4)
@@ -427,7 +458,7 @@ class TestCurves(unittest.TestCase):
         a = cubic_hermite_spline(points, tangents, time_points0)
         b = cubic_hermite_spline(points, tangents, time_points1)
         pc = piecewise_cubic_hermite_curve(a)
-        pc.add_curve(b)
+        pc.append(b)
         pc.min()
         pc.max()
         pc(0.4)
@@ -526,13 +557,178 @@ class TestCurves(unittest.TestCase):
         self.assertTrue(norm(a(0.3) - a_bc(0.3)) < __EPS)
         return
 
+    def test_piecewise_se3_curve(self):
+      init_quat = Quaternion.Identity()
+      end_quat = Quaternion(sqrt(2.) / 2., sqrt(2.) / 2., 0, 0)
+      init_rot = init_quat.matrix()
+      end_rot = end_quat.matrix()
+      waypoints = array([[1., 2., 3.], [4., 5., 6.], [4., 5., 6.], [4., 5., 6.], [4., 5., 6.]]).transpose()
+      min = 0.2
+      max = 1.5
+      translation = bezier(waypoints, min, max)
+      # test with bezier
+      se3 = SE3Curve(translation, init_rot, end_rot)
+      pc = piecewise_SE3_curve(se3)
+      self.assertEqual(pc.num_curves(),1)
+      self.assertEqual(pc.min(), min)
+      self.assertEqual(pc.max(), max)
+      pmin = pc(min)
+      pmax = pc(max)
+      self.assertTrue(isclose(pmin[:3, :3], init_rot).all())
+      self.assertTrue(isclose(pmax[:3, :3], end_rot).all())
+      self.assertTrue(isclose(pmin[0:3, 3], translation(min)).all())
+      self.assertTrue(isclose(pmax[0:3, 3], translation(max)).all())
+      # add another curve :
+      end_pos2 = array([-2,0.2,1.6])
+      max2 = 2.7
+      se3_2 = SE3Curve(translation(max).reshape(-1,1),end_pos2.reshape(-1,1),end_rot,end_rot,max,max2)
+      pc.append(se3_2)
+      self.assertEqual(pc.num_curves(),2)
+      pmin2 = pc(max)
+      pmax2 = pc(max2)
+      self.assertTrue(isclose(pmin2[:3, :3], end_rot).all())
+      self.assertTrue(isclose(pmax2[:3, :3], end_rot).all())
+      self.assertTrue(isclose(pmin2[0:3, 3], se3_2.translation(max)).all())
+      self.assertTrue(isclose(pmax2[0:3, 3], se3_2.translation(max2)).all())
+      self.assertTrue(pc.is_continuous(0))
+      self.assertFalse(pc.is_continuous(1))
+
+      # check if error are correctly raised :
+      with self.assertRaises(ValueError): # time intervals do not match
+        se3_3 = SE3Curve(se3_2(max2),se3_2(max2-0.5),max2-0.5,max2+1.5)
+        pc.append(se3_3)
+      with self.assertRaises(ValueError):
+        se3_3 = SE3Curve(se3_2(max2),se3_2(max2-0.5),max2+0.1,max2+1.5)
+        pc.append(se3_3)
+
+      # TODO : serialization
+
+      se3_3 = SE3Curve(se3(max),se3_2(max2-0.5),max2,max2+1.5)
+      pc.append(se3_3)
+      self.assertFalse(pc.is_continuous(0))
+
+
+      ###  test the different append methods :
+      init_quat = Quaternion.Identity()
+      end_quat = Quaternion(sqrt(2.) / 2., sqrt(2.) / 2., 0, 0)
+      init_rot = init_quat.matrix()
+      end_rot = end_quat.matrix()
+      waypoints = array([[1., 2., 3.], [4., 5., 6.], [4., 5., 6.], [4., 5., 6.], [4., 5., 6.]]).transpose()
+      min = 0.2
+      max = 1.5
+      translation = bezier(waypoints, min, max)
+      # test with bezier
+      se3 = SE3Curve(translation, init_rot, end_rot)
+      pc = piecewise_SE3_curve()
+      self.assertEqual(pc.num_curves(),0)
+      pc.append(se3)
+      self.assertEqual(pc.num_curves(),1)
+      self.assertEqual(pc.min(), min)
+      self.assertEqual(pc.max(), max)
+      pmin = pc(min)
+      pmax = pc(max)
+      self.assertTrue(isclose(pmin[:3, :3], init_rot).all())
+      self.assertTrue(isclose(pmax[:3, :3], end_rot).all())
+      self.assertTrue(isclose(pmin[0:3, 3], translation(min)).all())
+      self.assertTrue(isclose(pmax[0:3, 3], translation(max)).all())
+      # append a final tranform :
+      end_quat = Quaternion(sqrt(2.) / 2., 0., sqrt(2.) / 2., 0)
+      end_rot = end_quat.matrix()
+      end_translation = array([1.7, -0.8, 3.]).T
+      end_pose = array(np.identity(4))
+      end_pose[:3, :3] = end_rot
+      end_pose[:3, 3] = end_translation
+      max2 = 3.8
+      pc.append(end_pose,max2)
+      self.assertEqual(pc.num_curves(),2)
+      self.assertEqual(pc.min(), min)
+      self.assertEqual(pc.max(), max2)
+      pmin = pc(min)
+      pmax = pc(max2)
+      self.assertTrue(isclose(pmin[:3, :3], init_rot).all())
+      self.assertTrue(isclose(pmax[:3, :3], end_rot).all())
+      self.assertTrue(isclose(pmin[0:3, 3], translation(min)).all())
+      self.assertTrue(isclose(pmax[0:3, 3], end_translation).all())
+      self.assertTrue(pc.is_continuous(0))
+      if CURVES_WITH_PINOCCHIO_SUPPORT:
+        end_quat = Quaternion(sqrt(2.) / 2., 0., 0, sqrt(2.) / 2.)
+        end_rot = end_quat.matrix()
+        end_translation = array([-17., 3.7, 1.])
+        end_pose = SE3.Identity()
+        end_pose.rotation = end_rot
+        end_pose.translation = end_translation.reshape(-1,1)
+        max3 = 6.5
+        pc.append(end_pose,max3)
+        self.assertEqual(pc.num_curves(),3)
+        self.assertEqual(pc.min(), min)
+        self.assertEqual(pc.max(), max3)
+        pmin = pc(min)
+        pmax = pc(max3)
+        self.assertTrue(isclose(pmin[:3, :3], init_rot).all())
+        self.assertTrue(isclose(pmax[:3, :3], end_rot).all())
+        self.assertTrue(isclose(pmin[0:3, 3], translation(min)).all())
+        self.assertTrue(isclose(pmax[0:3, 3], end_translation).all())
+        self.assertTrue(pc.is_continuous(0))
+      pc = piecewise_SE3_curve()
+      with self.assertRaises(RuntimeError):
+        pc.append(end_pose,max)
+
+    if CURVES_WITH_PINOCCHIO_SUPPORT:
+
+        def test_piecewise_se3_curve_linear_pinocchio(self):
+            print("test piecewise SE3 pinocchio")
+            init_quat = Quaternion.Identity()
+            end_quat = Quaternion(sqrt(2.) / 2., sqrt(2.) / 2., 0, 0)
+            init_rot = init_quat.matrix()
+            end_rot = end_quat.matrix()
+            init_translation = array([0.2, -0.7, 0.6])
+            end_translation = array([3.6, -2.2, -0.9])
+            init_pose = SE3.Identity()
+            end_pose = SE3.Identity()
+            init_pose.rotation = init_rot
+            end_pose.rotation = end_rot
+            init_pose.translation = init_translation.reshape(-1,1)
+            end_pose.translation = end_translation.reshape(-1,1)
+            min = 0.7
+            max = 12.
+            se3 = SE3Curve(init_pose, end_pose, min, max)
+            pc = piecewise_SE3_curve(se3)
+            self.assertEqual(pc.num_curves(),1)
+            p = pc.evaluateAsSE3(min)
+            self.assertTrue(isinstance(p, SE3))
+            self.assertTrue(pc.evaluateAsSE3(min).isApprox(init_pose, 1e-6))
+            self.assertTrue(pc.evaluateAsSE3(max).isApprox(end_pose, 1e-6))
+            self.assertEqual(pc.min(), min)
+            self.assertEqual(pc.max(), max)
+            self.assertTrue(isclose(pc.rotation(min), init_rot).all())
+            self.assertTrue(isclose(pc.translation(min), init_translation).all())
+            self.assertTrue(isclose(pc.rotation(max), end_rot).all())
+            self.assertTrue(isclose(pc.translation(max), end_translation).all())
+            # add another curve :
+            end_translation2 = array([-2., 1.6, -14.])
+            end_pose2 = SE3.Identity()
+            end_pose2.rotation = end_rot
+            end_pose2.translation = end_translation2.reshape(-1,1)
+            max2 = 23.9
+            se3_2 = SE3Curve(end_pose, end_pose2, max, max2)
+            pc.append(se3_2)
+            self.assertEqual(pc.num_curves(),2)
+            p = pc.evaluateAsSE3(max2)
+            self.assertTrue(isinstance(p, SE3))
+            self.assertTrue(pc.evaluateAsSE3(max2).isApprox(end_pose2, 1e-6))
+            self.assertEqual(pc.min(), min)
+            self.assertEqual(pc.max(), max2)
+            self.assertTrue(isclose(pc.rotation(max2), end_rot).all())
+            self.assertTrue(isclose(pc.translation(max2), end_translation2).all())
+
+
     def test_conversion_piecewise_curves(self):
         __EPS = 1e-6
         waypoints = array([[1., 2., 3.], [4., 5., 6.]]).transpose()
         a = bezier(waypoints, 0., 1.)
         b = bezier(waypoints, 1., 2.)
         pc = piecewise_bezier_curve(a)
-        pc.add_curve(b)
+        pc.append(b)
         # Convert to piecewise polynomial
         pc_pol = pc.convert_piecewise_curve_to_polynomial()
         self.assertTrue(norm(pc_pol(0.3) - pc(0.3)) < __EPS)
@@ -600,6 +796,9 @@ class TestCurves(unittest.TestCase):
             so3Rot.derivate(3., 1)
         with self.assertRaises(ValueError):
             so3Rot.derivate(1., 0)
+        with self.assertRaises(ValueError):
+            test = SO3Linear(init_rot,end_rot,max,min)
+
 
     def test_se3_curve_linear(self):
         print("test SE3 Linear")
@@ -621,10 +820,8 @@ class TestCurves(unittest.TestCase):
         p = se3(min)
         if CURVES_WITH_PINOCCHIO_SUPPORT:
             self.assertTrue(isinstance(se3.evaluateAsSE3(min), SE3))
-            init_pose = SE3(init_pose)
-            end_pose = SE3(end_pose)
-            self.assertTrue(se3.evaluateAsSE3(min).isApprox(init_pose, 1e-6))
-            self.assertTrue(se3.evaluateAsSE3(max).isApprox(end_pose, 1e-6))
+            self.assertTrue(se3.evaluateAsSE3(min).isApprox(SE3(init_pose), 1e-6))
+            self.assertTrue(se3.evaluateAsSE3(max).isApprox(SE3(end_pose), 1e-6))
         self.assertEqual(p.shape[0], 4)
         self.assertEqual(p.shape[1], 4)
         self.assertTrue(isclose(se3(min), init_pose).all())
@@ -643,8 +840,8 @@ class TestCurves(unittest.TestCase):
             self.assertTrue(isclose(motion.linear, ((end_translation - init_translation) / (max - min))).all())
             self.assertTrue(isclose(motion.angular[0], 1.20830487))
             self.assertTrue(isclose(motion.angular[1:3], array([0, 0]).T).all())
-            self.assertTrue(d.isApprox(se3.derivateAsMotion(0.5, 1), 1e-6))
-            self.assertTrue(d.isApprox(se3.derivateAsMotion(max, 1), 1e-6))
+            self.assertTrue(motion.isApprox(se3.derivateAsMotion(0.5, 1), 1e-6))
+            self.assertTrue(motion.isApprox(se3.derivateAsMotion(max, 1), 1e-6))
             self.assertTrue(se3.derivateAsMotion(min, 2).isApprox(Motion.Zero(), 1e-6))
             self.assertTrue(se3.derivateAsMotion(min, 3).isApprox(Motion.Zero(), 1e-6))
         self.assertEqual(d.shape[0], 6)
@@ -669,6 +866,8 @@ class TestCurves(unittest.TestCase):
             se3.derivate(3., 1)
         with self.assertRaises(ValueError):
             se3.derivate(1., 0)
+        with self.assertRaises(ValueError):
+            test = SE3Curve(init_pose,end_pose,max,min)
 
     def test_se3_from_translation_curve(self):
         print("test SE3 From translation curves")
@@ -830,14 +1029,14 @@ class TestCurves(unittest.TestCase):
             end_quat = Quaternion(sqrt(2.) / 2., sqrt(2.) / 2., 0, 0)
             init_rot = init_quat.matrix()
             end_rot = end_quat.matrix()
-            init_translation = array([0.2, -0.7, 0.6]).T
-            end_translation = array([3.6, -2.2, -0.9]).T
+            init_translation = array([0.2, -0.7, 0.6])
+            end_translation = array([3.6, -2.2, -0.9])
             init_pose = SE3.Identity()
             end_pose = SE3.Identity()
             init_pose.rotation = init_rot
             end_pose.rotation = end_rot
-            init_pose.translation = init_translation
-            end_pose.translation = end_translation
+            init_pose.translation = init_translation.reshape(-1,1)
+            end_pose.translation = end_translation.reshape(-1,1)
             min = 0.7
             max = 12.
             se3 = SE3Curve(init_pose, end_pose, min, max)
@@ -867,11 +1066,11 @@ class TestCurves(unittest.TestCase):
             with self.assertRaises(ValueError):
                 se3(-0.1)
             with self.assertRaises(ValueError):
-                se3(3)
+                se3(13.)
             with self.assertRaises(ValueError):
                 se3.derivate(0, 1)
             with self.assertRaises(ValueError):
-                se3.derivate(3., 1)
+                se3.derivate(13., 1)
             with self.assertRaises(ValueError):
                 se3.derivate(1., 0)