From 2728085b8b1ccfb2a1da421a0141fa9e4b04c507 Mon Sep 17 00:00:00 2001
From: mnaveau <maximilien.naveau@laas.fr>
Date: Wed, 13 Apr 2016 11:39:03 +0200
Subject: [PATCH] add a class that uses the pinocchio framework

---
 .../jrl/walkgen/patterngeneratorinterface.hh  |   2 +-
 src/CMakeLists.txt                            |   4 +-
 .../FootTrajectoryGenerationAbstract.hh       |   2 +-
 ...ndRightFootTrajectoryGenerationMultiple.hh |   2 +-
 .../GlobalStrategyManager.hh                  |   2 +-
 .../FootConstraintsAsLinearSystem.hh          |   2 +-
 src/Mathematics/relative-feet-inequalities.hh |   2 +-
 src/MotionGeneration/ComAndFootRealization.hh |   4 +-
 .../ComAndFootRealizationByGeometry.cpp       |   2 +-
 src/MotionGeneration/StepOverPlanner.hh       |   2 +-
 src/PatternGeneratorInterfacePrivate.cpp      |   2 +-
 src/PreviewControl/rigid-body-system.hh       |   2 +-
 src/RobotDynamics/PinocchioRobot.cpp          | 460 ++++++++++++++++++
 src/RobotDynamics/PinocchioRobot.hh           | 201 ++++++++
 .../OrientationsPreview.hh                    |   2 +-
 .../ZMPDiscretization.hh                      |   2 +-
 .../generator-vel-ref.hh                      |   2 +-
 .../nmpc_generator.hh                         |   2 +-
 tests/TestObject.cpp                          |  10 +-
 tests/TestObject.hh                           |   6 +-
 20 files changed, 681 insertions(+), 32 deletions(-)
 create mode 100644 src/RobotDynamics/PinocchioRobot.cpp
 create mode 100644 src/RobotDynamics/PinocchioRobot.hh

diff --git a/include/jrl/walkgen/patterngeneratorinterface.hh b/include/jrl/walkgen/patterngeneratorinterface.hh
index b11ce78b..bc50ae29 100644
--- a/include/jrl/walkgen/patterngeneratorinterface.hh
+++ b/include/jrl/walkgen/patterngeneratorinterface.hh
@@ -35,7 +35,7 @@
 #define _PATTERN_GENERATOR_INTERFACE_H_
 
 #include <deque>
