diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5029d5d5595a3a061cbe345b897132fb1f2a873e..0e2347132bc9b539b0f16cd318e8335d89bd4641 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,7 +31,7 @@ SETUP_PROJECT()
 string (REPLACE "-Werror" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
 MESSAGE( STATUS "CMAKE_CXX_FLAGS: " ${CMAKE_CXX_FLAGS} )
 
-OPTION (BUILD_PYTHON_INTERFACE "Build the python binding" OFF)
+OPTION (BUILD_PYTHON_INTERFACE "Build the python binding" ON)
 IF(BUILD_PYTHON_INTERFACE)
 # search for python
 	FINDPYTHON(2.7 EXACT REQUIRED)
diff --git a/include/centroidal-dynamics-lib/centroidal_dynamics.hh b/include/centroidal-dynamics-lib/centroidal_dynamics.hh
index 8d437e9f8f2957fc7336154c1c69d6eab5c4c30a..1586f246f37168bf9a641d630683ca9efa4eee98 100644
--- a/include/centroidal-dynamics-lib/centroidal_dynamics.hh
+++ b/include/centroidal-dynamics-lib/centroidal_dynamics.hh
@@ -29,6 +29,8 @@ class CENTROIDAL_DYNAMICS_DLLAPI Equilibrium
 public:
   const double m_mass; /// mass of the system
   const Vector3 m_gravity; ///  gravity vector
+  /** Gravito-inertial wrench generators (6 X numberOfContacts*generatorsPerContact) */
+  Matrix6X m_G_centr;
 
 private:
   static bool m_is_cdd_initialized;   /// true if cdd lib has been initialized, false otherwise
@@ -40,8 +42,6 @@ private:
 
   unsigned int  m_generatorsPerContact; /// number of generators to approximate the friction cone per contact point
 
-  /** Gravito-inertial wrench generators (6 X numberOfContacts*generatorsPerContact) */
-  Matrix6X m_G_centr;
 
   /** Inequality matrix and vector defining the gravito-inertial wrench cone H w <= h */
   MatrixXX m_H;
@@ -222,6 +222,30 @@ public:
    */
   LP_status checkRobustEquilibrium(Cref_vector3 com, bool &equilibrium, double e_max=0.0);
 
+
+  /**
+   * @brief Check whether the specified com position is in robust equilibrium.
+   * This amounts to solving the following feasibility LP:
+   *       find          b
+   *       minimize      1
+   *       subject to    G b = D c + d
+   *                     b >= b0
+   *  where:
+   *     b         are the coefficient of the contact force generators (f = G b)
+   *     b0        is a parameter proportional to the specified robustness measure
+   *     c         is the specified CoM position
+   *     G         is the 6xm matrix whose columns are the gravito-inertial wrench generators
+   *     D         is the 6x3 matrix mapping the CoM position in gravito-inertial wrench
+   *     d         is the 6d vector containing the gravity part of the gravito-inertial wrench
+   * @param com The 3d center of mass position to test.
+   * @param acc The 3d acceleration of the CoM.
+   * @param equilibrium True if com is in robust equilibrium, false otherwise.
+   * @param e_max Desired robustness level.
+   * @return The status of the LP solver.
+   */
+  LP_status checkRobustEquilibrium(Cref_vector3 com, Cref_vector3 acc, bool &equilibrium, double e_max=0.0);
+
+
   /**
    * @brief Compute the extremum CoM position over the line a*x + a0 that is in robust equilibrium.
    * This amounts to solving the following LP:
diff --git a/include/centroidal-dynamics-lib/util.hh b/include/centroidal-dynamics-lib/util.hh
index cf97755f8281e2fc73f282810225eceb5463f0d3..284c7c35a4a6ba63c251a03856dfd15980680501 100644
--- a/include/centroidal-dynamics-lib/util.hh
+++ b/include/centroidal-dynamics-lib/util.hh
@@ -7,6 +7,8 @@
 
 #include <iostream>
 #include <fstream>
+#include <cmath>
+#include <cassert>
 
 #include <Eigen/Dense>
 #include <Eigen/src/Core/util/Macros.h>
@@ -136,6 +138,61 @@ namespace centroidal_dynamics
 
   std::string getDateAndTimeAsString();
 
+  /**
+ * Computes a binomal coefficient
+ * @return  n!/((n–k)! k!).
+ */
+  value_type nchoosek(const int n, const int k);
+
+  template < typename DerivedV, typename DerivedU>
+  void doCombs(Eigen::Matrix<typename DerivedU::Scalar,1,Eigen::Dynamic>& running,
+               int& running_i, int& running_j, Eigen::PlainObjectBase<DerivedU> & U, const Eigen::MatrixBase<DerivedV> & V,
+               int offset, int k)
+  {
+      int N = (int)(V.size());
+      if(k==0)
+      {
+          U.row(running_i) = running;
+          running_i++;
+          return;
+      }
+      for (int i = offset; i <= N - k; ++i)
+      {
+          running(running_j) = V(i);
+          running_j++;
+          doCombs(running, running_i, running_j, U, V, i+1,k-1);
+          running_j--;
+      }
+  }
+
+  /**
+ * Computes a matrix C containing all possible combinations of the elements of vector v taken k at a time.
+ * Matrix C has k columns and n!/((n–k)! k!) rows, where n is length(v).
+ * @param V  n-long vector of elements
+ * @param k  size of sub-set to consider
+ * @param U  result matrix
+ * @return nchoosek by k long matrix where each row is a unique k-size
+ * the first one, with all zeros.
+ */
+  template < typename DerivedV, typename DerivedU>
+  void nchoosek(
+    const Eigen::MatrixBase<DerivedV> & V,
+    const int k,
+    Eigen::PlainObjectBase<DerivedU> & U)
+    {
+        using namespace Eigen;
+        if(V.size() == 0)
+        {
+            U.resize(0,k);
+            return;
+        }
+        assert((V.cols() == 1 || V.rows() == 1) && "V must be a vector");
+        U.resize(nchoosek((int)(V.size()),k),k);
+        int running_i  = 0;
+        int running_j = 0;
+        Matrix<typename DerivedU::Scalar,1,Dynamic> running(1,k);
+        doCombs(running, running_i, running_j, U, V,0,k);
+    }
 } //namespace centroidal_dynamics
 
 #endif //_CENTROIDAL_DYNAMICS_LIB_UTIL_HH
