diff --git a/src/solver-dyn-reduced.cpp b/src/solver-dyn-reduced.cpp
index 4514af4a68211e944b86bdd0c341a1884da6f754..607092ed168ab8f90f2d88fbbad2eaa27f43cb72 100644
--- a/src/solver-dyn-reduced.cpp
+++ b/src/solver-dyn-reduced.cpp
@@ -14,7 +14,7 @@
  * with sot-dyninv.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-//#define VP_DEBUG
+#define VP_DEBUG
 #define VP_DEBUG_MODE 50
 #include <sot/core/debug.hh>
 #ifdef VP_DEBUG
@@ -86,6 +86,8 @@ namespace dynamicgraph
 	,CONSTRUCT_SIGNAL_OUT(Jc,ml::Matrix, sotNOSIGNAL)
 	,CONSTRUCT_SIGNAL_OUT(freeMotionBase,ml::Matrix,
 			      JcSOUT << inertiaSqrootInvSIN)
+	,CONSTRUCT_SIGNAL_OUT(driftContact,ml::Vector,
+			      freeMotionBaseSOUT<<JcSOUT )
 
 	,CONSTRUCT_SIGNAL_OUT(solution,ml::Vector,
 			      freeMotionBaseSOUT << inertiaSqrootInvSIN << inertiaSqrootSIN
@@ -101,6 +103,8 @@ namespace dynamicgraph
 	,CONSTRUCT_SIGNAL_OUT(torque,ml::Vector,
 			      JcSOUT << forcesSOUT << reducedControlSOUT << inertiaSqrootSIN )
 
+	,CONSTRUCT_SIGNAL(Jcdot,OUT,ml::Matrix)
+
 	,hsolver()
 
 	,Cforce(),Czero()
@@ -122,11 +126,15 @@ namespace dynamicgraph
 			    << inertiaSqrootInvOutSOUT
 			    << JcSOUT
 			    << freeMotionBaseSOUT
+			    << driftContactSOUT
+
 			    << solutionSOUT
 			    << reducedControlSOUT
 			    << accelerationSOUT
 			    << forcesSOUT
 			    << torqueSOUT
+
+			    << JcdotSOUT
 			    );
 
 	inertiaSqrootInvSIN.plug( &inertiaSqrootInvOutSOUT );
@@ -432,6 +440,25 @@ namespace dynamicgraph
 		  break;
 		}
 	    }
+	  return vb;
+	}
+
+	/* TODO: inherite from JacobiSVD a structure where rank can be computed dynamically. */
+	inline int svdRankDefEval( const Eigen::JacobiSVD<Eigen::MatrixXd >& Msvd,
+				   const double threshold = 1e-5 )
+	{
+	  return (Msvd.singularValues().array() > threshold ).count();
+	}
+  	template<typename D2>
+	Eigen::VectorXd svdRankDefSolve( const Eigen::JacobiSVD<Eigen::MatrixXd >& Msvd,
+					 const Eigen::MatrixBase<D2>& y,
+					 const int rank )
+	{
+	  assert( Msvd.computeU() && Msvd.computeV() );
+	  return
+	    Msvd.matrixV().leftCols(rank) *
+	    Msvd.singularValues().array().head(rank).inverse().matrix().asDiagonal() *
+	    Msvd.matrixU().leftCols(rank).transpose()*y;
 	}
       }
 
@@ -523,14 +550,21 @@ namespace dynamicgraph
 	using namespace Eigen;
 
 	const int& nf = sizeForceSOUT(t);
+	EIGEN_CONST_VECTOR_FROM_SIGNAL(qdot,velocitySIN(t));
 	const int nq= velocitySIN(t).size();
+
 	EIGEN_MATRIX_FROM_MATRIX(J,mlJ,nf,nq);