-#include <PinocchioRobot.hh>
+#include <RobotDynamics/PinocchioRobot.hh>
 #include <jrl/walkgen/pgtypes.hh>
 
 namespace PatternGeneratorJRL
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 07707360..73fb7cd5 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -32,7 +32,7 @@ ADD_DEFINITIONS("/DLSSOL_FOUND")
 ENDIF(USE_LSSOL)
 
 SET(INCLUDES
-  PinocchioRobot.hh
+  RobotDynamics/PinocchioRobot.hh
   PreviewControl/rigid-body.hh
   PreviewControl/OptimalControllerSolver.hh
   PreviewControl/rigid-body-system.hh
@@ -113,7 +113,7 @@ ENDIF(${qpOASES_FOUND} STREQUAL "TRUE")
 
 SET(SOURCES
   ${INCLUDES}
-  PinocchioRobot.cpp
+  RobotDynamics/PinocchioRobot.cpp
   FootTrajectoryGeneration/FootTrajectoryGenerationAbstract.cpp
   FootTrajectoryGeneration/FootTrajectoryGenerationStandard.cpp
   FootTrajectoryGeneration/FootTrajectoryGenerationMultiple.cpp
diff --git a/src/FootTrajectoryGeneration/FootTrajectoryGenerationAbstract.hh b/src/FootTrajectoryGeneration/FootTrajectoryGenerationAbstract.hh
index adb1fff1..b58441ae 100644
--- a/src/FootTrajectoryGeneration/FootTrajectoryGenerationAbstract.hh
+++ b/src/FootTrajectoryGeneration/FootTrajectoryGenerationAbstract.hh
@@ -39,7 +39,7 @@
 #include <jrl/mal/matrixabstractlayer.hh>
 
 /* dynamics pinocchio related inclusions */
-#include <PinocchioRobot.hh>
+#include <RobotDynamics/PinocchioRobot.hh>
 
 /* Walking pattern generation related inclusions */
 
diff --git a/src/FootTrajectoryGeneration/LeftAndRightFootTrajectoryGenerationMultiple.hh b/src/FootTrajectoryGeneration/LeftAndRightFootTrajectoryGenerationMultiple.hh
index b8518dd8..802dec1e 100644
--- a/src/FootTrajectoryGeneration/LeftAndRightFootTrajectoryGenerationMultiple.hh
+++ b/src/FootTrajectoryGeneration/LeftAndRightFootTrajectoryGenerationMultiple.hh
@@ -33,7 +33,7 @@
 #include <jrl/mal/matrixabstractlayer.hh>
 
 /* abstractRobotDynamics inclusion */
-#include <PinocchioRobot.hh>
+#include <RobotDynamics/PinocchioRobot.hh>
 
 /* Walking Pattern Generator inclusion */
 
diff --git a/src/GlobalStrategyManagers/GlobalStrategyManager.hh b/src/GlobalStrategyManagers/GlobalStrategyManager.hh
index 6e42e32c..98e9c556 100644
--- a/src/GlobalStrategyManagers/GlobalStrategyManager.hh
+++ b/src/GlobalStrategyManagers/GlobalStrategyManager.hh
@@ -33,7 +33,7 @@
 #include <jrl/mal/matrixabstractlayer.hh>
 
 // Dynamics
-#include <PinocchioRobot.hh>
+#include <RobotDynamics/PinocchioRobot.hh>
 
 // PG
 #include <jrl/walkgen/pgtypes.hh>
diff --git a/src/Mathematics/FootConstraintsAsLinearSystem.hh b/src/Mathematics/FootConstraintsAsLinearSystem.hh
index 971d2beb..dd624c5d 100644
--- a/src/Mathematics/FootConstraintsAsLinearSystem.hh
+++ b/src/Mathematics/FootConstraintsAsLinearSystem.hh
@@ -38,7 +38,7 @@
 
 #include <jrl/mal/matrixabstractlayer.hh>
 
-#include <PinocchioRobot.hh>
+#include <RobotDynamics/PinocchioRobot.hh>
 
 
 #include <jrl/walkgen/pgtypes.hh>
diff --git a/src/Mathematics/relative-feet-inequalities.hh b/src/Mathematics/relative-feet-inequalities.hh
index 7e0c651c..339a287e 100644
--- a/src/Mathematics/relative-feet-inequalities.hh
+++ b/src/Mathematics/relative-feet-inequalities.hh
@@ -34,7 +34,7 @@
 
 #include <jrl/mal/matrixabstractlayer.hh>
 
-#include <PinocchioRobot.hh>
+#include <RobotDynamics/PinocchioRobot.hh>
 
 
 #include <jrl/walkgen/pgtypes.hh>
diff --git a/src/MotionGeneration/ComAndFootRealization.hh b/src/MotionGeneration/ComAndFootRealization.hh
index accac247..9f891e2b 100644
--- a/src/MotionGeneration/ComAndFootRealization.hh
+++ b/src/MotionGeneration/ComAndFootRealization.hh
@@ -29,7 +29,7 @@
 #ifndef _COM_AND_FOOT_REALIZATION_H_
 #define _COM_AND_FOOT_REALIZATION_H_
 
-#include <PinocchioRobot.hh>
+#include <RobotDynamics/PinocchioRobot.hh>
 
 #include <SimplePlugin.hh>
 #include <StepStackHandler.hh>
@@ -132,7 +132,7 @@ namespace PatternGeneratorJRL
 
     /*! @param aHumanoidDynamicRobot: an object able to compute dynamic parameters
       of the robot. */
-    inline  virtual bool setHumanoidDynamicRobot(PinocchioRobot *aPinocchioRobot)
+    inline  virtual bool setPinocchioRobot(PinocchioRobot *aPinocchioRobot)
     { m_PinocchioRobot = aPinocchioRobot;
       return true;}
 
diff --git a/src/MotionGeneration/ComAndFootRealizationByGeometry.cpp b/src/MotionGeneration/ComAndFootRealizationByGeometry.cpp
index 59957973..f8e2021d 100644
--- a/src/MotionGeneration/ComAndFootRealizationByGeometry.cpp
+++ b/src/MotionGeneration/ComAndFootRealizationByGeometry.cpp
@@ -1280,7 +1280,7 @@ void ComAndFootRealizationByGeometry::
 bool ComAndFootRealizationByGeometry::
     setPinocchioRobot(PinocchioRobot * aPinocchioRobot)
 {
-  ComAndFootRealization::setHumanoidDynamicRobot(aPinocchioRobot);
+  ComAndFootRealization::setPinocchioRobot(aPinocchioRobot);
   PinocchioRobot *aPR =  aPinocchioRobot;
 
   MAL_VECTOR_RESIZE(m_prev_Configuration,aPR->numberDof());
diff --git a/src/MotionGeneration/StepOverPlanner.hh b/src/MotionGeneration/StepOverPlanner.hh
index 7461a6fb..bafb08a8 100644
--- a/src/MotionGeneration/StepOverPlanner.hh
+++ b/src/MotionGeneration/StepOverPlanner.hh
@@ -44,7 +44,7 @@
 #include <jrl/mal/matrixabstractlayer.hh>
 
 /*! Abstract Interface for dynamic robot. */
-#include <PinocchioRobot.hh>
+#include <RobotDynamics/PinocchioRobot.hh>
 
 /*! Humanoid Walking Pattern Generator */
 
diff --git a/src/PatternGeneratorInterfacePrivate.cpp b/src/PatternGeneratorInterfacePrivate.cpp
index 295bce58..7bb21e93 100644
--- a/src/PatternGeneratorInterfacePrivate.cpp
+++ b/src/PatternGeneratorInterfacePrivate.cpp
@@ -338,7 +338,7 @@ namespace PatternGeneratorJRL {
 
     // Read the robot VRML file model.
 
-    m_ComAndFootRealization[0]->setHumanoidDynamicRobot(m_PinocchioRobot);
+    m_ComAndFootRealization[0]->setPinocchioRobot(m_PinocchioRobot);
     m_ComAndFootRealization[0]->SetHeightOfTheCoM(m_PC->GetHeightOfCoM());
     m_ComAndFootRealization[0]->setSamplingPeriod(m_PC->SamplingPeriod());
     m_ComAndFootRealization[0]->Initialization();
diff --git a/src/PreviewControl/rigid-body-system.hh b/src/PreviewControl/rigid-body-system.hh
index 22813f1b..afee5a7a 100644
--- a/src/PreviewControl/rigid-body-system.hh
+++ b/src/PreviewControl/rigid-body-system.hh
@@ -30,7 +30,7 @@
 #include <privatepgtypes.hh>
 #include <PreviewControl/SupportFSM.hh>
 #include <FootTrajectoryGeneration/OnLineFootTrajectoryGeneration.h>
-#include <PinocchioRobot.hh>
+#include <RobotDynamics/PinocchioRobot.hh>
 
 namespace PatternGeneratorJRL
 {
diff --git a/src/RobotDynamics/PinocchioRobot.cpp b/src/RobotDynamics/PinocchioRobot.cpp
new file mode 100644
index 00000000..48046e50
--- /dev/null
+++ b/src/RobotDynamics/PinocchioRobot.cpp
@@ -0,0 +1,460 @@
+#include "RobotDynamics/PinocchioRobot.hh"
+#include "pinocchio/algorithm/rnea.hpp"
+#include "pinocchio/algorithm/kinematics.hpp"
+using namespace PatternGeneratorJRL;
+
+PinocchioRobot::PinocchioRobot(se3::Model * aModel, se3::Data * aData):
+  m_robotDataInInitialePose(*m_robotModel)
+{
+  m_robotModel = aModel ;
+  m_robotData = aData ;
+
+  m_q.resize(m_robotModel->nq,0.0);
+  m_v.resize(m_robotModel->nv,0.0);
+  m_a.resize(m_robotModel->nv,0.0);
+
+  m_robotData->v[0] = se3::Motion::Zero();
+  m_robotData->a[0] = -m_robotModel->gravity;
+  m_robotDataInInitialePose.v[0] = se3::Motion::Zero();
+  m_robotDataInInitialePose.a[0] = -m_robotModel->gravity;
+
+  m_mass=0.0;
+  for(unsigned i=0; m_robotModel->inertias.size() ; ++i)
+  {
+    m_mass += m_robotModel->inertias[i].mass();
+  }
+}
+
+void PinocchioRobot::InitializePinocchioRobot(se3::Model * aModel, se3::Data * aData)
+{
+  m_q.resize(m_robotModel->nq,0.0);
+  m_v.resize(m_robotModel->nv,0.0);
+  m_a.resize(m_robotModel->nv,0.0);
+  se3::forwardKinematics(*m_robotModel,m_robotDataInInitialePose,m_q);
+}
+
+
+void PinocchioRobot::computeForwardKinematics()
+{
+  computeForwardKinematics(m_qmal);
+}
+
+void PinocchioRobot::computeForwardKinematics(MAL_VECTOR_TYPE(double) & q)
+{
+  // euler to quaternion :
+  m_quat = Eigen::Quaternion<double>(
+        Eigen::AngleAxisd((double)q(3), Eigen::Vector3d::UnitX()) *
+        Eigen::AngleAxisd((double)q(4), Eigen::Vector3d::UnitX()) *
+        Eigen::AngleAxisd((double)q(5), Eigen::Vector3d::UnitX()) ) ;
+
+  // fill up m_q following the pinocchio standard : [pos quarternion DoFs]
+  for(unsigned i=0; i<3 ; ++i)
+  {
+    m_q(i) = q(i);
+  }
+  m_q(3) = m_quat.x() ;
+  m_q(4) = m_quat.y() ;
+  m_q(5) = m_quat.z() ;
+  m_q(6) = m_quat.w() ;
+  for(unsigned i=0; i<m_robotModel->nv-6 ; ++i)
+  {
+    m_q(7+i) = q(6+i);
+  }
+  se3::forwardKinematics(*m_robotModel,*m_robotData,m_q);
+}
+
+void PinocchioRobot::computeInverseDynamics()
+{
+  PinocchioRobot::computeInverseDynamics(m_qmal,m_vmal,m_amal);
+}
+
+void PinocchioRobot::computeInverseDynamics(MAL_VECTOR_TYPE(double) & q,
+                                            MAL_VECTOR_TYPE(double) & v,
+                                            MAL_VECTOR_TYPE(double) & a)
+{
+  // euler to quaternion :
+  m_quat = Eigen::Quaternion<double>(
+        Eigen::AngleAxisd((double)q(3), Eigen::Vector3d::UnitX()) *
+        Eigen::AngleAxisd((double)q(4), Eigen::Vector3d::UnitX()) *
+        Eigen::AngleAxisd((double)q(5), Eigen::Vector3d::UnitX()) ) ;
+
+  // fill up m_q following the pinocchio standard : [pos quarternion DoFs]
+  for(unsigned i=0; i<3 ; ++i)
+  {
+    m_q(i) = q(i);
+  }
+  m_q(3) = m_quat.x() ;
+  m_q(4) = m_quat.y() ;
+  m_q(5) = m_quat.z() ;
+  m_q(6) = m_quat.w() ;
+  for(unsigned i=0; i<m_robotModel->nv-6 ; ++i)
+  {
+    m_q(7+i) = q(6+i);
+  }
+
+  // fill up the velocity and acceleration vectors
+  for(unsigned i=0; i<m_robotModel->nv ; ++i)
+  {
+    m_v(i) = v(i);
+    m_a(i) = a(i);
+  }
+
+  // performing the inverse dynamics
+  se3::rnea(*m_robotModel,*m_robotData,m_q,m_v,m_a);
+}
+
+std::vector<se3::JointIndex> PinocchioRobot::fromRootToIt(se3::JointIndex it)
+{
+  std::vector<se3::JointIndex> fromRootToIt ;
+  fromRootToIt.clear();
+  se3::JointIndex i = it ;
+  while(i!=0)
+  {
+    fromRootToIt.insert(fromRootToIt.begin(),i);
+    i = m_robotModel->parents[i];
+  }
+  return fromRootToIt ;
+}
+
+std::vector<se3::JointIndex> PinocchioRobot::jointsBetween
+( se3::JointIndex first, se3::JointIndex second)
+{
+  std::vector<se3::JointIndex> fromRootToFirst  = fromRootToIt(first);
+  std::vector<se3::JointIndex> fromRootToSecond = fromRootToIt(second);
+
+  std::vector<se3::JointIndex> out ;
+  out.clear();
+  se3::JointIndex lastCommonRank = 0 ;
+  se3::JointIndex minChainLength =
+      fromRootToFirst.size() < fromRootToSecond.size()
+      ? fromRootToFirst.size() : fromRootToSecond.size() ;
+
+  for(unsigned k=1 ; k<minChainLength ; ++k)
+  {
+    if(fromRootToFirst[k] == fromRootToSecond[k])
+      ++lastCommonRank;
+  }
+
+  for(unsigned k=fromRootToFirst.size()-1; k>lastCommonRank ; --k)
+  {
+    out.push_back(fromRootToFirst[k]);
+  }
+  if(lastCommonRank==0)
+  {
+    out.push_back(fromRootToSecond[0]);
+  }
+  for(unsigned k=lastCommonRank+1 ; k<fromRootToSecond.size() ; ++k)
+  {
+    out.push_back(fromRootToSecond[k]);
+  }
+
+  return out ;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+bool PinocchioRobot::
+ComputeSpecializedInverseKinematics(
+    const se3::JointIndex &jointRoot,
+    const se3::JointIndex &jointEnd,
+    const MAL_S4x4_MATRIX_TYPE(double) & jointRootPosition,
+    const MAL_S4x4_MATRIX_TYPE(double) & jointEndPosition,
+    MAL_VECTOR_TYPE(double) &q )
+{
+
+  /*! Try to find out which kinematics chain the user
+    send to the method.*/
+  if (jointRoot==m_waist)
+  {
+    /* Consider here the legs. */
+    vector3d Dt;
+    bool ok=false;
+    if (jointEnd==m_leftFoot.associatedAnkle)
+    {
+      Dt(0)=0.0;Dt(1)=0.06;Dt(2)=0.0;
+      ok=true;
+    }
+    else if (jointEnd==m_rightFoot.associatedAnkle)
+    {
+      Dt(0)=0.0;Dt(1)=-0.06;Dt(2)=0.0;
+      ok=true;
+    }
+    if (ok)
+    {
+      getWaistFootKinematics(jointRootPosition,
+                             jointEndPosition,
+                             q,Dt);
+      return true;
+    }
+  }
+  else
+  {
+    if ( (m_leftShoulder==0) || (m_rightShoulder==0) )
+    {
+      DetectAutomaticallyShoulders();
+    }
+
+    /* Here consider the arms */
+    if (jointRoot==m_leftShoulder)
+    {
+      int Side;
+      bool ok=false;
+      if (jointEnd==m_leftHand.associatedWrist)
+      {
+        Side = 1;
+        ok=true;
+      }
+      if (ok)
+      {
+        getShoulderWristKinematics(jointRootPosition,
+                                   jointEndPosition,
+                                   q,Side);
+        return true;
+      }
+    }
+
+    if (jointRoot==m_rightShoulder)
+    {
+      int Side;
+      bool ok=false;
+
+      if (jointEnd==m_rightHand.associatedWrist)
+      {
+        Side = -1;
+        ok=true;
+      }
+      if (ok)
+      {
+        getShoulderWristKinematics(jointRootPosition,
+                                   jointEndPosition,
+                                   q,Side);
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+void PinocchioRobot::getWaistFootKinematics(const matrix4d & jointRootPosition,
+                                            const matrix4d & jointEndPosition,
+                                            vectorN &q,
+                                            vector3d Dt)
+{
+  double _epsilon=1.0e-6;
+  // definition des variables relatif au design du robot
+  double A = 0.3;//m_FemurLength;
+  double B = 0.3;//m_TibiaLength;
+  double C = 0.0;
+  double c5 = 0.0;
+  double q6a = 0.0;
+
+  vector3d r;
+
+  /* Build sub-matrices */
+  matrix3d Foot_R,Body_R;
+  vector3d Foot_P,Body_P;
+  for(unsigned int i=0;i<3;i++)
+  {
+    for(unsigned int j=0;j<3;j++)
+    {
+      MAL_S3x3_MATRIX_ACCESS_I_J(Body_R,i,j) =
+          MAL_S4x4_MATRIX_ACCESS_I_J(jointRootPosition,i,j);
+      MAL_S3x3_MATRIX_ACCESS_I_J(Foot_R,i,j) =
+          MAL_S4x4_MATRIX_ACCESS_I_J(jointEndPosition,i,j);
+    }
+    Body_P(i) = MAL_S4x4_MATRIX_ACCESS_I_J(jointRootPosition,i,3);
+    Foot_P(i) = MAL_S4x4_MATRIX_ACCESS_I_J(jointEndPosition,i,3);
+  }
+
+  matrix3d Foot_Rt;
+  MAL_S3x3_TRANSPOSE_A_in_At(Foot_R,Foot_Rt);
+
+  // Initialisation of q
+  if (MAL_VECTOR_SIZE(q)!=6)
+    MAL_VECTOR_RESIZE(q,6);
+
+  for(unsigned int i=0;i<6;i++)
+    q(i)=0.0;
+
+  double OppSignOfDtY = Dt(1) < 0.0 ? 1.0 : -1.0; // if Dt(1)<0.0 then Opp=1.0 else Opp=-1.0
+
+  vector3d d2,d3;
+  d2 = Body_P + Body_R * Dt;
+  d3 = d2 - Foot_P;
+
+  double l0 = sqrt(d3(0)*d3(0)+d3(1)*d3(1)+d3(2)*d3(2) - 0.035*0.035);
+  c5 = 0.5 * (l0*l0-A*A-B*B) / (A*B);
+  if (c5 > 1.0-_epsilon)
+  {
+    q[3] = 0.0;
+  }
+  if (c5 < -1.0+_epsilon)
+  {
+    q[3] = M_PI;
+  }
+  if (c5 >= -1.0+_epsilon && c5 <= 1.0-_epsilon)
+  {
+    q[3] = acos(c5);
+  }
+
+  vector3d r3;
+  r3 = Foot_Rt * d3;
+
+  q6a = asin((A/l0)*sin(M_PI- q[3]));
+
+  double l3 = sqrt(r3(1)*r3(1) + r3(2)*r3(2));
+  double l4 = sqrt(l3*l3 - 0.035*0.035);
+
+  double phi = atan2(r3(0), l4);
+  q[4] = -phi - q6a;
+
+  double psi1 = atan2(r3(1), r3(2)) * OppSignOfDtY;
+  double psi2 = 0.5*M_PI - psi1;
+  double psi3 = atan2(l4, 0.035);
+  q[5] = (psi3 - psi2) * OppSignOfDtY;
+
+  if (q[5] > 0.5*M_PI)
+  {
+    q[5] -= M_PI;
+  }
+  else if (q[5] < -0.5*M_PI)
+  {
+    q[5] += M_PI;
+  }
+
+  matrix3d R;
+  matrix3d BRt;
+  MAL_S3x3_TRANSPOSE_A_in_At(Body_R,BRt);
+
+  matrix3d Rroll;
+  double c = cos(q[5]);
+  double s = sin(q[5]);
+
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rroll,0,0) = 1.0;
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rroll,0,1) = 0.0;
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rroll,0,2) = 0.0;
+
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rroll,1,0) = 0.0;
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rroll,1,1) = c;
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rroll,1,2) = s;
+
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rroll,2,0) = 0.0;
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rroll,2,1) = -s;
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rroll,2,2) = c;
+
+  matrix3d Rpitch;
+  c = cos(q[4]+q[3]);
+  s = sin(q[4]+q[3]);
+
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rpitch,0,0) = c;
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rpitch,0,1) = 0.0;
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rpitch,0,2) = -s;
+
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rpitch,1,0) = 0.0;
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rpitch,1,1) = 1.0;
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rpitch,1,2) = 0.0;
+
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rpitch,2,0) = s;
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rpitch,2,1) = 0.0;
+  MAL_S3x3_MATRIX_ACCESS_I_J(Rpitch,2,2) = c;
+
+  R = BRt * Foot_R * Rroll * Rpitch;
+  q[0] = atan2(-R(0,1),R(1,1));
+
+  double cz = cos(q[0]);
+  double sz = sin(q[0]);
+
+  q[1] = atan2(R(2,1), -R(0,1)*sz+R(1,1)*cz);
+  q[2] = atan2( -R(2,0), R(2,2));
+}
+
+double PinocchioRobot::ComputeXmax(double & Z)
+{
+  double A=0.25,
+      B=0.25;
+  double Xmax;
+  if (Z<0.0)
+    Z = 2*A*cos(15*M_PI/180.0);
+  Xmax = sqrt(A*A - (Z - B)*(Z-B));
+  return Xmax;
+}
+
+void PinocchioRobot::getShoulderWristKinematics(const matrix4d & jointRootPosition,
+                                                const matrix4d & jointEndPosition,
+                                                vectorN &q,
+                                                int side)
+{
+
+  // Initialisation of q
+  if (MAL_VECTOR_SIZE(q)!=6)
+    MAL_VECTOR_RESIZE(q,6);
+
+  double Alpha,Beta;
+  for(unsigned int i=0;i<6;i++)
+    q(i)=0.0;
+
+  double X = MAL_S4x4_MATRIX_ACCESS_I_J(jointEndPosition,0,3)
+      - MAL_S4x4_MATRIX_ACCESS_I_J(jointRootPosition,0,3);
+  double Z = MAL_S4x4_MATRIX_ACCESS_I_J(jointEndPosition,2,3)
+      - MAL_S4x4_MATRIX_ACCESS_I_J(jointRootPosition,2,3);
+
+  double Xmax = ComputeXmax(Z);
+  X = X*Xmax;
+
+  double A=0.25, B=0.25;
+
+  double C=0.0,Gamma=0.0,Theta=0.0;
+  C = sqrt(X*X+Z*Z);
+
+  Beta = acos((A*A+B*B-C*C)/(2*A*B))- M_PI;
+  Gamma = asin((B*sin(M_PI+Beta))/C);
+  Theta = atan2(X,Z);
+  Alpha = Gamma - Theta;
+
+  // Fill in the joint values.
+  q(0)= Alpha;
+  q(1)= 10.0*M_PI/180.0;
+  q(2)= 0.0;
+  q(3)= Beta;
+  q(4)= 0.0;
+  q(5)= 0.0;
+
+  if (side==-1)
+    q(1) = -q(1);
+
+
+}
+
+void PinocchioRobot::DetectAutomaticallyShoulders()
+{
+  DetectAutomaticallyOneShoulder(m_leftHand,m_leftShoulder);
+  DetectAutomaticallyOneShoulder(m_rightHand,m_rightShoulder);
+}
+
+void PinocchioRobot::DetectAutomaticallyOneShoulder(
+    PRHand aHand,
+    se3::JointIndex & aShoulder)
+{
+  std::vector<se3::JointIndex>FromRootToJoint;
+
+  FromRootToJoint.clear();
+  FromRootToJoint = fromRootToIt(aHand.associatedWrist);
+
+  std::vector<se3::JointIndex>::iterator itJoint = FromRootToJoint.begin();
+  bool found=false;
+  while(itJoint!=FromRootToJoint.end())
+  {
+    std::vector<se3::JointIndex>::iterator current = itJoint;
+    if (*current==m_chest)
+      found=true;
+    else
+    {
+      if (found)
+      {
+        aShoulder = *current;
+        return;
+      }
+    }
+    itJoint++;
+  }
+}
diff --git a/src/RobotDynamics/PinocchioRobot.hh b/src/RobotDynamics/PinocchioRobot.hh
new file mode 100644
index 00000000..a43305b7
--- /dev/null
+++ b/src/RobotDynamics/PinocchioRobot.hh
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2016,
+ *
+ * Maximilien Naveau
+ * Olivier Stasse
+ *
+ * JRL, CNRS/AIST
+ *
+ * This file is part of jrl-walkgen.
+ * jrl-walkgen 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.
+ *
+ * jrl-walkgen is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with jrl-walkgen.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *  Research carried out within the scope of the
+ *  Joint Japanese-French Robotics Laboratory (JRL)
+ */
+/*! \file PinocchioRobot.hh
+  \brief This object defines a humanoid robot model based on the PinocchioRobot
+frame work */
+
+#ifndef PinocchioRobot_HH
+#define PinocchioRobot_HH
+
+#include "pinocchio/spatial/se3.hpp"
+#include "pinocchio/multibody/model.hpp"
+#include <jrl/mal/matrixabstractlayer.hh>
+#include <vector>
+namespace PatternGeneratorJRL
+{
+  struct PinocchioRobotFoot_t{
+    se3::JointIndex associatedAnkle ;
+    double soleDepth ; // z axis
+    double soleWidth ; // y axis
+    double soleHeight ;// x axis
+    vector3d anklePosition ;
+    unsigned JointNb ;
+    std::vector<unsigned> JointId ;
+  };
+  typedef PinocchioRobotFoot_t PRFoot ;
+
+  struct PinocchioRobotHand_t{
+    se3::JointIndex associatedWrist ;
+    vector3d center ;
+    vector3d thumbAxis ;
+    vector3d foreFingerAxis ;
+    vector3d palmNormal ;
+    unsigned JointNb ;
+    std::vector<unsigned> JointId ;
+  };
+  typedef PinocchioRobotHand_t PRHand ;
+
+
+
+  class PinocchioRobot
+  {
+  public:
+    /// Constructor and Destructor
+    PinocchioRobot(se3::Model *aModel, se3::Data *aData);
+    void InitializePinocchioRobot(se3::Model * aModel, se3::Data * aData);
+
+
+    /// Functions computing kinematics and dynamics
+    void computeInverseDynamics();
+    void computeInverseDynamics(MAL_VECTOR_TYPE(double) & q,
+                                MAL_VECTOR_TYPE(double) & v,
+                                MAL_VECTOR_TYPE(double) & a);
+
+    void computeForwardKinematics();
+    void computeForwardKinematics(MAL_VECTOR_TYPE(double) & q);
+
+    // compute POSITION (not velocity) of the joints from end effector pose
+    bool ComputeSpecializedInverseKinematics(
+        const se3::JointIndex &jointRoot,
+        const se3::JointIndex &jointEnd,
+        const MAL_S4x4_MATRIX_TYPE(double) & jointRootPosition,
+        const MAL_S4x4_MATRIX_TYPE(double) & jointEndPosition,
+        MAL_VECTOR_TYPE(double) &q);
+
+  public :
+    /// tools :
+    std::vector<se3::JointIndex> jointsBetween
+    ( se3::JointIndex first, se3::JointIndex second);
+    std::vector<se3::JointIndex> fromRootToIt (se3::JointIndex it);
+
+  private :
+    // need for the inverse geometry (ComputeSpecializedInverseKinematics)
+    void getWaistFootKinematics(const matrix4d & jointRootPosition,
+                                const matrix4d & jointEndPosition,
+                                vectorN &q,
+                                vector3d Dt);
+    double ComputeXmax(double & Z);
+    void getShoulderWristKinematics(const matrix4d & jointRootPosition,
+                                    const matrix4d & jointEndPosition,
+                                    vectorN &q,
+                                    int side);
+    void DetectAutomaticallyShoulders();
+    void DetectAutomaticallyOneShoulder(PRHand aHand,
+                                        se3::JointIndex & aShoulder);
+
+
+
+
+  public :
+    /// Getters
+    /// ///////
+    inline se3::Data * Data()
+    {return m_robotData;}
+    inline se3::Data * DataInInitialePose()
+    {return &m_robotDataInInitialePose;}
+    inline se3::Model * Model()
+    {return m_robotModel;}
+
+    inline PRFoot * leftFoot()
+    {return &m_leftFoot;}
+    inline PRFoot * rightFoot()
+    {return &m_rightFoot;}
+
+    inline PRHand * leftHand()
+    {return &m_leftHand;}
+    inline PRHand * rightHand()
+    {return &m_rightHand;}
+
+    inline se3::JointIndex chest()
+    {return m_chest;}
+    inline se3::JointIndex waist()
+    {return m_waist;}
+
+    inline double mass()
+    {return m_mass;}
+
+    inline se3::JointModelVector & getActuatedJoints()
+    {return m_robotModel->joints;}
+
+    inline MAL_VECTOR_TYPE(double) currentConfiguration()
+    {return m_qmal;}
+    inline MAL_VECTOR_TYPE(double) currentVelocity()
+    {return m_vmal;}
+    inline MAL_VECTOR_TYPE(double) currentAcceleration()
+    {return m_amal;}
+
+    inline unsigned numberDof()
+    {return m_robotModel->nv;}
+
+    inline void zeroMomentumPoint(MAL_S3_VECTOR_TYPE(double) & zmp)
+    {
+      se3::Force externalForces = m_robotData->oMi[1].act(m_robotData->f[1]) ;
+      m_f = externalForces.linear() ;
+      m_n = externalForces.angular() ;
+      zmp(0) = -m_n(1)/m_f(2) ;
+      zmp(1) =  m_n(0)/m_f(2) ;
+      zmp(2) = 0.0 ; // by default
+    }
+
+    inline void positionCenterOfMass(MAL_S3_VECTOR_TYPE(double) & com)
+    {
+      m_com = m_robotData->com[0] ;
+      com(0) = m_com(0) ;
+      com(1) = m_com(1) ;
+      com(2) = m_com(2) ;
+    }
+
+    /// SETTERS
+    /// ///////
+    inline void currentConfiguration(MAL_VECTOR_TYPE(double) conf)
+    {m_qmal=conf;}
+    inline void currentVelocity(MAL_VECTOR_TYPE(double) vel)
+    {m_vmal=vel;}
+    inline void currentAcceleration(MAL_VECTOR_TYPE(double) acc)
+    {m_amal=acc;}
+
+  private:
+    se3::Model * m_robotModel ;
+    se3::Data m_robotDataInInitialePose ; // internal variable
+    se3::Data * m_robotData ;
+    PRFoot m_leftFoot , m_rightFoot ;
+    PRHand m_leftHand , m_rightHand ;
+    double m_mass ;
+    se3::JointIndex m_chest, m_waist, m_leftShoulder, m_rightShoulder ;
+
+    MAL_VECTOR_TYPE(double) m_qmal ;
+    MAL_VECTOR_TYPE(double) m_vmal ;
+    MAL_VECTOR_TYPE(double) m_amal ;
+    Eigen::VectorXd m_q ;
+    Eigen::VectorXd m_v ;
+    Eigen::VectorXd m_a ;
+
+    // tmp variables
+    Eigen::Quaternion<double> m_quat ;
+    Eigen::Vector3d m_f,m_n; // external forces and torques
+    Eigen::Vector3d m_com; // multibody CoM
+  };
+}
+#endif // PinocchioRobot_HH
diff --git a/src/ZMPRefTrajectoryGeneration/OrientationsPreview.hh b/src/ZMPRefTrajectoryGeneration/OrientationsPreview.hh
index 1c94628b..fdbd55bc 100644
--- a/src/ZMPRefTrajectoryGeneration/OrientationsPreview.hh
+++ b/src/ZMPRefTrajectoryGeneration/OrientationsPreview.hh
@@ -38,7 +38,7 @@
 #include <privatepgtypes.hh>
 #include <jrl/walkgen/pgtypes.hh>
 #include <Mathematics/PolynomeFoot.hh>
