From 3e21e6e10c0d56cae04d71f490778b975abc80d1 Mon Sep 17 00:00:00 2001
From: Mansard <nmansard@laas.fr>
Date: Wed, 19 Jan 2011 19:10:53 +0100
Subject: [PATCH] IVIGIT.

---
 include/sot-dyninv/commands-helper.h | 133 ++++++++
 include/sot-dyninv/controller-pd.h   |  99 ++----
 src/controller-pd.cpp                | 484 ++++++++++++---------------
 3 files changed, 377 insertions(+), 339 deletions(-)
 create mode 100644 include/sot-dyninv/commands-helper.h

diff --git a/include/sot-dyninv/commands-helper.h b/include/sot-dyninv/commands-helper.h
new file mode 100644
index 0000000..d9d35c5
--- /dev/null
+++ b/include/sot-dyninv/commands-helper.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2011, Nicolas Mansard, LAAS-CNRS
+ *
+ * This file is part of sot-dyninv.
+ * sot-dyninv 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.
+ * sot-dyninv 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 Lesser General Public License for more details.  You should
+ * have received a copy of the GNU Lesser General Public License along
+ * with sot-dyninv.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __sot_dyninv_commands_helper_H__
+#define __sot_dyninv_commands_helper_H__
+
+/* --- COMMON INCLUDE -------------------------------------------------- */
+#include <dynamic-graph/command.h>
+#include <dynamic-graph/command-setter.h>
+#include <dynamic-graph/command-getter.h>
+
+
+/* --- GETTER --------------------------------------------------------- */
+namespace dynamicgraph {
+  namespace command {
+
+
+
+    template <class E, typename T>
+    class DirectGetter
+      : public Command
+    {
+    public:
+      /// Pointer to method that sets paramter of type T
+      typedef T (E::*GetterMethod) () const;
+
+      /// Constructor
+      DirectGetter(E& entity,T* ptr,
+		   const std::string& docString)
+	: Command(entity, std::vector<Value::Type>(), docString),
+	  T_ptr(ptr) {}
+
+    protected:
+      virtual Value doExecute() { return Value(*T_ptr); }
+    private:
+      T* T_ptr;
+    };
+
+    template <class E, typename T>
+    DirectGetter<E,T>*
+    makeDirectGetter( E& entity,T* ptr,
+		      const std::string& docString)
+    { return  new DirectGetter<E,T>(entity,ptr,docString); }
+
+    std::string docDirectGetter( const std::string& name,
+				 const std::string& type )
+    {
+      return std::string("\nGet the ")+name+".\n\nNo input.\nReturn an "+type+".\n\n";
+    }
+
+  } // namespace command
+} // namespace dynamicgraph
+
+
+/* --- SETTER --------------------------------------------------------- */
+namespace dynamicgraph {
+  namespace command {
+
+    template <class E, typename T>
+    class DirectSetter
+      : public Command
+    {
+    public:
+      DirectSetter(E& entity,T* ptr,const std::string& docString);
+      typedef void (E::*SetterMethod) (const int&);
+
+    protected:
+      virtual Value doExecute()
+      {
+	const std::vector<Value>& values = getParameterValues();
+	T val = values[0].value();
+	return (*T_ptr) = val;
+      }
+    private:
+      T* T_ptr;
+    };
+
+    template <class E>
+      class DirectSetter<E,int>
+      : public Command
+    {
+      typedef int T;
+    public:
+    DirectSetter(E& entity,T* ptr,const std::string& docString)
+      :Command(entity, boost::assign::list_of(Value::INT), docString)
+	,T_ptr(ptr)
+	{}
+
+    protected:
+      virtual Value doExecute()
+      {
+	const std::vector<Value>& values = getParameterValues();
+	T val = values[0].value();
+	(*T_ptr) = val;
+	return Value(); // void
+      }
+    private:
+      T* T_ptr;
+    };
+
+    template <class E, typename T>
+    DirectSetter<E,T>*
+    makeDirectSetter( E& entity,T* ptr,
+		      const std::string& docString)
+    { return  new DirectSetter<E,T>(entity,ptr,docString); }
+
+    std::string docDirectSetter( const std::string& name,
+				 const std::string& type )
+    {
+      return std::string("\nSet the ")+name+".\n\nInput:\n - a "
+	+type+".\nVoid return.\n\n";
+    }
+
+  } // namespace command
+} // namespace dynamicgraph
+
+
+#endif // __sot_dyninv_commands_helper_H__
+
+
diff --git a/include/sot-dyninv/controller-pd.h b/include/sot-dyninv/controller-pd.h
index a64e885..a0f2bf1 100644
--- a/include/sot-dyninv/controller-pd.h
+++ b/include/sot-dyninv/controller-pd.h
@@ -34,83 +34,58 @@
 /* --- INCLUDE --------------------------------------------------------- */
 /* --------------------------------------------------------------------- */
 