+	ml::Matrix mlJdot;
+	EIGEN_MATRIX_FROM_MATRIX(Jdot,mlJdot,nf,nq);
+	forceDrift.resize(nf);
 
 	BOOST_FOREACH(contacts_t::value_type& pContact, contactMap)
 	  {
 	    Contact& contact = pContact.second;
 	    EIGEN_CONST_MATRIX_FROM_SIGNAL(Ji,(*contact.jacobianSIN)(t));
+	    EIGEN_CONST_MATRIX_FROM_SIGNAL(Jdoti,(*contact.JdotSIN)(t));
 	    EIGEN_CONST_MATRIX_FROM_SIGNAL(support,(*contact.supportSIN)(t));
+	    EIGEN_CONST_VECTOR_FROM_SIGNAL(corrector,(*contact.correctorSIN)(t));
 	    const int n0 = contact.range.first, n1 = contact.range.second;
 	    assert( Ji.rows()==6 && Ji.cols()==nq );
 	    assert( n0>=0 && J.rows()>=n1 );
@@ -538,13 +572,21 @@ namespace dynamicgraph
 	    const int nbp = support.cols();
 	    assert( ((n1-n0) % 3 == 0) && nbp == (n1-n0)/3);
 	    Matrix3d X;
+	    VectorXd taskDrift = corrector - Jdoti*qdot;
+
 	    for( int i=0;i<nbp;++i )
 	      {
 		sotSolverDyn::preCross(support.col(i),X);
 		J.ROWS(n0+i*3,n0+(i+1)*3)
 		  = Ji.ROWS(0,3) - X* Ji.ROWS(3,6);
+		Jdot.ROWS(n0+i*3,n0+(i+1)*3)
+		  = Jdoti.ROWS(0,3) - X* Jdoti.ROWS(3,6);
+		forceDrift.ROWS(n0+i*3,n0+(i+1)*3)
+		  = taskDrift.ROWS(0,3) - X*taskDrift.ROWS(3,6);
 	      }
 	  }
+
+	JcdotSOUT = mlJdot;
 	return mlJ;
       }
 
@@ -554,18 +596,18 @@ namespace dynamicgraph
 	using namespace Eigen;
 	EIGEN_CONST_MATRIX_FROM_SIGNAL(B,inertiaSqrootInvSIN(t));
 	EIGEN_CONST_MATRIX_FROM_SIGNAL(J,JcSOUT(t));
-	const int nf = J.rows(), nq = B.cols();
+	const int nq = B.cols();
 	assert( J.cols()==nq && B.rows() == nq );
 
-	MatrixXd Gt = (J*B.triangularView<Eigen::Upper>()).transpose();
-	FullPivHouseholderQR<MatrixXd> qr( Gt );
-	qr.setThreshold( 1e-3 );
-	const unsigned int freeRank = nq-qr.rank();
+	MatrixXd G = (J*B.triangularView<Eigen::Upper>());
+	G_svd.compute(G,ComputeFullV|ComputeThinU);
+	G_rank = sotSolverDyn::svdRankDefEval(G_svd,1e-3);
+	const unsigned int freeRank = nq-G_rank;
 
 	EIGEN_MATRIX_FROM_MATRIX(V,mlV,nq,freeRank);
-	assert( qr.matrixQ().cols()==nq && qr.matrixQ().rows()==nq
-		&& qr.matrixQ().rows()==nq );
-	V = qr.matrixQ().rightCols(freeRank);
+	assert( G_svd.computeV() && G_svd.matrixV().cols()==nq && G_svd.matrixV().rows()==nq );
+	V = G_svd.matrixV().rightCols(freeRank);
+
 	return mlV;
       }
 
@@ -580,7 +622,7 @@ namespace dynamicgraph
 
 	bool toBeResize = hsolver==NULL
 	  || (nu+nf)!=(int)hsolver->sizeProblem
-	  || stack.size()+2!= (int)hsolver->nbStages();
+	  || stack.size()+2!= hsolver->nbStages();
 
 	/* Resize the force level. */
 	if( Cforce.rows()!=nf/3+6 || Cforce.cols()!=nf+nu || bforce.size()!=nf/3+6)
@@ -639,6 +681,28 @@ namespace dynamicgraph
 	  }
       }
 