diff --git a/python/centroidal_dynamics_python.cpp b/python/centroidal_dynamics_python.cpp
index 82f1b37628d29b7b35ed3441a77fece7d1bf6a1d..82c17b50c1a5755d7e1d783d871396b1b294b8c7 100644
--- a/python/centroidal_dynamics_python.cpp
+++ b/python/centroidal_dynamics_python.cpp
@@ -26,6 +26,25 @@ boost::python::tuple wrapComputeEquilibriumRobustness(Equilibrium& self, const V
     return boost::python::make_tuple(status, robustness);
 }
 
+boost::python::tuple wrapCheckRobustEquilibrium(Equilibrium& self, const Vector3& com)
+{
+    bool robustness;
+    LP_status status = self.checkRobustEquilibrium(com, robustness);
+    return boost::python::make_tuple(status, robustness);
+}
+
+bool wrapSetNewContacts(Equilibrium& self, const MatrixX3ColMajor& contactPoints, const MatrixX3ColMajor&  contactNormals,
+                        const double frictionCoefficient, const EquilibriumAlgorithm alg)
+{
+    return self.setNewContacts(contactPoints, contactNormals, frictionCoefficient, alg);
+}
+
+bool wrapSetNewContactsFull(Equilibrium& self, const MatrixX3ColMajor& contactPoints, const MatrixX3ColMajor&  contactNormals,
+                      const double frictionCoefficient, const EquilibriumAlgorithm alg)
+{
+    return self.setNewContacts(contactPoints, contactNormals, frictionCoefficient, alg);
+}
+
 boost::python::tuple wrapGetPolytopeInequalities(Equilibrium& self)
 {
     MatrixXX H;
@@ -86,17 +105,19 @@ BOOST_PYTHON_MODULE(centroidal_dynamics)
 
     /** END enum types **/
 
-    bool (Equilibrium::*setNewContacts)
-            (const MatrixX3ColMajor&, const MatrixX3ColMajor&, const double, const EquilibriumAlgorithm) = &Equilibrium::setNewContacts;
+    //bool (Equilibrium::*setNewContacts)
+    //        (const MatrixX3ColMajor&, const MatrixX3ColMajor&, const double, const EquilibriumAlgorithm, const int graspIndex, const double maxGraspForce) = &Equilibrium::setNewContacts;
 
     class_<Equilibrium>("Equilibrium", init<std::string, double, unsigned int, optional <SolverLP, bool, const unsigned int, const bool> >())
             .def("useWarmStart", &Equilibrium::useWarmStart)
             .def("setUseWarmStart", &Equilibrium::setUseWarmStart)
             .def("getName", &Equilibrium::getName)
             .def("getAlgorithm", &Equilibrium::getAlgorithm)
-            .def("setNewContacts", setNewContacts)
+            .def("setNewContacts", wrapSetNewContacts)
+            .def("setNewContacts", wrapSetNewContactsFull)
             .def("computeEquilibriumRobustness", wrapComputeQuasiEquilibriumRobustness)
             .def("computeEquilibriumRobustness", wrapComputeEquilibriumRobustness)
+            .def("checkRobustEquilibrium", wrapCheckRobustEquilibrium)
             .def("getPolytopeInequalities", wrapGetPolytopeInequalities)
     ;
 }