-#include <PinocchioRobot.hh>
+#include <RobotDynamics/PinocchioRobot.hh>
 
 namespace PatternGeneratorJRL
 {
diff --git a/src/ZMPRefTrajectoryGeneration/ZMPDiscretization.hh b/src/ZMPRefTrajectoryGeneration/ZMPDiscretization.hh
index 717d134a..61fb51d4 100644
--- a/src/ZMPRefTrajectoryGeneration/ZMPDiscretization.hh
+++ b/src/ZMPRefTrajectoryGeneration/ZMPDiscretization.hh
@@ -45,7 +45,7 @@
 using namespace::std;
 
 /*! Abstract robot dynamics includes */
-#include <PinocchioRobot.hh>
+#include <RobotDynamics/PinocchioRobot.hh>
 
 /*! Framework includes */
 #include <Mathematics/PolynomeFoot.hh>
diff --git a/src/ZMPRefTrajectoryGeneration/generator-vel-ref.hh b/src/ZMPRefTrajectoryGeneration/generator-vel-ref.hh
index cd14fb37..7cb3ab06 100644
--- a/src/ZMPRefTrajectoryGeneration/generator-vel-ref.hh
+++ b/src/ZMPRefTrajectoryGeneration/generator-vel-ref.hh
@@ -31,7 +31,7 @@
 
 #include <ZMPRefTrajectoryGeneration/mpc-trajectory-generation.hh>
 
-#include <PinocchioRobot.hh>
+#include <RobotDynamics/PinocchioRobot.hh>
 #include <ZMPRefTrajectoryGeneration/qp-problem.hh>
 #include <PreviewControl/SupportFSM.hh>
 #include <PreviewControl/LinearizedInvertedPendulum2D.hh>
diff --git a/src/ZMPRefTrajectoryGeneration/nmpc_generator.hh b/src/ZMPRefTrajectoryGeneration/nmpc_generator.hh
index a24ef71a..094e2a12 100644
--- a/src/ZMPRefTrajectoryGeneration/nmpc_generator.hh
+++ b/src/ZMPRefTrajectoryGeneration/nmpc_generator.hh
@@ -30,7 +30,7 @@
 
 #include <jrl/walkgen/pgtypes.hh>
 #include <Mathematics/relative-feet-inequalities.hh>
-#include <PinocchioRobot.hh>
+#include <RobotDynamics/PinocchioRobot.hh>
 #include <iomanip>
 #include <cmath>
 #include <qpOASES.hpp>
diff --git a/tests/TestObject.cpp b/tests/TestObject.cpp
index 920e7ab0..fbd2a985 100644
--- a/tests/TestObject.cpp
+++ b/tests/TestObject.cpp
@@ -124,14 +124,6 @@ namespace PatternGeneratorJRL
 	delete m_PGI;
     }
 