+      ml::Vector& SolverDynReduced::
+      driftContactSOUT_function( ml::Vector &mlres, int t )
+      {
+	/* BV has already been computed, but I don't know if it is the best
+	 * idea to go for it a second time. This suppose that the matrix has
+	 * not been modified in between. It should work, but start with that if
+	 * you are looking for a bug in ddq. */
+	/* Same for G_svd. */
+	using soth::MATLAB;
+	using namespace sotSolverDyn;
+	using namespace Eigen;
+
+	EIGEN_CONST_MATRIX_FROM_SIGNAL(sB,inertiaSqrootInvSIN(t));
+	Eigen::TriangularView<const_SigMatrixXd,Eigen::Upper> B(sB);
+	EIGEN_VECTOR_FROM_VECTOR(res,mlres,B.rows());
+	sotDEBUG(40) << "fdrift = " << (MATLAB)forceDrift << std::endl;
+	Eigen::VectorXd drift = svdRankDefSolve( G_svd,forceDrift,G_rank );
+	sotDEBUG(40) << "drift = " << (MATLAB)drift << std::endl;
+	res = B*drift;
+
+	return mlres;
+      }
       ml::Vector& SolverDynReduced::
       solutionSOUT_function( ml::Vector &mlres, int t )
       {
@@ -735,15 +799,14 @@ namespace dynamicgraph
 	    EIGEN_CONST_MATRIX_FROM_SIGNAL(Jdot,task.JdotSOUT(t));
 	    EIGEN_CONST_MATRIX_FROM_SIGNAL(J,task.jacobianSOUT(t));
 	    const dg::sot::VectorMultiBound & ddx = task.taskSOUT(t);
-	    const int nx = ddx.size();
 
 	    sotDEBUG(5) << "ddx"<<i<<" = " << ddx << std::endl;
 	    sotDEBUG(25) << "J"<<i<<" = " << (MATLAB)J << std::endl;
 	    sotDEBUG(45) << "Jdot"<<i<<" = " << (MATLAB)Jdot << std::endl;
 
-	    assert( Ctask1.rows() == nx && btask1.size() == nx );
-	    assert( J.rows()==nx && J.cols()==nq && (int)ddx.size()==nx );
-	    assert( Jdot.rows()==nx && Jdot.cols()==nq );
+	    assert( Ctask1.rows() == ddx.size() && btask1.size() == ddx.size() );
+	    assert( J.rows()==ddx.size() && J.cols()==nq && (int)ddx.size()==ddx.size() );
+	    assert( Jdot.rows()==ddx.size() && Jdot.cols()==nq );
 
 	    Ctask1.COLS_U = J*BV;	    Ctask1.COLS_F.fill(0);
 	    VectorXd Jdqd = Jdot*qdot;
@@ -808,7 +871,14 @@ namespace dynamicgraph
 	 * idea to go for it a second time. This suppose that the matrix has
 	 * not been modified in between. It should work, but start with that if
 	 * you are looking for a bug in ddq. */
-	ddq = BV*u;
+	/* Same for G_svd. */
+
+	using soth::MATLAB;
+	using namespace sotSolverDyn;
+
+	EIGEN_CONST_VECTOR_FROM_SIGNAL(Bdrift,driftContactSOUT(t));
+	sotDEBUG(40) << "drift = " << (MATLAB)Bdrift << std::endl;
+	ddq = BV*u + Bdrift;
 	return mlddq;
       }
       ml::Vector& SolverDynReduced::
diff --git a/src/solver-dyn-reduced.h b/src/solver-dyn-reduced.h
index 5fb9091deef7aa4f0471bff9cc996a163a7943ce..60651c15f4a79a9d909509d6c319747000b5034a 100644
--- a/src/solver-dyn-reduced.h
+++ b/src/solver-dyn-reduced.h
@@ -41,6 +41,8 @@
 #include <sot-dyninv/stack-template.h>
 #include <sot-dyninv/task-dyn-pd.h>
 #include <soth/HCOD.hpp>
+#include <Eigen/QR>
+#include <Eigen/SVD>
 
 namespace dynamicgraph {
   namespace sot {
@@ -101,13 +103,16 @@ namespace dynamicgraph {
 	  DECLARE_SIGNAL_OUT(Jc,ml::Matrix);
 
 	  DECLARE_SIGNAL_OUT(freeMotionBase,ml::Matrix);
+	  DECLARE_SIGNAL_OUT(driftContact,ml::Vector);
+
 	  DECLARE_SIGNAL_OUT(solution,ml::Vector);
 	  DECLARE_SIGNAL_OUT(reducedControl,ml::Vector);
 	  DECLARE_SIGNAL_OUT(acceleration,ml::Vector);
 	  DECLARE_SIGNAL_OUT(forces,ml::Vector);
 	  DECLARE_SIGNAL_OUT(torque,ml::Vector);
 
-
+	  /* Temporary time-dependant shared variables. */
+	  DECLARE_SIGNAL(Jcdot,OUT,ml::Matrix);
 
 	private:  /* --- CONTACT POINTS --- */
 
@@ -149,6 +154,10 @@ namespace dynamicgraph {
 	  typedef boost::shared_ptr<soth::HCOD> hcod_ptr_t;
 	  hcod_ptr_t hsolver;
 
+	  //Eigen::FullPivHouseholderQR<Eigen::MatrixXd> Gt_qr;
+	  Eigen::JacobiSVD<Eigen::MatrixXd> G_svd;
+	  int G_rank;
+
 	  Eigen::MatrixXd Cforce,Czero;
 	  soth::VectorBound bforce,bzero;
 	  std::vector< Eigen::MatrixXd > Ctasks;
@@ -156,7 +165,7 @@ namespace dynamicgraph {
 
 	  Eigen::MatrixXd BV;
 
-	  Eigen::VectorXd solution;
+	  Eigen::VectorXd solution,forceDrift;
 
 	}; // class SolverDynReduced