diff --git a/python/test/binding_tests.py b/python/test/binding_tests.py
index 1110c0f8c51ae86ff7a3429c414247ad18e12e53..683bad2b29b0383435de8c18063344b9c22aaa47 100644
--- a/python/test/binding_tests.py
+++ b/python/test/binding_tests.py
@@ -45,3 +45,23 @@ assert (robustness < 0), "first test should NOT be in equilibrirum"
 eq.setNewContacts(asmatrix(P),asmatrix(N),0.3,EquilibriumAlgorithm.EQUILIBRIUM_ALGORITHM_PP)
 H,h = eq.getPolytopeInequalities()
 
+#~ c= asmatrix(array([0.,0.,1.])).T
+status, stable = eq.checkRobustEquilibrium(c)
+assert (status == LP_STATUS_OPTIMAL), "checkRobustEquilibrium should not fail"
+assert (stable), "lat test should be in equilibrirum"
+
+
+from numpy import array, vstack, zeros, sqrt, cross, matrix, asmatrix
+from numpy.linalg import norm
+import numpy as np
+
+def compute_w(c, ddc, dL=array([0.,0.,0.]), m = 54., g_vec=array([0.,0.,-9.81])):
+	w1 = m * (ddc - g_vec)
+	return array(w1.tolist() + (cross(c, w1) + dL).tolist())
+	
+
+def is_stable(H,c=array([0.,0.,1.]), ddc=array([0.,0.,0.]), dL=array([0.,0.,0.]), m = 54., g_vec=array([0.,0.,-9.81]), robustness = 0.):
+	w = compute_w(c, ddc, dL, m, g_vec)	
+	return (H.dot(-w)<=-robustness).all()
+    
+assert(is_stable(H))
diff --git a/src/centroidal_dynamics.cpp b/src/centroidal_dynamics.cpp
index ace1b74a5faeca3f2dedfa0a13a19faf926c5299..b8f0cd798f9b8ea9aabf85afa0d9671fba7422c0 100644
--- a/src/centroidal_dynamics.cpp
+++ b/src/centroidal_dynamics.cpp
@@ -142,6 +142,7 @@ bool Equilibrium::computeGenerators(Cref_matrixX3 contactPoints, Cref_matrixX3 c
       // project generators in 6d centroidal space
       m_G_centr.block(0,cg*i,6,cg) = A * G;
     }
+
     // Compute the coefficient to convert b0 to e_max
     Vector3 f0 = Vector3::Zero();
     for(int j=0; j<cg; j++)