-/* Matrix */
-#include <jrl/mal/boost.hh>
-namespace ml = maal::boost;
 
 /* SOT */
-#include <dynamic-graph/entity.h>
-#include <dynamic-graph/signal-ptr.h>
-#include <dynamic-graph/signal-time-dependent.h>
-#include <sot-core/matrix-homogeneous.h>
-#include <sot-core/vector-roll-pitch-yaw.h>
-#include <sot-core/matrix-rotation.h>
+#include <sot-dyninv/signal-helper.h>
 
-/* STD */
-#include <string>
 
 
 namespace sot {
   namespace dyninv {
 
-    namespace dg = dynamicgraph;
-
   /* --------------------------------------------------------------------- */
   /* --- CLASS ----------------------------------------------------------- */
   /* --------------------------------------------------------------------- */
 
   class SOTCONTROLLERPD_EXPORT ControllerPD
-    :public dg::Entity
-    {
-    public:
-      static const std::string CLASS_NAME;
-
-    public: /* --- CONSTRUCTION --- */
-
-      ControllerPD( const std::string& name );
-      virtual ~ControllerPD( void );
-
-    public: /* --- SIGNAL --- */
-
-      dg::SignalPtr<MatrixRotation,int> sensorWorldRotationSIN; // estimate(worldRc)
-      dg::SignalPtr<MatrixHomogeneous,int> sensorEmbeddedPositionSIN; // waistRchest
-      dg::SignalPtr<MatrixHomogeneous,int> contactWorldPositionSIN; // estimate(worldRf)
-      dg::SignalPtr<MatrixHomogeneous,int> contactEmbeddedPositionSIN; // waistRleg
-      dg::SignalTimeDependent<ml::Vector,int> anglesSOUT;  // [ flex1 flex2 yaw_drift ]
-      dg::SignalTimeDependent<MatrixRotation,int> flexibilitySOUT;  // footRleg
-      dg::SignalTimeDependent<MatrixRotation,int> driftSOUT;  // Ryaw = worldRc est(wRc)^-1
-      dg::SignalTimeDependent<MatrixRotation,int> sensorWorldRotationSOUT;  // worldRc
-      dg::SignalTimeDependent<MatrixRotation,int> waistWorldRotationSOUT;  // worldRwaist
-      dg::SignalTimeDependent<MatrixHomogeneous,int> waistWorldPositionSOUT; // worldMwaist
-      dg::SignalTimeDependent<ml::Vector,int> waistWorldPoseRPYSOUT; // worldMwaist
-
-    public: /* --- FUNCTIONS --- */
-      ml::Vector& computeAngles( ml::Vector& res,
-				 const int& time );
-      MatrixRotation& computeFlexibilityFromAngles( MatrixRotation& res,
-						    const int& time );
-      MatrixRotation& computeDriftFromAngles( MatrixRotation& res,
-					      const int& time );
-      MatrixRotation& computeSensorWorldRotation( MatrixRotation& res,
-						  const int& time );
-      MatrixRotation& computeWaistWorldRotation( MatrixRotation& res,
-						 const int& time );
-      MatrixHomogeneous& computeWaistWorldPosition( MatrixHomogeneous& res,
-						    const int& time );
-      ml::Vector& computeWaistWorldPoseRPY( ml::Vector& res,
-					    const int& time );
-
-    public: /* --- PARAMS --- */
-      void fromSensor(const bool& inFromSensor) {    fromSensor_ = inFromSensor;  }
-      bool fromSensor() const {    return fromSensor_;  }
-    private:
-      bool fromSensor_;
-      virtual void commandLine( const std::string& cmdLine,
-				std::istringstream& cmdArgs,
-				std::ostream& os );
-    };
+    :public ::dynamicgraph::Entity
+      {
+
+      public: /* --- CONSTRUCTOR ---- */
+
+	ControllerPD( const std::string & name );
+
+      protected:
+	/* Parameters of the torque-control function:
+	 * tau = kp * (qd-q) + kd* (dqd-dq) */
+	int _dimension;
+
+      public:
+	void size(const int & dimension);
+	int size(void) const;
+
+      public: /* --- ENTITY INHERITANCE --- */
+
+	static const std::string CLASS_NAME;
+	virtual void display( std::ostream& os ) const;
+	virtual const std::string& getClassName( void ) const { return CLASS_NAME; }
+
+	virtual void commandLine( const std::string& cmdLine,
+				  std::istringstream& cmdArgs,
+				  std::ostream& os );
+
+      public:  /* --- SIGNALS --- */
+
+	DECLARE_SIGNAL_IN(Kp,ml::Vector);
+	DECLARE_SIGNAL_IN(Kd,ml::Vector);
+	DECLARE_SIGNAL_IN(position,ml::Vector);
+	DECLARE_SIGNAL_IN(positionRef,ml::Vector);
+	DECLARE_SIGNAL_IN(velocity,ml::Vector);
+	DECLARE_SIGNAL_IN(velocityRef,ml::Vector);
 
+	DECLARE_SIGNAL_OUT(control,ml::Vector);
 
+      }; // class ControllerPD
 
   } // namespace dyninv
 } // namespace sot