-    void TestObject::SpecializedRobotConstructor(   CjrlHumanoidDynamicRobot *& aHDR,
-					CjrlHumanoidDynamicRobot *& aDebugHDR)
-    {
-      aHDR = 0;
-      aDebugHDR = 0;
-    }
-
-
     void TestObject::CreateAndInitializeHumanoidRobot(string &RobotFileName,
 						      string &SpecificitiesFileName,
 						      string &LinkJointRank,
@@ -141,7 +133,7 @@ namespace PatternGeneratorJRL
 						      PatternGeneratorInterface * & aPGI)
     {
       // Creating the humanoid robot.
-      SpecializedRobotConstructor(aHDR,aDebugHDR);
+      PinocchioRobot
 
       if ((aHDR==0) || (aDebugHDR==0))
       {
diff --git a/tests/TestObject.hh b/tests/TestObject.hh
index 1e0185e1..e118970e 100644
--- a/tests/TestObject.hh
+++ b/tests/TestObject.hh
@@ -44,7 +44,7 @@
 #include <jrl/mal/matrixabstractlayer.hh>
 #include <jrl/dynamics/dynamicsfactory.hh>
 #include <jrl/walkgen/patterngeneratorinterface.hh>
-#include <MotionGeneration/ComAndFootRealizationByGeometry.hh>
+//#include <MotionGeneration/ComAndFootRealizationByGeometry.hh>
 
 #include "CommonTools.hh"
 #include "ClockCPUTime.hh"
@@ -76,10 +76,6 @@ namespace PatternGeneratorJRL
       /*! \brief Perform test. */
       bool doTest(std::ostream &os);
 
-      /*! \brief Decide from which object the robot is build from. */
-      virtual void SpecializedRobotConstructor(PinocchioRobot *& aPR,
-                           PinocchioRobot *& aDebugPR );
-
     protected:
 
       /*! \brief Choose which test to perform. */
-- 
GitLab