@@ -173,7 +174,6 @@ bool Equilibrium::setNewContacts(const MatrixX3& contactPoints, const MatrixX3&
                                  const double frictionCoefficient, const EquilibriumAlgorithm alg)
 {
   assert(contactPoints.rows()==contactNormals.rows());
-
   if(alg==EQUILIBRIUM_ALGORITHM_IP)
   {
     SEND_ERROR_MSG("Algorithm IP not implemented yet");
@@ -190,7 +190,7 @@ bool Equilibrium::setNewContacts(const MatrixX3& contactPoints, const MatrixX3&
   // Lists of contact generators (3 X generatorsPerContact)
   m_G_centr.resize(6,contactPoints.rows()*m_generatorsPerContact);
 
-  if (!computeGenerators(contactPoints,contactNormals,frictionCoefficient,false))
+  if (!computeGenerators(contactPoints,contactNormals,frictionCoefficient, false))
   {
     return false;
   }
@@ -351,13 +351,22 @@ LP_status Equilibrium::computeEquilibriumRobustness(Cref_vector3 com, Cref_vecto
     return lpStatus_dual;
   }
 
-  SEND_ERROR_MSG("checkRobustEquilibrium is not implemented for the specified algorithm");
+  SEND_ERROR_MSG("computeEquilibriumRobustness is not implemented for the specified algorithm");
   return LP_STATUS_ERROR;
 }
 
+LP_status Equilibrium::checkRobustEquilibrium(Cref_vector3 com, bool &equilibrium, double e_max){
+    checkRobustEquilibrium(com,zero_acc,equilibrium,e_max);
+}
 
-LP_status Equilibrium::checkRobustEquilibrium(Cref_vector3 com, bool &equilibrium, double e_max)
+LP_status Equilibrium::checkRobustEquilibrium(Cref_vector3 com, Cref_vector3 acc, bool &equilibrium, double e_max)
 {
+    // Take the acceleration in account in D and d :
+    m_D.block<3,3>(3,0) = crossMatrix(-m_mass * (m_gravity - acc));
+    m_d.head<3>()= m_mass * (m_gravity - acc);
+    m_HD = m_H * m_D;
+    m_Hd = m_H * m_d;
+
   if(m_G_centr.cols()==0)
   {
     equilibrium=false;
@@ -545,14 +554,19 @@ LP_status Equilibrium::findExtremumInDirection(Cref_vector3 direction, Ref_vecto
   SEND_ERROR_MSG("findExtremumInDirection not implemented yet");
   return LP_STATUS_ERROR;
 }
-
 bool Equilibrium::computePolytopeProjection(Cref_matrix6X v)
 {
-    int n = (int)(v.rows());
-    int m = (int)(v.cols());
 
+    // todo: for the moment using ad hoc upper bound = 500 N
+    int n = (int)v.rows();
+    int m = (int)v.cols();
+    if (n>m)
+    {
+        SEND_ERROR_MSG("V has more lines that columns, this case is not handled!");
+        return false;
+    }
 //  getProfiler().start("eigen_to_cdd");
-  dd_MatrixPtr V = cone_span_eigen_to_cdd(v.transpose(),canonicalize_cdd_matrix);
+    dd_MatrixPtr V = cone_span_eigen_to_cdd(v.transpose(),canonicalize_cdd_matrix);
 //  getProfiler().stop("eigen_to_cdd");
 
   dd_ErrorType error = dd_NoError;
@@ -611,7 +625,6 @@ bool Equilibrium::computePolytopeProjection(Cref_matrix6X v)
         return false;
     }
 
-
   return true;
 }
 
diff --git a/src/util.cpp b/src/util.cpp
index 85d069d31a8d1acecf4a0b48ebcb7866966e70fd..07989162e696d999d42af1b639d8a47c01734379 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -24,11 +24,9 @@ dd_MatrixPtr cone_span_eigen_to_cdd(Cref_matrixXX input, const bool canonicalize
   mytype value;
   dd_NumberType NT = dd_Real;
   dd_init(value);
-
   M=dd_CreateMatrix(m_input, d_input);
   M->representation=rep;
   M->numbtype=NT;
-
   for (i = 0; i < input.rows(); i++)
   {
     dd_set_d(value, 0);
@@ -50,7 +48,6 @@ dd_MatrixPtr cone_span_eigen_to_cdd(Cref_matrixXX input, const bool canonicalize
     set_free(impl_linset);
     free(newpos);
   }
-
   return M;
 }
 
@@ -165,6 +162,51 @@ std::string getDateAndTimeAsString()
   strftime(buffer,80,"%Y%m%d_%I%M%S",timeinfo);
   return std::string(buffer);
 }
+/*
+int fact(const int n)
+{
+    assert(n>=0);
+    int res = 1;
+    for (int i=2 ; i <= n ; ++i)
+       res *= i;
+    return res;
+}
+
+int choosenk(const int n, const int k)
+{
+    return fact(n) / (fact(k) * fact(n - k));
+}*/
+
+/* is this faster ?
+value_type choosenk(const int n, const int k)
+{
+    if(k>n/2)
+        return nchoosek(n,n-k);
+    else if(k==1)
+        return n;
+    else
+    {
+        double c = 1;
+        for(int i = 1;i<=k;i++)
+            c *= (((double)n-k+i)/((double)i));
+        return std::round(c);
+    }
+}*/
+
+value_type nchoosek(const int n, const int k)
+{
+    if(k>n/2)
+        return nchoosek(n,n-k);
+    else if(k==1)
+        return n;
+    else
+    {
+        value_type c = 1;
+        for(int i = 1;i<=k;i++)
+            c *= (((value_type)n-k+i)/((value_type)i));
+        return round(c);
+    }
+}
 
 } //namespace centroidal_dynamics
 
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 18bb1a7e5eab44002fa26e64f8fac3999f3dfd8b..b5c3176f2e48c058c3ec02589310c4a71e498fd4 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -42,4 +42,5 @@ endif ( MSVC )
 
 ADD_TESTCASE(test_static_equilibrium FALSE)
 ADD_TESTCASE(test_LP_solvers FALSE)
+PKG_CONFIG_USE_DEPENDENCY(test_LP_solvers qpOASES)
 
diff --git a/test/test_LP_solvers.cpp b/test/test_LP_solvers.cpp
index 6a90d8eacc3c5bf698db48f6872c4299af15f08c..9a575de886ac95cb3ffccf2e603ade5d05b6abdc 100644
--- a/test/test_LP_solvers.cpp
+++ b/test/test_LP_solvers.cpp
@@ -343,7 +343,7 @@ void test_small_LP()
   model.addRow(3, row2Index, row2Value,
                1.0, 1.0);
 
-  int n = model.getNumCols();
+  int n = model.getdimVarXs();
   int m = model.getNumRows();
   cout<<"Problem has "<<n<<" variables and "<<m<<" constraints.\n";