diff --git a/src/controller-pd.cpp b/src/controller-pd.cpp
index 5368670..838841c 100644
--- a/src/controller-pd.cpp
+++ b/src/controller-pd.cpp
@@ -17,339 +17,269 @@
 #include <sot-dyninv/controller-pd.h>
 #include <sot-core/debug.h>
 #include <dynamic-graph/factory.h>
-#include <dynamic-graph/command.h>
-#include <dynamic-graph/command-setter.h>
-#include <dynamic-graph/command-getter.h>
 
-#include <jrl/mal/matrixabstractlayer.hh>
+#include <sot-dyninv/commands-helper.h>
 
 namespace sot
 {
   namespace dyninv
   {
 
+
+    namespace dg = ::dynamicgraph;
     using namespace dg;
+    using ::dynamicgraph::command::makeDirectGetter;
+    using ::dynamicgraph::command::docDirectGetter;
+    using ::dynamicgraph::command::makeDirectSetter;
+    using ::dynamicgraph::command::docDirectSetter;
 
+    /* --- DG FACTORY ------------------------------------------------------- */
     DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(ControllerPD,"ControllerPD");
 
+    /* --- CONSTRUCTION ----------------------------------------------------- */
+    /* --- CONSTRUCTION ----------------------------------------------------- */
+    /* --- CONSTRUCTION ----------------------------------------------------- */
     ControllerPD::
     ControllerPD( const std::string & name )
-      :Entity(name)
-      ,sensorWorldRotationSIN(NULL,"sotControllerPD("+name
-			      +")::input(MatrixRotation)::sensorWorldRotation")
-      ,sensorEmbeddedPositionSIN(NULL,"sotControllerPD("+name
-				 +")::input(MatrixHomo)::sensorEmbeddedPosition")
-      ,contactWorldPositionSIN(NULL,"sotControllerPD("+name
-			       +")::input(MatrixHomo)::contactWorldPosition")
-      ,contactEmbeddedPositionSIN(NULL,"sotControllerPD("+name
-				  +")::input(MatrixHomo)::contactEmbeddedPosition")
-
-      ,anglesSOUT( boost::bind(&ControllerPD::computeAngles,this,_1,_2),
-		   sensorWorldRotationSIN<<sensorEmbeddedPositionSIN
-		   <<contactWorldPositionSIN<<contactEmbeddedPositionSIN,
-		   "sotControllerPD("+name+")::output(Vector)::angles" )
-      ,flexibilitySOUT( boost::bind(&ControllerPD::computeFlexibilityFromAngles
-				    ,this,_1,_2),
-			anglesSOUT,
-			"sotControllerPD("+name+")::output(matrixRotation)::flexibility" )
-      ,driftSOUT( boost::bind(&ControllerPD::computeDriftFromAngles,this,_1,_2),
-		  anglesSOUT,
-		  "sotControllerPD("+name+")::output(matrixRotation)::drift" )
-      ,sensorWorldRotationSOUT( boost::bind(&ControllerPD::computeSensorWorldRotation
-					    ,this,_1,_2),
-				anglesSOUT<<sensorWorldRotationSIN,
-				"sotControllerPD("+name
-				+")::output(matrixRotation)::sensorCorrectedRotation" )
-      ,waistWorldRotationSOUT( boost::bind(&ControllerPD::computeWaistWorldRotation
-					   ,this,_1,_2),
-			       sensorWorldRotationSOUT<<sensorEmbeddedPositionSIN,
-			       "sotControllerPD("+name
-			       +")::output(matrixRotation)::waistWorldRotation" )
-      ,waistWorldPositionSOUT( boost::bind(&ControllerPD::computeWaistWorldPosition
-					   ,this,_1,_2),
-			       flexibilitySOUT << contactEmbeddedPositionSIN,
-			       "sotControllerPD("+name
-			       +")::output(MatrixHomogeneous)::waistWorldPosition" )
-      ,waistWorldPoseRPYSOUT( boost::bind(&ControllerPD::computeWaistWorldPoseRPY
-					  ,this,_1,_2),
-			      waistWorldPositionSOUT,
-			      "sotControllerPD("+name
-			      +")::output(vectorRollPitchYaw)::waistWorldPoseRPY" )
-
-      ,fromSensor_(true)
+      : Entity(name)
+
+      ,CONSTRUCT_SIGNAL_IN(Kp,ml::Vector)
+      ,CONSTRUCT_SIGNAL_IN(Kd,ml::Vector)
+      ,CONSTRUCT_SIGNAL_IN(position,ml::Vector)
+      ,CONSTRUCT_SIGNAL_IN(positionRef,ml::Vector)
+      ,CONSTRUCT_SIGNAL_IN(velocity,ml::Vector)
+      ,CONSTRUCT_SIGNAL_IN(velocityRef,ml::Vector)
+
+      ,CONSTRUCT_SIGNAL_OUT(control,ml::Vector,ControllerPD,
+			    KpSIN << KdSIN << positionSIN << positionRefSIN
+			    << velocitySIN << velocityRefSIN )
     {
-      sotDEBUGIN(5);
-
-      signalRegistration( sensorWorldRotationSIN     << sensorEmbeddedPositionSIN
-			  << contactWorldPositionSIN << contactEmbeddedPositionSIN
-			  << anglesSOUT              << flexibilitySOUT
-			  << driftSOUT               << sensorWorldRotationSOUT
-			  << waistWorldRotationSOUT
-			  << waistWorldPositionSOUT  << waistWorldPoseRPYSOUT  );
-
-      // Commands
-      std::string docstring;
-      docstring = "    \n"
-	"    Set flag specifying whether angle is measured from sensors or simulated.\n"
-	"    \n"
-	"      Input:\n"
-	"        - a boolean value.\n"
-	"    \n";
-      addCommand("setFromSensor",
-		 new ::dynamicgraph::command::Setter<ControllerPD, bool>
-		 (*this, &ControllerPD::fromSensor, docstring));
-
-      docstring = "    \n"
-	"    Get flag specifying whether angle is measured from sensors or simulated.\n"
-	"    \n"
-	"      No input,\n"
-	"      return a boolean value.\n"
-	"    \n";
-      addCommand("getFromSensor",
-		 new ::dynamicgraph::command::Getter<ControllerPD, bool>
-		 (*this, &ControllerPD::fromSensor, docstring));
-
-      sotDEBUGOUT(5);
-    }
+      Entity::signalRegistration( KpSIN << KdSIN << positionSIN << positionRefSIN
+				  << velocitySIN << velocityRefSIN
+				  << controlSOUT );
 
 
-    ControllerPD::
-    ~ControllerPD( void )
-    {
-      sotDEBUGIN(5);
+      /* Commands. */
+      addCommand("getSize",
+		 makeDirectGetter(*this,&_dimension,
+				  docDirectGetter("dimension","int")));
+
+      // std::string docstring
+      // 		 = "\nSet the vectors dimension.\n\nInput:\n- an int.\nVoid return.\n\n";
+      // addCommand("setSize",
+      // 		 new ::dynamicgraph::command::Setter<ControllerPD,int>
+      // 		 (*this, &ControllerPD::size,docstring));
 
-      sotDEBUGOUT(5);
-      return;
+      addCommand("setSize",
+		 makeDirectSetter(*this, &_dimension,
+				  docDirectSetter("dimension","int")));
     }
 
-    /* --- SIGNALS -------------------------------------------------------------- */
-    /* --- SIGNALS -------------------------------------------------------------- */
-    /* --- SIGNALS -------------------------------------------------------------- */
+
+    /* --- SIGNALS ---------------------------------------------------------- */
+    /* --- SIGNALS ---------------------------------------------------------- */
+    /* --- SIGNALS ---------------------------------------------------------- */
+
     ml::Vector& ControllerPD::
-    computeAngles( ml::Vector& res,
-		   const int& time )
+    controlSOUT_function( ml::Vector &tau, int iter )
     {
       sotDEBUGIN(15);
-
-      res.resize(3);
-
-      const MatrixRotation &worldestRchest = sensorWorldRotationSIN( time );
-      sotDEBUG(35) << "worldestRchest = " << std::endl << worldestRchest;
-      const MatrixHomogeneous &waistMchest = sensorEmbeddedPositionSIN( time );
-      MatrixRotation waistRchest; waistMchest.extract( waistRchest );
-
-      const MatrixHomogeneous & waistMleg = contactEmbeddedPositionSIN( time );
-      MatrixRotation waistRleg; waistMleg.extract( waistRleg );
-      MatrixRotation chestRleg; waistRchest.transpose().multiply( waistRleg,chestRleg );
-      MatrixRotation worldestRleg; worldestRchest.multiply( chestRleg,worldestRleg );
-
-      sotDEBUG(35) << "worldestRleg = " << std::endl << worldestRleg;
-
-      /* Euler angles with following code: (-z)xy, -z being the yaw drift, x the
-       * first flexibility and y the second flexibility. */
-      const double TOLERANCE_TH = 1e-6;
-
-      const MatrixRotation &R = worldestRleg;
-      if( (fabs(R(0,1))<TOLERANCE_TH)&&(fabs(R(1,1))<TOLERANCE_TH) ) 
+      const ml::Vector& Kp = KpSIN(iter);
+      const ml::Vector& Kd = KdSIN(iter);
+      const ml::Vector& position = positionSIN(iter);
+      const ml::Vector& desiredposition = positionRefSIN(iter);
+      const unsigned int size = Kp.size();
+
+      assert( _dimension == (int)size );
+      assert( size==Kp.size() );        assert( size==Kd.size() );
+      assert( size==position.size() );  assert( size==desiredposition.size() );
+
+      bool useVelocity = velocitySIN;
+      ml::Vector velocity;
+      bool useVelocityDesired = false;
+      ml::Vector desiredvelocity;
+      if( useVelocity ) // TODO: there is a useless copy here. Use a pointer?
 	{
-	  /* This means that cos(X) is very low, ie flex1 is close to 90deg.
-	   * I take the case into account, but it is bloody never going 
-	   * to happens. */
-	  if( R(2,1)>0 ) res(0)=M_PI/2; else res(0) = -M_PI/2;
-	  res(2) = atan2( -R(0,2),R(0,0) );
-	  res(1) = 0;
-
-	  /* To sum up: if X=PI/2, then Y and Z are in singularity.
-	   * we cannot decide both of then. I fixed Y=0, which
-	   * means that all the measurement coming from the sensor
-	   * is assumed to be drift of the gyro. */
+	  velocity = velocitySIN(iter);
+	  assert( size==velocity.size() );
+	  useVelocityDesired = velocityRefSIN;
+	  if( useVelocityDesired )
+	    {
+	      desiredvelocity = velocityRefSIN(iter);
+	      assert( size==desiredvelocity.size() );
+	    }
 	}
-      else
+
+      tau.resize(size); double dv; // TODO: use dv from start to avoid the copy.
+      for(unsigned i = 0u; i < size; ++i)
 	{
-	  double &X = res(0);
-	  double &Y = res(1);
-	  double &Z = res(2);
-
-	  Y = atan2( R(2,0),R(2,2) );
-	  Z = atan2( R(0,1),R(1,1) );
-	  if( fabs(R(2,0))>fabs(R(2,2)) )
-	    { X=atan2( R(2,1)*sin(Y),R(2,0) ); }
-	  else 
-	    { X=atan2( R(2,1)*cos(Y),R(2,2) ); }
+	  tau(i) = Kp(i)*(desiredposition(i)-position(i));
+	  if( useVelocity )
+	    {
+	      dv= velocity(i);
+	      if( useVelocityDesired )
+		dv-=desiredvelocity(i);
+	      tau(i) -= Kd(i)*dv;
+	    }
 	}
-  
-      sotDEBUG(35) << "angles = " << res;
 
+      sotDEBUG(15) << "p = " << position << std::endl;
+      sotDEBUG(15) << "pd = " << desiredposition << std::endl;
+      if( useVelocity ) {sotDEBUG(15) << "v= " << velocity << std::endl;}
+      if( useVelocityDesired ) { sotDEBUG(15) << "vd= " << velocity << std::endl; }
+      sotDEBUG(15) << "kp = " << Kp << std::endl;
+      sotDEBUG(15) << "kd = " << Kd << std::endl;
+      sotDEBUG(15) << "PD torque= " << tau << std::endl;
 
       sotDEBUGOUT(15);
-      return res;
+      return tau;
     }
 
-    /* compute the transformation matrix of the flexibility, ie
-     * feetRleg. 
-     */
-    MatrixRotation& ControllerPD::
-    computeFlexibilityFromAngles( MatrixRotation& res,
-				  const int& time )
-    {
-      sotDEBUGIN(15);
-
-      const ml::Vector & angles = anglesSOUT( time );
-      double cx= cos( angles(0) );
-      double sx= sin( angles(0) );
-      double cy= cos( angles(1) );
-      double sy= sin( angles(1) );
-  
-      res(0,0) = cy;
-      res(0,1) = 0;
-      res(0,2) = -sy;
-
-      res(1,0) = -sx*sy;
-      res(1,1) = cx;
-      res(1,2) = -sx*cy;
 
-      res(2,0) = cx*sy;
-      res(2,1) = sx;
-      res(2,2) = cx*cy;
-
-      sotDEBUGOUT(15);
-      return res;
-    }
-
-    /* Compute the rotation matrix of the drift, ie the
-     * transfo from the world frame to the estimated (drifted) world
-     * frame: worldRworldest.
-     */
-    MatrixRotation& ControllerPD::
-    computeDriftFromAngles( MatrixRotation& res,
-			    const int& time )
+    /* --- COMMANDS ---------------------------------------------------------- */
+    /* --- MEMBERS ---------------------------------------------------------- */
+    void ControllerPD::
+    size(const int & dimension)
     {
-      sotDEBUGIN(15);
-  
-      const ml::Vector & angles = anglesSOUT( time );
-      double cz = cos( angles(2) );
-      double sz = sin( angles(2) );
-  
-      res(0,0) = cz;
-      res(0,1) = -sz;
-      res(0,2) = 0;
-
-      // z is the positive angle (R_{-z} has been computed
-      // in the <angles> function). Thus, the /-/sin(z) is in 0,1
-      res(1,0) = sz;  
-      res(1,1) = cz;
-      res(1,2) = 0;
-
-      res(2,0) = 0;
-      res(2,1) = 0;
-      res(2,2) = 1;
-
-      sotDEBUGOUT(15);
-      return res;
+      _dimension = dimension;
     }
 
-    MatrixRotation& ControllerPD::
-    computeSensorWorldRotation( MatrixRotation& res,
-				const int& time )
-    {
-      sotDEBUGIN(15);
-  
-      const MatrixRotation & worldRworldest = driftSOUT( time );
-      const MatrixRotation & worldestRsensor = sensorWorldRotationSIN( time );
-  
-      worldRworldest.multiply( worldestRsensor,res );
-
-      sotDEBUGOUT(15);
-      return res;
-    }
- 
-    MatrixRotation& ControllerPD::
-    computeWaistWorldRotation( MatrixRotation& res,
-			       const int& time )
+    int ControllerPD::
+    size(void) const
     {
-      sotDEBUGIN(15);
-  
-      // chest = sensor
-      const MatrixRotation & worldRsensor = sensorWorldRotationSOUT( time );
-      const MatrixHomogeneous & waistMchest = sensorEmbeddedPositionSIN( time );
-      MatrixRotation waistRchest; waistMchest.extract( waistRchest );
-  
-      worldRsensor .multiply( waistRchest.transpose(),res );
-
-      sotDEBUGOUT(15);
-      return res;
+      return _dimension;
     }
 
+    /* --- ENTITY ----------------------------------------------------------- */
+    /* --- ENTITY ----------------------------------------------------------- */
+    /* --- ENTITY ----------------------------------------------------------- */
 
-
-    MatrixHomogeneous& ControllerPD::
-    computeWaistWorldPosition( MatrixHomogeneous& res,
-			       const int& time )
+    void ControllerPD::
+    display( std::ostream& os ) const
     {
-      sotDEBUGIN(15);
-  
-      const MatrixHomogeneous & waistMleg = contactEmbeddedPositionSIN( time );
-      const MatrixHomogeneous& contactPos = contactWorldPositionSIN( time );
-      MatrixHomogeneous legMwaist; waistMleg.inverse( legMwaist );
-      MatrixHomogeneous tmpRes;
-      if( fromSensor_ )
-	{ 
-	  const MatrixRotation & Rflex = flexibilitySOUT( time ); // footRleg
-	  ml::Vector zero(3); zero.fill(0.);
-	  MatrixHomogeneous footMleg; footMleg.buildFrom( Rflex,zero );
-				    
-	  footMleg.multiply( legMwaist,tmpRes );
+      os << "ControllerPD "<<getName();
+      try
+	{
+	  os <<"control = "<<controlSOUT;
 	}
-      else { tmpRes = legMwaist; }
-
-      contactPos.multiply( tmpRes, res );
-      sotDEBUGOUT(15);
-      return res;
-    }
-
-    ml::Vector& ControllerPD::
-    computeWaistWorldPoseRPY( ml::Vector& res,
-			      const int& time )
-    {
-      const MatrixHomogeneous & M = waistWorldPositionSOUT( time );
-
-      MatrixRotation R; M.extract(R);
-      VectorRollPitchYaw r; r.fromMatrix(R);
-      ml::Vector t(3); M.extract(t);
-
-      res.resize(6);
-      for( int i=0;i<3;++i ) { res(i)=t(i); res(i+3)=r(i); }
-
-      return res;
+      catch (ExceptionSignal e) {}
     }
 
-    /* --- PARAMS --------------------------------------------------------------- */
-    /* --- PARAMS --------------------------------------------------------------- */
-    /* --- PARAMS --------------------------------------------------------------- */
     void ControllerPD::
     commandLine( const std::string& cmdLine,
 		 std::istringstream& cmdArgs,
 		 std::ostream& os )
     {
-      sotDEBUG(25) << "Cmd " << cmdLine <<std::endl;
-
       if( cmdLine == "help" )
 	{
-	  Entity::commandLine(cmdLine,cmdArgs,os);
+	  os << "sotControlPD:\n"
+	     << " - size <arg>\t\tset the size of the vector.\n"
+	     << " - stdGain \t\tset the input vector gains according to the size for HRP2.\n"
+	     << " - velocityonly <arg>\t\tset Kp = 0.\n"
+	     << std::endl;
 	}
-      else if( cmdLine == "fromSensor" )
+      else if( cmdLine == "size" )
 	{
-	  std::string val; cmdArgs>>val;
-	  if( ("true"==val)||("false"==val) )
+	  cmdArgs >> std::ws;
+	  if( cmdArgs.good() )
+	    {
+	      unsigned int i; cmdArgs >> i ;
+	      size(i);
+	    }
+	  else
 	    {
-	      fromSensor_ = ( val=="true" );
-	    } else {
-	    os << "fromSensor = " << (fromSensor_?"true":"false") << std::endl;
-	  }
+	      os << "size = " << size() << std::endl;
+	    }
+	}
+      else if( cmdLine == "velocityonly" )
+	{
+	  ml::Vector zero(_dimension); zero.fill(0);
+	  positionSIN = zero;
+	  positionRefSIN = zero;
+	  KpSIN = zero;
+	}
+      else if( cmdLine == "stdGain" )
+	{
+	  std::string config = "high";
+	  cmdArgs >> std::ws; if( cmdArgs.good() ) cmdArgs >> config;
+
+	  if( config =="low" )
+	    {
+	      // Low
+	      ml::Vector Kp(_dimension); Kp.fill(100);
+	      ml::Vector Kd(_dimension); Kp.fill(20);
+	      KpSIN = Kp;
+	      KdSIN = Kd;
+	    }
+	  else if( config =="medium" )
+	    {
+	      // Medium gains
+	      // Kp = [30](400,1000,2000,1800,2000,1000,400,1000,2000,1800,2000,1000,500,250,200,200,300,300,200,400,400,200,200,300, 300,200,400,400,200,200);
+	      // Kd = [30] (40,100,200,180,200,100,40,100,200,180,200,100,50,25,20,20,30,30,20,40,40,20,20,30, 30,20,40,40,20,20);
+	      if( _dimension != 30 )
+		{ os << "Only working for dim=30!" << std::endl; return; }
+
+	      ml::Vector Kp(_dimension),Kd(_dimension);
+	      unsigned int i=0;
+	      Kp(i++)=400;   Kp(i++)=1000; Kp(i++)=2000;  Kp(i++)=1800;  Kp(i++)=2000;
+	      Kp(i++)=1000;  Kp(i++)=400;  Kp(i++)=1000;  Kp(i++)=2000;  Kp(i++)=1800;
+	      Kp(i++)=2000;  Kp(i++)=1000; Kp(i++)=500;  Kp(i++)=250;  Kp(i++)=200;
+	      Kp(i++)=200;   Kp(i++)=300;  Kp(i++)=300;  Kp(i++)=200;  Kp(i++)=400;
+	      Kp(i++)=400;   Kp(i++)=200;  Kp(i++)=200;  Kp(i++)=300;  Kp(i++)= 300;
+	      Kp(i++)=200;   Kp(i++)=400;  Kp(i++)=400;  Kp(i++)=200;  Kp(i++)=200;
+
+	      i=0;
+	      Kd(i++)=40;  Kd(i++)=100;  Kd(i++)=200;  Kd(i++)=180;  Kd(i++)=200;
+	      Kd(i++)=100; Kd(i++)=40;   Kd(i++)=100;  Kd(i++)=200;  Kd(i++)=180;
+	      Kd(i++)=200; Kd(i++)=100;  Kd(i++)=50;   Kd(i++)=25;   Kd(i++)=20;
+	      Kd(i++)=20;  Kd(i++)=30;   Kd(i++)=30;   Kd(i++)=20;   Kd(i++)=40;
+	      Kd(i++)=40;  Kd(i++)=20;   Kd(i++)=20;   Kd(i++)=30;   Kd(i++)= 30;
+	      Kd(i++)=20;  Kd(i++)=40;   Kd(i++)=40;   Kd(i++)=20;   Kd(i++)=20;
+
+	      KpSIN = Kp;
+	      KdSIN = Kd;
+	    }
+	  else // high
+	    {
+	      // High gains
+	      // Kp = [30](4000,10000,20000,18000,20000,10000,4000,10000,20000,18000,20000,10000,5000,2500,2000,2000,3000,3000,2000,4000,4000,2000,2000,3000, 3000,2000,4000,4000,2000,2000);
+	      //Kd = [30](120,300,600,500,600,300,120,300,600,500,600,300,150,75,60,60,90,90,60,120,120,60,60,90, 90,60,120,120,60,60);
+
+	      if( _dimension != 30 )
+		{ os << "Only working for dim=30!" << std::endl; return; }
+
+	      ml::Vector Kp(_dimension),Kd(_dimension);
+	      unsigned int i=0;
+	      Kp(i++)=4000;  Kp(i++)=10000; Kp(i++)=20000; Kp(i++)=18000;  Kp(i++)=20000;
+	      Kp(i++)=10000; Kp(i++)=4000;  Kp(i++)=10000; Kp(i++)=20000;  Kp(i++)=18000;
+	      Kp(i++)=20000; Kp(i++)=10000; Kp(i++)=5000;  Kp(i++)=2500;   Kp(i++)=2000;
+	      Kp(i++)=2000;  Kp(i++)=3000;  Kp(i++)=3000;  Kp(i++)=2000;   Kp(i++)=4000;
+	      Kp(i++)=4000;  Kp(i++)=2000;  Kp(i++)=2000;  Kp(i++)=3000;   Kp(i++)= 3000;
+	      Kp(i++)=2000;  Kp(i++)=4000;  Kp(i++)=4000;  Kp(i++)=2000;   Kp(i++)=2000;
+
+	      i=0;
+	      Kd(i++)=120;   Kd(i++)=300;   Kd(i++)=600;   Kd(i++)=500;    Kd(i++)=600;
+	      Kd(i++)=300;   Kd(i++)=120;   Kd(i++)=300;   Kd(i++)=600;    Kd(i++)=500;
+	      Kd(i++)=600;   Kd(i++)=300;   Kd(i++)=150;   Kd(i++)=75;     Kd(i++)=60;
+	      Kd(i++)=60;    Kd(i++)=90;    Kd(i++)=90;    Kd(i++)=60;     Kd(i++)=120;
+	      Kd(i++)=120;   Kd(i++)=60;    Kd(i++)=60;    Kd(i++)=90;     Kd(i++)= 90;
+	      Kd(i++)=60;    Kd(i++)=120;   Kd(i++)=120;   Kd(i++)=60;     Kd(i++)=60;
+
+	      KpSIN = Kp;
+	      KdSIN = Kd;
+	    }
+	}
+      else
+	{
+	  Entity::commandLine(cmdLine,cmdArgs,os);
 	}
-      else { Entity::commandLine( cmdLine,cmdArgs,os); }
     }
 
+
+
+
+
+
   } // namespace dyninv
 } // namespace sot
 
-- 
GitLab