VrepRobotArmJacobian.hpp
Go to the documentation of this file.
1 #ifndef _GRL_VREP_ROBOT_ARM_JACOBIAN_HPP_
2 #define _GRL_VREP_ROBOT_ARM_JACOBIAN_HPP_
3 
4 #include <iostream>
5 #include <memory>
6 #include <array>
7 
8 #include <boost/log/trivial.hpp>
9 #include <boost/exception/all.hpp>
10 #include <boost/algorithm/string.hpp>
11 #include <Eigen/Core>
12 #include <Eigen/Geometry>
13 
14 #include "grl/vrep/Vrep.hpp"
16 #include "grl/vrep/Eigen.hpp"
17 
18 #include "v_repLib.h"
19 
20 
21 namespace grl { namespace vrep {
22 
23 /// @brief get the Jacobian as calculated by vrep in an Eigen::MatrixXf in column major format
24 /// @param driver the vrep arm driver object that provides access to vrep simulation state for a specific arm
25 /// @param jacobianOnly true calls simComputeJacobian, false uses simCheckIKGroup which incidentally calculates the Jacobian
26 ///
27 /// The jacobianOnly option is provided because some irregularities were seen with
28 /// simComputeJacobian (jacobianOnly == true). Thus (jacobianOnly == false) falls
29 /// back on using the full vrep provided inverse kinematics calculation which is
30 /// slower but didn't have the previously seen irregularities. The jacobianOnly option
31 /// should be eliminated in favor of the simComputeJacobian (jacobianOnly == true) case
32 /// once all issues are fully resolved.
33 ///
34 /// @return jacobian in ColumnMajor format where each row is a joint from base to tip, first 3 columns are translation component, last 3 columns are rotation component
35 Eigen::MatrixXf getJacobian(vrep::VrepRobotArmDriver& driver, bool jacobianOnly = false)
36 {
37 
38  // Initialize Variables for update
39  auto jointHandles_ = driver.getJointHandles();
40  int numJoints =jointHandles_.size();
41  std::vector<float> ikCalculatedJointValues(numJoints,0);
42  vrep::VrepRobotArmDriver::State currentArmState_;
43  driver.getState(currentArmState_);
44 
45  /// @todo get target position, probably relative to base
46  const auto& handleParams = driver.getVrepHandleParams();
47  auto ikGroupHandle_ = std::get<vrep::VrepRobotArmDriver::RobotIkGroup>(handleParams);
48 
49  if (jacobianOnly)
50  {
51  // http://www.coppeliarobotics.com/helpFiles/en/apiFunctions.htm#simComputeJacobian
52  auto jacobianResult = simComputeJacobian(ikGroupHandle_,NULL,NULL);
53 
54  if(jacobianResult == -1)
55  {
56  BOOST_LOG_TRIVIAL(error) << "VrepInverseKinematicsController: couldn't compute Jacobian";
57  return Eigen::MatrixXf();
58  }
59 
60  }
61  else
62  {
63 
64  auto target = std::get<vrep::VrepRobotArmDriver::RobotTargetName>(handleParams);
65  auto tip = std::get<vrep::VrepRobotArmDriver::RobotTipName>(handleParams);
66  // save the current tip to target transform
67  Eigen::Affine3d tipToTarget =getObjectTransform( target,tip);
68 
69  // set the current transform to the identity so simCheckIkGroup won't fail
70  // @see http://www.forum.coppeliarobotics.com/viewtopic.php?f=9&t=3967
71  // for details about this issue.
72  setObjectTransform( target,tip,Eigen::Affine3d::Identity());
73 
74  // debug:
75  // std::cout << "TipToTargetTransform:\n" << tipToTarget.matrix() << "\n";
76 
77  /// Run inverse kinematics, but all we really want is the jacobian
78  /// @see http://www.coppeliarobotics.com/helpFiles/en/apiFunctions.htm#simCheckIkGroup
79  auto ikcalcResult =
80  simCheckIkGroup(ikGroupHandle_
81  ,numJoints
82  ,&jointHandles_[0]
83  ,&ikCalculatedJointValues[0]
84  ,NULL /// @todo do we need to use these options?
85  );
86  /// @see http://www.coppeliarobotics.com/helpFiles/en/apiConstants.htm#ikCalculationResults
87  if(ikcalcResult!=sim_ikresult_success && ikcalcResult != sim_ikresult_not_performed)
88  {
89  BOOST_LOG_TRIVIAL(error) << "VrepInverseKinematicsController: didn't run inverse kinematics";
90  return Eigen::MatrixXf();
91  }
92 
93 
94  setObjectTransform( target,tip,tipToTarget);
95  }
96 
97  // debug verifying that get and set object transform don't corrupt underlying data
98 // Eigen::Affine3d tipToTarget2 =getObjectTransform( target,tip);
99 // std::cout << "\ntiptotarget\n" << tipToTarget.matrix();
100 // std::cout << "\ntiptotarget2\n" << tipToTarget2.matrix();
101 
102  // Get the Jacobian
103  int jacobianSize[2];
104  float* jacobian=simGetIkGroupMatrix(ikGroupHandle_,0,jacobianSize);
105  /// @todo FIX HACK jacobianSize include orientation component, should be 7x6 instead of 7x3
106 
107 #ifdef IGNORE_ROTATION
108  jacobianSize[1] = 3;
109 #endif
110 
111 
112 
113  // Transfer the Jacobian to cisst
114 
115  // jacobianSize[1] represents the row count of the Jacobian
116  // (i.e. the number of equations or the number of joints involved
117  // in the IK resolution of the given kinematic chain)
118  // Joints appear from tip to base.
119 
120  // jacobianSize[0] represents the column count of the Jacobian
121  // (i.e. the number of constraints, e.g. x,y,z,alpha,beta,gamma,jointDependency)
122 
123  // The Jacobian data is in RowMajor order, i.e.:
124  // https://en.wikipedia.org/wiki/Row-major_order
125 
126  std::string str;
127 
128  // jacobianSize[1] == eigen ColMajor "rows" , jacobianSize[0] == eigen ColMajor "cols"
129 
130  Eigen::Map<Eigen::Matrix<float,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> > mtestjacobian(jacobian,jacobianSize[1],jacobianSize[0]);
131  Eigen::MatrixXf eigentestJacobian = mtestjacobian.rowwise().reverse().transpose();
132 
133  return eigentestJacobian;
134 }
135 
136 
137 
138 
139 
140 
141 }} // grl::vrep
142 
143 #endif // _GRL_VREP_ROBOT_ARM_JACOBIAN_HPP_
ptrSimGetIkGroupMatrix simGetIkGroupMatrix
Definition: v_repLib.cpp:381
C++ interface for any open chain V-REP robot arm.
ptrSimComputeJacobian simComputeJacobian
Definition: v_repLib.cpp:427
Eigen::Affine3d getObjectTransform(int objectHandle, int relativeToObjectHandle=-1)
Definition: Eigen.hpp:135
Eigen::MatrixXf getJacobian(vrep::VrepRobotArmDriver &driver, bool jacobianOnly=false)
get the Jacobian as calculated by vrep in an Eigen::MatrixXf in column major format ...
const VrepHandleParams & getVrepHandleParams()
ptrSimCheckIkGroup simCheckIkGroup
Definition: v_repLib.cpp:135
void setObjectTransform(int objectHandle, int relativeToObjectHandle, T &transform)
Definition: Eigen.hpp:117
const std::vector< int > & getJointHandles()
std::tuple< JointScalar, JointScalar, JointScalar, JointScalar, JointScalar, TransformationMatrices, JointStateTag, JointScalar > State